1const BUILD_ID = '0.0.1-260921.1750'; 2self.build = BUILD_ID; 3 4function logEvent(data = {}) { 5 const url = '/client_api/log'; 6 const headers = { 'Content-Type': 'application/json' }; 7 8 // Telemetry is best-effort: a failed log must never reject a waitUntil chain. 9 return fetch(url, { 10 method: 'POST', 11 body: JSON.stringify(data), 12 headers, 13 }).catch(() => {}); 14} 15 16const updateServiceWorker = async () => { 17 try { 18 await self.registration.update(); 19 logEvent({ log: { message: 'Checking for updates', event: 'update', build: self.build } }); 20 self.skipWaiting(); // Optional: Force the waiting service worker to become the active service worker. 21 } catch (err) { 22 logEvent({ log: { message: 'Update failed', event: 'error', build: self.build, error: err } }); 23 } 24}; 25 26const updateAppOnEvent = (e) => { 27 if (e.data && e.data.command === 'UPDATE_APP') { 28 updateServiceWorker(); 29 } 30} 31 32function onInstall(event) { 33 console.log('[Serviceworker]', `Installing! ${self.build}`, event); 34 logEvent({ log: { message: 'Installing', event: 'install', build: self.build } }); 35} 36 37function onActivate(event) { 38 console.log('[Serviceworker]', "Activating!", event); 39 logEvent({ log: { message: 'Activating', event: 'activate', build: self.build } }); 40} 41 42function onFetch(event) { 43 // console.log('[Serviceworker]', "Fetching!", event); 44 // logEvent({ log: { message: 'Fetching', event: 'fetch', build: self.build } }); 45} 46 47const showMessageNotification = async function(payload) { 48 if ('setAppBadge' in self.navigator && payload.badge_count != null) { 49 try { 50 await self.navigator.setAppBadge(payload.badge_count); 51 } catch (e) { 52 // A badge failure must never block the notification. 53 } 54 } 55 56 if (Notification.permission !== 'granted') { 57 return logEvent({ log: { message: 'push_suppressed', event: 'push_suppressed', reason: 'permission_not_granted', build: self.build } }); 58 } 59 60 const badge = "https://www.niteflirt.com/niteflirt/images/favicon/push-notification-icon.png"; 61 62 const options = { 63 body: payload.body_text || 'You have new activity on NiteFlirt', 64 badge, 65 vibrate: [100, 50, 100], 66 data: { 67 dateOfArrival: Date.now(), 68 primaryKey: '2', 69 url: payload.notification_url || '/', 70 }, 71 }; 72 73 const title = payload.title || 'New activity on NiteFlirt'; 74 75 try { 76 await self.registration.showNotification(title, options); 77 } catch (e) { 78 return logEvent({ log: { message: 'push_suppressed', event: 'push_suppressed', reason: 'show_notification_failed', build: self.build, error: e.message } }); 79 } 80 81 return logEvent({ log: { message: 'push_shown', event: 'push_shown', build: self.build } }); 82}; 83 84const handlePush = async function(event) { 85 let payload = null; 86 87 try { 88 payload = event.data ? event.data.json() : null; 89 } catch (e) { 90 console.error('Error parsing event data', e); 91 logEvent({ log: { message: 'Error parsing event data', event: 'error', build: self.build, error: e.message } }); 92 } 93 94 if (payload && payload.type === 'UPDATE_APP') { 95 // Silent by design; must not be sent until the follow-up to NF-26656 lands. 96 return updateServiceWorker(); 97 } 98 99 // Always show a notification: the subscription promises userVisibleOnly, and 100 // iOS Safari/Firefox revoke subscriptions after repeated silent pushes (NF-26656). 101 return showMessageNotification(payload || {}); 102}; 103 104function onPush(event) { 105 console.log('[Serviceworker]', "Pushing!", event, "With build", self.build); 106 logEvent({ log: { message: 'Pushing', event: 'push', build: self.build } }); 107 event.waitUntil(handlePush(event)); 108}; 109 110async function onNotificationClick(event) { 111 logEvent({ log: { message: 'Notification clicked', event: 'notification_click', build: self.build } }); 112 const url = event.notification.data.url; 113 event.notification.close(); 114 event.waitUntil( 115 clients.matchAll({ type: "window" }).then((clientList) => { 116 for (const client of clientList) { 117 if ("focus" in client) { 118 client.focus(); 119 client.navigate(url); 120 return 121 } 122 } 123 124 if (clients.openWindow) { 125 return clients.openWindow(url); 126 } 127 }) 128 ); 129}; 130 131self.addEventListener('install', onInstall); 132self.addEventListener('activate', onActivate); 133self.addEventListener('fetch', onFetch); 134self.addEventListener('push', onPush); 135self.addEventListener('message', updateAppOnEvent); 136 137self.onnotificationclick = onNotificationClick;
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.