import { useEffect, useState } from 'react'; import { useAtomValue } from 'jotai'; import { MatrixEvent, NotificationCountType, Room, RoomEvent, RoomEventHandlerMap, ThreadEvent, } from 'matrix-js-sdk'; import { getThreadSummary, ThreadSummaryData } from '../features/room/thread/threadSummaryData'; import { threadNotificationsAtom } from '../state/threadNotifications'; import { getThreadNotificationMode, ThreadNotificationMode } from '../utils/threadNotifications'; /** * Reactive thread summary + unread count for a root event's "N replies" chip. * * Re-computes the summary on `ThreadEvent.Update` (the SDK re-emits this on the * root MatrixEvent) and the unread count on `RoomEvent.UnreadNotifications`. */ export const useThreadSummary = ( rootEvent: MatrixEvent, room: Room, ): { summary: ThreadSummaryData | undefined; unread: number; mode: ThreadNotificationMode } => { const threadId = rootEvent.getId(); const threadNotifications = useAtomValue(threadNotificationsAtom); const mode = threadId ? getThreadNotificationMode(threadNotifications, room.roomId, threadId) : ThreadNotificationMode.Default; const [summary, setSummary] = useState(() => getThreadSummary(rootEvent), ); const [unread, setUnread] = useState(() => threadId ? (room.getThreadUnreadNotificationCount(threadId, NotificationCountType.Total) ?? 0) : 0, ); useEffect(() => { const refreshSummary = () => setSummary(getThreadSummary(rootEvent)); const refreshUnread = () => { if (!threadId) return; setUnread(room.getThreadUnreadNotificationCount(threadId, NotificationCountType.Total) ?? 0); }; refreshSummary(); refreshUnread(); const handleUnread: RoomEventHandlerMap[RoomEvent.UnreadNotifications] = (_counts, tId) => { if (tId && tId !== threadId) return; refreshUnread(); }; rootEvent.on(ThreadEvent.Update, refreshSummary); room.on(RoomEvent.UnreadNotifications, handleUnread); return () => { rootEvent.removeListener(ThreadEvent.Update, refreshSummary); room.removeListener(RoomEvent.UnreadNotifications, handleUnread); }; }, [rootEvent, room, threadId]); const muted = mode === ThreadNotificationMode.Mute; return { summary, unread: muted ? 0 : unread, mode }; };