From 9d55044d4321233f6ffdbada737bccb5894a0f2a Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 11 Apr 2024 13:35:06 -0700 Subject: service worker for pwa --- bun.lockb | Bin 120851 -> 120851 bytes src/app.html | 1 + src/locales/en.json | 2 +- .../(app)/[username]/(profile)/+layout.svelte | 6 +- src/routes/(app)/[username]/(profile)/+page.svelte | 28 +++++-- src/routes/+layout.svelte | 17 +++++ src/service-worker.js | 83 +++++++++++++++++++++ static/home.png | Bin 0 -> 260144 bytes static/manifest.webmanifest | 66 ++++++++++++++-- static/receive.png | Bin 0 -> 247776 bytes static/screenshot.png | Bin 219558 -> 0 bytes svelte.config.js | 3 + 12 files changed, 188 insertions(+), 18 deletions(-) create mode 100644 src/service-worker.js create mode 100644 static/home.png create mode 100644 static/receive.png delete mode 100644 static/screenshot.png diff --git a/bun.lockb b/bun.lockb index 406ad71b..38d329c9 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/src/app.html b/src/app.html index 9d7e2fdb..728900ed 100644 --- a/src/app.html +++ b/src/app.html @@ -9,6 +9,7 @@ /> + %sveltekit.head% diff --git a/src/locales/en.json b/src/locales/en.json index f29c8d29..93affb7f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -155,7 +155,7 @@ "subheader": "Latest Updates" }, "user": { - "details": "Details", + "info": "Info", "noMessages": "You have not sent or received any messages yet", "profilePage": "Profile page", "nostrPubkey": "Nostr pubkey", diff --git a/src/routes/(app)/[username]/(profile)/+layout.svelte b/src/routes/(app)/[username]/(profile)/+layout.svelte index 5752491b..11e33dbf 100644 --- a/src/routes/(app)/[username]/(profile)/+layout.svelte +++ b/src/routes/(app)/[username]/(profile)/+layout.svelte @@ -168,14 +168,16 @@ {/if} + {#if user.username !== subject.username} + {/if} {#if user?.admin && user.username !== subject.username}
diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte index f0ab743a..9443c063 100644 --- a/src/routes/(app)/[username]/(profile)/+page.svelte +++ b/src/routes/(app)/[username]/(profile)/+page.svelte @@ -102,6 +102,21 @@ let reset = () => (dragDisabled = user?.username !== subject?.username || window.innerWidth < 768); + + let installPrompt; + onMount(() => { + if (!browser) return; + window.addEventListener("beforeinstallprompt", (event) => { + event.preventDefault(); + installPrompt = event; + }); + }); + + let install = async () => { + if (!installPrompt) return; + await installPrompt.prompt(); + installPrompt = null; + }; @@ -148,18 +163,17 @@ - + {#if installPrompt} - + {/if} {/if} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 545018ed..43e573ef 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -2,6 +2,23 @@ import { PUBLIC_DOMAIN } from "$env/static/public"; import "../app.css"; import { loading, t } from "$lib/translations"; + import { onMount } from "svelte"; + import { dev } from "$app/environment"; + + onMount(() => { + if ("serviceWorker" in navigator) { + navigator.serviceWorker + .register("/service-worker.js", { + type: dev ? "module" : "classic", + }) + .then((registration) => { + console.log("SW registered: ", registration); + }) + .catch((registrationError) => { + console.log("SW registration failed: ", registrationError); + }); + } + }); export let data; let { pathname } = data; diff --git a/src/service-worker.js b/src/service-worker.js new file mode 100644 index 00000000..a95ff268 --- /dev/null +++ b/src/service-worker.js @@ -0,0 +1,83 @@ +/// +import { build, files, version } from "$service-worker"; + +// Create a unique cache name for this deployment +const CACHE = `cache-${version}`; + +const ASSETS = [ + ...build, // the app itself + ...files, // everything in `static` +]; + +self.addEventListener("install", (event) => { + console.log("SW installed"); + + // Create a new cache and add all files to it + async function addFilesToCache() { + const cache = await caches.open(CACHE); + await cache.addAll(ASSETS); + } + + event.waitUntil(addFilesToCache()); +}); + +self.addEventListener("activate", (event) => { + // Remove previous cached data from disk + async function deleteOldCaches() { + for (const key of await caches.keys()) { + if (key !== CACHE) await caches.delete(key); + } + } + + event.waitUntil(deleteOldCaches()); +}); + +self.addEventListener("fetch", (event) => { + console.log("FETCH") + // ignore POST requests etc + if (event.request.method !== "GET") return; + + async function respond() { + const url = new URL(event.request.url); + const cache = await caches.open(CACHE); + + // `build`/`files` can always be served from the cache + if (ASSETS.includes(url.pathname)) { + const response = await cache.match(url.pathname); + + if (response) { + return response; + } + } + + // for everything else, try the network first, but + // fall back to the cache if we're offline + try { + const response = await fetch(event.request); + + // if we're offline, fetch can return a value that is not a Response + // instead of throwing - and we can't pass this non-Response to respondWith + if (!(response instanceof Response)) { + throw new Error("invalid response from fetch"); + } + + if (response.status === 200) { + cache.put(event.request, response.clone()); + } + + return response; + } catch (err) { + const response = await cache.match(event.request); + + if (response) { + return response; + } + + // if there's no cache, then just error out + // as there is nothing we can do to respond to this request + throw err; + } + } + + event.respondWith(respond()); +}); diff --git a/static/home.png b/static/home.png new file mode 100644 index 00000000..e6ba1b85 Binary files /dev/null and b/static/home.png differ diff --git a/static/manifest.webmanifest b/static/manifest.webmanifest index d09b8090..15f55603 100644 --- a/static/manifest.webmanifest +++ b/static/manifest.webmanifest @@ -11,30 +11,80 @@ { "src": "/icon-192x192.png", "sizes": "192x192", - "type": "image/png" + "type": "image/png", + "purpose": "maskable" }, { "src": "/icon-256x256.png", "sizes": "256x256", - "type": "image/png" + "type": "image/png", + "purpose": "maskable" }, { "src": "/icon-384x384.png", "sizes": "384x384", - "type": "image/png" + "type": "image/png", + "purpose": "maskable" }, { "src": "/icon-512x512.png", "sizes": "512x512", - "type": "image/png" + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/icon-256x256.png", + "sizes": "256x256", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/icon-384x384.png", + "sizes": "384x384", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" } ], "screenshots": [ { - "src": "/screenshot.png", - "sizes": "632x701", - "type": "image/gif", - "label": "Homepage" + "src": "/home.png", + "sizes": "801x920", + "type": "image/png", + "label": "Homepage", + "form_factor": "wide" + }, + { + "src": "/receive.png", + "sizes": "801x920", + "type": "image/png", + "label": "Receive", + "form_factor": "wide" + }, + { + "src": "/home.png", + "sizes": "801x920", + "type": "image/png", + "label": "Homepage", + "form_factor": "narrow" + }, + { + "src": "/receive.png", + "sizes": "801x920", + "type": "image/png", + "label": "Receive", + "form_factor": "narrow" } ], "protocol_handlers": [ diff --git a/static/receive.png b/static/receive.png new file mode 100644 index 00000000..8151e52c Binary files /dev/null and b/static/receive.png differ diff --git a/static/screenshot.png b/static/screenshot.png deleted file mode 100644 index e10fbd19..00000000 Binary files a/static/screenshot.png and /dev/null differ diff --git a/svelte.config.js b/svelte.config.js index bc89e810..ccd77e7d 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -17,6 +17,9 @@ const config = { crawl: false, entries: [], }, + serviceWorker: { + register: false + } }, onwarn: (warning, handler) => { if (warning.code.includes("caption") || warning.filename.includes("Toast")) -- cgit v1.2.3