// Web Push service worker. Deliberately minimal — no offline caching, no // asset interception. Its only job is to keep receiving push events even // when the page's own tab is frozen or closed, and turn them into an OS // notification. self.addEventListener("push", (event) => { let payload = { title: "Thunderbird Portal", body: "", url: "/inquiries" }; try { if (event.data) payload = { ...payload, ...event.data.json() }; } catch { // malformed payload — fall back to the generic notification above } event.waitUntil( (async () => { await self.registration.showNotification(payload.title, { body: payload.body, icon: "/icon-192.png", data: { url: payload.url }, }); // badgeCount is only present on payloads that affect the unread chat // count — other event types omit it entirely so the badge is left // alone. Android/desktop only; iOS Safari has no Badging API (the // calls just don't exist there, so this is a no-op, not an error). if (typeof payload.badgeCount === "number" && "setAppBadge" in self.navigator) { if (payload.badgeCount > 0) { await self.navigator.setAppBadge(payload.badgeCount); } else { await self.navigator.clearAppBadge(); } } })(), ); }); self.addEventListener("notificationclick", (event) => { event.notification.close(); const url = event.notification.data && event.notification.data.url ? event.notification.data.url : "/inquiries"; event.waitUntil( (async () => { const clientsList = await self.clients.matchAll({ type: "window", includeUncontrolled: true }); const existing = clientsList.find((c) => "focus" in c); if (existing) { await existing.navigate(url); await existing.focus(); return; } await self.clients.openWindow(url); })(), ); });