From 52045897e5524bd90dd93295f16c84f46877c4e9 Mon Sep 17 00:00:00 2001 From: Jose Luis Date: Sat, 21 Mar 2026 16:24:33 +0100 Subject: [PATCH] feat: add PWA support (installable app) - Web app manifest with name, icons, theme color, standalone display - Service worker with stale-while-revalidate caching strategy - 192px and 512px PNG icons generated from favicon.svg - Apple-specific meta tags for iOS home screen support - Register service worker on page load Co-Authored-By: Claude Opus 4.6 (1M context) --- index.html | 5 +++++ public/icon-192.png | Bin 0 -> 3589 bytes public/icon-512.png | Bin 0 -> 11173 bytes public/manifest.json | 15 +++++++++++++++ public/sw.js | 33 +++++++++++++++++++++++++++++++++ src/main.jsx | 7 +++++++ 6 files changed, 60 insertions(+) create mode 100644 public/icon-192.png create mode 100644 public/icon-512.png create mode 100644 public/manifest.json create mode 100644 public/sw.js diff --git a/index.html b/index.html index 10f01cf..56f0f0c 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,11 @@ Reaktor — MontLab Modular Synth + + + + +
diff --git a/public/icon-192.png b/public/icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..723ed12371feac344293ae6578f4b8493ffeb8d0 GIT binary patch literal 3589 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 literal 0 HcmV?d00001 diff --git a/public/icon-512.png b/public/icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..2de1180ab8ee646742776ea43a7d57434c5083f3 GIT binary patch literal 11173 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 { + self.skipWaiting(); +}); + +self.addEventListener('activate', (e) => { + e.waitUntil( + caches.keys().then(keys => + Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))) + ) + ); + self.clients.claim(); +}); + +self.addEventListener('fetch', (e) => { + // Only cache GET requests, skip API calls + if (e.request.method !== 'GET') return; + + e.respondWith( + caches.match(e.request).then(cached => { + const fetching = fetch(e.request).then(response => { + if (response.ok) { + const clone = response.clone(); + caches.open(CACHE_NAME).then(cache => cache.put(e.request, clone)); + } + return response; + }).catch(() => cached); + + return cached || fetching; + }) + ); +}); diff --git a/src/main.jsx b/src/main.jsx index fadf959..c7427ce 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -15,3 +15,10 @@ function Root() { } createRoot(document.getElementById('root')).render(); + +// Register service worker for PWA +if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/sw.js').catch(() => {}); + }); +}