+# children are chronological
+sub simple_sort_children {
+ sort {
+ (eval { $a->topmost->message->header('X-PI-TS') } || 0) <=>
+ (eval { $b->topmost->message->header('X-PI-TS') } || 0)
+ } @_;
+}
+
+sub simple_dump {
+ my ($dst, $root, $node, $level) = @_;
+ $$dst .= ' ' x $level;
+ if (my $x = $node->message) {
+ my $mid = $x->header('Message-ID');
+ if ($root->[0] ne $mid) {
+ my $s = clean_subj($x->header('Subject'));
+ if ($root->[1] eq $s) {
+ $s = ' ';
+ } else {
+ $s = PublicInbox::Hval->new($s);
+ $s = $s->as_html . ' ';
+ }
+ my $m = PublicInbox::Hval->new_msgid($mid);
+ my $f = PublicInbox::Hval->new($x->header('X-PI-From'));
+ my $d = PublicInbox::Hval->new($x->header('X-PI-Date'));
+ $m = $m->as_href . '.html';
+ $f = $f->as_html;
+ $d = $d->as_html;
+ $$dst .= "` <a\nhref=\"$m\">$s$f @ $d UTC</a>\n";
+ }
+ }
+ simple_dump($dst, $root, $node->child, $level + 1) if $node->child;
+ simple_dump($dst, $root, $node->next, $level) if $node->next;
+}
+
+sub clean_subj {
+ my ($subj) = @_;
+ $subj =~ s/\A\s+//;
+ $subj =~ s/\s+\z//;
+ $subj =~ s/^(?:re|aw):\s*//i; # remove reply prefix (aw: German)
+ $subj =~ s/\s+/ /;
+ $subj;
+}
+
+sub thread_replies {
+ my ($dst, $root, $res) = @_;
+ my @msgs = map { $_->mini_mime } @{$res->{msgs}};
+ require PublicInbox::Thread;
+ $root->header_set('X-PI-TS', '0');
+ my $th = PublicInbox::Thread->new($root, @msgs);
+ $th->thread;
+ $th->order(sub { simple_sort_children(@_) });
+ $root = [ $root->header('Message-ID'),
+ clean_subj($root->header('Subject')) ];
+ simple_dump($dst, $root, $_, 0) for $th->rootset;
+}
+