1/* Service worker for Courial â Web Push for driver chat notifications. */ 2 3self.addEventListener("install", () => { 4 // Activate this worker immediately on first install / update. 5 self.skipWaiting(); 6}); 7 8self.addEventListener("activate", (event) => { 9 event.waitUntil(self.clients.claim()); 10}); 11 12// A push arrives whenever the chauffeur sends a chat message (delivered by our 13// server-side bridge). If the app is currently in the foreground, the in-app 14// popup already handles it, so we suppress the system notification to avoid 15// double-alerting. 16self.addEventListener("push", (event) => { 17 let data = {}; 18 try { 19 data = event.data ? event.data.json() : {}; 20 } catch (e) { 21 data = {}; 22 } 23 24 const title = data.title || "Your chauffeur sent you a message"; 25 const body = data.body || "Tap to view your chat."; 26 const tag = data.tag || "driver-chat"; 27 const rideId = data.rideId || ""; 28 // Chauffeur photo (or bundled chauffeur fallback) sent by the server bridge; 29 // fall back to the app icon if it's ever missing. 30 const icon = data.icon || "/icon-192.png"; 31 32 event.waitUntil( 33 (async () => { 34 const clientsArr = await self.clients.matchAll({ 35 type: "window", 36 includeUncontrolled: true, 37 }); 38 39 const foregrounded = clientsArr.some( 40 (c) => c.focused === true && c.visibilityState === "visible" 41 ); 42 43 if (foregrounded) { 44 // App is open and on screen â let the in-app popup handle it. 45 clientsArr.forEach((c) => 46 c.postMessage({ type: "DRIVER_CHAT_PUSH", rideId, body }) 47 ); 48 return; 49 } 50 51 await self.registration.showNotification(title, { 52 body, 53 tag, 54 renotify: true, 55 icon, 56 badge: "/icon-192.png", 57 data: { rideId, url: "/" }, 58 }); 59 })() 60 ); 61}); 62 63// Tapping the notification focuses an existing window (and opens the chat) or 64// opens a new one. 65self.addEventListener("notificationclick", (event) => { 66 event.notification.close(); 67 const rideId = (event.notification.data && event.notification.data.rideId) || ""; 68 69 event.waitUntil( 70 (async () => { 71 const clientsArr = await self.clients.matchAll({ 72 type: "window", 73 includeUncontrolled: true, 74 }); 75 76 for (const c of clientsArr) { 77 if ("focus" in c) { 78 c.postMessage({ type: "OPEN_DRIVER_CHAT", rideId }); 79 return c.focus(); 80 } 81 } 82 83 if (self.clients.openWindow) { 84 return self.clients.openWindow("/?openDriverChat=" + encodeURIComponent(rideId)); 85 } 86 })() 87 ); 88});
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.