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 = ''; let title = ''; try { if (event.data) { const text = event.data.text(); rawText = text || ''; try { const json = JSON.parse(rawText || '{}'); kind = String(json.kind || ''); title = String(json.title || ''); body = String(json.text || ''); fromLogin = String(json.fromLogin || ''); } catch { body = rawText || ''; } } } catch { // ignore } const shouldNotify = kind === 'new_message' || kind === 'test_push' || (!kind && body); const notificationTitle = kind === 'test_push' ? (title || 'SHiNE: тестовый push') : 'SHiNE: входящее сообщение'; const notifyPromise = shouldNotify ? self.registration.showNotification(notificationTitle, { body: body || (fromLogin ? `Вам пришло сообщение от ${fromLogin}` : 'Вам пришло сообщение'), tag: kind === 'test_push' ? 'shine-test-push' : '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'); })()); });