From baaf93087d8802154783b56fd347c4f439d8b10d Mon Sep 17 00:00:00 2001 From: freamon Date: Wed, 2 Oct 2024 09:18:27 +0000 Subject: [PATCH] Add 'Account->Activity Alerts' page to show content subscriptions (not sure of best terminology for these - feel free to rename) --- app/templates/base.html | 1 + app/templates/user/alerts.html | 35 +++++++++ app/templates/user/alerts/_comments.html | 21 +++++ app/templates/user/alerts/_communities.html | 19 +++++ app/templates/user/alerts/_filter.html | 11 +++ app/templates/user/alerts/_posts.html | 19 +++++ app/templates/user/alerts/_topics.html | 18 +++++ app/templates/user/alerts/_type.html | 17 +++++ app/templates/user/alerts/_users.html | 18 +++++ app/user/routes.py | 85 ++++++++++++++++++++- 10 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 app/templates/user/alerts.html create mode 100644 app/templates/user/alerts/_comments.html create mode 100644 app/templates/user/alerts/_communities.html create mode 100644 app/templates/user/alerts/_filter.html create mode 100644 app/templates/user/alerts/_posts.html create mode 100644 app/templates/user/alerts/_topics.html create mode 100644 app/templates/user/alerts/_type.html create mode 100644 app/templates/user/alerts/_users.html diff --git a/app/templates/base.html b/app/templates/base.html index 5ea81870..6f55245a 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -197,6 +197,7 @@
  • {{ _('Edit profile & settings') }}
  • {{ _('Chats') }}
  • {{ _('Bookmarks') }}
  • +
  • {{ _('Activity Alerts') }}
  • {% if current_user.is_authenticated and current_user.hide_read_posts -%}
  • {{ _('Read Posts') }}
  • {% endif -%} diff --git a/app/templates/user/alerts.html b/app/templates/user/alerts.html new file mode 100644 index 00000000..a440af69 --- /dev/null +++ b/app/templates/user/alerts.html @@ -0,0 +1,35 @@ +{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') %} + {% extends 'themes/' + theme() + '/base.html' %} +{% else %} + {% extends "base.html" %} +{% endif %} +{% set active_child = 'alerts' %} + +{% block app_content %} +
    +
    + + {% include 'user/alerts/_type.html' %} + {% include 'user/alerts/_' + type + '.html' %} + + +
    +
    +{% endblock %} diff --git a/app/templates/user/alerts/_comments.html b/app/templates/user/alerts/_comments.html new file mode 100644 index 00000000..128b3734 --- /dev/null +++ b/app/templates/user/alerts/_comments.html @@ -0,0 +1,21 @@ +{% include 'user/alerts/_filter.html' %} +
    +

    {{ _('You will be notified of replies to these comments') }}

    + {% for reply in entities.items %} + + {% else %} +

    {{ _('You have not subscribed to any comments. Use the bell icon on each comment to do so.') }}

    + {% endfor %} +
    + diff --git a/app/templates/user/alerts/_communities.html b/app/templates/user/alerts/_communities.html new file mode 100644 index 00000000..421cbcba --- /dev/null +++ b/app/templates/user/alerts/_communities.html @@ -0,0 +1,19 @@ +{% include 'user/alerts/_filter.html' %} +
    +

    {{ _('You will be notified of new posts in these communities') }}

    + {% for community in entities.items %} + + {% else %} +

    {{ _('You have not subscribed to an alert for new content in any communities. Use the bell icon in each community to do so.') }}

    + {% endfor %} +
    + diff --git a/app/templates/user/alerts/_filter.html b/app/templates/user/alerts/_filter.html new file mode 100644 index 00000000..c6cb0197 --- /dev/null +++ b/app/templates/user/alerts/_filter.html @@ -0,0 +1,11 @@ +
    + + {{ _('All') }} + + + {{ _('Mine') }} + + + {{ _('Others') }} + +
    diff --git a/app/templates/user/alerts/_posts.html b/app/templates/user/alerts/_posts.html new file mode 100644 index 00000000..980c8ff6 --- /dev/null +++ b/app/templates/user/alerts/_posts.html @@ -0,0 +1,19 @@ +{% include 'user/alerts/_filter.html' %} +
    +

    {{ _('You will be notified of top-level replies to these posts') }}

    + {% for post in entities.items %} + + {% else %} +

    {{ _('You have not subscribed to any posts. Use the bell icon on each post to do so.') }}

    + {% endfor %} +
    + diff --git a/app/templates/user/alerts/_topics.html b/app/templates/user/alerts/_topics.html new file mode 100644 index 00000000..9e008e83 --- /dev/null +++ b/app/templates/user/alerts/_topics.html @@ -0,0 +1,18 @@ +
    +

    {{ _('You will be notified of new posts in communities covered by these topics') }}

    + {% for topic in entities.items -%} + + {% else -%} +

    {{ _('You have not subscribed to any topics. Use the bell icon on each topic to do so.') }}

    + {% endfor -%} +
    + diff --git a/app/templates/user/alerts/_type.html b/app/templates/user/alerts/_type.html new file mode 100644 index 00000000..6e06d535 --- /dev/null +++ b/app/templates/user/alerts/_type.html @@ -0,0 +1,17 @@ +
    + + {{ _('Posts') }} + + + {{ _('Comments') }} + + + {{ _('Communities') }} + + + {{ _('Topics') }} + + + {{ _('Users') }} + +
    diff --git a/app/templates/user/alerts/_users.html b/app/templates/user/alerts/_users.html new file mode 100644 index 00000000..e8ce1386 --- /dev/null +++ b/app/templates/user/alerts/_users.html @@ -0,0 +1,18 @@ +
    +

    {{ _('You will be notified of new posts by these users') }}

    + {% for user in entities.items %} + + {% else %} +

    {{ _('You have not subscribed to an alert for new content from any users. Use the bell icon on each person to do so.') }}

    + {% endfor %} +
    + diff --git a/app/user/routes.py b/app/user/routes.py index 8f3b15f8..8815a6de 100644 --- a/app/user/routes.py +++ b/app/user/routes.py @@ -12,12 +12,11 @@ from app.activitypub.signature import post_request, default_context from app.activitypub.util import find_actor_or_create from app.auth.util import random_token from app.community.util import save_icon_file, save_banner_file, retrieve_mods_and_backfill -from app.constants import SUBSCRIPTION_MEMBER, SUBSCRIPTION_PENDING, NOTIF_USER, POST_TYPE_VIDEO, POST_TYPE_LINK, \ - POST_TYPE_IMAGE, POST_TYPE_POLL +from app.constants import * from app.email import send_verification_email from app.models import Post, Community, CommunityMember, User, PostReply, PostVote, Notification, utcnow, File, Site, \ Instance, Report, UserBlock, CommunityBan, CommunityJoinRequest, CommunityBlock, Filter, Domain, DomainBlock, \ - InstanceBlock, NotificationSubscription, PostBookmark, PostReplyBookmark, read_posts + InstanceBlock, NotificationSubscription, PostBookmark, PostReplyBookmark, read_posts, Topic from app.user import bp from app.user.forms import ProfileForm, SettingsForm, DeleteAccountForm, ReportUserForm, \ FilterForm, KeywordFilterEditForm, RemoteFollowForm, ImportExportForm @@ -1143,6 +1142,86 @@ def user_bookmarks_comments(): next_url=next_url, prev_url=prev_url) +@bp.route('/alerts') +@bp.route('/alerts//') +@login_required +def user_alerts(type='posts', filter='all'): + page = request.args.get('page', 1, type=int) + low_bandwidth = request.cookies.get('low_bandwidth', '0') == '1' + + if type == 'comments': + if filter == 'mine': + entities = PostReply.query.filter_by(deleted=False, user_id=current_user.id).\ + join(NotificationSubscription, NotificationSubscription.entity_id == PostReply.id).\ + filter_by(type=NOTIF_REPLY, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + elif filter == 'others': + entities = PostReply.query.filter(PostReply.deleted == False, PostReply.user_id != current_user.id).\ + join(NotificationSubscription, NotificationSubscription.entity_id == PostReply.id).\ + filter_by(type=NOTIF_REPLY, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + else: # default to 'all' filter + entities = PostReply.query.filter_by(deleted=False).\ + join(NotificationSubscription, NotificationSubscription.entity_id == PostReply.id).\ + filter_by(type=NOTIF_REPLY, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + title = _('Reply Alerts') + + elif type == 'communities': + if filter == 'mine': + entities = Community.query.\ + join(CommunityMember, CommunityMember.community_id == Community.id).\ + filter_by(user_id=current_user.id, is_moderator=True).\ + join(NotificationSubscription, NotificationSubscription.entity_id == CommunityMember.community_id).\ + filter_by(type=NOTIF_COMMUNITY, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + elif filter == 'others': + entities = Community.query.\ + join(CommunityMember, CommunityMember.community_id == Community.id).\ + filter_by(user_id=current_user.id, is_moderator=False).\ + join(NotificationSubscription, NotificationSubscription.entity_id == CommunityMember.community_id).\ + filter_by(type=NOTIF_COMMUNITY, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + else: # default to 'all' filter + entities = Community.query.\ + join(NotificationSubscription, NotificationSubscription.entity_id == Community.id).\ + filter_by(type=NOTIF_COMMUNITY, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + title = _('Community Alerts') + + elif type == 'topics': + # ignore filter + entities = Topic.query.join(NotificationSubscription, NotificationSubscription.entity_id == Topic.id).\ + filter_by(type=NOTIF_TOPIC, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + title = _('Topic Alerts') + + elif type == 'users': + # ignore filter + entities = User.query.join(NotificationSubscription, NotificationSubscription.entity_id == User.id).\ + filter_by(type=NOTIF_USER, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + title = _('User Alerts') + + else: # default to 'posts' type + if filter == 'mine': + entities = Post.query.filter_by(deleted=False, user_id=current_user.id).\ + join(NotificationSubscription, NotificationSubscription.entity_id == Post.id).\ + filter_by(type=NOTIF_POST, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + elif filter == 'others': + entities = Post.query.filter(Post.deleted == False, Post.user_id != current_user.id).\ + join(NotificationSubscription, NotificationSubscription.entity_id == Post.id).\ + filter_by(type=NOTIF_POST, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + else: # default to 'all' filter + entities = Post.query.filter_by(deleted=False).\ + join(NotificationSubscription, NotificationSubscription.entity_id == Post.id).\ + filter_by(type=NOTIF_POST, user_id=current_user.id).order_by(desc(NotificationSubscription.created_at)) + title = _('Post Alerts') + + entities = entities.paginate(page=page, per_page=100 if not low_bandwidth else 50, error_out=False) + next_url = url_for('user.user_alerts', page=entities.next_num, type=type, filter=filter) if entities.has_next else None + prev_url = url_for('user.user_alerts', page=entities.prev_num, type=type, filter=filter) if entities.has_prev and page != 1 else None + + return render_template('user/alerts.html', title=title, entities=entities, + low_bandwidth=low_bandwidth, user=current_user, type=type, filter=filter, + moderating_communities=moderating_communities(current_user.get_id()), + joined_communities=joined_communities(current_user.get_id()), + menu_topics=menu_topics(), site=g.site, + next_url=next_url, prev_url=prev_url) + + @bp.route('/u//fediverse_redirect', methods=['GET', 'POST']) def fediverse_redirect(actor): actor = actor.strip()