Committer: dnikolaev
LJSUP-6869 sub LJ::Talk::get_thread_html createdU trunk/bin/upgrading/en.dat U trunk/cgi-bin/LJ/Talk.pm U trunk/htdocs/talkread.bml U trunk/htdocs/tools/endpoints/get_thread.bml
Modified: trunk/bin/upgrading/en.dat =================================================================== --- trunk/bin/upgrading/en.dat 2010-10-11 08:45:37 UTC (rev 17533) +++ trunk/bin/upgrading/en.dat 2010-10-11 09:00:59 UTC (rev 17534) @@ -4401,6 +4401,8 @@ talk.btn.preview=Preview +talk.collapselink=Collapse + talk.commentpermlink=link talk.commentpost=Post a new comment Modified: trunk/cgi-bin/LJ/Talk.pm =================================================================== --- trunk/cgi-bin/LJ/Talk.pm 2010-10-11 08:45:37 UTC (rev 17533) +++ trunk/cgi-bin/LJ/Talk.pm 2010-10-11 09:00:59 UTC (rev 17534) @@ -2109,4 +2109,446 @@ return $count; } +sub get_thread_html +{ + my ($u, $up, $entry, $thread, $input, $output) = @_; + + my $remote = LJ::get_remote(); + + my $tz_remote; + my $s2_ctx = []; # ghetto fake S2 context object + if ($remote) { + my $tz = $remote->prop("timezone"); + $tz_remote = $tz ? eval { DateTime::TimeZone->new(name => $tz); } : undef; + } + + my $viewsome = $input->{viewsome}; + my $viewall = $input->{viewall}; + + my $view_arg = $input->{view} || ""; + my $flat_mode = ($view_arg =~ /\bflat\b/); + my $view_num = ($view_arg =~ /(\d+)/) ? $1 : undef; + + my %user; + my %userpics; + + my $opts = { + flat => $flat_mode, + thread => $thread, + page => $input->{page}, + view => $view_num, + userpicref => \%userpics, + userref => \%user, + up => $up, + viewall => $viewall, + }; + + ## Expand all comments on page + unless ($LJ::DISABLED{allow_expand_all_comments}) { + $opts->{expand_all} = 1 if $input->{expand} eq 'all'; + } + + ## allow to modify strategies to load/expand comments tree. + LJ::run_hooks('load_comments_opts', $u, $entry->jitemid, $opts); + + my @comments = LJ::Talk::load_comments($u, $remote, "L", $entry->jitemid, $opts); + + if ($opts->{'out_error'} eq "nodb") + { + $output->{error} = BML::ml('error.nodbmaintenance'); + return undef; + } + + $output->{page} = $opts->{out_page}; + $output->{pages} = $opts->{out_pages}; + + ################################################## + + my $LJ_cmtinfo = $input->{LJ_cmtinfo}; + + my $formatlight = $input->{'format'} eq 'light' ? 'format=light' : ''; + my $stylemine = $input->{'style'} eq "mine" ? "style=mine" : ""; + + my ($last_talkid, $last_jid) = LJ::get_lastcomment(); + + my $fmt_time_short = "%%hh%%:%%min%% %%a%%m"; + my $jarg = "journal=$u->{'user'}&"; + my $jargent ="journal=$u->{'user'}&"; + my $show_thread_expander = LJ::run_hook('show_thread_expander'); + my $allow_commenting = $entry->posting_comments_allowed; + my $pics = LJ::Talk::get_subjecticons(); + my $talkurl = LJ::journal_base($u) . "/" . $entry->ditemid() . ".html"; + my $showmultiform = $input->{showmultiform}; + my $anum = $entry->anum(); + + my $comments = []; + + my $recurse_post = sub { + + my ($self, $post, $depth) = @_; + $depth ||= 0; + + my $tid = $post->{'talkid'}; + my $dtid = $tid * 256 + $anum; + my $LJci = $LJ_cmtinfo->{$dtid} = { rc => [], u => '', full => $post->{_loaded} }; + + my $s2_datetime = $tz_remote ? + LJ::S2::DateTime_tz($post->{'datepost_unix'}, $tz_remote) : + LJ::S2::DateTime_unix($post->{'datepost_unix'}); + + my $datepost = S2::Builtin::LJ::Date__date_format($s2_ctx, $s2_datetime, "iso") . " " . + S2::Builtin::LJ::DateTime__time_format($s2_ctx, $s2_datetime, $fmt_time_short) . + ($tz_remote ? " (local)" : " UTC"); + + my $bgcolor = ($depth % 2) ? "emcolorlite" : "emcolor"; + $bgcolor = BML::get_template_def($bgcolor); + if ($post->{'state'} eq "S") { + $bgcolor = BML::get_template_def("screenedbarcolor") || $bgcolor; + } elsif ($last_talkid == $dtid && $last_jid == $u->{'userid'}) { + $bgcolor = BML::get_template_def("altcolor1"); + } + + my $pu = $post->{'posterid'} ? $user{$post->{'posterid'}} : undef; + $LJci->{u} = $pu->{$pu->{journaltype} eq 'I' ? 'name' : 'user'} if $pu; + $LJci->{username} = $pu->{'user'} if $pu; + + my $userpost = $post->{'userpost'}; + my $upost = $post->{'upost'}; + + my $user; + if ($post->{'props'}->{'deleted_poster'}) { + $user = BML::ml('.deleteduser', { username => $post->{'deleted_poster'} }); + } else { + $user = BML::ml('.anonuser'); + } + + my $comment_header = sub { + my $table_style = shift || ''; + $table_style = ' ' . $table_style if $table_style; + + my $width = $depth * 25; + + return "<a name='t$dtid'></a><div id='ljcmt$dtid'><table$table_style><tr>" . + "<td><img src='$LJ::IMGPREFIX/dot.gif' height='1' width='$width'></td>" . + "<td id='ljcmtxt$dtid' width='100%'>"; + }; + + my $comment_footer = sub { + return "</td></tr></table></div>\n"; + }; + + my $html = {}; + + if ($post->{'state'} eq "D") ## LJSUP-6433 + { + $html->{header} = $comment_header->(); + $html->{text} = BML::ml('.deletepost'); + $html->{footer} = $comment_footer->(); + } + elsif ($post->{'state'} eq "S" && !$post->{'_loaded'} && !$post->{'_show'}) + { + $html->{header} = $comment_header->(); + $html->{text} = BML::ml('.screenedpost'); + $html->{footer} = $comment_footer->(); + } + elsif ($pu && $pu->is_suspended && !$viewsome) + { + $html->{header} = $comment_header->(); + $html->{footer} = $comment_footer->(); + + my $text = BML::ml('.replysuspended'); + if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) { + $text .= " <a href='$LJ::SITEROOT/delcomment.bml?${jargent}id=$dtid'>" . + LJ::img("btn_del", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . + "</a>"; + } + if ($post->{state} ne 'F' && LJ::Talk::can_freeze($remote, $u, $up, $userpost)) { + $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&${jargent}talkid=$dtid'>" . + LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . + "</a>"; + } + if ($post->{state} eq 'F' && LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) { + $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&${jargent}talkid=$dtid'>" . + LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . + "</a>"; + } + + $html->{text} = $text; + } + else + { + $user = LJ::ljuser($upost, { side_alias => 1 }) if $upost; + + my $icon = LJ::Talk::show_image($pics, $post->{'props'}->{'subjecticon'}); + + if ($post->{'_loaded'}) + { + my $comment = LJ::Comment->new($u, dtalkid => $dtid); + + my $edittime; + if ($comment->is_edited) + { + my $s2_datetime_edittime = $tz_remote ? + LJ::S2::DateTime_tz($comment->edit_time, $tz_remote) : + LJ::S2::DateTime_unix($comment->edit_time); + + $edittime = S2::Builtin::LJ::Date__date_format($s2_ctx, $s2_datetime_edittime, "iso") . " " . + S2::Builtin::LJ::DateTime__time_format($s2_ctx, $s2_datetime_edittime, $fmt_time_short) . + ($tz_remote ? " (local)" : " UTC"); + } + + $html->{header} = $comment_header->("width='100%' class='talk-comment'"); + $html->{footer} = $comment_footer->(); + + my $text = "<div id='cmtbar$dtid' style='background-color:$bgcolor'>"; + + if (my $picid = $post->{'picid'}) { + my $alt = $pu->{'name'}; + if ($post->{'props'}->{'picture_keyword'}) { + $alt .= ": $post->{'props'}->{'picture_keyword'}"; + } + $alt = LJ::ehtml($alt); + my ($w, $h) = ($userpics{$picid}->{'width'}, $userpics{$picid}->{'height'}); + $text .= "<img align='left' hspace='3' src='$LJ::USERPIC_ROOT/$picid/$post->{'posterid'}'"; + $text .= " width='$w' title='$alt' alt='' height='$h' />"; + } + + my $cleansubject = LJ::ehtml($post->{'subject'}); + $text .= "<font size='+1' face='Arial,Helvetica'><b>$cleansubject</b></font> $icon"; + $text .= "<br />$user\n"; + $text .= "<br /><font size='-1'>$datepost</font>\n"; + if ($post->{'props'}->{'poster_ip'} && + $remote && ($remote->{'user'} eq $up->{'user'} || LJ::can_manage($remote, $u) || $viewall)) + { + $text .= BML::ml('.fromip', { 'ip' => $post->{'props'}->{'poster_ip'} }); + } + + $text .= " <font size='-1'>(<a href='" . + LJ::Talk::talkargs($talkurl, "thread=$dtid", $formatlight) . + "#t$dtid'>" . + BML::ml('talk.commentpermlink') . "</a>)</font> "; + + if ($comment->remote_can_edit) { + $text .= "<a href='" . + LJ::Talk::talkargs($comment->edit_url, $stylemine, $formatlight) . + "'>" . + LJ::img("editcomment", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>"; + } + + if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) { + $text .= "<a href='$LJ::SITEROOT/delcomment.bml?${jargent}id=$dtid'>" . + LJ::img("btn_del", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . + "</a>"; + } + + if ($post->{'state'} ne 'F' && LJ::Talk::can_freeze($remote, $u, $up, $userpost)) { + $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&${jargent}talkid=$dtid'>" . + LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . + "</a>"; + } + + if ($post->{'state'} eq 'F' && LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) { + $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&${jargent}talkid=$dtid'>" . + LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . + "</a>"; + } + + if ($post->{'state'} ne 'S' && LJ::Talk::can_screen($remote, $u, $up, $userpost)) { + $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=screen&${jargent}talkid=$dtid'>" . + LJ::img("btn_scr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . + "</a>"; + } + + if ($post->{'state'} eq 'S' && LJ::Talk::can_unscreen($remote, $u, $up, $userpost)) { + $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unscreen&${jargent}talkid=$dtid'>" . + LJ::img("btn_unscr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . + "</a>"; + } + + if ($remote && $remote->can_use_esn) { + my $track_img = 'track'; + + my $comment_watched = $remote->has_subscription( + event => "JournalNewComment", + journal => $u, + arg2 => $comment->jtalkid, + require_active => 1, + ); + + if ($comment_watched) { + $track_img = 'track_active'; + } else { + # see if any parents are being watched + while ($comment && $comment->valid && $comment->parenttalkid) + { + # check cache + $comment->{_watchedby} ||= {}; + my $thread_watched = $comment->{_watchedby}->{$u->{userid}}; + + # not cached + if (!defined $thread_watched) + { + $thread_watched = $remote->has_subscription( + event => "JournalNewComment", + journal => $u, + arg2 => $comment->parenttalkid, + require_active => 1, + ); + } + + $track_img = 'track_thread_active' if ($thread_watched); + + # cache in this comment object if it's being watched by this user + $comment->{_watchedby}->{$u->{userid}} = $thread_watched; + + $comment = $comment->parent; + } + } + + my $track_url = "$LJ::SITEROOT/manage/subscriptions/comments.bml?journal=$u->{'user'}&talkid=$dtid"; + $text .= "<a href='$track_url'>" . LJ::img($track_img, '', {'align' => 'absmiddle'}) . "</a>"; + } + + if ($showmultiform) { + $text .= " <nobr><input type='checkbox' name='selected_$tid' id='s$tid' />"; + $text .= " <label for='s$tid'>" . BML::ml('.select') . "</label></nobr>"; + $output->{multiform_selects} = 1; + } + + # Comment Posted Notice + $text .= "<br /><b>" . BML::ml('.posted') . "</b>" + if $last_talkid == $dtid && $last_jid == $u->{'userid'}; + + $text .= "</div><div class='talk-comment-box'>"; + + LJ::CleanHTML::clean_comment( + \$post->{'body'}, + { + preformatted => $post->{'props'}->{'opt_preformatted'}, + anon_comment => (!$pu || $pu->{'journaltype'} eq 'I'), + nocss => 1, + } + ); + + BML::ebml(\$post->{'body'}); + my $event = $post->{'body'}; + + if ($input->{nohtml}) + { + # quote all non-LJ tags + $event =~ s{<(?!/?lj)(.*?)>} {<$1>}gi; + } + + my $edit_html = $edittime + ? "<br /><br /><span class='ljedittime'><em>" . + BML::ml('.edittime', { edittime => $edittime }) . + "</em></span>" + : ""; + + $text .= "$event$edit_html"; + + $text .= "<p style='margin: 0.7em 0 0.2em 0'><font size='-2'>"; + + if ($allow_commenting) + { + my $replyurl = LJ::Talk::talkargs($talkurl, "replyto=$dtid", $stylemine, $formatlight); + if ($post->{'state'} eq 'F') { + $text .= "(" . BML::ml('talk.frozen') . ")"; + } + elsif ($remote) { + # See if we want to force them to change their password + my $bp = LJ::bad_password_redirect({ 'returl' => 1 }); + if ($bp) { + $text .= "(<a href='$bp'>" . BML::ml('talk.replytothis') . "</a>) "; + } + else { + if ($post->{state} eq 'S') { + # show unscreen to reply link id comment screened + $text .= "(<a href='$LJ::SITEROOT/talkscreen.bml?mode=unscreen&${jargent}talkid=$dtid'>" . BML::ml('talk.unscreentoreply') . "</a>) "; + } + else { + $text .= "(" . LJ::make_qr_link($dtid, $post->{'subject'}, BML::ml('talk.replytothis'), $replyurl) . ") "; + } + } + } + else { + $text .= "(<a href='$replyurl'>" . BML::ml('talk.replytothis') . "</a>) "; + } + } + + my $parentid = $post->{'parenttalkid'} || $post->{'parenttalkid_actual'}; + if ($parentid != 0) { + my $dpid = $parentid * 256 + $anum; + $text .= "(<a href='" . LJ::Talk::talkargs($talkurl, "thread=$dpid", $stylemine, $formatlight) . "#t$dpid'>" . BML::ml('talk.parentlink') . "</a>)"; + } + + my $has_expandlink = 0; + if ($post->{'children'} && @{$post->{'children'}}) { + my $url = LJ::Talk::talkargs($talkurl, "thread=$dtid", $stylemine, $formatlight) . "#t$dtid"; + $text .= "(<a href='$url'>" . BML::ml('talk.threadlink') . "</a>)"; + + if ($show_thread_expander && + (grep {! $_->{_loaded} and !($_->{state} eq "D")} @{$post->{'children'}})) { + $text .= "(<a href='$url' " . + qq[onClick="Expander.make(this,'$url','$dtid',true);return false;"] . + ">" . BML::ml('talk.expandlink') . "</a>)"; + $has_expandlink = 1; + } + } + + if ($show_thread_expander && + !$has_expandlink && + $input->{show_collapselink}) + { + my $url = LJ::Talk::talkargs($talkurl, "thread=$dtid", $stylemine, $formatlight) . "#t$dtid"; + $text .= "(<a href='$url' " . + qq[onClick="Expander.collapse(this,'$url','$dtid',true);return false;"] . + ">" . BML::ml('talk.collapselink') . "</a>)"; + } + + $text .= "</font></p>"; + $text .= LJ::make_qr_target($dtid) if $remote; + $text .= "</div>"; + + $html->{text} = $text; + } + else { + # link to message + + $html->{header} = $comment_header->(); + $html->{footer} = $comment_footer->(); + + my $text = "<a href='" . LJ::Talk::talkargs($talkurl, "thread=$dtid", $stylemine, $formatlight) . "#t$dtid'>" . LJ::ehtml($post->{'subject'} || BML::ml('.nosubject')) . "</a> - $user, <i>$datepost</i>"; + my $url = LJ::Talk::talkargs($talkurl, "thread=$dtid", $stylemine, $formatlight) . "#t$dtid"; + $text .= " (<a href='$url' " . + qq[onClick="Expander.make(this,'$url','$dtid',true);return false;"] . + ">" . BML::ml('talk.expandlink') . "</a>)" if $show_thread_expander; + + # Comment Posted Notice + $text .= " - <b>" . BML::ml('.posted') . "</b>" + if $last_talkid == $dtid && $last_jid == $u->{'userid'}; + + $html->{text} = $text; + } + } + + push @$comments, { + thread => $dtid, + depth => $depth, + html => $html, + }; + + if ($post->{'children'}) { + foreach my $childpost (@{$post->{'children'}}) { + push @{$LJci->{rc}}, $childpost->{talkid} * 256 + $anum; + $self->($self, $childpost, $depth + 1); + } + } + }; + + $recurse_post->($recurse_post, $_, 0) foreach @comments; + + return $comments; +} + 1; Modified: trunk/htdocs/talkread.bml =================================================================== --- trunk/htdocs/talkread.bml 2010-10-11 08:45:37 UTC (rev 17533) +++ trunk/htdocs/talkread.bml 2010-10-11 09:00:59 UTC (rev 17534) @@ -3,464 +3,13 @@ <?_code use strict; - - sub A - { - my ($u, $up, $entry, $thread, $get, $output) = @_; - - my $remote = LJ::get_remote(); - - my $tz_remote; - my $s2_ctx = []; # ghetto fake S2 context object - if ($remote) { - my $tz = $remote->prop("timezone"); - $tz_remote = $tz ? eval { DateTime::TimeZone->new( name => $tz); } : undef; - } - - my $viewsome = $get->{viewsome}; - my $viewall = $get->{viewall}; - - my %user; - my %userpics; - - my $view_arg = $get->{view} || ""; - my $flat_mode = ($view_arg =~ /\bflat\b/); - my $view_num = ($view_arg =~ /(\d+)/) ? $1 : undef; - - my $opts = { - flat => $flat_mode, - thread => $thread, - page => $get->{page}, - view => $view_num, - userpicref => \%userpics, - userref => \%user, - up => $up, - viewall => $viewall, - }; - - ## Expand all comments on page - unless ($LJ::DISABLED{allow_expand_all_comments}) { - $opts->{expand_all} = 1 if $get->{expand} eq 'all'; - } - - ## allow to modify strategies to load/expand comments tree. - LJ::run_hooks('load_comments_opts', $u, $entry->jitemid, $opts); - - my @comments = LJ::Talk::load_comments($u, $remote, "L", $entry->jitemid, $opts); - - return $ML{'error.nodbmaintenance'} if $opts->{'out_error'} eq "nodb"; - - $output->{page} = $opts->{out_page}; - $output->{pages} = $opts->{out_pages}; - - ################################################## - - my $LJ_cmtinfo = $get->{LJ_cmtinfo}; - - my $formatlight = $get->{'format'} eq 'light' ? 'format=light' : ''; - my $stylemine = $get->{'style'} eq "mine" ? "style=mine" : ""; - - my ($last_talkid, $last_jid) = LJ::get_lastcomment(); - - my $fmt_time_short = "%%hh%%:%%min%% %%a%%m"; - my $jarg = "journal=$u->{'user'}&"; - my $jargent ="journal=$u->{'user'}&"; - my $show_thread_expander = LJ::run_hook('show_thread_expander'); - my $allow_commenting = $entry->posting_comments_allowed; - my $pics = LJ::Talk::get_subjecticons(); - my $talkurl = LJ::journal_base($u) . "/" . $entry->ditemid() . ".html"; - my $showmultiform = $get->{showmultiform}; - my $multiform_selects_ref = $get->{multiform_selects}, - my $anum = $entry->anum(); - - my $comments = []; - - my $recurse_post = sub { - - my ($self, $post, $depth) = @_; - - $depth ||= 0; - - my $tid = $post->{'talkid'}; - my $dtid = $tid * 256 + $anum; - my $LJci = $LJ_cmtinfo->{$dtid} = { rc => [], u => '', full => $post->{_loaded} }; - - my $s2_datetime = $tz_remote ? - LJ::S2::DateTime_tz($post->{'datepost_unix'}, $tz_remote) : - LJ::S2::DateTime_unix($post->{'datepost_unix'}); - - my $datepost = S2::Builtin::LJ::Date__date_format($s2_ctx, $s2_datetime, "iso") . " " . - S2::Builtin::LJ::DateTime__time_format($s2_ctx, $s2_datetime, $fmt_time_short) . - ($tz_remote ? " (local)" : " UTC"); - - my $bgcolor = ($depth % 2) ? "emcolorlite" : "emcolor"; - $bgcolor = BML::get_template_def($bgcolor); - if ($post->{'state'} eq "S") { - $bgcolor = BML::get_template_def("screenedbarcolor") || $bgcolor; - } elsif ($last_talkid == $dtid && $last_jid == $u->{'userid'}) { - $bgcolor = BML::get_template_def("altcolor1"); - } - - my $pu = $post->{'posterid'} ? $user{$post->{'posterid'}} : undef; - $LJci->{u} = $pu->{$pu->{journaltype} eq 'I' ? 'name' : 'user'} if $pu; - $LJci->{username} = $pu->{'user'} if $pu; - - my $userpost = $post->{'userpost'}; - my $upost = $post->{'upost'}; - - my $user; - if ($post->{'props'}->{'deleted_poster'}) { - $user = BML::ml('.deleteduser', { username => $post->{'deleted_poster'} }); - } else { - $user = $ML{'.anonuser'}; - } - - my $comment_header = sub { - my $table_style = shift || ''; - $table_style = ' ' . $table_style if $table_style; - - my $width = $depth * 25; - - return "<a name='t$dtid'></a><div id='ljcmt$dtid'><table$table_style><tr>" . - "<td><img src='$LJ::IMGPREFIX/dot.gif' height='1' width='$width'></td>" . - "<td id='ljcmtxt$dtid' width='100%'>"; - }; - - my $comment_footer = sub { - return "</td></tr></table></div>\n"; - }; - - my $html = {}; - - if ($post->{'state'} eq "D") ## LJSUP-6433 - { - $html->{header} = $comment_header->(); - $html->{text} = $ML{'.deletepost'}; - $html->{footer} = $comment_footer->(); - } - elsif ($post->{'state'} eq "S" && !$post->{'_loaded'} && !$post->{'_show'}) - { - $html->{header} = $comment_header->(); - $html->{text} = $ML{'.screenedpost'}; - $html->{footer} = $comment_footer->(); - } - elsif ($pu && $pu->is_suspended && !$viewsome) - { - $html->{header} = $comment_header->(); - $html->{footer} = $comment_footer->(); - - my $text = $ML{'.replysuspended'}; - if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) - { - $text .= " <a href='$LJ::SITEROOT/delcomment.bml?${jargent}id=$dtid'>" . - LJ::img("btn_del", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . - "</a>"; - } - if ($post->{state} ne 'F' && LJ::Talk::can_freeze($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&${jargent}talkid=$dtid'>" . - LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . - "</a>"; - } - if ($post->{state} eq 'F' && LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&${jargent}talkid=$dtid'>" . - LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . - "</a>"; - } - - $html->{text} = $text; - } - else - { - $user = LJ::ljuser($upost, { side_alias => 1 }) if $upost; - - my $icon = LJ::Talk::show_image($pics, $post->{'props'}->{'subjecticon'}); - - if ($post->{'_loaded'}) - { - my $comment = LJ::Comment->new($u, dtalkid => $dtid); - - my $edittime; - if ($comment->is_edited) - { - my $s2_datetime_edittime = $tz_remote ? - LJ::S2::DateTime_tz($comment->edit_time, $tz_remote) : - LJ::S2::DateTime_unix($comment->edit_time); - - $edittime = S2::Builtin::LJ::Date__date_format($s2_ctx, $s2_datetime_edittime, "iso") . " " . - S2::Builtin::LJ::DateTime__time_format($s2_ctx, $s2_datetime_edittime, $fmt_time_short) . - ($tz_remote ? " (local)" : " UTC"); - } - - # <table...><tbody><tr>... - $html->{header} = $comment_header->("width='100%' class='talk-comment'"); - $html->{footer} = $comment_footer->(); - - my $text = "<div id='cmtbar$dtid' style='background-color:$bgcolor'>"; - - if (my $picid = $post->{'picid'}) { - my $alt = $pu->{'name'}; - if ($post->{'props'}->{'picture_keyword'}) { - $alt .= ": $post->{'props'}->{'picture_keyword'}"; - } - $alt = LJ::ehtml($alt); - my ($w, $h) = ($userpics{$picid}->{'width'}, $userpics{$picid}->{'height'}); - $text .= "<img align='left' hspace='3' src='$LJ::USERPIC_ROOT/$picid/$post->{'posterid'}'"; - $text .= " width='$w' title='$alt' alt='' height='$h' />"; - } - - my $cleansubject = LJ::ehtml($post->{'subject'}); - $text .= "<font size='+1' face='Arial,Helvetica'><b>$cleansubject</b></font> $icon"; - $text .= "<br />$user\n"; - $text .= "<br /><font size='-1'>$datepost</font>\n"; - if ($post->{'props'}->{'poster_ip'} && - $remote && ($remote->{'user'} eq $up->{'user'} || LJ::can_manage($remote, $u) || $viewall)) - { - $text .= BML::ml('.fromip', { 'ip' => $post->{'props'}->{'poster_ip'} }); - } - - $text .= " <font size='-1'>(<a href='" . - LJ::Talk::talkargs($talkurl, "thread=$dtid", $formatlight) . - "#t$dtid'>" . - BML::ml('talk.commentpermlink') . "</a>)</font> "; - - if ($comment->remote_can_edit) { - $text .= "<a href='" . - LJ::Talk::talkargs($comment->edit_url, $stylemine, $formatlight) . - "'>" . - LJ::img("editcomment", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>"; - } - - if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/delcomment.bml?${jargent}id=$dtid'>" . - LJ::img("btn_del", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . - "</a>"; - } - - if ($post->{'state'} ne 'F' && LJ::Talk::can_freeze($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&${jargent}talkid=$dtid'>" . - LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . - "</a>"; - } - - if ($post->{'state'} eq 'F' && LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&${jargent}talkid=$dtid'>" . - LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . - "</a>"; - } - if ($post->{'state'} ne 'S' && LJ::Talk::can_screen($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=screen&${jargent}talkid=$dtid'>" . - LJ::img("btn_scr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . - "</a>"; - } - - if ($post->{'state'} eq 'S' && LJ::Talk::can_unscreen($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unscreen&${jargent}talkid=$dtid'>" . - LJ::img("btn_unscr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . - "</a>"; - } - - if ($remote && $remote->can_use_esn) - { - my $track_img = 'track'; - - my $comment_watched = $remote->has_subscription( - event => "JournalNewComment", - journal => $u, - arg2 => $comment->jtalkid, - require_active => 1, - ); - - if ($comment_watched) - { - $track_img = 'track_active'; - } - else - { - # see if any parents are being watched - while ($comment && $comment->valid && $comment->parenttalkid) - { - # check cache - $comment->{_watchedby} ||= {}; - my $thread_watched = $comment->{_watchedby}->{$u->{userid}}; - - # not cached - if (!defined $thread_watched) - { - $thread_watched = $remote->has_subscription( - event => "JournalNewComment", - journal => $u, - arg2 => $comment->parenttalkid, - require_active => 1, - ); - } - - $track_img = 'track_thread_active' if ($thread_watched); - - # cache in this comment object if it's being watched by this user - $comment->{_watchedby}->{$u->{userid}} = $thread_watched; - - $comment = $comment->parent; - } - } - - my $track_url = "$LJ::SITEROOT/manage/subscriptions/comments.bml?journal=$u->{'user'}&talkid=$dtid"; - $text .= "<a href='$track_url'>" . LJ::img($track_img, '', {'align' => 'absmiddle'}) . "</a>"; - } - - if ($showmultiform) - { - $text .= " <nobr><input type='checkbox' name='selected_$tid' id='s$tid' />"; - $text .= " <label for='s$tid'>$ML{'.select'}</label></nobr>"; - $$multiform_selects_ref = 1; - } - - # Comment Posted Notice - $text .= "<br /><b>$ML{'.posted'}</b>" - if $last_talkid == $dtid && $last_jid == $u->{'userid'}; - - $text .= "</div><div class='talk-comment-box'>"; - - LJ::CleanHTML::clean_comment( - \$post->{'body'}, - { - preformatted => $post->{'props'}->{'opt_preformatted'}, - anon_comment => (!$pu || $pu->{'journaltype'} eq 'I'), - nocss => 1, - } - ); - - BML::ebml(\$post->{'body'}); - my $event = $post->{'body'}; - - if ($GET{'nohtml'}) - { - # quote all non-LJ tags - $event =~ s{<(?!/?lj)(.*?)>} {<$1>}gi; - } - - my $edit_html = $edittime - ? "<br /><br /><span class='ljedittime'><em>" . - BML::ml('.edittime', { edittime => $edittime }) . - "</em></span>" - : ""; - - $text .= "$event$edit_html"; - - $text .= "<p style='margin: 0.7em 0 0.2em 0'><font size='-2'>"; - - if ($allow_commenting) - { - my $replyurl = LJ::Talk::talkargs($talkurl, "replyto=$dtid", $stylemine, $formatlight); - if ($post->{'state'} eq 'F') - { - $text .= "(" . BML::ml('talk.frozen') . ")"; - } - elsif ($remote) - { - # See if we want to force them to change their password - my $bp = LJ::bad_password_redirect({ 'returl' => 1 }); - if ($bp) - { - $text .= "(<a href='$bp'>" . BML::ml('talk.replytothis') . "</a>) "; - } - else - { - if ($post->{state} eq 'S') - { - # show unscreen to reply link id comment screened - $text .= "(<a href='$LJ::SITEROOT/talkscreen.bml?mode=unscreen&${jargent}talkid=$dtid'>" . BML::ml('talk.unscreentoreply') . "</a>) "; - } - else - { - $text .= "(" . LJ::make_qr_link($dtid, $post->{'subject'}, BML::ml('talk.replytothis'), $replyurl) . ") "; - } - } - } - else - { - $text .= "(<a href='$replyurl'>" . BML::ml('talk.replytothis') . "</a>) "; - } - } - - my $parentid = $post->{'parenttalkid'} || $post->{'parenttalkid_actual'}; - if ($parentid != 0) - { - my $dpid = $parentid * 256 + $anum; - $text .= "(<a href='" . LJ::Talk::talkargs($talkurl, "thread=$dpid", $stylemine, $formatlight) . "#t$dpid'>" . BML::ml('talk.parentlink') . "</a>)"; - } - - if ($post->{'children'} && @{$post->{'children'}}) - { - my $url = LJ::Talk::talkargs($talkurl, "thread=$dtid", $stylemine, $formatlight) . "#t$dtid"; - $text .= "(<a href='$url'>" . BML::ml('talk.threadlink') . "</a>)"; - - if ($show_thread_expander && - (grep {! $_->{_loaded} and !($_->{state} eq "D")} @{$post->{'children'}})) - { - $text .= qq[(<a href='$url' onClick="Expander.make(this,'$url','$dtid',true);return false;">] . - BML::ml('talk.expandlink') . - qq[</a>)]; - } - } - - $text .= "</font></p>"; - $text .= LJ::make_qr_target($dtid) if $remote; - $text .= "</div>"; - - $html->{text} = $text; - } - else - { - # link to message - - $html->{header} = $comment_header->(); - $html->{footer} = $comment_footer->(); - - my $text = "<a href='" . LJ::Talk::talkargs($talkurl, "thread=$dtid", $stylemine, $formatlight) . "#t$dtid'>" . LJ::ehtml($post->{'subject'} || BML::ml('.nosubject')) . "</a> - $user, <i>$datepost</i>"; - my $url = LJ::Talk::talkargs($talkurl, "thread=$dtid", $stylemine, $formatlight) . "#t$dtid"; - $text .= qq[ (<a href='$url' onClick="Expander.make(this,'$url','$dtid',true);return false;">] . BML::ml('talk.expandlink') . qq[</a>)] if $show_thread_expander; - - # Comment Posted Notice - $text .= " - <b>$ML{'.posted'}</b>" - if $last_talkid == $dtid && $last_jid == $u->{'userid'}; - - $html->{text} = $text; - } - } - - push @$comments, { - thread => $dtid, - depth => $depth, - html => $html, - }; - - if ($post->{'children'}) - { - foreach my $childpost (@{$post->{'children'}}) - { - push @{$LJci->{rc}}, $childpost->{talkid} * 256 + $anum; - $self->($self, $childpost, $depth + 1); - } - } - }; - - $recurse_post->($recurse_post, $_, 0) foreach @comments; - - return $comments; - } - use vars qw($r_head $r_title %GET %ML $r_bodyopts); # load package for formatting current music use LJ::LastFM; + use LJ::Talk; + # make refs to both title and head, that work in cached or non-cached contexts # $_[0] is a pre-request scratch area. $r_head = ""; @@ -480,7 +29,6 @@ $GET{'thread'} =~ s/^3D//; } - LJ::Request->notes("codepath" => "bml.talkread"); my $uri = BML::get_uri(); @@ -906,30 +454,30 @@ my $output = {}; - my $comments = A( + my $comments = LJ::Talk::get_thread_html( $u, $up, $entry, $thread, { - page => $GET{page}, - expand => $GET{expand}, - view => $GET{view}, - format => $GET{format}, - style => $init->{style}, - viewsome => $viewsome, - viewall => $viewall, - LJ_cmtinfo => $LJ_cmtinfo, - showmultiform => $showmultiform, - multiform_selects => \$multiform_selects, + page => $GET{page}, + expand => $GET{expand}, + view => $GET{view}, + format => $GET{format}, + style => $init->{style}, + viewsome => $viewsome, + viewall => $viewall, + LJ_cmtinfo => $LJ_cmtinfo, + showmultiform => $showmultiform, }, $output ); - return $comments unless ref $comments; + return $output->{error} if $output->{error}; my $page = $output->{page}; my $pages = $output->{pages}; + $multiform_selects ||= $output->{multiform_selects}; ########## make the navcrap my $navcrap = ''; Modified: trunk/htdocs/tools/endpoints/get_thread.bml =================================================================== --- trunk/htdocs/tools/endpoints/get_thread.bml 2010-10-11 08:45:37 UTC (rev 17533) +++ trunk/htdocs/tools/endpoints/get_thread.bml 2010-10-11 09:00:59 UTC (rev 17534) @@ -1,457 +1,8 @@ <?_code { use strict; + use LJ::Talk; - sub A - { - my ($u, $up, $entry, $thread, $get, $output) = @_; - - my $remote = LJ::get_remote(); - - my $tz_remote; - my $s2_ctx = []; # ghetto fake S2 context object - if ($remote) { - my $tz = $remote->prop("timezone"); - $tz_remote = $tz ? eval { DateTime::TimeZone->new( name => $tz); } : undef; - } - - my $viewsome = $get->{viewsome}; - my $viewall = $get->{viewall}; - - my %user; - my %userpics; - - my $view_arg = $get->{view} || ""; - my $flat_mode = ($view_arg =~ /\bflat\b/); - my $view_num = ($view_arg =~ /(\d+)/) ? $1 : undef; - - my $opts = { - flat => $flat_mode, - thread => $thread, - page => $get->{page}, - view => $view_num, - userpicref => \%userpics, - userref => \%user, - up => $up, - viewall => $viewall, - }; - - ## Expand all comments on page - unless ($LJ::DISABLED{allow_expand_all_comments}) { - $opts->{expand_all} = 1 if $get->{expand} eq 'all'; - } - - ## allow to modify strategies to load/expand comments tree. - LJ::run_hooks('load_comments_opts', $u, $entry->jitemid, $opts); - - my @comments = LJ::Talk::load_comments($u, $remote, "L", $entry->jitemid, $opts); - - return $ML{'error.nodbmaintenance'} if $opts->{'out_error'} eq "nodb"; - - $output->{page} = $opts->{out_page}; - $output->{pages} = $opts->{out_pages}; - - ################################################## - - my $LJ_cmtinfo = $get->{LJ_cmtinfo}; - - my $formatlight = $get->{'format'} eq 'light' ? 'format=light' : ''; - my $stylemine = $get->{'style'} eq "mine" ? "style=mine" : ""; - - my ($last_talkid, $last_jid) = LJ::get_lastcomment(); - - my $fmt_time_short = "%%hh%%:%%min%% %%a%%m"; - my $jarg = "journal=$u->{'user'}&"; - my $jargent ="journal=$u->{'user'}&"; - my $show_thread_expander = LJ::run_hook('show_thread_expander'); - my $allow_commenting = $entry->posting_comments_allowed; - my $pics = LJ::Talk::get_subjecticons(); - my $talkurl = LJ::journal_base($u) . "/" . $entry->ditemid() . ".html"; - my $showmultiform = $get->{showmultiform}; - my $multiform_selects_ref = $get->{multiform_selects}, - my $anum = $entry->anum(); - - my $comments = []; - - my $recurse_post = sub { - - my ($self, $post, $depth) = @_; - - $depth ||= 0; - - my $tid = $post->{'talkid'}; - my $dtid = $tid * 256 + $anum; - my $LJci = $LJ_cmtinfo->{$dtid} = { rc => [], u => '', full => $post->{_loaded} }; - - my $s2_datetime = $tz_remote ? - LJ::S2::DateTime_tz($post->{'datepost_unix'}, $tz_remote) : - LJ::S2::DateTime_unix($post->{'datepost_unix'}); - - my $datepost = S2::Builtin::LJ::Date__date_format($s2_ctx, $s2_datetime, "iso") . " " . - S2::Builtin::LJ::DateTime__time_format($s2_ctx, $s2_datetime, $fmt_time_short) . - ($tz_remote ? " (local)" : " UTC"); - - my $bgcolor = ($depth % 2) ? "emcolorlite" : "emcolor"; - $bgcolor = BML::get_template_def($bgcolor); - if ($post->{'state'} eq "S") { - $bgcolor = BML::get_template_def("screenedbarcolor") || $bgcolor; - } elsif ($last_talkid == $dtid && $last_jid == $u->{'userid'}) { - $bgcolor = BML::get_template_def("altcolor1"); - } - - my $pu = $post->{'posterid'} ? $user{$post->{'posterid'}} : undef; - $LJci->{u} = $pu->{$pu->{journaltype} eq 'I' ? 'name' : 'user'} if $pu; - $LJci->{username} = $pu->{'user'} if $pu; - - my $userpost = $post->{'userpost'}; - my $upost = $post->{'upost'}; - - my $user; - if ($post->{'props'}->{'deleted_poster'}) { - $user = BML::ml('.deleteduser', { username => $post->{'deleted_poster'} }); - } else { - $user = $ML{'.anonuser'}; - } - - my $comment_header = sub { - my $table_style = shift || ''; - $table_style = ' ' . $table_style if $table_style; - - my $width = $depth * 25; - - return "<a name='t$dtid'></a><div id='ljcmt$dtid'><table$table_style><tr>" . - "<td><img src='$LJ::IMGPREFIX/dot.gif' height='1' width='$width'></td>" . - "<td id='ljcmtxt$dtid' width='100%'>"; - }; - - my $comment_footer = sub { - return "</td></tr></table></div>\n"; - }; - - my $html = {}; - - if ($post->{'state'} eq "D") ## LJSUP-6433 - { - $html->{header} = $comment_header->(); - $html->{text} = $ML{'.deletepost'}; - $html->{footer} = $comment_footer->(); - } - elsif ($post->{'state'} eq "S" && !$post->{'_loaded'} && !$post->{'_show'}) - { - $html->{header} = $comment_header->(); - $html->{text} = $ML{'.screenedpost'}; - $html->{footer} = $comment_footer->(); - } - elsif ($pu && $pu->is_suspended && !$viewsome) - { - $html->{header} = $comment_header->(); - $html->{footer} = $comment_footer->(); - - my $text = $ML{'.replysuspended'}; - if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) - { - $text .= " <a href='$LJ::SITEROOT/delcomment.bml?${jargent}id=$dtid'>" . - LJ::img("btn_del", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . - "</a>"; - } - if ($post->{state} ne 'F' && LJ::Talk::can_freeze($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&${jargent}talkid=$dtid'>" . - LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . - "</a>"; - } - if ($post->{state} eq 'F' && LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&${jargent}talkid=$dtid'>" . - LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . - "</a>"; - } - - $html->{text} = $text; - } - else - { - $user = LJ::ljuser($upost, { side_alias => 1 }) if $upost; - - my $icon = LJ::Talk::show_image($pics, $post->{'props'}->{'subjecticon'}); - - if ($post->{'_loaded'}) - { - my $comment = LJ::Comment->new($u, dtalkid => $dtid); - - my $edittime; - if ($comment->is_edited) - { - my $s2_datetime_edittime = $tz_remote ? - LJ::S2::DateTime_tz($comment->edit_time, $tz_remote) : - LJ::S2::DateTime_unix($comment->edit_time); - - $edittime = S2::Builtin::LJ::Date__date_format($s2_ctx, $s2_datetime_edittime, "iso") . " " . - S2::Builtin::LJ::DateTime__time_format($s2_ctx, $s2_datetime_edittime, $fmt_time_short) . - ($tz_remote ? " (local)" : " UTC"); - } - - # <table...><tbody><tr>... - $html->{header} = $comment_header->("width='100%' class='talk-comment'"); - $html->{footer} = $comment_footer->(); - - my $text = "<div id='cmtbar$dtid' style='background-color:$bgcolor'>"; - - if (my $picid = $post->{'picid'}) { - my $alt = $pu->{'name'}; - if ($post->{'props'}->{'picture_keyword'}) { - $alt .= ": $post->{'props'}->{'picture_keyword'}"; - } - $alt = LJ::ehtml($alt); - my ($w, $h) = ($userpics{$picid}->{'width'}, $userpics{$picid}->{'height'}); - $text .= "<img align='left' hspace='3' src='$LJ::USERPIC_ROOT/$picid/$post->{'posterid'}'"; - $text .= " width='$w' title='$alt' alt='' height='$h' />"; - } - - my $cleansubject = LJ::ehtml($post->{'subject'}); - $text .= "<font size='+1' face='Arial,Helvetica'><b>$cleansubject</b></font> $icon"; - $text .= "<br />$user\n"; - $text .= "<br /><font size='-1'>$datepost</font>\n"; - if ($post->{'props'}->{'poster_ip'} && - $remote && ($remote->{'user'} eq $up->{'user'} || LJ::can_manage($remote, $u) || $viewall)) - { - $text .= BML::ml('.fromip', { 'ip' => $post->{'props'}->{'poster_ip'} }); - } - - $text .= " <font size='-1'>(<a href='" . - LJ::Talk::talkargs($talkurl, "thread=$dtid", $formatlight) . - "#t$dtid'>" . - BML::ml('talk.commentpermlink') . "</a>)</font> "; - - if ($comment->remote_can_edit) { - $text .= "<a href='" . - LJ::Talk::talkargs($comment->edit_url, $stylemine, $formatlight) . - "'>" . - LJ::img("editcomment", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>"; - } - - if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/delcomment.bml?${jargent}id=$dtid'>" . - LJ::img("btn_del", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . - "</a>"; - } - - if ($post->{'state'} ne 'F' && LJ::Talk::can_freeze($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&${jargent}talkid=$dtid'>" . - LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . - "</a>"; - } - - if ($post->{'state'} eq 'F' && LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&${jargent}talkid=$dtid'>" . - LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . - "</a>"; - } - if ($post->{'state'} ne 'S' && LJ::Talk::can_screen($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=screen&${jargent}talkid=$dtid'>" . - LJ::img("btn_scr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . - "</a>"; - } - - if ($post->{'state'} eq 'S' && LJ::Talk::can_unscreen($remote, $u, $up, $userpost)) - { - $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unscreen&${jargent}talkid=$dtid'>" . - LJ::img("btn_unscr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . - "</a>"; - } - - if ($remote && $remote->can_use_esn) - { - my $track_img = 'track'; - - my $comment_watched = $remote->has_subscription( - event => "JournalNewComment", - journal => $u, - arg2 => $comment->jtalkid, - require_active => 1, - ); - - if ($comment_watched) - { - $track_img = 'track_active'; - } - else - { - # see if any parents are being watched - while ($comment && $comment->valid && $comment->parenttalkid) - { - # check cache - $comment->{_watchedby} ||= {}; - my $thread_watched = $comment->{_watchedby}->{$u->{userid}}; - - # not cached - if (!define... (truncated)