// // Playpass (c) Playco // https://github.com/playpassgames/playpass/blob/main/LICENSE.txt /// declare let self: ServiceWorkerGlobalScope; declare global { interface Navigator { // Currently Chrome-only: https://web.dev/badging-api/ setAppBadge (count?: number): Promise; clearAppBadge (): Promise; } } /** Data attached to incoming web push events. */ type WebPushData = { title: string; url: string; body?: string; icon?: string; badge?: string; image?: string; timestamp?: number; }; /** Data attached to displayed notifications. */ type NotificationData = { url: string; }; function waitUntil (handler: (event: T) => Promise) { return (event: T) => { event.waitUntil(handler(event)); }; } function trackEvent (url: string, eventName: string): Promise { // playpass-opengrapher will track these events in Amplitude, with the full set of tracking // properties return fetch(url, { headers: { "X-Playpass-Event": eventName, }, }); } /** Initialize the service worker, adding the necessary event listeners. */ export function init () { self.addEventListener("fetch", () => { // Implementing this listener is required for installability }); self.addEventListener("push", waitUntil(async event => { const webPushData: WebPushData = event.data!.json(); const notificationData: NotificationData = { url: webPushData.url, }; // Show an unread indicator on the app icon when notifications come in if (navigator.setAppBadge) { void navigator.setAppBadge(); } await self.registration.showNotification(webPushData.title, { body: webPushData.body, icon: webPushData.icon, badge: webPushData.badge, timestamp: webPushData.timestamp, image: webPushData.image, data: notificationData, }); await trackEvent(webPushData.url, "NotificationShown"); })); self.addEventListener("notificationclick", waitUntil(async event => { const notification = event.notification; notification.close(); const notificationData: NotificationData = notification.data; const windowClient = await self.clients.openWindow(notificationData.url); if (windowClient) { await windowClient.focus(); } await trackEvent(notificationData.url, "NotificationClicked"); })); }