const CACHE_NAME = 'janichat-v1'; const STATIC_ASSETS = ['/', '/index.html']; self.addEventListener('install', (event) => { self.skipWaiting(); event.waitUntil( caches.open(CACHE_NAME).then(cache => cache.addAll(STATIC_ASSETS).catch(() => {})) ); }); self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then(keys => Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))) ) ); self.clients.claim(); }); self.addEventListener('fetch', (event) => { if (event.request.url.includes('/api/') || event.request.url.includes('/ws')) return; event.respondWith( fetch(event.request).catch(() => caches.match(event.request)) ); }); self.addEventListener('push', (event) => { let data = { title: 'JaniChat', body: 'Новое сообщение', chatId: null }; try { data = event.data.json(); } catch {} event.waitUntil( self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then(clients => { // Suppress if any app window is focused const appFocused = clients.some(c => c.focused); if (appFocused) return; return self.registration.showNotification(data.title, { body: data.body, icon: '/icon-192.png', badge: '/icon-192.png', data: { chatId: data.chatId }, vibrate: [200, 100, 200], }); }) ); }); self.addEventListener('notificationclick', (event) => { event.notification.close(); const chatId = event.notification.data?.chatId; const url = chatId ? `/?chat=${chatId}` : '/'; event.waitUntil( self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then(clients => { for (const client of clients) { if (client.url.includes(self.location.origin) && 'focus' in client) { client.postMessage({ type: 'open_chat', chatId }); return client.focus(); } } return self.clients.openWindow(url); }) ); });