diff --git a/public/index.html b/public/index.html index 4f47abdebd44def06142405d80f96ccacb543c94..369b33f73eb472472a8c77aab87f8ec6866611df 100644 --- a/public/index.html +++ b/public/index.html @@ -2,6 +2,22 @@ <html lang="en"> <head> <meta charset="UTF-8" /> + <link rel="manifest" href="manifest.json"> + <link rel="shortcut icon" href="logo.png"> + <script> + if (navigator.serviceWorker) { + navigator.serviceWorker + .register("service-worker.js") + .then( + (registration) => + console.log( + `Service worker registered on scope ${registration.scope}`, + ), + (reason) => + console.log(`Service worker failed to register ~ ${reason}`), + ) + } + </script> </head> <body> <div> diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e4266dca24a4059dcb0a7eec22db9384378d0bf3 Binary files /dev/null and b/public/logo.png differ diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..1b94f0d658806221b9b2bec412b6311ba6a108a3 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,13 @@ +{ + "short_name": "Drawing App", + "name": "Drawing App", + "icons": [ + { + "src": "/logo.png", + "type": "image/png", + "sizes": "144x144" + } + ], + "display": "standalone", + "start_url": "/index.html" +} diff --git a/public/service-worker.js b/public/service-worker.js new file mode 100644 index 0000000000000000000000000000000000000000..006388a3b8328861fec68f7f1d5c7d0bf1c82c9b --- /dev/null +++ b/public/service-worker.js @@ -0,0 +1,66 @@ +self.addEventListener("install", (event) => { + console.info("Service worker installed.", event) +}) + +self.addEventListener("activate", (event) => { + console.info("Service worker activated.", event) +}) + +const CACHE_NAME = "APP-V0" +const FILES_TO_CACHE = [ + "/index.html", + "/js/app.js", + "/manifest.json", +] +const FILE_ALIASES = new Map([ + ["/", "/index.html"] +]) + +const normalizeUrl = (url) => { + const url_ = new URL(url) + url_.pathname = url_.pathname.replace(/\/+/g, "/").replace(/\/$/, "") + if (FILE_ALIASES.has(url_.pathname)) { + url_.pathname = FILE_ALIASES.get(url_.pathname) + } + return url_.href +} + +self.addEventListener("install", async (event) => { + const cache = await caches.open(CACHE_NAME) + const additions = cache.addAll(FILES_TO_CACHE) + await additions + console.info(`Files cached: [\n ${FILES_TO_CACHE.join(`,\n `)}\n]`) +}) + +self.addEventListener("activate", async (event) => { + const oldCacheKeys = (await caches.keys()).filter((key) => key != CACHE_NAME) + oldCacheKeys.forEach((key) => caches.delete(key)) +}) + + +self.addEventListener("fetch", (event) => { + const normalizedUrl = normalizeUrl(event.request.url) + let response = fetch(event.request) + if (FILES_TO_CACHE.includes(normalizedUrl)) { + response = response + .then(async (response) => { + const cache = await caches.open(CACHE_NAME) + await cache.put(normalizedUrl, response.clone()) + return response + }) + .catch(() => caches.match(normalizedUrl)) + .catch(e => null) + } + event.respondWith( + fetch(event.request) + .then(async (response) => { + if (FILES_TO_CACHE.includes(new URL(normalizedUrl).pathname)) { + const cache = await caches.open(CACHE_NAME) + await cache.put(normalizedUrl, response.clone()) + } + return response + }) + .catch(() => caches.match(normalizedUrl)) + .catch(e => null) + ) +})