mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 12:36:57 +00:00
group notifications regardless of when they happened - fix #633
This commit is contained in:
parent
a9a7e4b9d0
commit
c882a4294d
1 changed files with 67 additions and 32 deletions
|
@ -104,53 +104,88 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
}
|
}
|
||||||
|
|
||||||
// grouping
|
// grouping
|
||||||
let groupedNotifications = [notifications[0]] as MiGroupedNotification[];
|
const groupedNotifications : MiGroupedNotification[] = [];
|
||||||
for (let i = 1; i < notifications.length; i++) {
|
// keep track of where reaction / renote notifications are, by note id
|
||||||
const notification = notifications[i];
|
const reactionIdxByNoteId = new Map();
|
||||||
const prev = notifications[i - 1];
|
const renoteIdxByNoteId = new Map();
|
||||||
let prevGroupedNotification = groupedNotifications.at(-1)!;
|
|
||||||
|
|
||||||
if (prev.type === 'reaction' && notification.type === 'reaction' && prev.noteId === notification.noteId) {
|
// group notifications by type+note; notice that we don't try to
|
||||||
if (prevGroupedNotification.type !== 'reaction:grouped') {
|
// split groups if they span a long stretch of time, because
|
||||||
groupedNotifications[groupedNotifications.length - 1] = {
|
// it's probably overkill: if the user has very few
|
||||||
|
// notifications, there should be very little difference; if the
|
||||||
|
// user has many notifications, the pagination will break the
|
||||||
|
// groups
|
||||||
|
|
||||||
|
// scan `notifications` newest-to-oldest
|
||||||
|
for (let i = 0; i < notifications.length; i++) {
|
||||||
|
const notification = notifications[i];
|
||||||
|
|
||||||
|
if (notification.type === 'reaction') {
|
||||||
|
const reactionIdx = reactionIdxByNoteId.get(notification.noteId);
|
||||||
|
if (reactionIdx === undefined) {
|
||||||
|
// first reaction to this note that we see, add it as-is
|
||||||
|
// and remember where we put it
|
||||||
|
groupedNotifications.push(notification);
|
||||||
|
reactionIdxByNoteId.set(notification.noteId, groupedNotifications.length - 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prevReaction = groupedNotifications[reactionIdx];
|
||||||
|
// if the previous reaction is not a group, make it into one
|
||||||
|
if (prevReaction.type !== 'reaction:grouped') {
|
||||||
|
prevReaction = groupedNotifications[reactionIdx] = {
|
||||||
type: 'reaction:grouped',
|
type: 'reaction:grouped',
|
||||||
id: '',
|
id: prevReaction.id, // this will be the newest id in this group
|
||||||
createdAt: prev.createdAt,
|
createdAt: prevReaction.createdAt,
|
||||||
noteId: prev.noteId!,
|
noteId: prevReaction.noteId!,
|
||||||
reactions: [{
|
reactions: [{
|
||||||
userId: prev.notifierId!,
|
userId: prevReaction.notifierId!,
|
||||||
reaction: prev.reaction!,
|
reaction: prevReaction.reaction!,
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
prevGroupedNotification = groupedNotifications.at(-1)!;
|
|
||||||
}
|
}
|
||||||
(prevGroupedNotification as FilterUnionByProperty<MiGroupedNotification, 'type', 'reaction:grouped'>).reactions.push({
|
// add this new reaction to the existing group
|
||||||
|
(prevReaction as FilterUnionByProperty<MiGroupedNotification, 'type', 'reaction:grouped'>).reactions.push({
|
||||||
userId: notification.notifierId!,
|
userId: notification.notifierId!,
|
||||||
reaction: notification.reaction!,
|
reaction: notification.reaction!,
|
||||||
});
|
});
|
||||||
prevGroupedNotification.id = notification.id;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (prev.type === 'renote' && notification.type === 'renote' && prev.targetNoteId === notification.targetNoteId) {
|
|
||||||
if (prevGroupedNotification.type !== 'renote:grouped') {
|
|
||||||
groupedNotifications[groupedNotifications.length - 1] = {
|
|
||||||
type: 'renote:grouped',
|
|
||||||
id: '',
|
|
||||||
createdAt: notification.createdAt,
|
|
||||||
noteId: prev.noteId!,
|
|
||||||
userIds: [prev.notifierId!],
|
|
||||||
};
|
|
||||||
prevGroupedNotification = groupedNotifications.at(-1)!;
|
|
||||||
}
|
|
||||||
(prevGroupedNotification as FilterUnionByProperty<MiGroupedNotification, 'type', 'renote:grouped'>).userIds.push(notification.notifierId!);
|
|
||||||
prevGroupedNotification.id = notification.id;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (notification.type === 'renote') {
|
||||||
|
const renoteIdx = renoteIdxByNoteId.get(notification.targetNoteId);
|
||||||
|
if (renoteIdx === undefined) {
|
||||||
|
// first renote of this note that we see, add it as-is and
|
||||||
|
// remember where we put it
|
||||||
|
groupedNotifications.push(notification);
|
||||||
|
renoteIdxByNoteId.set(notification.targetNoteId, groupedNotifications.length - 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prevRenote = groupedNotifications[renoteIdx];
|
||||||
|
// if the previous renote is not a group, make it into one
|
||||||
|
if (prevRenote.type !== 'renote:grouped') {
|
||||||
|
prevRenote = groupedNotifications[renoteIdx] = {
|
||||||
|
type: 'renote:grouped',
|
||||||
|
id: prevRenote.id, // this will be the newest id in this group
|
||||||
|
createdAt: prevRenote.createdAt,
|
||||||
|
noteId: prevRenote.noteId!,
|
||||||
|
userIds: [prevRenote.notifierId!],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// add this new renote to the existing group
|
||||||
|
(prevRenote as FilterUnionByProperty<MiGroupedNotification, 'type', 'renote:grouped'>).userIds.push(notification.notifierId!);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not a groupable notification, just push it
|
||||||
groupedNotifications.push(notification);
|
groupedNotifications.push(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
groupedNotifications = groupedNotifications.slice(0, ps.limit);
|
// sort the groups by their id, newest first
|
||||||
|
groupedNotifications.sort(
|
||||||
|
(a, b) => a.id < b.id ? 1 : a.id > b.id ? -1 : 0,
|
||||||
|
);
|
||||||
|
|
||||||
return await this.notificationEntityService.packGroupedMany(groupedNotifications, me.id);
|
return await this.notificationEntityService.packGroupedMany(groupedNotifications, me.id);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue