const CACHE_NAME = 'rpigroupplay-v4'; const ASSETS = [ './', './index.php', './manifest.json', './css/style.css', './css/bootstrap.css', './css/animation.css', './js/app.js', './js/bootstrap.js', './img/RpiGroupPlayWHITE.png', './img/logoapp.png' ]; // Install Event self.addEventListener('install', (e) => { e.waitUntil( caches.open(CACHE_NAME) .then((cache) => { console.log('[Service Worker] Caching static shell'); return cache.addAll(ASSETS).catch(err => { console.warn('[Service Worker] Asset caching warning:', err); }); }) .then(() => self.skipWaiting()) ); }); // Activate Event self.addEventListener('activate', (e) => { e.waitUntil( caches.keys().then((keys) => { return Promise.all( keys.map((key) => { if (key !== CACHE_NAME) { console.log('[Service Worker] Removing old cache', key); return caches.delete(key); } }) ); }).then(() => self.clients.claim()) ); }); // Fetch Event self.addEventListener('fetch', (e) => { const url = e.request.url; // Skip non-GET requests if (e.request.method !== 'GET') { return; } // Bypass streaming content, APIs, and external domains (like radio/tv streams) if ( url.includes('stream') || url.includes('.mp3') || url.includes('.aac') || url.includes('.m3u8') || url.includes('.ts') || url.includes('icecast') || url.includes('shoutcast') || url.includes('radiocitta105') || url.includes('radiodiffusionelibera') || !url.startsWith(self.location.origin) ) { return; // Let the browser handle standard streaming/external fetch requests directly } e.respondWith( caches.match(e.request).then((cachedResponse) => { if (cachedResponse) { // Return cached resource immediately and fetch fresh copy in background (Stale-While-Revalidate) fetch(e.request).then((networkResponse) => { if (networkResponse.status === 200) { caches.open(CACHE_NAME).then((cache) => { cache.put(e.request, networkResponse); }); } }).catch(() => { // Silent catch network failures }); return cachedResponse; } // Fallback to network return fetch(e.request).then((response) => { // Cache standard successful requests if (response.status === 200) { const responseClone = response.clone(); caches.open(CACHE_NAME).then((cache) => { cache.put(e.request, responseClone); }); } return response; }).catch(() => { // Fallback offline: restituiamo l'app shell se l'utente sta navigando if (e.request.mode === 'navigate') { return caches.match('./index.php'); } }); }) ); });