Browse Source

Add mark all read button to unread notifications

This will only mark notifications upto the timestamp of the last one shown on
the unread_notifications page where it was clicked
merge-requests/21/head
James Southern 7 years ago
parent
commit
18e80707cf
  1. 15
      tildes/tildes/templates/notifications_unread.jinja2
  2. 110
      tildes/tildes/views/api/web/comment.py

15
tildes/tildes/templates/notifications_unread.jinja2

@ -5,7 +5,20 @@
{% block title %}Unread notifications{% endblock %}
{% block main_heading %}Unread notifications{% endblock %}
{% block main_heading %}Unread notifications
{% if notifications and not request.user.auto_mark_notifications_read %}
<button
class="btn btn-link-minimal ml-2"
data-ic-put-to="{{ request.route_url(
'ic_comment_mark_read',
comment_id36=notifications[0].comment.comment_id36,
_query={"mark_all_previous": "true"},
)}}",
data-ic-target="closest main"
>Mark all read</button>
{% endif %}
{% endblock %}
{% block content %}
{% if notifications %}

110
tildes/tildes/views/api/web/comment.py

@ -1,9 +1,12 @@
"""Web API endpoints related to comments."""
from marshmallow.fields import String
from marshmallow.validate import OneOf
from pyramid.request import Request
from pyramid.response import Response
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import joinedload
from sqlalchemy.orm.exc import FlushError
from webargs.pyramidparser import use_kwargs
from zope.sqlalchemy import mark_changed
@ -22,6 +25,40 @@ from tildes.views import IC_NOOP
from tildes.views.decorators import ic_view_config
def _increment_topic_comments_seen(
request: Request,
comment: Comment,
) -> None:
"""If the user has the "track comment visits" feature enabled, we want to
increment the number of comments they've seen in the thread that the
comment came from, so that they don't *both* get a notification as well as
have the thread highlight with "(1 new)". This should only happen if their
last visit was before the comment was posted, however. Below, this is
implemented as a INSERT ... ON CONFLICT DO UPDATE so that it will insert
a new topic visit with 1 comment if they didn't previously have one at
all. """
if request.user.track_comment_visits:
statement = (
insert(TopicVisit.__table__)
.values(
user_id=request.user.user_id,
topic_id=comment.topic_id,
visit_time=utc_now(),
num_comments=1,
)
.on_conflict_do_update(
constraint=TopicVisit.__table__.primary_key,
set_={'num_comments': TopicVisit.num_comments + 1},
where=TopicVisit.visit_time < comment.created_time,
)
)
request.db_session.execute(statement)
mark_changed(request.db_session)
return
@ic_view_config(
route_name='topic_comments',
request_method='POST',
@ -287,41 +324,52 @@ def untag_comment(request: Request, name: CommentTagOption) -> Response:
request_method='PUT',
permission='mark_read',
)
def mark_read_comment(request: Request) -> Response:
@use_kwargs({
'clear_all_previous': String(
load_from='mark_all_previous',
validate=OneOf(('true', 'false')),
),
})
def put_mark_comments_read(
request: Request,
clear_all_previous: str = 'false'
) -> Response:
"""Mark a comment read (clear all notifications)."""
comment = request.context
request.query(CommentNotification).filter(
CommentNotification.user == request.user,
CommentNotification.comment == comment,
).update(
{CommentNotification.is_unread: False}, synchronize_session=False)
# If the user has the "track comment visits" feature enabled, we want to
# increment the number of comments they've seen in the thread that the
# comment came from, so that they don't *both* get a notification as well
# as have the thread highlight with "(1 new)". This should only happen if
# their last visit was before the comment was posted, however.
# Below, this is implemented as a INSERT ... ON CONFLICT DO UPDATE so that
# it will insert a new topic visit with 1 comment if they didn't previously
# have one at all.
if request.user.track_comment_visits:
statement = (
insert(TopicVisit.__table__)
.values(
user_id=request.user.user_id,
topic_id=comment.topic_id,
visit_time=utc_now(),
num_comments=1,
)
.on_conflict_do_update(
constraint=TopicVisit.__table__.primary_key,
set_={'num_comments': TopicVisit.num_comments + 1},
where=TopicVisit.visit_time < comment.created_time,
if clear_all_previous == 'true':
prev_notifications = (
request.query(CommentNotification).filter(
CommentNotification.is_unread == True, #noqa
CommentNotification.created_time <=
request.db_session.query(CommentNotification.created_time)
.filter(
CommentNotification.user == request.user,
CommentNotification.comment_id == comment.comment_id,
)
.as_scalar()
)
.options(joinedload(CommentNotification.comment))
.all()
)
request.db_session.execute(statement)
mark_changed(request.db_session)
for notification in prev_notifications:
notification.is_unread = False
_increment_topic_comments_seen(request, notification.comment)
return Response('Your comment notifications have been cleared.')
else:
request.query(CommentNotification).filter(
CommentNotification.user == request.user,
CommentNotification.comment == comment,
).update(
{CommentNotification.is_unread: False}, synchronize_session=False)
_increment_topic_comments_seen(request, comment)
return IC_NOOP
return IC_NOOP
Loading…
Cancel
Save