From ff2b8167b4d663b7bd2ed2348a6b8db2803b960f Mon Sep 17 00:00:00 2001 From: binwiederhier Date: Wed, 14 Jan 2026 21:17:21 -0500 Subject: [PATCH] Make closing notifications work --- web/public/sw.js | 15 ++++++++++++++- web/src/app/Notifier.js | 15 +++++++++++++++ web/src/components/hooks.js | 4 ++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/web/public/sw.js b/web/public/sw.js index 07a89415..db87e7f8 100644 --- a/web/public/sw.js +++ b/web/public/sw.js @@ -81,6 +81,13 @@ const handlePushMessageDelete = async (data) => { await db.notifications.where({ subscriptionId, sequenceId }).delete(); } + // Close browser notification with matching tag + const tag = message.sequence_id || message.id; + if (tag) { + const notifications = await self.registration.getNotifications({ tag }); + notifications.forEach((notification) => notification.close()); + } + // Update subscription last message id (for ?since=... queries) await db.subscriptions.update(subscriptionId, { last: message.id, @@ -101,6 +108,13 @@ const handlePushMessageClear = async (data) => { await db.notifications.where({ subscriptionId, sequenceId }).modify({ new: 0 }); } + // Close browser notification with matching tag + const tag = message.sequence_id || message.id; + if (tag) { + const notifications = await self.registration.getNotifications({ tag }); + notifications.forEach((notification) => notification.close()); + } + // Update subscription last message id (for ?since=... queries) await db.subscriptions.update(subscriptionId, { last: message.id, @@ -108,7 +122,6 @@ const handlePushMessageClear = async (data) => { // Update badge count const badgeCount = await db.notifications.where({ new: 1 }).count(); - console.log("[ServiceWorker] Setting new app badge count", { badgeCount }); self.navigator.setAppBadge?.(badgeCount); }; diff --git a/web/src/app/Notifier.js b/web/src/app/Notifier.js index 77bbdb1e..79089749 100644 --- a/web/src/app/Notifier.js +++ b/web/src/app/Notifier.js @@ -31,6 +31,21 @@ class Notifier { ); } + async cancel(notification) { + if (!this.supported()) { + return; + } + try { + const tag = notification.sequence_id || notification.id; + console.log(`[Notifier] Cancelling notification with ${tag}`); + const registration = await this.serviceWorkerRegistration(); + const notifications = await registration.getNotifications({ tag }); + notifications.forEach((notification) => notification.close()); + } catch (e) { + console.log(`[Notifier] Error cancelling notification`, e); + } + } + async playSound() { // Play sound const sound = await prefs.sound(); diff --git a/web/src/components/hooks.js b/web/src/components/hooks.js index 2d88f2cf..1c9c2bff 100644 --- a/web/src/components/hooks.js +++ b/web/src/components/hooks.js @@ -55,11 +55,11 @@ export const useConnectionListeners = (account, subscriptions, users, webPushTop // and FirebaseService::handleMessage(). if (notification.event === EVENT_MESSAGE_DELETE && notification.sequence_id) { - // Handle delete: remove notification from database await subscriptionManager.deleteNotificationBySequenceId(subscriptionId, notification.sequence_id); + await notifier.cancel(notification); } else if (notification.event === EVENT_MESSAGE_CLEAR && notification.sequence_id) { - // Handle read: mark notification as read await subscriptionManager.markNotificationReadBySequenceId(subscriptionId, notification.sequence_id); + await notifier.cancel(notification); } else { // Regular message: delete existing and add new const sequenceId = notification.sequence_id || notification.id;