From 05b6e93d136455e795ca7ba1117cce330588ea56 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 18 Jul 2025 08:20:05 -0700 Subject: [PATCH] Service worker fixes --- app.js | 20 ++++++++++++++-- sw.js | 75 +++++++++++++++++++++++++++------------------------------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/app.js b/app.js index 012eb17..3a7e600 100644 --- a/app.js +++ b/app.js @@ -362,8 +362,10 @@ document.addEventListener('DOMContentLoaded', function () { progressCircular.className = 'progress-circular'; controlsContainer.appendChild(progressCircular); - installBtn.addEventListener('click', () => { - if (navigator.serviceWorker.controller) { + installBtn.addEventListener('click', async () => { + if (navigator.serviceWorker && navigator.serviceWorker.controller) { + await requestPersistentStorage(); + const selectedLanguage = languageSelect.value; installBtn.style.display = 'none'; uninstallBtn.style.display = 'none'; @@ -390,6 +392,20 @@ document.addEventListener('DOMContentLoaded', function () { checkInitialCacheStatus(); }); + async function requestPersistentStorage() { + if (navigator.storage && navigator.storage.persist) { + const isPersisted = await navigator.storage.persisted(); + if (!isPersisted) { + const wasGranted = await navigator.storage.persist(); + if (wasGranted) { + console.log('Persistent storage was granted.'); + } else { + console.log('Persistent storage request was denied.'); + } + } + } + } + function checkInitialCacheStatus() { if (navigator.serviceWorker.controller) { const selectedLanguage = languageSelect.value; diff --git a/sw.js b/sw.js index ca93ebb..b8748db 100644 --- a/sw.js +++ b/sw.js @@ -13,9 +13,9 @@ const coreAppFiles = [ '/', '/index.html', '/cancel_off.webp', '/cancel_on.webp', '/cdspin.gif', '/configure_off.webp', '/configure_on.webp', '/favicon.png', '/favicon.svg', '/free_stuff_off.webp', '/free_stuff_on.webp', '/install_off.webp', '/install_on.webp', - '/island.webp', '/isle.js', '/isle.wasm', '/poster.pdf', '/read_me_off.webp', + '/island.webp', '/isle.js', '/isle.wasm', '/poster.pdf', '/read_me_off.webp', '/read_me_on.webp', '/run_game_off.webp', '/run_game_on.webp', '/shark.webp', - '/uninstall_off.webp', '/uninstall_on.webp', 'app.js', 'style.css', 'manifest.json' + '/uninstall_off.webp', '/uninstall_on.webp', '/app.js', '/style.css', '/manifest.json' ]; const gameFiles = [ @@ -45,6 +45,7 @@ self.addEventListener('install', (event) => { }); }) ); + self.skipWaiting(); }); registerRoute( @@ -131,43 +132,36 @@ async function installLanguagePack(language, client) { for (const file of fileMetadata) { const request = new Request(file.url, { headers: { 'Accept-Language': language } }); + const response = await fetch(request); - try { - const response = await fetch(request); - - if (!response.ok || !response.body) { - throw new Error(`Failed to fetch ${file.url}`); - } - - const [streamForCaching, streamForProgress] = response.body.tee(); - - const responseToCache = new Response(streamForCaching, response); - const cachePromise = cache.put(request, responseToCache); - - const reader = streamForProgress.getReader(); - while (true) { - const { done, value } = await reader.read(); - if (done) break; - - bytesDownloaded += value.length; - const now = Date.now(); - - if (now - lastProgressUpdate > THROTTLE_MS) { - lastProgressUpdate = now; - client.postMessage({ - action: 'install_progress', - progress: (bytesDownloaded / totalBytesToDownload) * 100, - language: language - }); - } - } - - await cachePromise; - } catch (error) { - console.error("Aborting installation due to a persistent error:", error); - await caches.delete(cacheName); - client.postMessage({ action: 'install_failed', language: language }); + if (!response.ok || !response.body) { + throw new Error(`Failed to fetch ${file.url}`); } + + const [streamForCaching, streamForProgress] = response.body.tee(); + + const responseToCache = new Response(streamForCaching, response); + const cachePromise = cache.put(request, responseToCache); + + const reader = streamForProgress.getReader(); + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + bytesDownloaded += value.length; + const now = Date.now(); + + if (now - lastProgressUpdate > THROTTLE_MS) { + lastProgressUpdate = now; + client.postMessage({ + action: 'install_progress', + progress: (bytesDownloaded / totalBytesToDownload) * 100, + language: language + }); + } + } + + await cachePromise; } client.postMessage({ @@ -177,8 +171,9 @@ async function installLanguagePack(language, client) { }); client.postMessage({ action: 'install_complete', success: true, language: language }); } catch (error) { - console.error('Error during language pack installation:', error); - client.postMessage({ action: 'install_failed', success: false, language: language, error: error.message }); + console.error("Aborting installation due to an error:", error); + await caches.delete(cacheName); + client.postMessage({ action: 'install_failed', language: language }); } } @@ -214,5 +209,5 @@ self.addEventListener('activate', (event) => { ); }) ); - self.clients.claim(); + event.waitUntil(self.clients.claim()); });