fix(threads): review-wave fixes for per-thread notifications
- useRoomsListener now PREPENDS the emitting Room (was appended): the SDK emits RoomEvent.UnreadNotifications with VARIABLE arity (0/1/2 args), so a trailing extra arg landed in the wrong positional slot on the most common room-count sync path — room.isSpaceRoom() threw inside the SDK emit loop and the badge PUT never ran. Both consumers updated (CONFIRMED HIGH review finding). - roomToUnread: SpaceChild RESET now passes the thread prefs so muted-thread subtraction survives space-child state changes. Reviewer also verified: badge subtraction math exact (no double-subtraction), encrypted thread replies caught by the timeline guard (m.relates_to is cleartext), fresh prefs flow to handlers, single-owner wiring load-bearing. Documented-acceptable: hasCurrentUserParticipated can lag until the server bundle refreshes after your first reply; dedupe maps grow per-session only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,6 @@ import {
|
||||
IRoomTimelineData,
|
||||
MatrixClient,
|
||||
MatrixEvent,
|
||||
NotificationCount,
|
||||
Room,
|
||||
RoomEvent,
|
||||
SyncState,
|
||||
@@ -282,18 +281,15 @@ export const useBindRoomToUnreadAtom = (mx: MatrixClient, unreadAtom: typeof roo
|
||||
|
||||
// RoomEvent.UnreadNotifications is emitted room-level only (never re-emitted
|
||||
// client-side), so the main Timeline pathway misses thread-count changes and
|
||||
// room badges lag. useRoomsListener appends the emitting Room as the final
|
||||
// arg, making this a surgical per-room PUT (not a full RESET per emit) with
|
||||
// muted-thread subtraction re-applied. Room-mute keeps its DELETE semantics.
|
||||
// room badges lag. useRoomsListener PREPENDS the emitting Room (the SDK emits
|
||||
// this event with variable arity — 0/1/2 args — so only a leading slot is
|
||||
// positionally stable), making this a surgical per-room PUT with muted-thread
|
||||
// subtraction re-applied. Room-mute keeps its DELETE semantics.
|
||||
useRoomsListener(
|
||||
mx,
|
||||
RoomEvent.UnreadNotifications,
|
||||
useCallback(
|
||||
(
|
||||
_unreadNotifications: NotificationCount | undefined,
|
||||
_threadId: string | undefined,
|
||||
room: Room,
|
||||
) => {
|
||||
(room: Room) => {
|
||||
if (room.isSpaceRoom()) return;
|
||||
if (getNotificationType(mx, room.roomId) === NotificationType.Mute) {
|
||||
setUnreadAtom({ type: 'DELETE', roomId: room.roomId });
|
||||
@@ -333,7 +329,7 @@ export const useBindRoomToUnreadAtom = (mx: MatrixClient, unreadAtom: typeof roo
|
||||
if (mEvent.getType() === StateEvent.SpaceChild) {
|
||||
setUnreadAtom({
|
||||
type: 'RESET',
|
||||
unreadInfos: getUnreadInfos(mx),
|
||||
unreadInfos: getUnreadInfos(mx, threadNotificationsRef.current),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user