[dw-free] Add a link on comments that goes to the root of the thread
[commit: http://hg.dwscoalition.org/dw-free/rev/cc90e8be4b68]
http://bugs.dwscoalition.org/show_bug.cgi?id=153
Add support for link back to root of comment thread to comments.
Patch by
afuna.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=153
Add support for link back to root of comment thread to comments.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- bin/upgrading/en.dat
- bin/upgrading/s2layers/core2.s2
- cgi-bin/LJ/Comment.pm
- cgi-bin/LJ/S2/EntryPage.pm
- doc/raw/memcache-keys.txt
- htdocs/go.bml
- htdocs/talkread.bml
- t/comment.t
-------------------------------------------------------------------------------- diff -r 9603e41b3cc3 -r cc90e8be4b68 bin/upgrading/en.dat --- a/bin/upgrading/en.dat Tue Nov 03 00:50:48 2009 +0000 +++ b/bin/upgrading/en.dat Tue Nov 03 00:54:44 2009 +0000 @@ -3599,6 +3599,8 @@ talk.spellcheck=Check spelling during pr talk.threadlink=Thread +talk.threadrootlink=Thread from start + talk.unscreentoreply=Unscreen to reply time.ago.day=[[num]] [[?num|day|days]] ago diff -r 9603e41b3cc3 -r cc90e8be4b68 bin/upgrading/s2layers/core2.s2 --- a/bin/upgrading/s2layers/core2.s2 Tue Nov 03 00:50:48 2009 +0000 +++ b/bin/upgrading/s2layers/core2.s2 Tue Nov 03 00:54:44 2009 +0000 @@ -412,6 +412,7 @@ class Comment extends EntryLite var readonly string parent_url "URL to parent comment, or blank if a top-level comment."; var readonly string reply_url "URL to reply to this comment."; var readonly string thread_url "URL to view threaded rooted at this comment, or blank if comment has no children."; + var readonly string threadroot_url "URL to view the entire thread this comment is part of, or blank if a top-level comment."; var readonly bool screened "True if comment is in screened state."; var readonly bool frozen "True if comment is in frozen state."; var readonly bool deleted "True if comment has been deleted. Deleted comments still show up if they are the parent of a thread."; @@ -2182,6 +2183,11 @@ property string text_comment_thread { example = "Thread"; maxlength = "50"; } +property string text_comment_threadroot { + des = "Text to link to the entire thread this comment is part of"; + example = "Thread from start"; + maxlength = "50"; +} property string text_comment_expand { des = "Text to expand a collapsed comment thread"; example = "Expand"; @@ -2192,6 +2198,7 @@ set text_comment_parent = "Parent"; set text_comment_parent = "Parent"; set text_comment_link = "Link"; set text_comment_thread = "Thread"; +set text_comment_threadroot = "Thread from start"; set text_comment_expand = "Expand"; ##=============================== @@ -4226,6 +4233,7 @@ function Comment::print_interaction_link $this->print_reply_link({"linktext" => $*text_comment_reply}); """</li>\n"""; } + if ($this.threadroot_url != "") { print safe """<li class="link threadroot"><a href="$this.threadroot_url">$*text_comment_threadroot</a></li>\n""";} if ($this.parent_url != "") { print safe """<li class="link commentparent"><a href="$this.parent_url">$*text_comment_parent</a></li>\n"""; } if ($this.thread_url != "") { print safe """<li class="link thread"><a href="$this.thread_url">$*text_comment_thread</a></li>\n"""; diff -r 9603e41b3cc3 -r cc90e8be4b68 cgi-bin/LJ/Comment.pm --- a/cgi-bin/LJ/Comment.pm Tue Nov 03 00:50:48 2009 +0000 +++ b/cgi-bin/LJ/Comment.pm Tue Nov 03 00:54:44 2009 +0000 @@ -216,15 +216,29 @@ sub absorb_row { } sub url { - my $self = shift; + my ( $self, $url_args ) = @_; my $dtalkid = $self->dtalkid; my $entry = $self->entry; my $url = $entry->url; - return "$url?thread=$dtalkid" . LJ::Talk::comment_anchor( $dtalkid ); + return "$url?thread=$dtalkid" . ( $url_args ? "&$url_args" : "" ) . LJ::Talk::comment_anchor( $dtalkid ); } *thread_url = \&url; + +=head2 C<< $self->threadroot_url >> +URL to the thread root. It would be unnecessarily expensive to look up the thread +root, since it is only rarely needed. So we set up a redirect then look up the +thread root only if the user clicks the link. +=cut +sub threadroot_url { + my ( $self, $url_args ) = @_; + my $dtalkid = $self->dtalkid; + my $jitemid = $self->entry->jitemid; + my $journal =$self->entry->journal->user; + + return "$LJ::SITEROOT/go?redir_type=threadroot&journal=$journal&talkid=$dtalkid" . ( $url_args ? "&$url_args" : "" ); +} sub reply_url { my $self = shift; @@ -347,6 +361,56 @@ sub nodetype { __PACKAGE__->preload_rows([ $self->unloaded_singletons] ); return $self->{nodetype}; } + +=head2 C<< $self->threadrootid >> +Gets the id of the topmost comment in the thread this comment is part of. +If you just want to create a link, do not call this directly. Instead, use +$self->threadroot_url. +=cut +sub threadrootid { + + my ( $self ) = @_; + + # if this has no parent, then this is the thread root + return $self->jtalkid unless $self->parenttalkid; + + # if we have the information already, then just return it + return $self->{threadrootid} if $self->{threadrootid}; + + my $entry = $self->entry; + + # if it is in memcache, then use the cached value + my $jid = $entry->journalid; + my $memkey = [ $jid, "talkroot:$jid:" . $self->jtalkid ]; + + my $cached_threadrootid = LJ::MemCache::get( $memkey ); + if ( $cached_threadrootid ) { + $self->{threadrootid} = $cached_threadrootid; + return $cached_threadrootid; + } + + + # not cached anywhere; let's look it up + + # get all comments to post + my $comments = LJ::Talk::get_talk_data( $entry->journal, 'L', $entry->jitemid ) || {}; + + # see if our comment exists + return undef unless $comments->{$self->jtalkid}; + + # walk up the tree + my $id = $self->jtalkid; + while ( $comments->{$id} && $comments->{$id}->{parenttalkid} ) { + # avoid (the unlikely chance of) an infinite loop + $id = delete $comments->{$id}->{parenttalkid}; + } + + # cache the value, for future lookup + $self->{threadrootid} = $id; + LJ::MemCache::set( $memkey, $id ); + return $id; +} + sub parenttalkid { my $self = shift; diff -r 9603e41b3cc3 -r cc90e8be4b68 cgi-bin/LJ/S2/EntryPage.pm --- a/cgi-bin/LJ/S2/EntryPage.pm Tue Nov 03 00:50:48 2009 +0000 +++ b/cgi-bin/LJ/S2/EntryPage.pm Tue Nov 03 00:54:44 2009 +0000 @@ -143,6 +143,8 @@ sub EntryPage my $seconds_since_entry = $com->{'datepost_unix'} - $entry->logtime_unix; my $datetime_poster = DateTime_tz($com->{'datepost_unix'}, $pu); + my $threadroot_url; + my ($edited, $edit_url, $edittime, $edittime_remote, $edittime_poster); if ($com->{_loaded}) { my $comment = LJ::Comment->new($u, jtalkid => $com->{talkid}); @@ -154,6 +156,8 @@ sub EntryPage $edittime_remote = $tz_remote ? DateTime_tz($comment->edit_time, $tz_remote) : undef; $edittime_poster = DateTime_tz($comment->edit_time, $pu); } + + $threadroot_url = $comment->threadroot_url( LJ::viewing_style_args( %$get ) ) if $com->{parenttalkid}; } my $subject_icon = undef; @@ -235,6 +239,7 @@ sub EntryPage 'full' => $com->{'_loaded'} ? 1 : 0, 'depth' => $depth, 'parent_url' => $par_url, + threadroot_url => $threadroot_url, 'screened' => $com->{'state'} eq "S" ? 1 : 0, 'frozen' => $com->{'state'} eq "F" ? 1 : 0, 'deleted' => $com->{'state'} eq "D" ? 1 : 0, diff -r 9603e41b3cc3 -r cc90e8be4b68 doc/raw/memcache-keys.txt --- a/doc/raw/memcache-keys.txt Tue Nov 03 00:50:48 2009 +0000 +++ b/doc/raw/memcache-keys.txt Tue Nov 03 00:54:44 2009 +0000 @@ -13,6 +13,7 @@ <uid> talk2row:<uid>:<jtalkid> == packed data <uid> talk2ct:<uid> == # rows for user <uid> talkleftct:<uid> == # rows for user +<uid> talkroot:<uid>:<jtalkid> == scalar: root of the thread containing this comment <uid> logtext:<cid>:<uid>:<jitemid> == [ subject, text ] <uid> logprop:<uid>:<jitemid> == { propname => $value, ... } diff -r 9603e41b3cc3 -r cc90e8be4b68 htdocs/go.bml --- a/htdocs/go.bml Tue Nov 03 00:50:48 2009 +0000 +++ b/htdocs/go.bml Tue Nov 03 00:54:44 2009 +0000 @@ -6,7 +6,7 @@ $title = $ML{'.defaulttitle'}; $body = $ML{'.defaultbody'}; - # S2 Redirector + # S2 monthview Redirector if ($POST{'redir_type'} eq "monthview") { my $user = LJ::canonical_username($POST{'redir_user'}); my $vhost; @@ -20,6 +20,20 @@ return BML::redirect("$base/$year/$month/"); } + # comment thread root redirector + my $talkid = $GET{talkid}+0; + if ( $GET{redir_type} eq "threadroot" && $talkid ) { + my $journal = $GET{journal}; + my $u = LJ::load_user( $journal ); + return unless $u; + + my $comment = LJ::Comment->new( $u, dtalkid => $talkid ); + return unless $comment; + + my $threadroot = LJ::Comment->new( $u, jtalkid => $comment->threadrootid ); + return BML::redirect( $threadroot->url( LJ::viewing_style_args( %GET ) ) ); + } + # prev/next talkread links my $itemid = $GET{'itemid'}+0; if ($GET{'journal'} && $itemid) diff -r 9603e41b3cc3 -r cc90e8be4b68 htdocs/talkread.bml --- a/htdocs/talkread.bml Tue Nov 03 00:50:48 2009 +0000 +++ b/htdocs/talkread.bml Tue Nov 03 00:54:44 2009 +0000 @@ -48,6 +48,7 @@ body<= readcomments talk.commentsread parent talk.parentlink thread talk.threadlink + threadroot talk.threadrootlink expand talk.expandlink replythis talk.replytothis unscreentoreply talk.unscreentoreply @@ -711,6 +712,9 @@ body<= 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>)"; + my $dpid = $parentid * 256 + $init->{'anum'}; $ret .= "(<a href='" . LJ::Talk::talkargs($talkurl, "thread=$dpid", $stylemine, $formatlight); $ret .= LJ::Talk::comment_anchor( $dpid ) . "'>$T{'parent'}</a>)"; diff -r 9603e41b3cc3 -r cc90e8be4b68 t/comment.t --- a/t/comment.t Tue Nov 03 00:50:48 2009 +0000 +++ b/t/comment.t Tue Nov 03 00:54:44 2009 +0000 @@ -1,7 +1,7 @@ # -*-perl-*- use strict; -use Test::More tests => 189; +use Test::More tests => 405; use lib "$ENV{LJHOME}/cgi-bin"; require 'ljlib.pl'; require 'ljprotocol.pl'; @@ -266,6 +266,38 @@ sub run_tests { ok( $access_ct{data} == 1, "$step: Only one talk data access with legacy interaction"); ok( $access_ct{text} == 1, "$step: Only one text data access with legacy interaction"); ok( $access_ct{props} == 1, "$step: Only one prop data access with legacy interaction"); + + # Add to the tree: + # - child 6 + # + child 6.1 + # + child 6.1.1 + # + child 6.1.1.1 + my $comment = $entry->t_enter_comment; + my $curr = [ $comment => [] ]; + push @tree, $curr; + foreach ( 1..3 ) { + $comment = $comment->t_reply; + push @{$curr->[1]}, $comment; + } + + # look up root + foreach my $parent (map { $_->[0] } @tree) { + ok ( $parent->threadrootid eq $parent->jtalkid, "Comment depth 1: this is the thread root" ); + + my @children = $parent->children; + foreach my $child ( @children ) { + ok ( $child->parenttalkid == $child->threadrootid, "Comment depth 2: thread root and parent are equivalent." ); + + my $descendant = $child; + my $depth = 2; + foreach ( $descendant->children ) { + ok ( $child->parenttalkid == $descendant->threadrootid, "Comment depth $depth: thread root is no longer directly linked to this comment." ); + + $depth++; + $descendant = $_; + } + } + } } } --------------------------------------------------------------------------------
no subject
no subject
no subject