diff --git a/public/sw.js b/public/sw.js index 0029938..778b806 100644 --- a/public/sw.js +++ b/public/sw.js @@ -3,7 +3,7 @@ // // This value is rewritten automatically before each build so deployed clients // refresh to the newest shell and cached assets. -const CACHE_NAME = 'radioplayer-pwa-v5-1777473175316'; +const CACHE_NAME = 'radioplayer-pwa-v5-1777474420392'; const STATION_SYNC_CACHE_NAME = 'radioplayer-station-sync-v1'; const MANAGED_CATALOG_CACHE_NAME = 'radioplayer-managed-catalog-v1'; const RADIO_BROWSER_API_ENDPOINT = 'https://de1.api.radio-browser.info/json/stations/search'; @@ -377,10 +377,23 @@ async function refreshManagedCatalogCache() { const response = await fetch(url, { cache: 'no-store' }); if (isCacheableResponse(response)) { await managedCatalogCache.put(url, response); + return { updated: true, error: null }; } + + return { + updated: false, + error: `Unexpected managed catalog response: ${response.status} ${response.statusText}`.trim(), + }; } catch { // Network unavailable — keep existing cache as-is. } + + return { updated: false, error: 'Managed catalog request failed.' }; +} + +async function notifyClients(message) { + const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true }); + await Promise.allSettled(clients.map((client) => client.postMessage(message))); } async function respondWithManagedCatalog(request) { @@ -530,7 +543,23 @@ self.addEventListener('activate', (event) => { self.addEventListener('sync', (event) => { if (event.tag !== STATION_SYNC_TAG) return; - event.waitUntil(syncRadioStations('background-sync')); + event.waitUntil( + syncRadioStations('background-sync') + .then((meta) => notifyClients({ + type: 'station-catalog-updated', + reason: 'background-sync', + meta, + })) + .catch(async (error) => { + await notifyClients({ + type: 'station-catalog-update-failed', + reason: 'background-sync', + error: error instanceof Error ? error.message : 'Unknown error', + failedAt: new Date().toISOString(), + }); + throw error; + }) + ); }); self.addEventListener('message', (event) => { @@ -544,6 +573,14 @@ self.addEventListener('message', (event) => { ? await syncRadioStations('country-selection-update', syncSettings.selectedCountryCodes) : null; + if (syncResult) { + await notifyClients({ + type: 'station-catalog-updated', + reason: 'country-selection-update', + meta: syncResult, + }); + } + event.ports?.[0]?.postMessage({ ok: true, selectedCountryCodes: syncSettings.selectedCountryCodes, @@ -560,11 +597,43 @@ self.addEventListener('message', (event) => { self.addEventListener('periodicsync', (event) => { if (event.tag === STATION_PERIODIC_SYNC_TAG) { - event.waitUntil(syncRadioStations('periodic-sync')); + event.waitUntil( + syncRadioStations('periodic-sync') + .then((meta) => notifyClients({ + type: 'station-catalog-updated', + reason: 'periodic-sync', + meta, + })) + .catch(async (error) => { + await notifyClients({ + type: 'station-catalog-update-failed', + reason: 'periodic-sync', + error: error instanceof Error ? error.message : 'Unknown error', + failedAt: new Date().toISOString(), + }); + throw error; + }) + ); return; } if (event.tag === MANAGED_CATALOG_PERIODIC_SYNC_TAG) { - event.waitUntil(refreshManagedCatalogCache()); + event.waitUntil( + refreshManagedCatalogCache().then((result) => { + if (!result.updated) { + return notifyClients({ + type: 'managed-catalog-update-failed', + reason: 'periodic-sync', + error: result.error || 'Unknown error', + failedAt: new Date().toISOString(), + }); + } + + return notifyClients({ + type: 'managed-catalog-updated', + reason: 'periodic-sync', + }); + }) + ); } }); diff --git a/src/App.jsx b/src/App.jsx index e3e7807..f39ca8f 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -199,6 +199,11 @@ function TrackInfo() {
+
+ +
+
Output: