self.addEventListener('install', () => self.skipWaiting()); self.addEventListener('activate', (event) => event.waitUntil(self.clients.claim())); async function broadcastToClients(payload) { const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true }); clients.forEach((client) => { client.postMessage({ type: 'SHINE_WEB_PUSH_EVENT', payload, }); }); } self.addEventListener('push', (event) => { let body = ''; let rawText = ''; let kind = ''; let fromLogin = ''; try { if (event.data) { const text = event.data.text(); rawText = text || ''; try { const json = JSON.parse(rawText || '{}'); kind = String(json.kind || ''); body = String(json.text || ''); fromLogin = String(json.fromLogin || ''); } catch { body = rawText || ''; } } } catch { // ignore } const shouldNotify = kind === 'new_message' || (!kind && body); const notifyPromise = shouldNotify ? self.registration.showNotification('SHiNE: входящее сообщение', { body: body || (fromLogin ? `Вам пришло сообщение от ${fromLogin}` : 'Вам пришло сообщение'), tag: 'shine-direct-message', renotify: true, }) : Promise.resolve(); event.waitUntil(Promise.all([ notifyPromise, broadcastToClients({ kind, body, fromLogin, rawText, receivedAt: Date.now(), }), ])); }); self.addEventListener('notificationclick', (event) => { event.notification?.close(); event.waitUntil((async () => { const allClients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true }); const existing = allClients.find((client) => { try { return client.url.includes('/index.html') || client.url.endsWith('/'); } catch { return false; } }); if (existing) { await existing.focus(); return; } await self.clients.openWindow('./index.html'); })()); });