Skip to content

fix(notifications): notification delivery and routing fixes#99

Open
Just-Insane wants to merge 9 commits intoSableClient:devfrom
Just-Insane:fix/notification-delivery-bugs
Open

fix(notifications): notification delivery and routing fixes#99
Just-Insane wants to merge 9 commits intoSableClient:devfrom
Just-Insane:fix/notification-delivery-bugs

Conversation

@Just-Insane
Copy link
Contributor

@Just-Insane Just-Insane commented Mar 9, 2026

A collection of notification reliability fixes.

  • OS notification always fires on desktop — system notifications are sent regardless of focus state (matching Discord behaviour); in-app banner also shows when the window is visible, so both fire simultaneously when focused
  • Fix deep-link navigationuseNotificationJumper uses getOrphanParents and guessPerfectParent to navigate correctly to threaded/nested events, avoiding the JoinBeforeNavigate dead-end caused by navigating via a sub-space
  • Fix DM badge highlight — the accent badge is now only shown for actual mentions and replies (unread.highlight > 0); unreads without a mention show count or dot per user badge settings
  • Fix DM notification sound — DMs are treated as loud to work around a sliding sync limitation where the m.rule.room_one_to_one push rule cannot be evaluated; muted rooms are unaffected

@Just-Insane Just-Insane requested a review from a team March 9, 2026 20:46
@Just-Insane Just-Insane force-pushed the fix/notification-delivery-bugs branch from ec938e2 to 6fd0dc7 Compare March 9, 2026 21:03
@Just-Insane Just-Insane marked this pull request as draft March 9, 2026 21:13
@Just-Insane Just-Insane marked this pull request as ready for review March 9, 2026 21:34
@Just-Insane Just-Insane force-pushed the fix/notification-delivery-bugs branch 3 times, most recently from 8335b46 to 634d9d8 Compare March 9, 2026 23:13
Evie Gauthier added 9 commits March 9, 2026 21:39
… audio, media session)

- resolveSilent = () => false — OS/Sygnal handles push sound entirely; the
  in-app sound setting no longer affects push notification sound
- remove notificationSoundEnabled from SW postMessage payload
- move OS notification block before visibilityState guard so desktop
  notifications fire even when the browser window is minimised
- pass isEncryptedRoom:false for in-app banner preview — events are already
  decrypted by the SDK so the actual message body is always shown
- call clearMediaSessionQuickly() after play() to dismiss the iOS lock screen
  media player; only clears playbackState if no real media metadata is set
… sound tweak

Two bugs caused by sliding sync's limited required_state (only $ME member):

1. DM badge was grey instead of green
   Synapse sends highlight_count=0 for DMs without mention; the badge only
   showed as Success (green) when highlight>0. DMs should always display
   the green badge for any unread. Fix: RoomNavItem treats direct && total>0
   as highlight for the UnreadBadge highlight prop.

2. DM OS notification was silent
   PushProcessor evaluates .m.rule.room_one_to_one by checking
   room_member_count==2, but with only m.room.member/$ME in required_state
   the member count is 1, so the rule fails. Events fall through to
   .m.rule.message (notify, no sound), leaving loudByRule=false and the
   OS notification silent:true. Fix: isLoud = loudByRule || isDM so that
   known DM rooms always produce non-silent notifications when sounds are on.
useNotificationJumper was using roomToParents.get(roomId) — the direct
parent set — which could be a subspace rather than a root-level space.
The router only recognises /space/<root-space-id>/room paths, so linking
via a subspace ID would hit JoinBeforeNavigate instead of opening the room.

Replace with the same logic as useRoomNavigate:
  getOrphanParents() walks the full hierarchy to find root-level spaces,
  guessPerfectParent() picks the best one to route through.
…p in try/catch

Two bugs caused in-app notifications to silently vanish on desktop when
the window was focused:

1. window.Notification() was called unconditionally even when the window
   had focus.  In some browsers/environments (certain Chrome versions,
   Electron, macOS DnD mode) calling the Notification constructor throws
   or is silently rejected when the tab is active.  Without a try/catch
   the uncaught exception aborted the entire RoomEvent.Timeline handler
   before setInAppBanner was ever reached — so neither the OS notification
   NOR the in-app banner appeared.  InviteNotifications already used
   try/catch for the same reason; MessageNotifications did not.

2. The OS notification was semantically wrong when focused: the in-app
   banner is the correct alert while the window is active.  Added a
   !document.hasFocus() guard to match the comment's stated intent
   ("alert when minimised or tab not active") and to prevent a duplicate
   OS+in-app banner when another window is simply on top.

Mobile is unaffected: mobileOrTablet() already gates the OS block.
The in-app banner path (visibilityState === 'visible' → setInAppBanner)
is unchanged and continues to fire correctly on both desktop (focused)
and mobile (app visible in browser).
@Just-Insane Just-Insane force-pushed the fix/notification-delivery-bugs branch from 634d9d8 to f655498 Compare March 10, 2026 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant