Skip to content

Commit 77f5b12

Browse files
Fix unsupported grouped notifications from streaming causing duplicate IDs (mastodon#32243)
1 parent 463f919 commit 77f5b12

File tree

1 file changed

+38
-35
lines changed

1 file changed

+38
-35
lines changed

app/javascript/mastodon/reducers/notification_groups.ts

+38-35
Original file line numberDiff line numberDiff line change
@@ -206,50 +206,53 @@ function processNewNotification(
206206
groups: NotificationGroupsState['groups'],
207207
notification: ApiNotificationJSON,
208208
) {
209-
if (shouldGroupNotificationType(notification.type)) {
210-
const existingGroupIndex = groups.findIndex(
211-
(group) =>
212-
group.type !== 'gap' && group.group_key === notification.group_key,
213-
);
209+
if (!shouldGroupNotificationType(notification.type)) {
210+
notification = {
211+
...notification,
212+
group_key: `ungrouped-${notification.id}`,
213+
};
214+
}
214215

215-
// In any case, we are going to add a group at the top
216-
// If there is currently a gap at the top, now is the time to update it
217-
if (groups.length > 0 && groups[0]?.type === 'gap') {
218-
groups[0].maxId = notification.id;
219-
}
216+
const existingGroupIndex = groups.findIndex(
217+
(group) =>
218+
group.type !== 'gap' && group.group_key === notification.group_key,
219+
);
220220

221-
if (existingGroupIndex > -1) {
222-
const existingGroup = groups[existingGroupIndex];
221+
// In any case, we are going to add a group at the top
222+
// If there is currently a gap at the top, now is the time to update it
223+
if (groups.length > 0 && groups[0]?.type === 'gap') {
224+
groups[0].maxId = notification.id;
225+
}
223226

224-
if (
225-
existingGroup &&
226-
existingGroup.type !== 'gap' &&
227-
!existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post
228-
) {
229-
// Update the existing group
230-
if (
231-
existingGroup.sampleAccountIds.unshift(notification.account.id) >
232-
NOTIFICATIONS_GROUP_MAX_AVATARS
233-
)
234-
existingGroup.sampleAccountIds.pop();
227+
if (existingGroupIndex > -1) {
228+
const existingGroup = groups[existingGroupIndex];
235229

236-
existingGroup.most_recent_notification_id = notification.id;
237-
existingGroup.page_max_id = notification.id;
238-
existingGroup.latest_page_notification_at = notification.created_at;
239-
existingGroup.notifications_count += 1;
230+
if (
231+
existingGroup &&
232+
existingGroup.type !== 'gap' &&
233+
!existingGroup.sampleAccountIds.includes(notification.account.id) // This can happen for example if you like, then unlike, then like again the same post
234+
) {
235+
// Update the existing group
236+
if (
237+
existingGroup.sampleAccountIds.unshift(notification.account.id) >
238+
NOTIFICATIONS_GROUP_MAX_AVATARS
239+
)
240+
existingGroup.sampleAccountIds.pop();
240241

241-
groups.splice(existingGroupIndex, 1);
242-
mergeGapsAround(groups, existingGroupIndex);
242+
existingGroup.most_recent_notification_id = notification.id;
243+
existingGroup.page_max_id = notification.id;
244+
existingGroup.latest_page_notification_at = notification.created_at;
245+
existingGroup.notifications_count += 1;
243246

244-
groups.unshift(existingGroup);
247+
groups.splice(existingGroupIndex, 1);
248+
mergeGapsAround(groups, existingGroupIndex);
245249

246-
return;
247-
}
250+
groups.unshift(existingGroup);
248251
}
252+
} else {
253+
// We have not found an existing group, create a new one
254+
groups.unshift(createNotificationGroupFromNotificationJSON(notification));
249255
}
250-
251-
// We have not found an existing group, create a new one
252-
groups.unshift(createNotificationGroupFromNotificationJSON(notification));
253256
}
254257

255258
function trimNotifications(state: NotificationGroupsState) {

0 commit comments

Comments
 (0)