Description:
This box lists recently commented stories.
The stories are sorted by the date-and-time of each story's most recent comment. Whenever a comment is posted anywhere in your forum, the story pops to the top of this list.
This box will allow your users to keep alive any discussion on the forum, no matter how old. It will also help you catch comment spam, the spam will show up no matter where it's been posted. (Except under downvoted stories.)
The listing includes comment count, complete with "N new". Below each story, the last few comments that are new to the user are listed. (To disable this, set count to 0 below.)
See example at www.theworldforum.org.
Box Code:
####
#
# This box lists recently commented stories.
#
# The stories are sorted by the date-and-time of each story's
# most recent comment. Whenever a comment is posted anywhere
# in your forum, the story pops to the top of this list.
#
# This box will allow your users to keep alive any discussion
# on the forum, no matter how old. It will also help you catch
# comment spam, the spam will show up no matter where it's been
# posted. (Except under downvoted stories.)
#
# The listing includes comment count, complete with "N new".
# Below each story, the last few comments that are new to the
# user are listed. (To disable this, set count to 0 below.)
#
# See example at www.theworldforum.org.
#
# STYLE CLASSES -----------------------------------------------
#
# You need to define two style classes (or modify the
# presentation code). Here's how I've done it at The
# World Forum:
#
# .box .NewCommentCount
# { color: #f00;
# }
#
# .box .TinyCommentTitle
# { padding-left: 0.9em;
# text-indent: -0.9em;
# }
#
# DETAILS ------------------------------------------------------
#
# For anonymous visitors the listing skips stories in editing
# and voting. For users without Trusted status the listing skips
# hidden comments.
#
# Comments under downvoted stories are not included in the listing.
# Unfortunately they can be accessed with yourdomain/comments/...
# They should be inaccessible to users who are not allowed to
# moderate.
#
# Warning: Seems to take about 0.2 seconds for 10 stories
# (measured as 15 seconds for 780 stories with 1876 comments
# -- unreliable, I just listed start and end time on a
# somewhat busy server.)
#
# Bug: When comments have been deleted the new-comment count
# ("N new") will sometimes be incorrect, a negative number.
#
# Bug: May split " in titles so that it's shown as
# " rather than ".
#
# IF YOU EDIT THIS SOURCE TEXT ---------------------------------
#
# Warning: Due to some bug you can't fetch the source in Scoop
# and edit. Something gets corrupted in the Scoop textarea. You
# must keep a copy in a text file.
#
# Warning: contains hacked, ugly HTML and a weird mixture of
# font tags and CSS.
#
# SETTINGS -----------------------------------------------------
#
# num_stories_to_show: how many stories to show in the box.
#
# num_comments_to_show: max number of comments below each story.
#
# titletrim_length: length of title to trim to for display
# (will display complete words up to this length).
#
# split_with: what to split long words with.
#
# wordsplit_length: longest words allowed in title without
# splitting.
#
# --------------------------------------------------------------
#
# By QuickFox, based on recent_stories by Drog, which I
# think in turn was based on recent_diaries by graouts,
# which in turn was a tweak of some box whose author's
# name seems to be lost in the mists of history.
#
####
# Settings -- Modify these to suit your forum.
my $new_comment_bullet = '<span class="NewCommentCount">»</span>';
my $old_comment_bullet = '»';
my $num_stories_to_show = 10;
my $story_titletrim_length = 45;
my $story_wordsplit_length = 17;
my $num_comments_to_show = 3;
my $comment_titletrim_length = 40;
my $comment_wordsplit_length = 17;
my $split_with = "<wbr>";
# End of settings. Preparations.
my $anonymous_nick = $S->var('anon_user_nick');
my $rating_min = $S->var('rating_min');
my $content = '';
my $uid = $S->{UID};
# Get stories sorted by comment date-and-time.
my ($rv, $sth) = $S->db_select
({ WHAT => q(c.sid, s.title, s.aid, s.tid, s.time, s.section, MAX(c.date) as max_c_date),
FROM => qq(comments AS c LEFT JOIN stories AS s ON s.sid = c.sid),
WHERE =>
( $S->have_perm('moderate') ?
'(s.displaystatus != -1)' :
'(s.displaystatus = 0 OR s.displaystatus = 1)'
) .
( $S->{TRUSTLEV} == 2 \|\| $S->have_perm('super_mojo') ?
'' :
" AND ((c.points >= $rating_min) OR ISNULL(c.points))"
),
GROUP_BY => q(c.sid),
ORDER_BY => q(max_c_date DESC),
LIMIT => $num_stories_to_show
});
my $story_table = $sth->fetchall_arrayref;
my $sids = join ',', map qq('$_->[0]'), @$story_table;
# Count the comments. Counting comments above would get incorrect
# results, since above we include only comments that the user can see.
my %comment_counts = ();
my ($rv, $sth) = $S->db_select
({ WHAT => q(c.sid, COUNT(c.sid)),
FROM => qq(comments AS c),
WHERE => qq(c.sid IN ($sids)),
GROUP_BY => q(c.sid)
});
my $commentcount_table = $sth->fetchall_arrayref;
$comment_counts{$_->[0]} = $_->[1] for @$commentcount_table;
# Get the viewed_story information for each of the selected stories.
# Doing it this way is MUCH faster than doing two outer joins.
# Skip this step if the viewer isn't logged in.
my %lastseen = ();
if ($uid > 0)
{ my ($rv, $sth) = $S->db_select
({ WHAT => q(v.sid, v.lastseen),
FROM => qq(viewed_stories AS v),
WHERE => qq(v.uid=$uid AND v.sid IN ($sids)),
});
my $tmp_table = $sth->fetchall_arrayref;
$lastseen{$_->[0]} = $_->[1] for @$tmp_table;
}
for (@$story_table)
{ my ($sid, $title, $aid, $tid, $time, $section, $max_c_date) = @$_;
my $lastseen = exists $lastseen{$sid} ? $lastseen{$sid} : 0;
my $comments = $comment_counts{$sid};
my $helptext = my $cutmark = '';
# Trim the title if it's too long.
if (length $title > $story_titletrim_length)
{ $helptext = qq(title="$title");
$title = substr($title, 0, $story_titletrim_length);
$title =~ s/(\S)\s+\S*$/$1/;
$cutmark = '...';
}
# Split long words in the title.
$title =~ s[(\S{$story_wordsplit_length,})][join $split_with, grep(/^./, split/(\S{$story_wordsplit_length})/, $1)]ge;
my $new_text = exists $lastseen{$sid} ? '' : qq(<span style="color: red;">[!] </span>);
$new_text = '' unless $uid > 0;
my $new_comments = $comments - $lastseen;
my $comments_text = '';
if ($comments)
{ $comments_text = qq(<b>$comments</b> comment) . ($comments == 1 ? '' : 's');
if ($new_comments && ($uid > 0))
{ $comments_text .= qq(<span class="NewCommentCount"> – $new_comments new</span>);
}
$comments_text = qq(<br>$comments_text\n)
};
my $nick = $S->get_nick_from_uid($aid) \|\| $anonymous_nick;
my $month =
(qw/Null January February March April May June July August September October November December/)
[substr($time, 5, 2)];
my $day = 0 + substr($time, 8, 2);
$content .=
qq{ <font face="arial, helvetica, sans-serif" size="-1">$new_text<b><a href="|rootdir|/story/$sid" $helptext
>$title</a
>$cutmark</b></font><br>
<font face="arial, helvetica, sans-serif" size="-2">
<a href="|rootdir|/search/?topic=$tid">$S->{TOPIC_DATA}->{$tid}->{alttext}</a> <wbr>–
<a href="|rootdir|/section/$section">$S->{SECTION_DATA}->{$section}->{title}</a>
<br>by <a href="|rootdir|/user/$nick">$nick</a>, $month $day$comments_text<br>
};
my $num_comments_to_fetch;
if ($new_comments > $num_comments_to_show)
{ $num_comments_to_fetch = $num_comments_to_show;
}
else
{ $num_comments_to_fetch = $new_comments;
}
# Get the most recent comments under this story
if ($num_comments_to_fetch)
{ #if ($new_comments > $num_comments_to_fetch)
#{ $content .= qq{<div class="TinyCommentTitle">...</div>};
#}
my ($rv, $sth) = $S->db_select
({ WHAT => 'u.nickname, c.subject, c.cid, c.sid, c.date',
FROM => qq(comments AS c LEFT JOIN users AS u ON u.uid = c.uid),
WHERE =>
"(c.sid = '$sid')" .
( $S->{TRUSTLEV} == 2 \|\| $S->have_perm('super_mojo') ?
'' :
" AND ((c.points >= $rating_min) OR ISNULL(c.points))"
),
ORDER_BY => 'date DESC',
LIMIT => $num_comments_to_fetch
});
my $comment_table = $sth->fetchall_arrayref;
my $subarray;
my ($nickname, $title, $cid, $sid, $date);
while ($subarray = pop @$comment_table)
{ ($nickname, $title, $cid, $sid, $date) = @$subarray;
$nickname \|\|= $anonymous_nick;
# trim the comment title if it is too long
$helptext = $cutmark = '';
if (length $title > $comment_titletrim_length)
{ $helptext = qq(title="$title");
$title = substr($title, 0, $comment_titletrim_length);
$title =~ s/(\S)\s+\S*$/$1/;
$cutmark .= '...';
}
# Split long words in the title.
$title =~ s[(\S{$comment_wordsplit_length,})][join $split_with, grep(/^./, split/(\S{$comment_wordsplit_length})/, $1)]ge;
my $month = (qw/Null Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/)[substr($date, 5, 2)];
my $day = 0 + substr($date, 8, 2);
my $bullet = (($uid > 0) ? $new_comment_bullet : $old_comment_bullet);
$content .=
qq{ <div class="TinyCommentTitle">
$bullet <A HREF="|rootdir|/comments/$sid/$cid#$cid" $helptext>$title</a>$cutmark <wbr>–
<a href="|rootdir|/user/$nickname">$nickname</a>, $month $day
</div>
};
}
}
$content .=
'</font><br>';
}
# Add the "More..." link
$content .=
qq{ <A HREf="|rootdir|/?op=search&offset=0&type=comment&search=Search">Comment search...</a>
|smallfont_end|
};
# Return content.
return {content => $content};
|