1/* Skinscore Push Notification Service Worker */ 2 3self.addEventListener("push", (event) => { 4 if (!event.data) return; 5 6 let data; 7 try { 8 data = event.data.json(); 9 } catch { 10 data = { title: "Skinscore", body: event.data.text(), url: "/" }; 11 } 12 13 const title = data.title || "Skinscore"; 14 const options = { 15 body: data.body || "", 16 icon: data.icon || "/logo192.png", 17 badge: "/logo192.png", 18 data: { url: data.url || "/" }, 19 tag: "skinscore-notification", 20 renotify: true, 21 }; 22 23 // If a Skinscore tab is visible, skip the OS notification (in-app toast handles it) 24 event.waitUntil( 25 self.clients 26 .matchAll({ type: "window", includeUncontrolled: true }) 27 .then((clients) => { 28 const hasVisibleClient = clients.some( 29 (c) => c.visibilityState === "visible" 30 ); 31 if (hasVisibleClient) return; 32 return self.registration.showNotification(title, options); 33 }) 34 ); 35}); 36 37self.addEventListener("notificationclick", (event) => { 38 event.notification.close(); 39 40 const url = event.notification.data?.url || "/"; 41 42 event.waitUntil( 43 self.clients 44 .matchAll({ type: "window", includeUncontrolled: true }) 45 .then((clients) => { 46 // Focus an existing Skinscore tab if one exists 47 for (const client of clients) { 48 if ( 49 client.url.includes("skinscore.app") || 50 client.url.includes("localhost") 51 ) { 52 client.focus(); 53 client.navigate(url); 54 return; 55 } 56 } 57 // No existing tab â open a new one 58 return self.clients.openWindow(url); 59 }) 60 ); 61});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.