From fa1769c3c21cb2478b698a73157fbef9abb0015f Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Wed, 14 Dec 2022 22:46:50 +0800 Subject: [PATCH] New feature: Grouped notifications - Grouped based on notification.type and notification.status.id - Crossing fingers here --- src/components/avatar.jsx | 1 + src/pages/notifications.jsx | 76 ++++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/components/avatar.jsx b/src/components/avatar.jsx index 81666864..1f6d98b8 100644 --- a/src/components/avatar.jsx +++ b/src/components/avatar.jsx @@ -17,6 +17,7 @@ export default ({ url, size, alt = '' }) => { width: size, height: size, }} + title={alt} > {!!url && ( {alt} diff --git a/src/pages/notifications.jsx b/src/pages/notifications.jsx index 355e8c6c..7650b17b 100644 --- a/src/pages/notifications.jsx +++ b/src/pages/notifications.jsx @@ -4,6 +4,7 @@ import { Link } from 'preact-router/match'; import { useEffect, useRef, useState } from 'preact/hooks'; import { useSnapshot } from 'valtio'; +import Avatar from '../components/avatar'; import Icon from '../components/icon'; import Loader from '../components/loader'; import NameText from '../components/name-text'; @@ -43,13 +44,13 @@ const contentText = { const LIMIT = 20; function Notification({ notification }) { - const { id, type, status, account } = notification; + const { id, type, status, account, _accounts } = notification; // status = Attached when type of the notification is favourite, reblog, status, mention, poll, or update const actualStatusID = status?.reblog?.id || status?.id; const currentAccount = store.session.get('currentAccount'); - const isSelf = currentAccount?.id === account.id; + const isSelf = currentAccount?.id === account?.id; const isVoted = status?.poll?.voted; const text = @@ -84,11 +85,50 @@ function Notification({ notification }) {

{!/poll|update/i.test(type) && ( <> - {' '} + {_accounts?.length > 1 ? ( + <> + {_accounts.length} people{' '} + + ) : ( + <> + {' '} + + )} )} {text}

+ {_accounts?.length > 1 && ( +

+ {_accounts.map((account, i) => ( + <> + { + e.preventDefault(); + states.showAccount = account; + }} + > + + {' '} + + ))} +

+ )} {status && ( @@ -103,9 +143,34 @@ function NotificationsList({ notifications, emptyCopy }) { if (!notifications.length && emptyCopy) { return

{emptyCopy}

; } + + // Create new flat list of notifications + // Combine sibling notifications based on type and status id, ignore the id + // Concat all notification.account into an array of _accounts + const cleanNotifications = [notifications[0]]; + for (let i = 1, j = 0; i < notifications.length; i++) { + const notification = notifications[i]; + const cleanNotification = cleanNotifications[j]; + const { status, account, type } = notification; + if ( + account && + cleanNotification?.account && + cleanNotification?.status?.id === status?.id && + cleanNotification?.type === type + ) { + cleanNotification._accounts.push(account); + } else { + cleanNotifications[++j] = { + ...notification, + _accounts: [account], + }; + } + } + // console.log({ notifications, cleanNotifications }); + return (