diff --git a/app/models.py b/app/models.py index 229ee164..455ad0b7 100644 --- a/app/models.py +++ b/app/models.py @@ -19,7 +19,7 @@ import jwt import os from app.constants import SUBSCRIPTION_NONMEMBER, SUBSCRIPTION_MEMBER, SUBSCRIPTION_MODERATOR, SUBSCRIPTION_OWNER, \ - SUBSCRIPTION_BANNED, SUBSCRIPTION_PENDING + SUBSCRIPTION_BANNED, SUBSCRIPTION_PENDING, NOTIF_USER # datetime.utcnow() is depreciated in Python 3.12 so it will need to be swapped out eventually @@ -880,6 +880,18 @@ class User(UserMixin, db.Model): else: return '@' + self.user_name + '@' + self.ap_domain + # True if user_id wants to be notified about posts by self + def notify_new_posts(self, user_id): + existing_notification = NotificationSubscription.query.filter(NotificationSubscription.entity_id == self.id, + NotificationSubscription.user_id == user_id, + NotificationSubscription.type == NOTIF_USER).first() + return existing_notification is not None + + # ids of all the users who want to be notified when self makes a post + def notification_subscribers(self): + return db.session.execute(text('SELECT user_id FROM "notification_subscription" WHERE entity_id = :user_id AND type = :type '), + {'user_id': self.id, 'type': NOTIF_USER}).scalars() + class ActivityLog(db.Model): id = db.Column(db.Integer, primary_key=True) diff --git a/app/templates/user/_notification_toggle.html b/app/templates/user/_notification_toggle.html new file mode 100644 index 00000000..23c05af3 --- /dev/null +++ b/app/templates/user/_notification_toggle.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/app/templates/user/show_profile.html b/app/templates/user/show_profile.html index ea8d6dfe..3f9babd8 100644 --- a/app/templates/user/show_profile.html +++ b/app/templates/user/show_profile.html @@ -22,7 +22,11 @@ {{ _('Profile pic') }} -

{{ user.display_name() if user.is_local() else user.display_name() + ', ' + user.ap_id }}

+

{{ user.display_name() if user.is_local() else user.display_name() + ', ' + user.ap_id }} + {% if current_user.is_authenticated %} + {% include 'user/_notification_toggle.html' %} + {% endif %} +

{% elif user.avatar_image() != '' %}
@@ -39,7 +43,11 @@ {% endif %}
-

{{ user.display_name() if user.is_local() else user.display_name() + ', ' + user.ap_id }}

+

{{ user.display_name() if user.is_local() else user.display_name() + ', ' + user.ap_id }} + {% if current_user.is_authenticated %} + {% include 'user/_notification_toggle.html' %} + {% endif %} +

{% else %} @@ -50,7 +58,11 @@ -

{{ user.display_name() if user.is_local() else user.display_name() + ', ' + user.ap_id }}

+

{{ user.display_name() if user.is_local() else user.display_name() + ', ' + user.ap_id }} + {% if current_user.is_authenticated %} + {% include 'user/_notification_toggle.html' %} + {% endif %} +

{% endif %} {% if current_user.is_authenticated and current_user != user %}
diff --git a/app/user/routes.py b/app/user/routes.py index c1b2efa9..e4dcd750 100644 --- a/app/user/routes.py +++ b/app/user/routes.py @@ -9,10 +9,10 @@ from app import db, cache, celery from app.activitypub.signature import post_request from app.activitypub.util import default_context, find_actor_or_create from app.community.util import save_icon_file, save_banner_file, retrieve_mods_and_backfill -from app.constants import SUBSCRIPTION_MEMBER, SUBSCRIPTION_PENDING +from app.constants import SUBSCRIPTION_MEMBER, SUBSCRIPTION_PENDING, NOTIF_USER from app.models import Post, Community, CommunityMember, User, PostReply, PostVote, Notification, utcnow, File, Site, \ Instance, Report, UserBlock, CommunityBan, CommunityJoinRequest, CommunityBlock, Filter, Domain, DomainBlock, \ - InstanceBlock + InstanceBlock, NotificationSubscription from app.user import bp from app.user.forms import ProfileForm, SettingsForm, DeleteAccountForm, ReportUserForm, FilterEditForm from app.user.utils import purge_user_then_delete @@ -220,6 +220,26 @@ def change_settings(): joined_communities=joined_communities(current_user.get_id()) ) + +@bp.route('/user//notification', methods=['GET', 'POST']) +@login_required +def user_notification(user_id: int): + user = User.query.get_or_404(user_id) + existing_notification = NotificationSubscription.query.filter(NotificationSubscription.entity_id == user.id, + NotificationSubscription.user_id == current_user.id, + NotificationSubscription.type == NOTIF_USER).first() + if existing_notification: + db.session.delete(existing_notification) + db.session.commit() + else: # no subscription yet, so make one + if user.id != current_user.id and not user.has_blocked_user(current_user.id): + new_notification = NotificationSubscription(user_id=current_user.id, entity_id=user.id, type=NOTIF_USER) + db.session.add(new_notification) + db.session.commit() + + return render_template('user/_notification_toggle.html', user=user) + + @bp.route('/u//ban', methods=['GET']) @login_required def ban_profile(actor): @@ -287,6 +307,8 @@ def block_profile(actor): if not existing_block: block = UserBlock(blocker_id=current_user.id, blocked_id=user.id) db.session.add(block) + db.session.execute(text('DELETE FROM "notification_subscription" WHERE entity_id = :current_user AND user_id = :user_id'), + {'current_user': current_user.id, 'user_id': user.id}) db.session.commit() if not user.is_local():