Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

924 lines (775 sloc) 43.562 kb
<?_c
# This code was forked from the LiveJournal project owned and operated
# by Live Journal, Inc. The code has been modified and expanded by
# Dreamwidth Studios, LLC. These files were originally licensed under
# the terms of the license supplied by Live Journal, Inc, which can
# currently be found at:
#
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
#
# In accordance with the original license, this code and all its
# modifications are provided under the GNU General Public License.
# A copy of that license can be found in the LICENSE file included as
# part of this distribution.
_c?>
<?page
body<=
<?_code
{
use strict;
use vars qw($actual_title $r_head $r_title %GET %ML $r_bodyopts);
# make refs to both title and head, that work in cached or non-cached contexts
# $_[0] is the BML $req object, $_[1] is a pre-request scratch area.
$r_head = "";
$r_title = "";
my $head = $_[1] ? \$_[1]->{'head'} : \$r_head;
my $title = $_[1] ? \$_[1]->{'title'} : \$r_title;
my $bodyopts = $_[1] ? \$_[1]->{'bodyopts'} : \$r_bodyopts;
my $pics = LJ::Talk::get_subjecticons();
## 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 $r = BML::get_request();
$r->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'} = $r->notes->{_journal};
BML::set_language_scope("/talkread.bml");
} else {
$old_url = 1;
}
# pre-load common strings for little speed and less typing later
# (we're doing this *after* set_language_scope is called, because
# a few below are relative strings)
my %T = qw(postcomments talk.commentpost
readcomments talk.commentsread
parent talk.parentlink
thread talk.threadlink
threadroot talk.threadrootlink
expand talk.expandlink
expandall talk.expandalllink
replythis talk.replytothis
screened talk.screened
frozen talk.frozen
link talk.commentpermlink
deleted .subjectdeleted
nosubject .nosubject
hide talk.hide
unhide talk.unhide
maxcomments .maxcomments
);
foreach (keys %T) { $T{$_} = $ML{$T{$_}}; }
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");
}
# redirect if account was renamed
if ( $u->is_redirect ) {
my $redirect = $u->redirect_rename( "/$ditemid.html" );
return $redirect if $redirect;
}
# 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'};
# FIXME: Only gets past here if handle_with_bml has been set
# to 1. (eg. format=light, lynx site scheme)
$r->notes->{journalid} = $u->{userid};
my $thread = $init->{'thread'};
my $dthread = $init->{'dthread'};
$itemid = $init->{'itemid'}+0;
# Get format/style parameters to pass to the URL later
my $style_args = LJ::viewing_style_args( %GET, %$init );
my $item = LJ::Talk::get_journal_item($u, $itemid);
# translate from old to new url styles
if ($init->{'oldurl'} && $item) {
$init->{'anum'} = $item->{'anum'};
$init->{'ditemid'} = $init->{'itemid'}*256 + $item->{'anum'};
$ditemid = $init->{'ditemid'} + 0;
}
my $entry = LJ::Entry->new($u, ditemid => $ditemid);
my $maxcomments = ( $entry->reply_count >= $u->count_maxcomments ) ? 1 : 0;
# canonical link to the entry or comment thread
$$head .= LJ::canonical_link( $entry->url, $GET{thread} );
$u->preload_props("opt_blockrobots", "adult_content") if $u->is_visible;
if (!$u->is_visible || $u->should_block_robots || ($entry && $entry->should_block_robots)) {
$$head .= LJ::robot_meta_tags();
}
unless ($item && $item->{'anum'} == $init->{'anum'}) {
return "<?h1 $ML{'Error'} h1?><?p $ML{'talk.error.noentry'} p?>";
}
my $jarg = "journal=$u->{user}&";
my $jargent ="journal=$u->{user}&amp;";
my $talkurl = $u->journal_base . "/$ditemid.html";
my $ret = "";
### load users
my ($up); # $up = user posted journal item
LJ::load_userids_multiple([ $item->{'posterid'} => \$up, ], [ $u ]);
LJ::text_out(\$u->{'name'});
# get currently logged in user
my $remote = LJ::get_remote();
#
# Lots of logic to determine permissions for what can be viewed
#
# set viewall/viewsome
my $viewall = 0;
my $viewsome = 0;
if ( $remote ) {
( $viewall, $viewsome ) =
$remote->view_priv_check( $u, $GET{viewall}, 'entry', $item->{itemid} );
}
# check for deleted/suspended/security
unless ($viewsome) {
# check suspended user
return "<?h1 $ML{'talk.error.suspended.title'} h1?><?p $ML{'talk.error.suspended'} p?>"
if ($u->is_suspended || $up->is_suspended);
# check deleted
if ( $u->is_deleted ) {
$$title = "";
return $u->display_journal_deleted( $remote, bml => {
title => \$actual_title,
head => $head } );
}
# check suspended entry
return "<?h1 $ML{'talk.error.suspended.title'} h1?><?p " . BML::ml('talk.error.suspendedentry', { aopts => "href='" . $u->journal_base . "/'" }) . " p?>"
if $entry && $entry->is_suspended_for($remote);
}
unless ($viewall) {
#### Check security before viewing this post
my $errtxt;
return $errtxt unless LJ::Talk::check_viewable($remote, $item, \%GET, \$errtxt);
}
my $props = $item->{'props'};
my $nocomments = $viewall ? 0 :
$u->{'opt_showtalklinks'} eq "N" ? 1 : $entry->comments_disabled;
#
# End of permissions logic
#
# See if we should inject QuickReply javascript
LJ::Hooks::run_hooks("need_res_for_journals", $u);
LJ::need_res( qw(
js/thread_expander.js
stc/talkpage.css
) );
LJ::need_res( { group => "jquery" }, qw(
js/jquery.threadexpander.js
js/jquery.poll.js
js/jquery.mediaplaceholder.js
stc/talkpage.css
) );
LJ::set_active_resource_group( "jquery" )
if LJ::BetaFeatures->user_in_beta( $remote => "journaljquery" );
if ( ( $remote && ! $remote->prop( "opt_no_quickreply" ) ) && ! $nocomments ) {
# quickreply js libs
LJ::need_res( qw(
js/x_core.js
js/quickreply.js
) );
LJ::need_res( { group => "jquery" }, qw(
js/jquery/jquery.ui.widget.js
js/jquery.quickreply.js
) );
LJ::need_res( LJ::Talk::init_iconbrowser_js( LJ::BetaFeatures->user_in_beta( $remote => "journaljquery" ), 'stc/lj_base.css' ) )
if $remote->can_use_userpic_select;
}
my $showmultiform = $remote && ( ( $up && $remote->equals( $up) ) ||
$remote->can_manage( $u ) );
my $multiform_selects = 0; # are there select boxes? don't show form if not.
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, });
LJ::expand_embedded($u, $ditemid, $remote, \$event);
BML::ebml(\$event);
# make the title, which should be "(no subject)" if there isn't one
{
my $subject = $item->{'subject'} || BML::ml('.nosubject');
# 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";
}
$ret .= "<p>";
$ret .= "<table summary='' id='poster'><tr>";
my ( $userpic, $kw ) = $entry->userpic;
LJ::Hooks::run_hook('notify_event_displayed', $entry);
# Build the userpic image tag for the entry's userpic
my %userpics;
if ($userpic) {
my $apre = "<td class='userpic' valign='bottom'><a href='". $up->allpics_base . "'>";
my $apost = "</a></td>";
# for each image, get the html imgtag
$ret .= $apre . $userpic->imgtag( keyword => $kw, user => $up ) . $apost;
}
$ret .= "<td class='attrib' valign='bottom'>";
unless ( $u->equals( $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 $etime = LJ::mysqldate_to_time( $item->{eventtime} );
$etime = LJ::S2::sitescheme_secs_to_iso( $etime );
$ret .= LJ::Talk::format_eventtime( $etime, $u );
$ret .= "</td></tr></table>";
## standout bar
$ret .= LJ::Talk::link_bar({ 'u' => $u, 'up' => $up, 'headref' => $head,
'remote' => $remote, 'itemid' => $ditemid, });
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>";
}
## dump the log entry, unless we're browsing a thread.
my %current = LJ::currents( $props, $up, { entry => $entry } );
$ret .= "<div id='entry' class='usercontent' style='margin-left: 30px'>";
$ret .= LJ::currents_table( %current );
### 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");
}
}
# age restriction settings
my $age_restriction = "";
my $entry_age_prop = $item->{props}->{adult_content} || "";
if ( $entry_age_prop eq "explicit" ) {
$age_restriction = LJ::img( "adult-18" );
} elsif ( $entry_age_prop eq "concepts" ) {
$age_restriction = LJ::img( "adult-nsfw" );
}
###
my $subject;
if ( $item->{subject} ) {
$subject = LJ::CleanHTML::quote_html( $item->{subject}, $GET{nohtml} );
LJ::CleanHTML::clean_subject(\$subject);
BML::ebml(\$subject);
} else {
$subject = $T{nosubject};
}
my $flags = ( $sec or $age_restriction ) ? "$sec$age_restriction " : "";
$ret .= qq{<div id='entrysubj'>$flags<h2><a href="$talkurl">$subject</a></h2></div>\n};
$event = LJ::CleanHTML::quote_html( $event, $GET{nohtml} );
$ret .= $event;
$ret .= "</div>";
$ret .= "<br style='clear: both' /><hr width='100%' size='2' align='center' />";
my $view_arg = $GET{'view'} || "";
my $flat_mode = ($view_arg =~ /\bflat\b/);
my $top_only = ($view_arg =~ /\btop-only\b/);
my $view_num = ($view_arg =~ /(\d+)/) ? $1 : undef;
my $expand_all = ( $u->thread_expand_all( $remote ) && $GET{'expand_all'} );
my %user;
my $opts = {
'flat' => $flat_mode,
'top-only' => $top_only,
'thread' => $thread,
'page' => $GET{'page'},
'view' => $view_num,
'userpicref' => \%userpics,
'userref' => \%user,
'up' => $up,
'viewall' => $viewall,
'filter' => $GET{comments},
'expand_all' => $expand_all,
};
my @comments = LJ::Talk::load_comments($u, $remote, "L", $itemid, $opts);
return $ML{'error.nodbmaintenance'} if $opts->{'out_error'} eq "nodb";
my $page = $opts->{out_page};
my $pages = $opts->{out_pages};
my $has_collapsed = $opts->{out_has_collapsed};
# this overrides the default self_link to add the #comments anchor
my $self_link = sub { BML::self_link( { page => $_[0] } ) . "#comments" };
my $nav = LJ::paging_bar( $page, $pages, { self_link => $self_link } );
# Quick reply variables. Not always set.
my ($last_talkid, $last_jid) = LJ::get_lastcomment();
# data structure to give to javascript for commentmanage
my %LJ_cmtinfo = %{ LJ::Comment->info( $u ) };
$LJ_cmtinfo{form_auth} = LJ::form_auth( 1 );
my $show_thread_expander = $u->show_thread_expander( $remote );
#
# Recurse through a thread and display each comment
#
my $recurse_post = sub
{
my ($self_sub, $post, $opts) = @_;
$opts ||= { 'depth' => 0 };
my $tid = $post->{'talkid'};
my $dtid = $tid * 256 + $init->{'anum'};
my $LJci = $LJ_cmtinfo{$dtid} = { rc => [], u => '', full => $post->{_loaded}, deleted => ( $post->{state} eq "D" ), screened => ( $post->{state} eq "S" ) };
my $datepost = LJ::S2::sitescheme_secs_to_iso( $post->{datepost_unix}, tz => 1 );
my $level = ($opts->{'depth'} % 2) ? "even" : "odd";
my $additional_classes = "";
$additional_classes .= "screened " if $post->{state} eq "S";
$additional_classes .= "highlight " if $last_talkid == $dtid && $last_jid == $u->userid;
$additional_classes .= "noicon " unless $post->{picid};
# Gather information about the comment poster
my $pu = $post->{'posterid'} ? $user{$post->{'posterid'}} : undef;
$LJci->{u} = $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 $htmlid = LJ::Talk::comment_htmlid( $dtid );
my $hidestyle = $post->{'hidden_child'} ? " style=\"display: none;\"" : "";
if ($post->{'state'} eq "D") {
$ret .= "<div class='comment dwexpcomment' id='$htmlid'><p><a name='$htmlid'></a><table summary='' class='delcomment'$hidestyle><tr>";
$ret .= "<td class='spacer'><img src='$LJ::IMGPREFIX/dot.gif' alt='' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
$ret .= "<td>$ML{'.deletedpost'}</td>";
if ($post->{'hide_children'} && $post->{'children'} && @{$post->{'children'}}) {
if ( grep {! $_->{_loaded} and !($_->{state} eq "D")} @{$post->{'children'}} ) {
my $url = LJ::Talk::talkargs( $talkurl, "thread=$dtid", $style_args ) . LJ::Talk::comment_anchor( $dtid );
$ret .= "<td>";
# if we're in top-only mode, then we display the
# expand link as the unhide ('show x comments')
# message
if ( LJ::BetaFeatures->user_in_beta( $remote => "journaljquery" ) ) {
$ret .= qq[(<a href='$url' onClick="Expander.make(this,'$url','$dtid',true,true);return false;">];
$ret .= BML::ml( 'talk.unhide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
} else {
# unhide only works with jquery; if the user
# isn't in the jquery beta, drop back down to
# the no-javascript option
$ret .= qq[(<a href='$url'>];
$ret .= BML::ml( 'talk.unhide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
}
$ret .= "</td>";
}
}
$ret .= "</tr></table></div>\n";
} elsif ($post->{'state'} eq "S" && !$post->{'_loaded'} && !$post->{'_show'}) {
$ret .= "<p><a name='$htmlid'></a><table summary='' class='screenedcomment'$hidestyle><tr>";
$ret .= "<td class='spacer'><img src='$LJ::IMGPREFIX/dot.gif' alt='' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
my $screenedtext = $ML{'.screenedpost'};
$ret .= "<td>$screenedtext</td>";
if ($post->{'hide_children'} && $post->{'children'} && @{$post->{'children'}}) {
if ( grep {! $_->{_loaded} and !($_->{state} eq "D")} @{$post->{'children'}} ) {
my $url = LJ::Talk::talkargs( $talkurl, "thread=$dtid", $style_args ) . LJ::Talk::comment_anchor( $dtid );
$ret .= "<td>";
# if we're in top-only mode, then we display the
# expand link as the unhide ('show x comments')
# message
if ( LJ::BetaFeatures->user_in_beta( $remote => "journaljquery" ) ) {
$ret .= qq[(<a href='$url' onClick="Expander.make(this,'$url','$dtid',true,true);return false;">];
$ret .= BML::ml( 'talk.unhide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
} else {
# unhide only works with jquery; if the user
# isn't in the jquery beta, drop back down to
# the no-javascript option
$ret .= qq[(<a href='$url'>];
$ret .= BML::ml( 'talk.unhide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
}
$ret .= "</td>";
}
}
$ret .= "</tr></table>\n";
} elsif ($pu && $pu->is_suspended && !$viewsome) {
$ret .= "<p><a name='$htmlid'></a><table summary='' class='suspendedcomment'$hidestyle><tr>";
$ret .= "<td class='spacer'><img src='$LJ::IMGPREFIX/dot.gif' alt='' 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?${jargent}id=$dtid'>" . LJ::img("btn_del", "", { align => 'absmiddle', hspace => 2 }) . "</a>";
}
if ($post->{state} ne 'F' && LJ::Talk::can_freeze($remote, $u, $up, $userpost)) {
$ret .= "<a href='$LJ::SITEROOT/talkscreen?mode=freeze&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2 }) . "</a>";
}
if ($post->{state} eq 'F' && LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) {
$ret .= "<a href='$LJ::SITEROOT/talkscreen?mode=unfreeze&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2 }) . "</a>";
}
$ret .= "</td></tr></table>\n";
} else {
if ($upost) {
$user = LJ::ljuser($upost);
}
my $icon = LJ::Talk::show_image($pics, $post->{'props'}->{'subjecticon'});
if ($post->{'_loaded'}) {
my $comment = LJ::Comment->new($u, dtalkid => $dtid);
my $edittime;
my $editreason = "";
if ($comment->is_edited) {
$edittime = LJ::S2::sitescheme_secs_to_iso( $comment->edit_time, tz => 1 );
$editreason = LJ::ehtml( $comment->edit_reason );
$editreason = "($editreason)" if $editreason;
}
$ret .= "<div class='comment dwexpcomment' id='$htmlid'><table summary='' width='100%' class='talk-comment'><tbody><tr>";
$ret .= "<td rowspan='2' class='spacer'><img src='$LJ::IMGPREFIX/dot.gif' alt='' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
$ret .= "<td id='cmtbar$dtid' class='cmtbar $level $additional_classes' width='100%'>";
# Build the image tag for the comment's userpic, if there is one
if ($post->{picid}) {
# get the userpic object
my $postpic = LJ::Userpic->new( $pu, $post->{picid} );
# get the picture keyword from the comment properties
# get the comment poster as well
my %kwopts = (
keyword => $post->{pickw},
user => $upost,
);
# build the imgtag for the userpic associated with the keyword
$ret .= "<div class='icon'><a href='" . $upost->allpics_base . "'>" . $postpic->imgtag( %kwopts ) . "</a></div>";
}
my $cleansubject = LJ::ehtml( $post->{'subject'} );
if ( $cleansubject eq "" ) {
$cleansubject = "<span class='invisible'>no subject</span>";
}
my $echitext = "";
if ( $post->{echi} ) {
$echitext = qq{<span class="echi">$post->{echi}.</span> };
}
if ( $post->{state} eq 'S' ) {
$ret .= "<h3 class='commentsubject'>" . BML::ml( '.comment.screened.subject' ) . "$echitext$cleansubject</h3> $icon";
} else {
$ret .= "<h3 class='commentsubject'>$echitext$cleansubject</h3> $icon";
}
$ret .= "<br />$user\n";
$ret .= " " . BML::ml( '.from_external', {site=>$post->{props}->{imported_from}} ) if $post->{props}->{imported_from};
$ret .= "<br /><span class='datepost'>$datepost</span>\n";
if ( $post->{'props'}->{'poster_ip'} && $remote &&
( $viewall || $remote->equals( $up ) ||
$remote->can_manage( $u ) ) ) {
$ret .= BML::ml('.fromip', {'ip'=>$post->{'props'}->{'poster_ip'}});
}
$ret .= " <span class='talkargs'>(<a href='";
$ret .= LJ::Talk::talkargs( $talkurl, "thread=$dtid", $style_args );
$ret .= LJ::Talk::comment_anchor( $dtid ) . "'>$T{'link'}</a>)</span>";
if ($comment->remote_can_edit) {
$ret .= "<a href='" . LJ::Talk::talkargs( $comment->edit_url, $style_args ) . "'>" . LJ::img("editcomment", "", { align => 'absmiddle', hspace => 2 }) . "</a>";
}
if (LJ::Talk::can_delete($remote, $u, $up, $userpost)) {
$ret .= "<a href='$LJ::SITEROOT/delcomment?${jargent}id=$dtid'>" . LJ::img("btn_del", "", { align => 'absmiddle', hspace => 2 }) . "</a>";
}
if ($post->{'state'} ne 'F' &&
LJ::Talk::can_freeze($remote, $u, $up, $userpost)) {
$ret .= "<a href='$LJ::SITEROOT/talkscreen?mode=freeze&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_freeze", "", { align => 'absmiddle', hspace => 2 }) . "</a>";
}
if ($post->{'state'} eq 'F' &&
LJ::Talk::can_unfreeze($remote, $u, $up, $userpost)) {
$ret .= "<a href='$LJ::SITEROOT/talkscreen?mode=unfreeze&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_unfreeze", "", { align => 'absmiddle', hspace => 2 }) . "</a>";
}
if ($post->{'state'} ne 'S' &&
LJ::Talk::can_screen($remote, $u, $up, $userpost)) {
$ret .= "<a href='$LJ::SITEROOT/talkscreen?mode=screen&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_scr", "", { align => 'absmiddle', hspace => 2 }) . "</a>";
}
if ($post->{'state'} eq 'S' &&
LJ::Talk::can_unscreen($remote, $u, $up, $userpost)) {
$ret .= "<a href='$LJ::SITEROOT/talkscreen?mode=unscreen&amp;${jargent}talkid=$dtid'>" . LJ::img("btn_unscr", "", { align => 'absmiddle', hspace => 2 }) . "</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
$track_img = 'track_thread_active' if $comment->thread_has_subscription( $remote, $u );
}
my $track_url = "$LJ::SITEROOT/manage/tracking/comments?journal=$u->{'user'}&amp;talkid=$dtid";
$ret .= "<a href='$track_url'>" . LJ::img($track_img, '', {'align' => 'absmiddle'}) . "</a>";
}
if ($showmultiform) {
$ret .= " <nobr><input type='checkbox' name='selected_$tid' id='s$tid' />";
$ret .= " <label for='s$tid'>$ML{'.select'}</label></nobr>";
$multiform_selects = 1;
}
# Comment Posted Notice
$ret .= "<br /><b>$ML{'.posted'}</b>"
if $last_talkid == $dtid && $last_jid == $u->userid;
$ret .= "</td></tr><tr><td class='commentbody usercontent'>";
LJ::CleanHTML::clean_comment( \$post->{body}, { preformatted => $post->{'props'}->{'opt_preformatted'},
anon_comment => LJ::Talk::treat_as_anon( $pu, $u ),
} );
BML::ebml(\$post->{'body'});
my $event = LJ::CleanHTML::quote_html( $post->{body}, $GET{nohtml} );
my $edit_html = $edittime ? "<br /><br /><span class='edittime'><em>" . BML::ml('.edittime', { editreason => $editreason, edittime => $edittime }) . "</em></span>" : "";
$ret .= "$event$edit_html";
$ret .= "<p style='margin: 0.7em 0 0.2em 0'><font size='-2'>";
my $replyurl = LJ::Talk::talkargs( $talkurl, "replyto=$dtid", $style_args );
if ($post->{'state'} eq 'F') {
$ret .= "($T{'frozen'})&nbsp; ";
} elsif ( ! $maxcomments ) {
if ($remote) {
if ( $post->{state} eq 'S' ) {
# if the user can see the comment, they can also reply
# if they can also unscreen, they are given the option to reply and unscreen
$ret .= "(" . LJ::make_qr_link( $dtid, $post->{subject}, $T{replythis}, $replyurl ) . ")&nbsp; ";
} else {
$ret .= "(" . LJ::make_qr_link($dtid, $post->{'subject'}, $T{'replythis'}, $replyurl) . ")&nbsp; ";
}
} else {
$ret .= "(<a href='$replyurl'>$T{'replythis'}</a>)&nbsp; ";
}
}
my $parentid = $post->{'parenttalkid'} || $post->{'parenttalkid_actual'};
if ($parentid != 0) {
my $rooturl = $comment->threadroot_url( LJ::viewing_style_args( %GET ) );
$ret .= "(<a href='$rooturl'>$T{'threadroot'}</a>)&nbsp; ";
my $dpid = $parentid * 256 + $init->{'anum'};
$ret .= "(<a href='" . LJ::Talk::talkargs( $talkurl, "thread=$dpid", $style_args );
$ret .= LJ::Talk::comment_anchor( $dpid ) . "'>$T{'parent'}</a>)&nbsp; ";
}
if ($post->{'children'} && @{$post->{'children'}}) {
my $url = LJ::Talk::talkargs( $talkurl, "thread=$dtid", $style_args ) . LJ::Talk::comment_anchor( $dtid );
$ret .= "(<a href='$url'>$T{'thread'}</a>)&nbsp; ";
if ((grep {! $_->{_loaded} and !($_->{state} eq "D")} @{$post->{'children'}}) && $show_thread_expander) {
if ( $post->{'hide_children'} ) {
# if we're in top-only mode, then we display the
# expand link as the unhide ('show x comments')
# message
if ( LJ::BetaFeatures->user_in_beta( $remote => "journaljquery" ) ) {
$ret .= qq[(<a href='$url' onClick="Expander.make(this,'$url','$dtid',true,true);return false;">];
$ret .= BML::ml( 'talk.unhide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
} else {
# unhide only works with jquery; if the user
# isn't in the jquery beta, drop back down to
# the no-javascript option
$ret .= qq[(<a href='$url'>];
$ret .= BML::ml( 'talk.unhide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
}
} else {
$ret .= qq[(<a href='$url' onClick="Expander.make(this,'$url','$dtid',true);return false;">$T{'expand'}</a>)];
}
}
if ( $show_thread_expander ) {
if ( LJ::BetaFeatures->user_in_beta( $remote => "journaljquery" ) ) {
my $hideclass = $post->{'hide_children'} ? "" : " cmt_show_hide_default";
$ret .= qq[ <span id="cmt${dtid}_hide" class="cmt_hide$hideclass" style="display:none;">(<a href='#' onClick="Expander.hideComments(this,'$dtid',true);return false;">];
$ret .= BML::ml( 'talk.hide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
$ret .= qq[ <span id="cmt${dtid}_unhide" style="display: none;" class="cmt_unhide">(<a href='#' onClick="Expander.unhideComments(this,'$dtid',true);return false;">];
$ret .= BML::ml( 'talk.unhide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
}
}
}
$ret .= "</font></p><br />";
$ret .= LJ::make_qr_target($dtid) if $remote;
$ret .= "</td></tr></tbody></table></div>\n"; # close colored table
} else {
# link to message
my $url = LJ::Talk::talkargs( $talkurl, "thread=$dtid", $style_args ) . LJ::Talk::comment_anchor( $dtid );
$ret .= "<div class='comment dwexpcomment' id='$htmlid'$hidestyle><table summary=''><tbody><tr>";
$ret .= "<td class='spacer'><img src='$LJ::IMGPREFIX/dot.gif' alt='' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
$ret .= "<td class='cmtpartial'>";
if ($post->{'state'} eq 'F') {
$ret .= "($T{'frozen'}) ";
}
my $echitext = "";
if ( $post->{echi} ) {
$echitext = qq{<span class="echi">$post->{echi}.</span> };
}
$ret .= "<a href='$url'>$echitext" . LJ::ehtml($post->{'subject'} || $T{'nosubject'}) . "</a> - $user, <i>$datepost</i>";
$ret .= qq[ (<a href='$url' onClick="Expander.make(this,'$url','$dtid',true);return false;">$T{'expand'}</a>)] if $show_thread_expander;
# Comment Posted Notice
$ret .= " - <b>$ML{'.posted'}</b>"
if $last_talkid == $dtid && $last_jid == $u->userid;
$ret .= "</td></tr></tbody></table></div>\n";
}
}
if ($post->{'children'}) {
foreach my $childpost (@{$post->{'children'}}) {
push @{$LJci->{rc}}, $childpost->{talkid} * 256 + $init->{'anum'};
$self_sub->($self_sub, $childpost, { "depth" => $opts->{'depth'} + 1});
}
}
};
#
# Display comment threads and commenting UI
#
if ( $nocomments ) {
$ret .= BML::ml( "talk.comments.disabled_maintainer" ) if $entry->comments_disabled_maintainer;
} else {
$ret .= "<div id='Comments'>";
$ret .= "<a name='comments'></a>";
$ret .= "<p>$nav</p>" if $nav;
my $readlink;
my $replycount = $entry->prop("replycount");
my $readlink_text;
my $comments_count;
my $totalcount = $replycount;
# show total number of comments, including screened comments if the viewer is allowed to
if ( $remote && LJ::Talk::can_screen( $remote, $u, $up ) && $entry->prop("hasscreened") ) {
my $screenedcount = LJ::Talk::get_screenedcount( $u, $itemid );
$totalcount = $replycount + $screenedcount;
$readlink_text = BML::ml( "talk.commentsread.counted.screened",
{ replycount => $replycount, screenedcount => $screenedcount } );
$comments_count = BML::ml( "talk.comments.counted.screened",
{ replycount => $replycount, screenedcount => $screenedcount } );
} else {
$readlink_text = BML::ml( "talk.commentsread.counted",
{ replycount => $replycount } );
$comments_count = BML::ml( "talk.comments.counted",
{ replycount => $replycount } ) if $replycount > 0;
}
if ( $dthread && $pages == 1 ) {
my $readurl = LJ::Talk::talkargs( $talkurl, $style_args );
$readlink = "(<a href='$readurl#comments'>$readlink_text</a>) - ";
} else {
$readlink = "($comments_count) - " if $totalcount > 0;
}
#
# Commenting UI
#
my $posturl = LJ::Talk::talkargs( $talkurl, "mode=reply", $style_args );
$ret .= "<form style='display: inline' method='post' action='$LJ::SITEROOT/talkmulti' name='multiform' id='multiform' >";
# Quick Reply when posting a new top level comment
# requires setup when logged in.
$ret .= "<p class='lesstop' align='center'><b>$readlink";
if ( $maxcomments ) {
$ret .= "($T{maxcomments})";
} else {
if ($remote) {
$ret .= "(" . LJ::make_qr_link('top', '', $T{'postcomments'}, $posturl) . ")";
} else {
$ret .= "(<a href='$posturl'>$T{'postcomments'}</a>)";
}
}
$ret .= "<br>\n";
# comment nav
my $viewlinks = "";
my $view_mode = $flat_mode ? "flat" : $top_only ? "top-only" : "threaded";
if ( $view_mode eq "threaded" ) {
$viewlinks .= "(<a href = '" . BML::self_link( { view => 'flat' } ) . "#comments'>" . BML::ml('.commentnav.flat') . "</a>) (<a href = '" . BML::self_link( { view => 'top-only' } ) . "#comments'>" . BML::ml('.commentnav.toponly') . "</a>)";
} elsif ( $view_mode eq "flat" ) {
$viewlinks .= "(<a href = '" . BML::self_link( { view => '' } ) . "#comments'>" . BML::ml('.commentnav.threaded') . "</a>) (<a href = '" . BML::self_link( { view => 'top-only' } ) . "#comments'>" . BML::ml('.commentnav.toponly') . "</a>)";
} elsif ( $view_mode eq "top-only" ) {
$viewlinks .= "(<a href = '" . BML::self_link( { view => '' } ) . "#comments'>" . BML::ml('.commentnav.threaded') . "</a>) (<a href = '" . BML::self_link( { view => 'flat' } ) . "#comments'>" . BML::ml('.commentnav.flat') . "</a>)";
}
if ( $u->thread_expand_all( $remote ) && $has_collapsed && $view_mode ne "top-only" ) {
my $expand_all_url = $page > 1 ? BML::self_link( { expand_all => '1', page => $page } ) . "#comments" : BML::self_link( { expand_all => '1' } ) . "#comments";
$viewlinks .= "<span class='expand_all'> (<a href=\"$expand_all_url\" onClick=\"Expander.make(this,'$expand_all_url',-1,true,false);return false;\">" . $T{expandall} . "</a>)</span>";
}
$ret .= $viewlinks;
$ret .= "</b></p>";
$ret .= "<div align='center'>" . LJ::make_qr_target('top') . "</div>" if $remote;
my $styleopts = LJ::viewing_style_opts( %GET );
#
# Comment thread display
#
my $viewing_thread;
if (defined $GET{'thread'}) {
$viewing_thread = $GET{'thread'};
}
$ret .= LJ::create_qr_div( $u, $ditemid, $styleopts, $GET{prop_picture_keyword}, $viewing_thread );
$ret .= LJ::html_hidden("ditemid", $ditemid);
$ret .= LJ::html_hidden("journal", $u->{'user'});
# Print out each comment
if (@comments > 0)
{
$recurse_post->($recurse_post, $_, { "depth" => 0 }) foreach (@comments);
my $do_commentmanage_js = LJ::is_enabled('commentmanage', $remote);
if ($do_commentmanage_js) {
LJ::need_res('js/commentmanage.js');
LJ::need_res( { group => "jquery" }, qw(
js/jquery/jquery.ui.tooltip.js
js/jquery.ajaxtip.js
js/jquery/jquery.ui.button.js
js/jquery/jquery.ui.dialog.js
js/jquery.commentmanage.js
js/jquery/jquery.ui.position.js
stc/jquery/jquery.ui.tooltip.css
stc/jquery/jquery.ui.button.css
stc/jquery/jquery.ui.dialog.css
stc/ajaxtip.css
stc/jquery.commentmanage.css
) );
my $js_screen_color = "\"" . LJ::ejs(BML::get_template_def("screenedbarcolor") || BML::get_template_def("emcolor")) . "\"";
my $js_normal_color = "\"" . LJ::ejs(BML::get_template_def("emcolor")) . "\"";
$$head .= "<script>var LJ_cmtinfo = " . LJ::js_dumper(\%LJ_cmtinfo) . ";\n" .
"function userhook_screen_comment_ARG (dIid) { setStyle('cmtbar'+dIid, 'background', $js_screen_color); }\n".
"function userhook_unscreen_comment_ARG (dIid) { setStyle('cmtbar'+dIid, 'background', $js_normal_color); }\n".
"var Site; if (!Site) Site = new Object(); Site.imgprefix = \"$LJ::IMGPREFIX\";\n".
"</script>\n";
}
$ret .= "<hr /><p class='lesstop' align='center'><b>$readlink";
if ( $maxcomments ) {
$ret .= "($T{maxcomments})";
} else {
if ( $remote ) {
$ret .= "(" . LJ::make_qr_link('bottom', '', $T{'postcomments'}, $posturl) . ")";
} else {
$ret .= "(<a href='$posturl'>$T{'postcomments'}</a>)";
}
}
$ret .= "<br>\n";
$ret .= $viewlinks;
$ret .= "</b></p>";
$ret .= "<div align='center'>" . LJ::make_qr_target('bottom') . "</div>" if $remote;
if ($showmultiform && $multiform_selects) {
$ret .= "<p><label for='multiform_mode'>$ML{'.talkmulti.des'}</label>";
my @actions = ( '' => '',
unscreen => $ML{'.talkmulti.unscreen'},
screen => $ML{'.talkmulti.screen'},
delete => $ML{'.talkmulti.delete'},
);
push @actions, deletespam => $ML{'.talkmulti.deletespam'} unless LJ::sysban_check( 'spamreport', $u->user );
$ret .= LJ::html_select( { name => 'mode', id => 'multiform_mode' }, @actions );
$ret .= " " . LJ::html_submit('', $ML{'.talkmulti.submit'},
{
"onclick" =>
'return ((document.multiform.mode.value != "delete" ' .
'&& document.multiform.mode.value != "deletespam")) ' .
"|| confirm(\"" . LJ::ejs($ML{'.confirm.action'}) . "\");"
});
$ret .= "</p>";
}
}
$ret .= "</form>";
if ($nav) {
$ret .= "<p>$nav</p>";
}
$ret .= "</div>";
}
BML::noparse();
return $ret;
}
_code?>
<=body
title=><?_code return $actual_title; _code?>
windowtitle=><?_code return $_[1] ? $_[1]->{'title'} : $r_title _code?>
head=><?_code return $_[1] ? $_[1]->{'head'} : $r_head _code?>
bodyopts=><?_code return "id='page_talkread' class='self_wrap'" . $_[1]->{'bodyopts'}; _code?>
page?>
Jump to Line
Something went wrong with that request. Please try again.