diff --git a/assets/app.js b/assets/app.js index 86f4d35..c4b7d3e 100644 --- a/assets/app.js +++ b/assets/app.js @@ -20,6 +20,15 @@ const modalInput = document.getElementById('modalInput'); const modalTitle = document.getElementById('modalTitle'); const hapticTick = () => { if ('vibrate' in navigator) navigator.vibrate(12); }; +// --- Service Worker --- +if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/sw.js').catch(() => { + // fail silently; optional log + }); + }); +} + // --- Sweet-ish Alerts --- function removeSwal() { const existing = document.querySelector('.swal-overlay'); diff --git a/assets/site.webmanifest b/assets/site.webmanifest index 4e00e86..d7c60cc 100644 --- a/assets/site.webmanifest +++ b/assets/site.webmanifest @@ -1,6 +1,8 @@ { "name": "Toadstool Tally", "short_name": "Toadstool", + "start_url": ".", + "scope": ".", "icons": [ { "src": "icons/web-app-manifest-192x192.png", diff --git a/sw.js b/sw.js new file mode 100644 index 0000000..b4308db --- /dev/null +++ b/sw.js @@ -0,0 +1,50 @@ +const CACHE_NAME = 'toadstool-tally-v1'; +const ASSETS = [ + '/', + '/index.html', + '/assets/style.css', + '/assets/app.js', + '/assets/textures/mushroom.svg', + '/assets/icons/favicon-96x96.png', + '/assets/icons/favicon.ico', + '/assets/icons/favicon.svg', + '/assets/icons/apple-touch-icon.png', + '/assets/icons/web-app-manifest-192x192.png', + '/assets/icons/web-app-manifest-512x512.png', + '/assets/site.webmanifest' +]; + +self.addEventListener('install', (event) => { + event.waitUntil( + caches.open(CACHE_NAME).then((cache) => cache.addAll(ASSETS)) + ); +}); + +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then((keys) => + Promise.all( + keys + .filter((key) => key !== CACHE_NAME) + .map((key) => caches.delete(key)) + ) + ) + ); + self.clients.claim(); +}); + +self.addEventListener('fetch', (event) => { + const { request } = event; + if (request.method !== 'GET') return; + + event.respondWith( + caches.match(request).then((cached) => { + if (cached) return cached; + return fetch(request).then((response) => { + const copy = response.clone(); + caches.open(CACHE_NAME).then((cache) => cache.put(request, copy)); + return response; + }).catch(() => cached); + }) + ); +});