changelog_bot (changelog_bot) wrote in changelog,
changelog_bot
changelog_bot
changelog

[livejournal] r17530: LJSUP-6869 New endpoint for retrieving d...

Committer: dnikolaev
LJSUP-6869 New endpoint for retrieving data by thread expander

U   trunk/htdocs/talkread.bml
A   trunk/htdocs/tools/endpoints/get_thread.bml
Modified: trunk/htdocs/talkread.bml
===================================================================
--- trunk/htdocs/talkread.bml	2010-10-11 07:12:06 UTC (rev 17529)
+++ trunk/htdocs/talkread.bml	2010-10-11 07:18:30 UTC (rev 17530)
@@ -2,959 +2,1129 @@
 body<=
 <?_code
 
- use strict;
- use vars qw($r_head $r_title %GET %ML $r_bodyopts);
+    use strict;
 
- # load package for formatting current music
- use LJ::LastFM;
+    sub A
+    {
+    	my ($u, $up, $entry, $thread, $get, $output) = @_;
 
- # make refs to both title and head, that work in cached or non-cached contexts
- # $_[0] is a pre-request scratch area.
- $r_head = "";
- $r_title = "";
- my $head = $_[0] ? \$_[0]->{'head'} : \$r_head;
- my $title = $_[0] ? \$_[0]->{'title'} : \$r_title;
- my $bodyopts = $_[0] ? \$_[0]->{'bodyopts'} : \$r_bodyopts;
+        my $remote = LJ::get_remote();
 
- return LJ::server_down_html() if $LJ::SERVER_DOWN;
+        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 $pics = LJ::Talk::get_subjecticons();
+        my $viewsome = $get->{viewsome};
+        my $viewall = $get->{viewall};
 
- ## workaround mail client bug when don't understand quoted-printable.
- ## Only correct 'journal' if 'itemid' was also broken, to avoid the
- ## unlikely clash with a journal name.
- if ($GET{'itemid'} =~ s/^3D//) {
-     $GET{'journal'} =~ s/^3D//;
-     $GET{'thread'} =~ s/^3D//;
- }
+        my %user;
+        my %userpics;
 
- LJ::Request->notes("codepath" => "bml.talkread");
+        my $view_arg = $get->{view} || "";
+        my $flat_mode = ($view_arg =~ /\bflat\b/);
+        my $view_num = ($view_arg =~ /(\d+)/) ? $1 : undef;
 
- my $uri = BML::get_uri();
- my $itemid;
-my $old_url = 0;
+        my $opts = {
+            flat       => $flat_mode,
+            thread     => $thread,
+            page       => $get->{page},
+            view       => $view_num,
+            userpicref => \%userpics,
+            userref    => \%user,
+            up         => $up,
+            viewall    => $viewall,
+        };
 
- if ($uri =~ m!/(\d+)\.html$!) {
-     $itemid = $1;
-     $GET{'itemid'} = $itemid;
-     $GET{'journal'} = LJ::Request->notes("_journal");
-     BML::set_language_scope("/talkread.bml");
- } else {
-     $old_url = 1;
- }
+        ## Expand all comments on page
+        unless ($LJ::DISABLED{allow_expand_all_comments}) {
+            $opts->{expand_all} = 1 if $get->{expand} eq 'all';
+        }
 
- # pre-load common strings for little speed and less typing later
- # (we're doing this *after* set_language_scope is called, because
- # two below are relative strings)
- my %T = qw(postcomments    talk.commentpost
-            readcomments    talk.commentsread
-            parent          talk.parentlink
-            thread          talk.threadlink
-            expand          talk.expandlink
-            replythis       talk.replytothis
-            unscreentoreply talk.unscreentoreply
-            frozen          talk.frozen
-            link            talk.commentpermlink
-            deleted         .subjectdeleted
-            nosubject       .nosubject
-            );
- foreach (keys %T) { $T{$_} = $ML{$T{$_}}; }
+        ## allow to modify strategies to load/expand comments tree.
+        LJ::run_hooks('load_comments_opts', $u, $entry->jitemid, $opts);
 
- my $init = LJ::Talk::init(\%GET);
- return "<?h1 $ML{'Error'} h1?><?p $init->{'error'} p?>" if $init->{'error'};
+        my @comments = LJ::Talk::load_comments($u, $remote, "L", $entry->jitemid, $opts);
+        
+        return $ML{'error.nodbmaintenance'} if $opts->{'out_error'} eq "nodb";
 
- my $u = $init->{'journalu'};
- return $ML{'talk.error.nojournal'} unless $u;
+        $output->{page} = $opts->{out_page};
+        $output->{pages} = $opts->{out_pages};
 
- my $ditemid = $init->{'ditemid'}+0;
+        ##################################################
+        
+        my $LJ_cmtinfo = $get->{LJ_cmtinfo};
 
- if ($old_url && $GET{'journal'}) {
-     # FIXME: add args
-     my %args = %GET;
-     delete $args{'journal'};
-     delete $args{'itemid'};
-     my $args = "";
-     if (%args) {
-         $args = "?" . join("&", map { LJ::eurl($_) . "=" . LJ::eurl($args{$_}) } keys %args);
-     }
-     return BML::redirect($u->journal_base . "/$ditemid.html$args");
- }
+        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'}&amp;";
+        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();
 
- # redirect if account was renamed
- if ($u->{'journaltype'} eq "R") {
-     LJ::load_user_props($u, "renamedto");
-     if ($u->{'renamedto'} ne "") {
-         return BML::redirect(LJ::journal_base($u->{'renamedto'}) . "/$ditemid.html");
-     }
- }
+        my $comments = [];
 
- # now check for init->error, since we know the account wasn't renamed
- return "<?h1 $ML{'Error'} h1?><?p $init->{'error'} p?>" if $init->{'error'};
+        my $recurse_post = sub {
 
- LJ::Request->notes("journalid" => $u->{'userid'});
+            my ($self, $post, $depth) = @_;
 
- my $thread = $init->{'thread'};
- my $dthread = $init->{'dthread'};
- $itemid = $init->{'itemid'}+0;
+            $depth ||= 0;
+        
+            my $tid = $post->{'talkid'};
+            my $dtid = $tid * 256 + $anum;
+            my $LJci = $LJ_cmtinfo->{$dtid} = { rc => [], u => '', full => $post->{_loaded} };
 
- my $stylemine = $init->{'style'} eq "mine" ? "style=mine" : "";
- my $formatlight = $GET{'format'} eq 'light' ? 'format=light' : '';
+            my $s2_datetime = $tz_remote ?
+                LJ::S2::DateTime_tz($post->{'datepost_unix'}, $tz_remote) :
+                LJ::S2::DateTime_unix($post->{'datepost_unix'});
 
- my $item = LJ::Talk::get_journal_item($u, $itemid);
+            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");
 
- if ($init->{'oldurl'} && $item) {
-     $init->{'anum'} = $item->{'anum'};
-     $init->{'ditemid'} = $init->{'itemid'}*256 + $item->{'anum'};
-     $ditemid = $init->{'ditemid'} + 0;
- }
+            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 $entry = LJ::Entry->new($u, ditemid => $ditemid);
+            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;
 
- $u->preload_props("opt_blockrobots", "adult_content", "admin_content_flag") if $u->is_visible;
- if (!$u->is_visible || $u->should_block_robots || ($entry && $entry->should_block_robots)) {
-     $$head .= LJ::robot_meta_tags();
- }
+            my $userpost = $post->{'userpost'};
+            my $upost    = $post->{'upost'};
 
- $$head .= $LJ::SHARE_THIS_URL_GEN->(journal => $u->username)
-    unless $LJ::DISABLED{'sharethis'};
+            my $user;
+            if ($post->{'props'}->{'deleted_poster'}) {
+                $user = BML::ml('.deleteduser', { username => $post->{'deleted_poster'} });
+            } else {
+                $user = $ML{'.anonuser'};
+            }
 
- unless ($item && $item->{'anum'} == $init->{'anum'}) {
-     LJ::Request->pnotes ('error' => 'e404');
-     LJ::Request->pnotes ('remote' => LJ::get_remote());
-     BML::return_error_status(404);
-     return;
- }
+            my $comment_header = sub {
+                my $table_style = shift || '';
+                $table_style = ' ' . $table_style if $table_style;
 
- my $jarg = "journal=$u->{'user'}&";
- my $jargent ="journal=$u->{'user'}&amp;";
- my $talkurl = LJ::journal_base($u) . "/$ditemid.html";
+                my $width = $depth * 25;
 
- my $ret = "";
+                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%'>";
+            };
 
- ### load users
- my ($up);  # $up = user posted journal item
- LJ::load_userids_multiple([ $item->{'posterid'} => \$up, ], [ $u ]);
+            my $comment_footer = sub {
+                return "</td></tr></table></div>\n";
+            };
 
- LJ::text_out(\$u->{'name'});
+            my $html = {};
 
- my $remote = LJ::get_remote();
+            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 $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 $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&amp;${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&amp;${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'});
 
- # set viewall/viewsome
- my $viewall = 0;
- my $viewsome = 0;
- if ($GET{viewall} && LJ::check_priv($remote, 'canview', 'suspended')) {
-     LJ::statushistory_add($u->{'userid'}, $remote->{'userid'},
-                           "viewall", "entry: $u->{'user'}, itemid: $item->{'itemid'}, statusvis: " . $u->statusvis);
-     $viewall = LJ::check_priv($remote, 'canview', '*');
-     $viewsome = $viewall || LJ::check_priv($remote, 'canview', 'suspended');
- }
+                if ($post->{'_loaded'})
+                {
+                    my $comment = LJ::Comment->new($u, dtalkid => $dtid);
 
- # check for deleted/suspended/security
- unless ($viewsome) {
-     # check suspended user
-     if ($u->is_suspended || $up->is_suspended) {
-        LJ::Request->pnotes ('error' => 'suspended');
-        LJ::Request->pnotes ('remote' => LJ::get_remote());
-        BML::return_error_status(404);
-        return;
-     }
+                    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);
 
-     # check deleted
-     if ($u->is_deleted) {
-        LJ::Request->pnotes ('error' => 'deleted');
-        LJ::Request->pnotes ('remote' => LJ::get_remote());
-        BML::return_error_status(404);
-        return;
-     }
+                            $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");
+                    }
 
-     # check suspended entry
-     if ($entry && $entry->is_suspended_for($remote)) {
-        LJ::Request->pnotes ('error' => 'suspended_post');
-        LJ::Request->pnotes ('remote' => LJ::get_remote());
-        BML::return_error_status(404);
-        return;
-     }
- }
+                    # <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'>";
 
- unless ($viewall) {
-     ####  Check security before viewing this post
-     my $errtxt;
-     return $errtxt unless LJ::Talk::check_viewable($remote, $item, \%GET, \$errtxt);
- }
+                    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 $props = $item->{'props'};
- my $nocomments_old = $viewall ? 0 :
-                  $u->{'opt_showtalklinks'} eq "N" ? 1 : $props->{'opt_nocomments'};
- my $comments_shown = $viewall || $entry->comments_shown;
- my $allow_commenting = $entry->posting_comments_allowed;
+                    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'} });
+                    }
 
- # See if we should inject QuickReply javascript
- LJ::load_user_props($remote, "opt_no_quickreply");
+                    $text .= " <font size='-1'>(<a href='" .
+                             LJ::Talk::talkargs($talkurl, "thread=$dtid", $formatlight) .
+                             "#t$dtid'>" .
+                             BML::ml('talk.commentpermlink') . "</a>)</font> ";
 
- LJ::run_hooks("need_res_for_journals", $u);
- my $graphicpreviews_obj = LJ::graphicpreviews_obj();
- $graphicpreviews_obj->need_res($u);
+                    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>";
+                    }
 
- LJ::need_res(qw(
-    js/thread_expander.js
-    js/journal.js
-    ));
+                    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 (($remote && !$remote->{'opt_no_quickreply'}) && $allow_commenting) {
-    # quickreply js libs
-    LJ::need_res(qw(
-                    js/json.js
-                    js/template.js
-                    js/ippu.js
-                    js/lj_ippu.js
-                    js/userpicselect.js
-                    js/hourglass.js
-                    js/inputcomplete.js
-                    stc/ups.css
-                    stc/lj_base.css
-                    js/datasource.js
-                    js/selectable_table.js
-                    )) unless $LJ::DISABLED{userpicselect} || ! $remote->get_cap('userpicselect');
+                    if ($post->{'state'} ne 'F' && LJ::Talk::can_freeze($remote, $u, $up, $userpost))
+                    {
+                        $text .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&amp;${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&amp;${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&amp;${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&amp;${jargent}talkid=$dtid'>" .
+                                 LJ::img("btn_unscr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) .
+                                 "</a>";
+                    }
 
-      LJ::need_res(qw(
-                      js/quickreply.js
-                      ));
- }
+                    if ($remote && $remote->can_use_esn)
+                    {
+                        my $track_img = 'track';
 
- my $showmultiform = $remote &&
-    ($remote->{'user'} eq $u->{'user'} ||
-     $remote->{'user'} eq $up->{'user'} ||
-     LJ::can_manage($remote, $u));
- my $multiform_selects = 0;  # are there select boxes?  don't show form if not.
+                        my $comment_watched = $remote->has_subscription(
+                            event   => "JournalNewComment",
+                            journal => $u,
+                            arg2    => $comment->jtalkid,
+                            require_active => 1,
+                        );
 
- my $event = $item->{'event'};
- my $suspend_msg = $entry && $entry->should_show_suspend_msg_to($remote) ? 1 : 0;
- LJ::CleanHTML::clean_event(\$event, { 'preformatted' => $props->{'opt_preformatted'},
-                                       'suspend_msg' => $suspend_msg,
-                                       'unsuspend_supportid' => $suspend_msg ? $entry->prop("unsuspend_supportid") : 0, 
-                                       'cuturl' => $talkurl, 
-                                       'expand_cut' => 1,
-                                       });
- LJ::expand_embedded($u, $ditemid, $remote, \$event);
- BML::ebml(\$event);
+                        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}};
 
- # make the title
-{
-    my $subject = $item->{'subject'} || $event;
-    # yes, the 3 param to text_trim is chars, and length returns bytes, but
-    # it works, as bytes >= chars:
-    $subject = LJ::CleanHTML::clean_and_trim_subject(\$subject, length($item->{'subject'}) || 40);
-    $$title = "$u->{'user'}: $subject";
-    # prevent BML tags interpretation inside post body
-    $$title =~ s/<\?/&lt;?/g;
-    $$title =~ s/\?>/?&gt;/g;
-}
+                                # not cached
+                                if (!defined $thread_watched)
+                                {
+                                    $thread_watched = $remote->has_subscription(
+                                        event   => "JournalNewComment",
+                                        journal => $u,
+                                        arg2    => $comment->parenttalkid,
+                                        require_active => 1,
+                                    );
+                                }
 
- $ret .= "<p>";
- $ret .= "<table><tr valign='middle'>";
+                                $track_img = 'track_thread_active' if ($thread_watched);
 
- my $userpic = $entry->userpic;
- LJ::run_hook('notify_event_displayed', $entry);
+                                # cache in this comment object if it's being watched by this user
+                                $comment->{_watchedby}->{$u->{userid}} = $thread_watched;
 
- my %userpics;
- if ($userpic) {
-     my $alt = $up->{'name'};
-     if ($props->{'picture_keyword'}) {
-         $alt .= ": $props->{'picture_keyword'}";
-     }
-     LJ::text_out(\$alt);
-     $alt = LJ::ehtml($alt);
-     my ($w, $h) = $userpic->dimensions;
-     $ret .= "<td><img src='" . $userpic->url . "' width='$w' height='$h' " .
-         "align='absmiddle' ".
-         "hspace='3' title='$alt' alt=''></td>";
- }
+                                $comment = $comment->parent;
+                            }
+                        }
 
- $ret .= "<td>";
- if (!LJ::u_equals($u, $up)) {
-     $ret .= BML::ml("talk.somebodywrote_comm", { 'realname' => LJ::ehtml($up->{'name'}),
-                                                  'userlink' => LJ::ljuser($up),
-                                                  'commlink' => LJ::ljuser($u) });
- } else {
-     $ret .= BML::ml("talk.somebodywrote", { 'realname' => LJ::ehtml($up->{'name'}),
-                                             'userlink' => LJ::ljuser($up) });
- }
+                        my $track_url = "$LJ::SITEROOT/manage/subscriptions/comments.bml?journal=$u->{'user'}&amp;talkid=$dtid";
+                        $text .= "<a href='$track_url'>" . LJ::img($track_img, '', {'align' => 'absmiddle'}) . "</a>";
+                    }
 
- my $etime = $item->{'eventtime'};
- $etime =~ s!(\d\d\d\d)-(\d\d)-(\d\d)!LJ::date_to_view_links($u, $&)!e;
- $ret .= "<br /><font size='-1'>@ $etime</font>";
- $ret .= "</td></tr></table>";
+                    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;
+                    }
 
- ## standout bar
- $ret .= LJ::Talk::link_bar({ 'u' => $u, 'up' => $up, 'headref' => $head,
-                              'remote' => $remote, 'itemid' => $ditemid, });
+                    # Comment Posted Notice
+                    $text .= "<br /><b>$ML{'.posted'}</b>"
+                        if $last_talkid == $dtid && $last_jid == $u->{'userid'};
 
- if ($u->is_locked) {
-     $ret .= "<div class='warningbar warning-background' style='text-align: center; margin: 5px auto;'>$ML{'statusvis_message.locked'}</div>";
- } elsif ($u->is_memorial) {
-     $ret .= "<div class='warningbar warning-background' style='text-align: center; margin: 5px auto;'>$ML{'statusvis_message.memorial'}</div>";
- } elsif ($u->is_readonly) {
-     $ret .= "<div class='warningbar warning-background' style='text-align: center; margin: 5px auto;'>$ML{'statusvis_message.readonly'}</div>";
- }
+                    $text .= "</div><div class='talk-comment-box'>";
 
- ## dump the log entry, unless we're browsing a thread.
- my %current;
- if ($props->{'current_mood'} || $props->{'current_moodid'}) {
-     my $themeid = $up->{'moodthemeid'};
-     my $moodid = $props->{'current_moodid'};
-     my $mood = $props->{'current_mood'};
+                    LJ::CleanHTML::clean_comment(
+                        \$post->{'body'},
+                        {
+                            preformatted => $post->{'props'}->{'opt_preformatted'},
+                            anon_comment => (!$pu || $pu->{'journaltype'} eq 'I'),
+                            nocss        => 1,
+                        }
+                    );
 
-     my $moodname;
-     my $moodpic;
+                    BML::ebml(\$post->{'body'});
+                    my $event = $post->{'body'};
+    
+                    if ($GET{'nohtml'})
+                    {
+                        # quote all non-LJ tags
+                        $event =~ s{<(?!/?lj)(.*?)>} {&lt;$1&gt;}gi;
+                    }
 
-     # favor custom mood over system mood
-     if (my $val = $mood) {
-          LJ::CleanHTML::clean_subject(\$val);
-          $moodname = $val;
-     }
+                    my $edit_html = $edittime
+                                    ? "<br /><br /><span class='ljedittime'><em>" .
+                                      BML::ml('.edittime', { edittime => $edittime }) .
+                                      "</em></span>"
+                                    : "";
 
-     if (my $val = $moodid) {
-          $moodname ||= LJ::mood_name($val);
-          my %pic;
-          if (LJ::get_mood_picture($themeid, $val, \%pic)) {
-              $moodpic = "<img src=\"$pic{'pic'}\" align='absmiddle' ".LJ::mood_size_attributes(%pic)." vspace='1' alt='' /> ";
-          }
-     }
+                    $text .= "$event$edit_html";
 
-     $current{'Mood'} = "$moodpic$moodname";
- }
- if ($props->{'current_music'}) {
-     $current{'Music'} = $props->{'current_music'};
-     LJ::CleanHTML::clean_subject(\$current{'Music'});
- }
- if ($props->{'current_location'} || $props->{'current_coords'}) {
-     my $loc = eval { LJ::Location->new(coords   => $props->{'current_coords'},
-                                        location => $props->{'current_location'}) };
-     $current{'Location'} = $loc->as_html_current if $loc;
- }
+                    $text .= "<p style='margin: 0.7em 0 0.2em 0'><font size='-2'>";
 
- # custom friend groups
- my $group_names = $entry->group_names;
- $current{'Groups'} = $group_names if $group_names;
+                    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&amp;${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>)";
 
- my $logtags = LJ::Tags::get_logtags($u, $itemid);
- if ($logtags->{$itemid} && %{$logtags->{$itemid}}) {
-     my $base = LJ::journal_base($u);
-     $current{'Tags'} = join(', ',
-                            map { "<a href='$base/tag/" . LJ::eurl($_) . "'>" . LJ::ehtml($_) . "</a>" }
-                            sort values %{$logtags->{$itemid}}
-                        );
- }
+                        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>";
 
- $ret .= "<div style='margin-left: 30px'>";
+                    $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;
 
-    ## copyright
-    if (LJ::is_enabled('show_copyright', $u)) {
-        if ($props->{'copyright'} eq 'C' and $item->{'security'} eq "public") {
-            $ret .= '<div class="copyrighted">&Oslash; ' . BML::ml("talk.copyright") . '</div>';
+                    # Comment Posted Notice
+                    $text .= " - <b>$ML{'.posted'}</b>"
+                       if $last_talkid == $dtid && $last_jid == $u->{'userid'};
+                }
+            }
+
+            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;
+
+    # make refs to both title and head, that work in cached or non-cached contexts
+    # $_[0] is a pre-request scratch area.
+    $r_head = "";
+    $r_title = "";
+    my $head = $_[0] ? \$_[0]->{'head'} : \$r_head;
+    my $title = $_[0] ? \$_[0]->{'title'} : \$r_title;
+    my $bodyopts = $_[0] ? \$_[0]->{'bodyopts'} : \$r_bodyopts;
+
+    return LJ::server_down_html() if $LJ::SERVER_DOWN;
+
+    ## workaround mail client bug when don't understand quoted-printable.
+    ## Only correct 'journal' if 'itemid' was also broken, to avoid the
+    ## unlikely clash with a journal name.
+    if ($GET{'itemid'} =~ s/^3D//)
+    {
+        $GET{'journal'} =~ s/^3D//;
+        $GET{'thread'} =~ s/^3D//;
+    }
+
+
+    LJ::Request->notes("codepath" => "bml.talkread");
+
+    my $uri = BML::get_uri();
+    my $itemid;
+    my $old_url = 0;
+
+    if ($uri =~ m!/(\d+)\.html$!) {
+        $itemid = $1;
+        $GET{'itemid'} = $itemid;
+        $GET{'journal'} = LJ::Request->notes("_journal");
+        BML::set_language_scope("/talkread.bml");
+    } else {
+        $old_url = 1;
+    }
+
+    my $init = LJ::Talk::init(\%GET);
+    return "<?h1 $ML{'Error'} h1?><?p $init->{'error'} p?>" if $init->{'error'};
+
+    my $u = $init->{'journalu'};
+    return $ML{'talk.error.nojournal'} unless $u;
+
+    my $ditemid = $init->{'ditemid'} + 0;
+
+    if ($old_url && $GET{'journal'}) {
+        # FIXME: add args
+        my %args = %GET;
+        delete $args{'journal'};
+        delete $args{'itemid'};
+        my $args = "";
+        if (%args) {
+            $args = "?" . join("&", map { LJ::eurl($_) . "=" . LJ::eurl($args{$_}) } keys %args);
         }
+        return BML::redirect($u->journal_base . "/$ditemid.html$args");
     }
 
- if (%current)
- {
-     $ret .= "<table border=0>\n";
-     foreach (sort keys %current) {
-         my $curkey = "talk.curname_" . $_;
-         my $curname = BML::ml($curkey);
-         $curname = "<b>Current $_:</b>" unless $curname;
-         
-         $ret .= "<tr><td align=right>$curname</td>";
-         
-         if ($_ eq 'Music') {
-            $ret .= "<td>" . LJ::LastFM::format_current_music_string($current{$_}) . "</td></tr>\n";
-         } else {
-            $ret .= "<td>$current{$_}</td></tr>\n";
-         }
-     }
-     $ret .= "</table><p>\n";
- }
+    # redirect if account was renamed
+    if ($u->{'journaltype'} eq "R") {
+        LJ::load_user_props($u, "renamedto");
+        if ($u->{'renamedto'} ne "") {
+            return BML::redirect(LJ::journal_base($u->{'renamedto'}) . "/$ditemid.html");
+        }
+    }
 
- ### security indicator
- my $sec = "";
- if ($item->{'security'} eq "private") {
-     $sec = BML::fill_template("securityprivate");
- } elsif ($item->{'security'} eq "usemask") {
-     if ($item->{'allowmask'} == 0) { # custom security with no group -- essentially private
-        $sec = BML::fill_template("securityprivate");
-     } elsif ($item->{'allowmask'} > 1 && $u && $u->equals($remote)) { # custom group -- only show to journal owner
-        $sec = BML::fill_template("securitygroups");
-     } else { # friends only or custom group showing to non journal owner
-        $sec = BML::fill_template("securityprotected");
-     }
- }
+    # now check for init->error, since we know the account wasn't renamed
+    return "<?h1 $ML{'Error'} h1?><?p $init->{'error'} p?>" if $init->{'error'};
 
- $sec .= "<br />\n" unless $sec eq "" or $item->{'subject'};
- $ret .= $sec;
+    LJ::Request->notes("journalid" => $u->{'userid'});
 
- ###
- if ($item->{'subject'}) {
-     my $subject = $item->{'subject'};
-     if ($GET{'nohtml'}) {
-         # quote all non-LJ tags
-         $subject =~ s{<(?!/?lj)(.*?)>} {&lt;$1&gt;}gi;
-     }
-     LJ::CleanHTML::clean_subject(\$subject);
-     BML::ebml(\$subject);
-     $ret .= "<font face='Arial,Helvetica' size='+1'><i><b>$subject</b></i></font><br />\n";
- }
+    my $thread = $init->{'thread'};
+    my $dthread = $init->{'dthread'};
+    $itemid = $init->{'itemid'} + 0;
 
+    my $stylemine = $init->{'style'} eq "mine" ? "style=mine" : "";
+    my $formatlight = $GET{'format'} eq 'light' ? 'format=light' : '';
 
-  if ($GET{'nohtml'}) {
-      # quote all non-LJ tags
-      $event =~ s{<(?!/?lj)(.*?)>} {&lt;$1&gt;}gi;
-  }
- $ret .= $event;
- $ret .= "</div>";
+    my $item = LJ::Talk::get_journal_item($u, $itemid);
 
- $ret .= "<br style='clear: both' /><hr width='100%' size='2' align='center' />";
+    if ($init->{'oldurl'} && $item) {
+        $init->{'anum'} = $item->{'anum'};
+        $init->{'ditemid'} = $init->{'itemid'} * 256 + $item->{'anum'};
+        $ditemid = $init->{'ditemid'} + 0;
+    }
 
- my $qotd = 0;
- $qotd = $entry->prop("qotdid") if $entry;
+    my $entry = LJ::Entry->new($u, ditemid => $ditemid);
 
- my @verticals = $entry->verticals_list_for_ad;
- if (@verticals) {
-     $LJ::REQ_GLOBAL{verticals_of_first_public_post} = join(",", @verticals);
- }
- 
- my $ad = LJ::get_ads ({
-    location        => 'bml.talkread.ebox',
-    nowrap          => 1,
-    journalu        => $u, 
-    vertical        => $LJ::REQ_GLOBAL{verticals_of_first_public_post}, 
-    interests_extra => $qotd ? { qotd => $qotd } : {},
-    s1_view         => 'entry',
-    
- });
- 
- if ($ad) {
-     $ret .= $ad;
-     $ret .= "<hr width='100%' size='2' align='center' />";
- }
+    $u->preload_props("opt_blockrobots", "adult_content", "admin_content_flag") if $u->is_visible;
+    if (!$u->is_visible || $u->should_block_robots || ($entry && $entry->should_block_robots)) {
+        $$head .= LJ::robot_meta_tags();
+    }
 
- my $view_arg = $GET{'view'} || "";
- my $flat_mode = ($view_arg =~ /\bflat\b/);
- my $view_num = ($view_arg =~ /(\d+)/) ? $1 : undef;
+    $$head .= $LJ::SHARE_THIS_URL_GEN->(journal => $u->username)
+       unless $LJ::DISABLED{'sharethis'};
 
- my %user;
- my $opts = {
-     'flat' => $flat_mode,
-     'thread' => $thread,
-     'page' => $GET{'page'},
-     'view' => $view_num,
-     'userpicref' => \%userpics,
-     'userref' => \%user,
-     'up' => $up,
-     'viewall' => $viewall,
-     'init_comobj' => 0,
- };
+    unless ($item && $item->{'anum'} == $init->{'anum'}) {
+        LJ::Request->pnotes ('error' => 'e404');
+        LJ::Request->pnotes ('remote' => LJ::get_remote());
+        BML::return_error_status(404);
+        return;
+    }
 
- ## Expand all comments on page
- unless ($LJ::DISABLED{allow_expand_all_comments}){
-    $opts->{expand_all} = 1 if $GET{expand} eq 'all';
- }
+    my $talkurl = LJ::journal_base($u) . "/$ditemid.html";
 
- ## allow to modify strategies to load/expand comments tree.
- LJ::run_hooks('load_comments_opts', $u, $itemid, $opts);
+    ### load users
+    my ($up);  # $up = user posted journal item
+    LJ::load_userids_multiple([ $item->{'posterid'} => \$up, ], [ $u ]);
 
- my @comments = LJ::Talk::load_comments($u, $remote, "L", $itemid, $opts);
- return $ML{'error.nodbmaintenance'} if $opts->{'out_error'} eq "nodb";
+    LJ::text_out(\$u->{'name'});
 
- my $page = $opts->{'out_page'};
- my $pages = $opts->{'out_pages'};
+    my $remote = LJ::get_remote();
 
- ########## make the navcrap
- my $navcrap = '';
- if ($pages > 1) {
-     $navcrap .= "<table style='font-weight: bold'>";
-     $navcrap .= "<tr><td align='center' colspan='3'>";
-     $navcrap .= BML::ml('ljlib.pageofpages',{'page'=>$page, 'total'=>$pages});
-     $navcrap .= "</td></tr>";
-     my $left = "&lt;&lt;";
-     if ($page > 1) { $left = "<a href='" . BML::self_link({ 'page' => $page-1 }) . "#comments'>$left</a>"; }
+    ### set viewall/viewsome
+    my $viewall = 0;
+    my $viewsome = 0;
+    if ($GET{viewall} && LJ::check_priv($remote, 'canview', 'suspended')) {
+        LJ::statushistory_add(
+            $u->{'userid'},
+            $remote->{'userid'},
+            "viewall",
+            "entry: $u->{'user'}, itemid: $item->{'itemid'}, statusvis: " . $u->statusvis
+        );
+        $viewall = LJ::check_priv($remote, 'canview', '*');
+        $viewsome = $viewall || LJ::check_priv($remote, 'canview', 'suspended');
+    }
 
-     my $right = "&gt;&gt;";
-     if ($page < $pages) { $right = "<a href='" . BML::self_link({ 'page' => $page+1 }) . "#comments'>$right</a>"; }
+    ### check for deleted/suspended/security
+    unless ($viewsome) {
 
-     $navcrap .= "<tr><td style='font-size: 85%' align='center'>$left</td><td style='font-size: 85%' align='center'>";
+        # check suspended user
+        if ($u->is_suspended || $up->is_suspended) {
+            LJ::Request->pnotes ('error' => 'suspended');
+            LJ::Request->pnotes ('remote' => LJ::get_remote());
+            BML::return_error_status(404);
+            return;
+        }
 
-     for (my $i=1; $i<=$pages; $i++) {
-         my $link = "[$i]";
-         if ($i != $page) { $link = "<a href='" . BML::self_link({ 'page' => $i }) . "#comments'>$link</a>"; }
-         else { $link = "<span style='font-size: 130%; font-weight: bolder'>$link</span>"; }
-         $navcrap .= "$link ";
-         if ($i == 11)  { $navcrap .= "<br />"; }
-         elsif ($i > 10 && $i % 10 == 0) { $navcrap .= "<br />"; }
-     }
+        # check deleted
+        if ($u->is_deleted) {
+            LJ::Request->pnotes ('error' => 'deleted');
+            LJ::Request->pnotes ('remote' => LJ::get_remote());
+            BML::return_error_status(404);
+            return;
+        }
 
-     $navcrap .= "</td><td style='font-size: 85%' align='center'>$right</td></tr>";
-     $navcrap .= "</table>\n";
-     $navcrap = BML::fill_template("standout", { 'DATA' => $navcrap });
- }
- ####### end navcrap
+        # check suspended entry
+        if ($entry && $entry->is_suspended_for($remote)) {
+            LJ::Request->pnotes ('error' => 'suspended_post');
+            LJ::Request->pnotes ('remote' => LJ::get_remote());
+            BML::return_error_status(404);
+            return;
+        }
+    }
 
- # Quick reply variables.  Not always set.
- my ($last_talkid, $last_jid) = LJ::get_lastcomment();
- my %LJ_cmtinfo;  # data structure to give to javascript for commentmanage
- $LJ_cmtinfo{'form_auth'} = LJ::form_auth(1);
- $LJ_cmtinfo{'journal'} = $u->{user};
- $LJ_cmtinfo{'canAdmin'} = LJ::can_manage($remote, $u) ? 1 : 0;
- $LJ_cmtinfo{'remote'} = $remote ? $remote->{user} : "";
- my $fmt_time_short = "%%hh%%:%%min%% %%a%%m";
- my $show_thread_expander = LJ::run_hook('show_thread_expander');
+    unless ($viewall) {
+        ###  Check security before viewing this post
+        my $errtxt;
+        return $errtxt unless LJ::Talk::check_viewable($remote, $item, \%GET, \$errtxt);
+    }
 
- my $recurse_post = sub
- {
-     my ($self_sub, $post, $opts) = @_;
+    my $props = $item->{'props'};
+    my $nocomments_old = $viewall ?
+                         0 :
+                         $u->{'opt_showtalklinks'} eq "N" ? 1 : $props->{'opt_nocomments'};
+    my $comments_shown = $viewall || $entry->comments_shown;
+    my $allow_commenting = $entry->posting_comments_allowed;
 
-     $opts ||= { 'depth' => 0 };
+    # See if we should inject QuickReply javascript
+    LJ::load_user_props($remote, "opt_no_quickreply");
 
-     my $tid = $post->{'talkid'};
-     my $dtid = $tid * 256 + $init->{'anum'};
-     my $LJci = $LJ_cmtinfo{$dtid} = { rc => [], u => '', full => $post->{_loaded} };
+    LJ::run_hooks("need_res_for_journals", $u);
+    my $graphicpreviews_obj = LJ::graphicpreviews_obj();
+    $graphicpreviews_obj->need_res($u);
 
-     my $s2_datetime = $tz_remote ?
-         LJ::S2::DateTime_tz($post->{'datepost_unix'}, $tz_remote) :
-         LJ::S2::DateTime_unix($post->{'datepost_unix'});
+    my $ret = "";
 
-     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");
+    LJ::need_res(qw(
+        js/thread_expander.js
+        js/journal.js
+    ));
 
-    
-     my $bgcolor = ($opts->{'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");
-     }
+    if (($remote && !$remote->{'opt_no_quickreply'}) && $allow_commenting) {
+        # quickreply js libs
+        LJ::need_res(qw(
+            js/json.js
+            js/template.js
+            js/ippu.js
+            js/lj_ippu.js
+            js/userpicselect.js
+            js/hourglass.js
+            js/inputcomplete.js
+            stc/ups.css
+            stc/lj_base.css
+            js/datasource.js
+            js/selectable_table.js
+        )) unless $LJ::DISABLED{userpicselect} || !$remote->get_cap('userpicselect');
 
-     my $pu = $post->{'posterid'} ? $user{$post->{'posterid'}} : undef;
-     $LJci->{u} = $pu->{'I' eq $pu->{journaltype} ? 'name' : 'user'} if $pu;
-     $LJci->{'username'} = $pu->{'user'} if $pu;
+        LJ::need_res(qw(
+            js/quickreply.js
+        ));
+    }
 
-     my $userpost = $post->{'userpost'};
-     my $upost    = $post->{'upost'};
+    my $showmultiform = $remote &&
+                        ($remote->{'user'} eq $u->{'user'} ||
+                         $remote->{'user'} eq $up->{'user'} ||
+                         LJ::can_manage($remote, $u));
 
-     my $user;
-     if ($post->{'props'}->{'deleted_poster'}) {
-         $user = BML::ml('.deleteduser', {'username'=>$post->{'deleted_poster'}});
-     }
-     else {
-         $user = $ML{'.anonuser'};
-     }
+    my $multiform_selects = 0;  # are there select boxes?  don't show form if not.
 
-     if ($post->{'state'} eq "D") { ## LJSUP-6433
-         $ret .= "<p><a name='t$dtid'></a><table><tr>";
-         $ret .= "<td><img src='$LJ::IMGPREFIX/dot.gif' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
-         $ret .= "<td>$ML{'.deletedpost'}</td></tr></table>\n";
-     } elsif ($post->{'state'} eq "S" && !$post->{'_loaded'} && !$post->{'_show'}) {
-         $ret .= "<p><a name='t$dtid'></a><table><tr>";
-         $ret .= "<td><img src='$LJ::IMGPREFIX/dot.gif' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
-         my $screenedtext = $ML{'.screenedpost'};
-         $ret .= "<td>$screenedtext</td></tr></table>\n";
-     } elsif ($pu && $pu->is_suspended && !$viewsome) {
-         $ret .= "<p><a name='t$dtid'></a><table><tr>";
-         $ret .= "<td><img src='$LJ::IMGPREFIX/dot.gif' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
-         $ret .= "<td>$ML{'.replysuspended'}";
-         if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) {
-             $ret .= " <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)) {
-             $ret .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&amp;${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)) {
-             $ret .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . "</a>";
-         }
-         $ret .= "</td></tr></table>\n";
-     } else {
-         if ($upost) {
-             $user = LJ::ljuser($upost, { side_alias => 1 });
-         }
-         my $icon = LJ::Talk::show_image($pics, $post->{'props'}->{'subjecticon'});
-         if ($post->{'_loaded'}) {
-             my $comment = LJ::Comment->new($u, dtalkid => $dtid);
+    my $event = $item->{'event'};
+    my $suspend_msg = $entry && $entry->should_show_suspend_msg_to($remote) ? 1 : 0;
+    LJ::CleanHTML::clean_event(
+        \$event,
+        {
+            preformatted        => $props->{'opt_preformatted'},
+            suspend_msg         => $suspend_msg,
+            unsuspend_supportid => $suspend_msg ? $entry->prop("unsuspend_supportid") : 0, 
+            cuturl              => $talkurl, 
+            expand_cut          => 1,
+        }
+    );
+    LJ::expand_embedded($u, $ditemid, $remote, \$event);
+    BML::ebml(\$event);
 
-             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);
+    # make the title
+    {
+        my $subject = $item->{'subject'} || $event;
+        # yes, the 3 param to text_trim is chars, and length returns bytes, but
+        # it works, as bytes >= chars:
+        $subject = LJ::CleanHTML::clean_and_trim_subject(\$subject, length($item->{'subject'}) || 40);
+        $$title = "$u->{'user'}: $subject";
+        # prevent BML tags interpretation inside post body
+        $$title =~ s/<\?/&lt;?/g;
+        $$title =~ s/\?>/?&gt;/g;
+    }
 
-                 $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");
-             }
+    $ret .= "<p>";
+    $ret .= "<table><tr valign='middle'>";
 
-             $ret .= "<a name='t$dtid'></a><span id='ljcmt$dtid'><table width='100%' class='talk-comment'><tbody><tr>";
-             $ret .= "<td rowspan='2'><img src='$LJ::IMGPREFIX/dot.gif' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
-             $ret .= "<td id='cmtbar$dtid' bgcolor='$bgcolor' width='100%'>";
-             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'});
-                 $ret .= "<img align='left' hspace='3' src='$LJ::USERPIC_ROOT/$picid/$post->{'posterid'}'";
-                 $ret .= " width='$w' title='$alt' alt='' height='$h' />";
-             }
+    my $userpic = $entry->userpic;
+    LJ::run_hook('notify_event_displayed', $entry);
 
-             my $cleansubject = LJ::ehtml($post->{'subject'});
-             $ret .= "<font size='+1' face='Arial,Helvetica'><b>$cleansubject</b></font> $icon";
-             $ret .= "<br />$user\n";
-             $ret .= "<br /><font size='-1'>$datepost</font>\n";
-             if ($post->{'props'}->{'poster_ip'} && $remote &&
-                 ($remote->{'user'} eq $up->{'user'} ||
-                  LJ::can_manage($remote, $u) || $viewall))
-             {
-                 $ret .= BML::ml('.fromip', {'ip'=>$post->{'props'}->{'poster_ip'}});
-             }
+    if ($userpic) {
+        my $alt = $up->{'name'};
+        if ($props->{'picture_keyword'}) {
+            $alt .= ": $props->{'picture_keyword'}";
+        }
+        LJ::text_out(\$alt);
+        $alt = LJ::ehtml($alt);
+        my ($w, $h) = $userpic->dimensions;
+        $ret .= "<td><img src='" . $userpic->url . "' width='$w' height='$h' align='absmiddle' hspace='3' title='$alt' alt=''></td>";
+    }
 
-             $ret .= " <font size='-1'>(<a href='" . LJ::Talk::talkargs($talkurl, "thread=$dtid", $formatlight) . "#t$dtid'>$T{'link'}</a>)</font> ";
+    $ret .= "<td>";
+    if (!LJ::u_equals($u, $up)) {
+        $ret .= BML::ml(
+            "talk.somebodywrote_comm",
+            {
+                realname => LJ::ehtml($up->{'name'}),
+                userlink => LJ::ljuser($up),
+                commlink => LJ::ljuser($u)
+            }
+        );
+    } else {
+        $ret .= BML::ml(
+            "talk.somebodywrote",
+            {
+                realname => LJ::ehtml($up->{'name'}),
+                userlink => LJ::ljuser($up)
+            }
+        );
+    }
 
-             if ($comment->remote_can_edit) {
-                 $ret .= "<a href='" . LJ::Talk::talkargs($comment->edit_url, $stylemine, $formatlight) . "'>" . LJ::img("editcomment", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>";
-             }
+    my $etime = $item->{'eventtime'};
+    $etime =~ s!(\d\d\d\d)-(\d\d)-(\d\d)!LJ::date_to_view_links($u, $&)!e;
+    $ret .= "<br /><font size='-1'>@ $etime</font>";
+    $ret .= "</td></tr></table>";
 
-             if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) {
-                 $ret .= "<a href='$LJ::SITEROOT/delcomment.bml?${jargent}id=$dtid'>" . LJ::img("btn_del", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>";
-             }
+    ## standout bar
+    $ret .= LJ::Talk::link_bar({ 'u' => $u, 'up' => $up, 'headref' => $head, 'remote' => $remote, 'itemid' => $ditemid, });
 
-             if ($post->{'state'} ne 'F' &&
-                 LJ::Talk::can_freeze($remote, $u, $up, $userpost)) {
-                 $ret .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=freeze&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . "</a>";
-             }
+    if ($u->is_locked) {
+        $ret .= "<div class='warningbar warning-background' style='text-align: center; margin: 5px auto;'>$ML{'statusvis_message.locked'}</div>";
+    } elsif ($u->is_memorial) {
+        $ret .= "<div class='warningbar warning-background' style='text-align: center; margin: 5px auto;'>$ML{'statusvis_message.memorial'}</div>";
+    } elsif ($u->is_readonly) {
+        $ret .= "<div class='warningbar warning-background' style='text-align: center; margin: 5px auto;'>$ML{'statusvis_message.readonly'}</div>";
+    }
 
-             if ($post->{'state'} eq 'F' &&
-                 LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) {
-                 $ret .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unfreeze&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2, vspace => }) . "</a>";
-             }
+    ### dump the log entry, unless we're browsing a thread.
+    my %current;
 
-             if ($post->{'state'} ne 'S' &&
-                 LJ::Talk::can_screen($remote, $u, $up, $userpost)) {
-                 $ret .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=screen&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_scr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'vspace' => }) . "</a>";
-             }
+    if ($props->{'current_mood'} || $props->{'current_moodid'}) {
+        my $themeid = $up->{'moodthemeid'};
+        my $moodid = $props->{'current_moodid'};
+        my $mood = $props->{'current_mood'};
 
-             if ($post->{'state'} eq 'S' &&
-                 LJ::Talk::can_unscreen($remote, $u, $up, $userpost)) {
-                 $ret .= "<a href='$LJ::SITEROOT/talkscreen.bml?mode=unscreen&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_unscr", "", { 'align' => 'absmiddle', 'hspace' => 2, 'v...
 (truncated)
Tags: bml, changelog_bot, livejournal
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments