From f054abfbd2c90689f0a2831f94a17019ec0ba612 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Thu, 18 Jun 2026 18:37:19 -0400 Subject: [PATCH] fix(notifications): click navigates to specific message, not inbox OS notifications now show the real message body ("user: text" instead of "New inbox notification from user"), clicking jumps directly to the room at the triggering event, and window.focus() brings the tab to front. Reminder toasts also link to the specific event via eventId. Co-Authored-By: Claude Sonnet 4.6 --- LOTUS_TODO.md | 5 +++-- src/app/pages/client/ClientNonUIFeatures.tsx | 16 ++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/LOTUS_TODO.md b/LOTUS_TODO.md index c3f5e8a31..1ad1962c3 100644 --- a/LOTUS_TODO.md +++ b/LOTUS_TODO.md @@ -299,11 +299,12 @@ Themes: --- -### [ ] P5-20 · Quick Reply from Browser Notification +### [~] P5-20 · Quick Reply from Browser Notification **What:** Inline reply field in browser notification toasts via Notification Actions API. Reply sends as threaded reply to the triggering message. **[AUDIT REQUIRED]** (1) Verify browser Notification Actions API support in target browsers. (2) Confirmed: service worker EXISTS at `src/sw.ts` — add `notificationclick` handler there. -**Complexity:** Medium-High. +**Complexity:** Medium-High. +**Partial Fix Applied ⚠️ UNTESTED:** Notifications now (a) show the real message body (`username: message` instead of "New inbox notification from..."), (b) click navigates directly to the room at the specific event (not the inbox), (c) `window.focus()` called on click so the tab comes to front, (d) reminder toasts also link to the specific event. Full inline-reply via Notification Actions API still needs the SW `push`+`notificationclick` pipeline (requires switching from `new Notification()` to `showNotification()` through the SW). --- diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index e6dfcf101..f42723d35 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -19,7 +19,6 @@ import { getDirectRoomPath, getHomeRoomPath, getInboxInvitesPath, - getInboxNotificationsPath, } from '../pathUtils'; import { mDirectAtom } from '../../state/mDirectList'; import { @@ -255,6 +254,10 @@ function MessageNotifications() { eventId: string; body?: string; }) => { + const roomPath = mDirects.has(roomId) + ? getDirectRoomPath(roomId, eventId) + : getHomeRoomPath(roomId, eventId); + if (document.hasFocus()) { setToast({ id: `${roomId}-${eventId}-${Date.now()}`, @@ -263,7 +266,7 @@ function MessageNotifications() { body: (body ?? '').slice(0, 80), roomName, roomId, - hashPath: mDirects.has(roomId) ? getDirectRoomPath(roomId) : getHomeRoomPath(roomId), + hashPath: roomPath, }); return; } @@ -271,12 +274,13 @@ function MessageNotifications() { const noti = new window.Notification(roomName, { icon: roomAvatar, badge: roomAvatar, - body: `New inbox notification from ${username}`, + body: body ? `${username}: ${body}`.slice(0, 120) : username, silent: true, }); noti.onclick = () => { - if (!window.closed) navigate(getInboxNotificationsPath()); + window.focus(); + navigate(roomPath); noti.close(); notifRef.current = undefined; }; @@ -400,8 +404,8 @@ function ReminderMonitor() { firedRef.current.add(key); const room = mx.getRoom(r.roomId); const hashPath = mDirects.has(r.roomId) - ? getDirectRoomPath(r.roomId) - : getHomeRoomPath(r.roomId); + ? getDirectRoomPath(r.roomId, r.eventId) + : getHomeRoomPath(r.roomId, r.eventId); setToast({ id: `reminder-${key}`, displayName: 'Reminder',