Something went wrong. Try again.
leaflet fork for copy edit / bug fixes forked from leaflet.pub/leaflet
Something went wrong. Try again.
TypeScript
at ghost-import
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778import type { HydratedNotification, HydratedRecommendNotification, HydratedSubscribeNotification,} from "src/notifications";
// Modeled on Bluesky's notification grouping: interactions of the same kind on// the same subject collapse into one "X people [actioned]" item. Grouping runs// per fetched page (groups never span pages), so items and their keys stay// stable as further pages load.const GROUP_WINDOW_MS = 1000 * 60 * 60 * 48;
export type GroupableNotification = | HydratedSubscribeNotification | HydratedRecommendNotification;
export type NotificationGroup = { // head notification id — stable across refetches, used as the React key id: string; type: GroupableNotification["type"]; // newest first; the head sets the group's timestamp and 48h window notifications: GroupableNotification[];};
export type NotificationListItem = | { kind: "single"; notification: HydratedNotification } | { kind: "group"; group: NotificationGroup };
function groupKey(n: HydratedNotification): string | null { if (n.type === "subscribe") return `subscribe:${n.subscriptionData.publication}`; if (n.type === "recommend") return `recommend:${n.document_uri}`; return null;}
function actorDid(n: GroupableNotification): string | null { if (n.type === "subscribe") return n.subscriptionData.identity; return n.recommendData.recommender_did;}
export function groupNotifications( notifications: HydratedNotification[],): NotificationListItem[] { let items: NotificationListItem[] = []; let openGroups = new Map<string, NotificationGroup>(); for (let n of notifications) { let key = groupKey(n); if (key === null) { items.push({ kind: "single", notification: n }); continue; } let groupable = n as GroupableNotification; let group = openGroups.get(key); let headTime = group ? new Date(group.notifications[0].created_at).getTime() : 0; if ( group && headTime - new Date(n.created_at).getTime() < GROUP_WINDOW_MS ) { // duplicate actions by the same actor (e.g. unsubscribe/resubscribe) // collapse into their newest occurrence let did = actorDid(groupable); if (did === null || group.notifications.every((m) => actorDid(m) !== did)) group.notifications.push(groupable); continue; } let newGroup: NotificationGroup = { id: n.id, type: groupable.type, notifications: [groupable], }; openGroups.set(key, newGroup); items.push({ kind: "group", group: newGroup }); } return items;}