Dashboard: Subgrouping of notifications based on posts

This commit is contained in:
Jaakko Keränen 2023-11-10 22:14:50 +02:00
parent 263498483c
commit 82955491ae
No known key found for this signature in database
GPG Key ID: BACCFCFB98DB2EDC
2 changed files with 56 additions and 16 deletions

View File

@ -100,7 +100,8 @@ class Notification:
def __init__(self, id, type, dst, src, post, subspace, comment, is_sent, ts,
src_name=None, post_title=None, post_issueid=None, post_summary=None,
post_subname=None, post_subowner=None, subname=None, reaction=None):
post_subname=None, post_subowner=None, subname=None, reaction=None,
post_subid=None):
self.id = id
self.type = type
self.dst = dst
@ -114,6 +115,7 @@ class Notification:
self.post_title = post_title
self.post_issueid = post_issueid
self.post_summary = post_summary
self.post_subid = post_subid
self.post_subname = post_subname
self.post_subowner = post_subowner
self.subname = subname
@ -128,6 +130,11 @@ class Notification:
def age(self):
return ago_text(self.ts)
def title_text(self):
return shorten_text(self.post_title, 50) if self.post_title \
else shorten_text(strip_links(clean_title(self.post_summary)), 50) if self.post_summary \
else None
def entry(self, show_age=True, with_time=False, with_title=True, tz=None) -> tuple:
"""Returns (link, label) to use in the notification list."""
@ -195,9 +202,7 @@ class Notification:
event = f"reported the {kind}"
if with_title:
vis_title = shorten_text(self.post_title, 50) if self.post_title \
else shorten_text(strip_links(clean_title(self.post_summary)), 50) if self.post_summary \
else None
vis_title = self.title_text()
if vis_title:
if self.type == Notification.MENTION:
event += ' in'
@ -383,8 +388,6 @@ class Post:
return self.title
elif self.parent:
text = f'Comment on {"u" if self.sub_owner else "s"}/{self.sub_name}/{self.parent}'
#if self.summary:
# text += f': "{shorten_text(self.summary(30))}"'
return text
else:
return '(untitled issue)' if self.issueid else '(untitled post)'
@ -2387,7 +2390,7 @@ class Database:
n.id, n.type, n.dst, n.src, n.post, n.subspace, n.comment, n.is_sent, UNIX_TIMESTAMP(n.ts),
u.name,
p.title, p.issueid, p.summary,
s.name, s.owner,
s.id, s.name, s.owner,
s2.name,
r.reaction
FROM notifs n
@ -2405,10 +2408,11 @@ class Database:
""", tuple(values))
notifs = []
for (id, type, dst, src, post, subspace, comment, is_sent, ts, src_name, post_title, post_issueid,
post_summary, post_subname, post_subowner, subname, reaction) in cur:
post_summary, post_subid, post_subname, post_subowner, subname, reaction) in cur:
notifs.append(Notification(id, type, dst, src, post, subspace, comment, is_sent, ts,
src_name, post_title, post_issueid, post_summary,
post_subname, post_subowner, subname, reaction))
post_subname, post_subowner, subname, reaction,
post_subid=post_subid))
notifs = self.resolve_notifications(notifs)
notifs.sort(key=lambda n: n.ts, reverse=sort_desc)

50
user.py
View File

@ -244,6 +244,38 @@ def user_actions(session):
return 42, 'Invalid notification'
class Subgrouping:
"""Sorts notifications by related post ID and descending time."""
def __init__(self, user, notifs):
self.user = user
self.by_post = {}
ordered = sorted(notifs, key=lambda n: -n.ts)
for notif in ordered:
if not notif.post in self.by_post:
self.by_post[notif.post] = []
self.by_post[notif.post].append(notif)
def render(self):
src = []
top_head = False
for post_id, notifs in self.by_post.items():
if top_head:
# Separate subgroups.
src.append('')
top_head = post_id and len(notifs) > 1
if top_head:
n = notifs[0]
if n.post_subname and n.post_subowner != self.user.id:
sub_text = f" in {'u/' if n.post_subowner else 's/'}{n.post_subname}"
else:
sub_text = ''
src.append(f'"{n.title_text()}"{sub_text}:')
for notif in notifs:
src.append('=> %s %s' % notif.entry(with_title=not top_head))
return '\n'.join(src) + '\n'
def make_dashboard_page(session):
if not session.user:
return 60, "Login required"
@ -263,6 +295,7 @@ def make_dashboard_page(session):
if n:
# Group in two: @user and Followed.
yours = []
moderated = []
followed = []
for notif in notifs:
if not notif.type in Notification.PRIORITY or \
@ -270,19 +303,22 @@ def make_dashboard_page(session):
Notification.PRIORITY[notif.type] >= 10:
yours.append(notif)
else:
followed.append(notif)
if notif.post_subid in user.moderated_subspace_ids:
moderated.append(notif)
else:
followed.append(notif)
if yours:
page += f'\n### @{session.user.name}\n'
for notif in sorted(yours, key=lambda n: -n.ts):
link, label = notif.entry()
page += f'=> {link} {label}\n'
page += Subgrouping(user, yours).render()
if moderated:
page += f'\n### Moderated\n'
page += Subgrouping(user, moderated).render()
if followed:
page += f'\n### Followed\n'
for notif in sorted(followed, key=lambda n: -n.ts):
link, label = notif.entry()
page += f'=> {link} {label}\n'
page += Subgrouping(user, followed).render()
page += '\n=> /notif/clear 🧹 Clear all\n'
page += '=> /notif/feed Notifications feed\nSubscribe to this Gemini feed to view your unread notifications in a feed reader.\n'