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;