Skip to content
This repository has been archived by the owner on Apr 17, 2018. It is now read-only.

Comment highlighting #83

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions r2/example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ HOT_PAGE_AGE = 1
#
media_period = 10 minutes
rising_period = 12 hours
comment_visits_period = 600

# time of ratelimit purgatory (min)
RATELIMIT = 1
Expand Down
48 changes: 46 additions & 2 deletions r2/r2/controllers/front.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import re
import time as time_module
from urllib import quote_plus
from datetime import datetime

class FrontController(RedditController):

Expand Down Expand Up @@ -117,6 +118,42 @@ def GET_details(self, article):
rightbox, so it is only useful for Admin-only wizardry."""
return DetailsPage(link = article).render()

def _comment_visits(self, article, user, new_visit=None):

hc_key = "comment_visits-%s-%s" % (user.name, article._id36)
old_visits = g.permacache.get(hc_key, [])

append = False

if new_visit is None:
pass
elif len(old_visits) == 0:
append = True
else:
last_visit = max(old_visits)
time_since_last = new_visit - last_visit
if (time_since_last.days > 0 or time_since_last.seconds > int(g.comment_visits_period)):
append = True
else:
# They were just here a few seconds ago; consider that
# the same "visit" as right now
old_visits.pop()

if append:
copy = list(old_visits) # make a copy
copy.append(new_visit)
if len(copy) > 3:
copy.pop(0)
g.permacache.set(hc_key, copy, time = 86400 * 2)

if len(old_visits) > 0:
time_since_pub = new_visit - article._date
ten_percent = new_visit - (time_since_pub // 10)
old_visit = min(old_visits)
if ten_percent < old_visit:
old_visits.insert(0, ten_percent)

return old_visits

@validate(article = VLink('article'),
comment = VCommentID('comment'),
Expand All @@ -142,10 +179,14 @@ def GET_comments(self, article, comment, context, sort, num_comments):
#check for 304
self.check_modified(article, 'comments')

# if there is a focal comment, communicate down to comment_skeleton.html who
# that will be
# If there is a focal comment, communicate down to
# comment_skeleton.html who that will be. Also, skip
# comment_visits check
previous_visits = None
if comment:
c.focal_comment = comment._id36
elif (c.user_is_loggedin):
previous_visits = self._comment_visits(article, c.user, datetime.now(g.tz))

# check if we just came from the submit page
infotext = None
Expand Down Expand Up @@ -180,6 +221,9 @@ def GET_comments(self, article, comment, context, sort, num_comments):
)
displayPane.append(permamessage)

if previous_visits:
displayPane.append(CommentVisitsBox(previous_visits))

# insert reply box only for logged in user
if c.user_is_loggedin and article.subreddit_slow.can_comment(c.user):
displayPane.append(CommentReplyBox())
Expand Down
46 changes: 45 additions & 1 deletion r2/r2/controllers/meetupscontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from r2.lib.filters import python_websafe
from r2.lib.jsonresponse import Json
from r2.lib.menus import CommentSortMenu,NumCommentsMenu
from r2.lib.pages import BoringPage, ShowMeetup, NewMeetup, EditMeetup, PaneStack, CommentListing, LinkInfoPage, CommentReplyBox, NotEnoughKarmaToPost
from r2.lib.pages import BoringPage, ShowMeetup, NewMeetup, EditMeetup, PaneStack, CommentListing, LinkInfoPage, CommentReplyBox, NotEnoughKarmaToPost, CommentVisitsBox
from r2.models import Meetup,Link,Subreddit,CommentBuilder,PendingJob
from r2.models.listing import NestedListing
from validator import validate, VUser, VModhash, VRequired, VMeetup, VEditMeetup, VFloat, ValueOrBlank, ValidIP, VMenu, VCreateMeetup, VTimestamp
Expand Down Expand Up @@ -168,6 +168,43 @@ def GET_edit(self, meetup):
timestamp=int(meetup.timestamp * 1000),
tzoffset=meetup.tzoffset)).render()

def _comment_visits(self, article, user, new_visit=None):

hc_key = "comment_visits-%s-%s" % (user.name, article._id36)
old_visits = g.permacache.get(hc_key, [])

append = False

if new_visit is None:
pass
elif len(old_visits) == 0:
append = True
else:
last_visit = max(old_visits)
time_since_last = new_visit - last_visit
if (time_since_last.days > 0 or time_since_last.seconds > int(g.comment_visits_period)):
append = True
else:
# They were just here a few seconds ago; consider that
# the same "visit" as right now
old_visits.pop()

if append:
copy = list(old_visits) # make a copy
copy.append(new_visit)
if len(copy) > 3:
copy.pop(0)
g.permacache.set(hc_key, copy, time = 86400 * 2)

if len(old_visits) > 0:
time_since_pub = new_visit - article._date
ten_percent = new_visit - (time_since_pub // 10)
old_visit = min(old_visits)
if ten_percent < old_visit:
old_visits.insert(0, ten_percent)

return old_visits

# Show a meetup. Most of this code was coped from GET_comments in front.py
@validate(meetup = VMeetup('id'),
sort = VMenu('controller', CommentSortMenu),
Expand All @@ -179,6 +216,10 @@ def GET_show(self, meetup, sort, num_comments):
user_num = c.user.pref_num_comments or g.num_comments
num = g.max_comments if num_comments == 'true' else user_num

previous_visits = None
if (c.user_is_loggedin):
previous_visits = self._comment_visits(article, c.user, datetime.now(g.tz))

builder = CommentBuilder(article, CommentSortMenu.operator(sort), None, None)
listing = NestedListing(builder, num=num, parent_name = article._fullname)
displayPane = PaneStack()
Expand All @@ -189,6 +230,9 @@ def GET_show(self, meetup, sort, num_comments):
displayPane.append(CommentReplyBox(link_name =
article._fullname))

if previous_visits:
displayPane.append(CommentVisitsBox(previous_visits))

# finally add the comment listing
displayPane.append(listing.listing())

Expand Down
10 changes: 9 additions & 1 deletion r2/r2/lib/pages/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from r2.lib.menus import NavButton, NamedButton, NavMenu, JsButton, ExpandableButton, AbsButton
from r2.lib.menus import SubredditButton, SubredditMenu, menu
from r2.lib.strings import plurals, rand_strings, strings
from r2.lib.utils import title_to_url, query_string, UrlParser
from r2.lib.utils import title_to_url, query_string, UrlParser, timesince
from r2.lib.template_helpers import add_sr, get_domain
from r2.lib.promote import promote_builder_wrapper
from r2.lib.wikipagecached import WikiPageCached
Expand Down Expand Up @@ -1102,6 +1102,14 @@ class Frame(Wrapped):
def __init__(self, url='', title='', fullname=''):
Wrapped.__init__(self, url = url, title = title, fullname = fullname)

class CommentVisitsBox(Wrapped):
def __init__(self, visits, *a, **kw):
self.visits = []
for visit in reversed(visits):
pretty = timesince(visit, resultion=1)
self.visits.append([pretty, visit])
Wrapped.__init__(self, *a, **kw)

class FrameToolbar(Wrapped):
"""The reddit voting toolbar used together with Frame."""
extension_handling = False
Expand Down
2 changes: 1 addition & 1 deletion r2/r2/lib/template_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def path_info():
params = dict(request.get))

return unsafe(simplejson.dumps(loc))


def replace_render(listing, item, style = None, display = True):
style = style or c.render_style or 'html'
Expand Down
30 changes: 21 additions & 9 deletions r2/r2/public/static/comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,19 +241,31 @@ function morechildren(form, link_id, children, depth) {

function getAttrTime(e) { return parseInt(e.readAttribute('time')); }

function highlightNewComments() {
var lastViewed = $('lastViewed')
if (!lastViewed)
return;

var last = getAttrTime(lastViewed);
if (last<=0)
return;
function highlightNewComments(last) {
if (!last) {
var lastViewed = $("comment-visits");
if (!lastViewed) {
lastViewed = $('lastViewed');
if (!lastViewed)
return;
last = getAttrTime(lastViewed);
}
else {
last = lastViewed.options[lastViewed.selectedIndex].value;
}
}

$$('div.comment').each(function(div, i) {
var t = getAttrTime(div.select('.comment-date')[0]);
if (last<t) {
if (last<=0) {
div.removeClassName('new-comment')
}
else if (last<t) {
div.addClassName('new-comment')
}
else {
div.removeClassName('new-comment')
}
});
}

Expand Down
12 changes: 12 additions & 0 deletions r2/r2/public/static/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,18 @@ div.footer ul.footer-links li a {
display: inline;
}

.comment-visits-box {
float: left;
clear: left;
position: relative;
margin-bottom: 5px;
}

.comment-visits-box .title {
color: #666666;
font-size: 11px;
}

/* A hack to fix the layout of "Load more comments" */
span.deepthread,
span.morecomments {
Expand Down
40 changes: 40 additions & 0 deletions r2/r2/templates/commentvisitsbox.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## The contents of this file are subject to the Common Public Attribution
## License Version 1.0. (the "License"); you may not use this file except in
## compliance with the License. You may obtain a copy of the License at
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
## License Version 1.1, but Sections 14 and 15 have been added to cover use of
## software over a computer network and provide for limited attribution for the
## Original Developer. In addition, Exhibit A has been modified to be
## consistent with Exhibit B.
##
## Software distributed under the License is distributed on an "AS IS" basis,
## WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
## the specific language governing rights and limitations under the License.
##
## The Original Code is reddit.
##
## The Original Developer is the Initial Developer. The Initial Developer of
## the Original Code is reddit Inc.
##
## All portions of the code written by reddit are Copyright (c) 2006-2013
## reddit Inc. All Rights Reserved.
###############################################################################
<%!
from r2.lib.utils import epochtime
%>

<div class="comment-visits-box">
<div class="title">
${_("Highlight comments posted since:")}&#32;
<select id="comment-visits" onchange="highlightNewComments(this.value)">
%for i, visit in enumerate(thing.visits, start=1):
<option value="${epochtime(visit[1])}"
%if i == 1:
selected="selected"
%endif
>${visit[0]} ${_("ago")}</option>
%endfor
<option value="-1">${_("no highlighting")}</option>
</select>
</div>
</div>
22 changes: 22 additions & 0 deletions r2/r2/templates/commentvisitsbox.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## The contents of this file are subject to the Common Public Attribution
## License Version 1.0. (the "License"); you may not use this file except in
## compliance with the License. You may obtain a copy of the License at
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
## License Version 1.1, but Sections 14 and 15 have been added to cover use of
## software over a computer network and provide for limited attribution for the
## Original Developer. In addition, Exhibit A has been modified to be consistent
## with Exhibit B.
##
## Software distributed under the License is distributed on an "AS IS" basis,
## WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
## the specific language governing rights and limitations under the License.
##
## The Original Code is Reddit.
##
## The Original Developer is the Initial Developer. The Initial Developer of
## the Original Code is CondeNet, Inc.
##
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
## CondeNet, Inc. All Rights Reserved.
################################################################################