/ src / utils / group-notifications.jsx
group-notifications.jsx
 1  function groupNotifications(notifications) {
 2    // Create new flat list of notifications
 3    // Combine sibling notifications based on type and status id
 4    // Concat all notification.account into an array of _accounts
 5    const notificationsMap = {};
 6    const cleanNotifications = [];
 7    for (let i = 0, j = 0; i < notifications.length; i++) {
 8      const notification = notifications[i];
 9      const { status, account, type, createdAt } = notification;
10      const date = new Date(createdAt).toLocaleDateString();
11      let virtualType = type;
12      if (type === 'favourite' || type === 'reblog') {
13        virtualType = 'favourite+reblog';
14      }
15      const key = `${status?.id}-${virtualType}-${date}`;
16      const mappedNotification = notificationsMap[key];
17      if (virtualType === 'follow_request') {
18        cleanNotifications[j++] = notification;
19      } else if (mappedNotification?.account) {
20        const mappedAccount = mappedNotification._accounts.find(
21          (a) => a.id === account.id,
22        );
23        if (mappedAccount) {
24          mappedAccount._types.push(type);
25          mappedAccount._types.sort().reverse();
26        } else {
27          account._types = [type];
28          mappedNotification._accounts.push(account);
29        }
30      } else {
31        account._types = [type];
32        let n = (notificationsMap[key] = {
33          ...notification,
34          type: virtualType,
35          _accounts: [account],
36        });
37        cleanNotifications[j++] = n;
38      }
39    }
40  
41    // 2nd pass to group "favourite+reblog"-type notifications by account if _accounts.length <= 1
42    // This means one acount has favourited and reblogged the multiple statuses
43    // The grouped notification
44    // - type: "favourite+reblog+account"
45    // - _statuses: [status, status, ...]
46    const notificationsMap2 = {};
47    const cleanNotifications2 = [];
48    for (let i = 0, j = 0; i < cleanNotifications.length; i++) {
49      const notification = cleanNotifications[i];
50      const { account, _accounts, type, createdAt } = notification;
51      const date = new Date(createdAt).toLocaleDateString();
52      if (type === 'favourite+reblog' && account && _accounts.length === 1) {
53        const key = `${account?.id}-${type}-${date}`;
54        const mappedNotification = notificationsMap2[key];
55        if (mappedNotification) {
56          mappedNotification._statuses.push(notification.status);
57        } else {
58          let n = (notificationsMap2[key] = {
59            ...notification,
60            type,
61            _statuses: [notification.status],
62          });
63          cleanNotifications2[j++] = n;
64        }
65      } else {
66        cleanNotifications2[j++] = notification;
67      }
68    }
69  
70    console.log({ notifications, cleanNotifications, cleanNotifications2 });
71  
72    // return cleanNotifications;
73    return cleanNotifications2;
74  }
75  
76  export default groupNotifications;