fix(desktop): navigate to the message on notification click (route via rich toast)
On the Windows/Tauri build, clicking a message notification opened the app but didn't navigate to the message. showOsNotification preferred the service worker (registration.showNotification) and returned early; WebView2 has a service worker, so the SW-owned toast always won and its click (SW notificationclick → client.focus + postMessage → navigate) focused the app but the navigate didn't complete in WebView2. The desktop build injects a window.Notification shim that routes tagged message toasts to the native rich WinRT toast, whose click emits lotus-notification- activate with the path → useTauriToastActions → navigate. But the SW path shadowed `new Notification()`, so that shim (and show_rich_toast) never ran on desktop. Skipping the SW path under Tauri lets the shim take over and navigate. Web browsers are unchanged (isDesktopApp() is false → SW path as before). Two review agents verified the diagnosis + no web regression across both repos. DESKTOP-QA REQUIRED — this activates a previously-dead code path. Known desktop follow-ups it exposes (documented in LOTUS_TODO, both in cinny-desktop Rust): - tag-coalescing is lost (rapid same-room messages stack toasts instead of collapsing) — show_rich_toast doesn't dedupe by room. - thread/invite quick-reply misroutes: the reply target is the coalescing tag (roomId:threadId / 'lotus-invites'), not a real room id → sendMessage fails. Navigation itself (body click) is correct for all cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+14
-1
@@ -268,13 +268,26 @@ export const notificationPermission = (permission: NotificationPermission) => {
|
||||
* (with the provided `onClick`) when no service worker is available, preserving
|
||||
* the previous behaviour.
|
||||
*/
|
||||
// Tauri v2 injects `__TAURI_INTERNALS__` into the webview. On the desktop build,
|
||||
// an injected `window.Notification` shim routes `tag`-bearing message toasts to
|
||||
// the native rich WinRT toast, whose click focuses the app AND navigates to the
|
||||
// message (via the `lotus-notification-activate` event → useTauriToastActions).
|
||||
const isDesktopApp = (): boolean =>
|
||||
(window as unknown as { __TAURI_INTERNALS__?: { invoke?: unknown } }).__TAURI_INTERNALS__
|
||||
?.invoke !== undefined;
|
||||
|
||||
export const showOsNotification = async (
|
||||
title: string,
|
||||
options: NotificationOptions & { data?: { path?: string } },
|
||||
onClick?: () => void,
|
||||
): Promise<void> => {
|
||||
try {
|
||||
if ('serviceWorker' in navigator) {
|
||||
// On desktop, skip the service-worker notification: WebView2 exposes a
|
||||
// service worker, so the SW-owned toast would win here and bypass the
|
||||
// Notification shim above — its click focuses the app but never navigates to
|
||||
// the message. Falling through to `new Notification()` lets the shim route
|
||||
// to the native rich toast, which does navigate.
|
||||
if (!isDesktopApp() && 'serviceWorker' in navigator) {
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
if (registration && typeof registration.showNotification === 'function') {
|
||||
await registration.showNotification(title, options);
|
||||
|
||||
Reference in New Issue
Block a user