/* Prabhupāda Says — Web Push service worker. * * Handles incoming push messages (shows a notification) and clicks (focuses * an existing same-origin tab and navigates it, or opens a new one). The push * payload is the JSON the BFF sends: * { title, body, url, icon, tag, require_interaction } */ self.addEventListener("install", () => self.skipWaiting()); self.addEventListener("activate", (event) => event.waitUntil(self.clients.claim()), ); self.addEventListener("push", (event) => { event.waitUntil( (async () => { let data = {}; if (event.data) { try { // event.data.json() is synchronous; text() is a Promise — only // awaited in the fallback. data = event.data.json(); } catch { data = { body: await event.data.text() }; } } const title = data.title || "Prabhupāda Says"; const options = { body: data.body || "", icon: data.icon || "/icon-192.png", badge: "/icon-192.png", // A tag dedupes a series (e.g. daily reminders replace the previous // one); renotify re-alerts when a tagged notification is replaced. tag: data.tag || undefined, renotify: !!data.tag, // Reminders set this so they stay until acted on (desktop otherwise // auto-dismisses). Defaults off for everything else. requireInteraction: data.require_interaction === true, vibrate: [100, 50, 100], data: { url: data.url || "/" }, actions: [{ action: "open", title: "Open" }], }; await self.registration.showNotification(title, options); })(), ); }); self.addEventListener("notificationclick", (event) => { event.notification.close(); // The only action is "open"; the default body click behaves the same. const url = (event.notification.data && event.notification.data.url) || "/"; const target = new URL(url, self.location.origin).href; event.waitUntil( (async () => { const list = await self.clients.matchAll({ type: "window", includeUncontrolled: true, }); // Reuse a single existing same-origin tab — focus it and navigate only // that one (not every matched window). for (const client of list) { if (client.url.startsWith(self.location.origin)) { await client.focus(); if ("navigate" in client) { try { await client.navigate(target); } catch { /* cross-document navigation can reject; focus already happened */ } } return; } } if (self.clients.openWindow) await self.clients.openWindow(target); })(), ); });