+sub thread_html {
+ my ($ctx) = @_;
+ my $mid = $ctx->{mid};
+ my $srch = $ctx->{srch};
+ my $sres = $srch->get_thread($mid);
+ my $msgs = load_results($srch, $sres);
+ my $nr = $sres->{total};
+ return missing_thread($ctx) if $nr == 0;
+ my $skel = '<hr><pre>';
+ $skel .= $nr == 1 ? 'only message in thread' : 'end of thread';
+ $skel .= ", back to <a\nhref=\"../../\">index</a>\n\n";
+ $skel .= "<b\nid=t>Thread overview:</b> ";
+ $skel .= $nr == 1 ? '(only message)' : "$nr+ messages";
+ $skel .= " (download: <a\nhref=\"../t.mbox.gz\">mbox.gz</a>";
+ $skel .= " / follow: <a\nhref=\"../t.atom\">Atom feed</a>)\n";
+ $skel .= "-- links below jump to the message on this page --\n";
+ $ctx->{-upfx} = '../../';
+ $ctx->{cur_level} = 0;
+ $ctx->{dst} = \$skel;
+ $ctx->{prev_attr} = '';
+ $ctx->{prev_level} = 0;
+ $ctx->{root_anchor} = anchor_for($mid);
+ $ctx->{mapping} = {};
+ $ctx->{s_nr} = "$nr+ messages in thread";
+
+ my $rootset = thread_results($msgs, $srch);
+
+ # reduce hash lookups in pre_thread->skel_dump
+ my $inbox = $ctx->{-inbox};
+ $ctx->{-obfs_ibx} = $inbox->{obfuscate} ? $inbox : undef;
+ walk_thread($rootset, $ctx, *pre_thread);
+
+ $skel .= '</pre>';
+ return stream_thread($rootset, $ctx) unless $ctx->{flat};
+
+ # flat display: lazy load the full message from smsg
+ my $mime;
+ while ($mime = shift @$msgs) {
+ $mime = $inbox->msg_by_smsg($mime) and last;
+ }
+ return missing_thread($ctx) unless $mime;
+ $mime = PublicInbox::MIME->new($mime);
+ $ctx->{-title_html} = ascii_html($mime->header('Subject'));
+ $ctx->{-html_tip} = '<pre>'.index_entry($mime, $ctx, scalar @$msgs);
+ $mime = undef;
+ PublicInbox::WwwStream->response($ctx, 200, sub {
+ return unless $msgs;
+ while ($mime = shift @$msgs) {
+ $mime = $inbox->msg_by_smsg($mime) and last;
+ }
+ if ($mime) {
+ $mime = PublicInbox::MIME->new($mime);
+ return index_entry($mime, $ctx, scalar @$msgs);
+ }
+ $msgs = undef;
+ $skel;
+ });