From 3b7c05bfa0fd2ba71b05bd509cbe84dbee883eb8 Mon Sep 17 00:00:00 2001 From: Benjamin Toby Date: Sun, 25 Oct 2026 10:17:40 +0100 Subject: [PATCH] Name each install, fix the notification badge, switch to Archivo - Settings > General: an App name (super admin) for the installed app. The manifest's name/short_name, the iOS head tags and the loading page's title use it, so two installs on one phone can be told apart. - Notifications get a real badge (white stone silhouette): Android masks the badge by alpha, so the opaque app icon showed as a square. - The loading and offline pages load the app's font. - The font is now Archivo (variable, one request for every weight), matching the marketing site. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 2 + public/icons/badge-96.png | Bin 0 -> 760 bytes public/loading.html | 7 +- public/offline.html | 5 +- public/sw.js | 15 ++- src/data/pwa-data.ts | 20 ++++ .../db/app-settings/grab-install-name.ts | 12 +++ .../server/pwa/handle-precache-gate.ts | 15 ++- src/functions/server/pwa/handle-pwa-file.ts | 25 ++++- src/pages/__root.server.ts | 2 + src/pages/__root.tsx | 14 ++- .../general/(partials)/install-name-form.tsx | 101 ++++++++++++++++++ .../(sections)/install-name-section.tsx | 25 +++++ src/pages/admin/settings/general/index.tsx | 2 + src/pages/api/admin/settings/install-name.ts | 47 ++++++++ src/schemas/push-schema.ts | 5 + src/scripts/generate-brand-assets.ts | 63 ++++++++++- src/styles/main.css | 2 +- src/types/index.ts | 5 + src/utils/escape-html.ts | 15 +++ src/utils/install-display-name.ts | 13 +++ src/utils/name-pwa-manifest.test.ts | 34 ++++++ src/utils/name-pwa-manifest.ts | 27 +++++ 23 files changed, 440 insertions(+), 16 deletions(-) create mode 100644 public/icons/badge-96.png create mode 100644 src/functions/backend/db/app-settings/grab-install-name.ts create mode 100644 src/pages/admin/settings/general/(partials)/install-name-form.tsx create mode 100644 src/pages/admin/settings/general/(sections)/install-name-section.tsx create mode 100644 src/pages/api/admin/settings/install-name.ts create mode 100644 src/utils/escape-html.ts create mode 100644 src/utils/install-display-name.ts create mode 100644 src/utils/name-pwa-manifest.test.ts create mode 100644 src/utils/name-pwa-manifest.ts diff --git a/AGENTS.md b/AGENTS.md index d397502..3cf219f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -147,6 +147,8 @@ Set in Settings > Environment (super admin), not `.env`. `envs` (private; encryp ### PWA and notifications - Generated assets (manifest, icons, `offline.html`, `loading.html`) come from `bun run gen:favicon`, which reads `main.css`; outputs are committed. Shared paths in `src/data/pwa-data.ts`. +- **Install name:** app setting `install_name` (Settings > General, super admin). `handlePwaFile` rewrites the manifest's `name`/`short_name` per request (`namePwaManifest`), the root head uses it for iOS tags, the loading page's `` is the `{{name}}` placeholder. Devices pick up a new name only on reinstall. +- Notification `badge` is `icons/badge-96.png` (white silhouette; Android masks by alpha, so never the opaque app icon). Brave on Android has no WebAPK, so its notifications always carry Brave's name and icon. - `public/sw.js` is served `no-store`; navigations network-only (authenticated HTML never cached); `/api/`, `/ws`, `/media/`, `/computers/`, `/build-info.json` never intercepted. It never reloads on its own. In development the worker and caches are actively removed (`clear-development-service-worker.ts`, stub `/sw.js`). - **Precache (production):** a navigation without the current build cookie gets `loading.html`, which downloads all of `.bunext/public` into `cobble-assets-<build_id>`, verifies, sets the cookie and reloads (falls back to network on stall). React knows nothing of this. - Phone shell: rail is a slide-over below `md`; rail internals use the `@rail:` container variant, not viewport `lg:`. `LiveSocket` is remounted on online/pageshow/visibility since twui stops retrying after three attempts. Nothing is queued offline. diff --git a/public/icons/badge-96.png b/public/icons/badge-96.png new file mode 100644 index 0000000000000000000000000000000000000000..b9011a0980439626884dd2ec0747098d9e0ef260 GIT binary patch literal 760 zcmV<U0tfwxP)<h;3K|Lk000e1NJLTq003YB003YJ1^@s6;+S_h00009a7bBm000B% z000B%0kwNlYXATOs!2paRCt{2-M`CKbsPuqGnHY1gBd6exrBd#PH9UDi3Sa}6fI89 z5x4|Rf`cN|5IpjLdo{R-?J13wB<WO;f<qc!tf!urT)6my!siapy`S$n=l%Kz&iQ`d z+;i^v{`h>mE+Qf#A|j$ucnyc~F}}oQ{D9wa-?RS2ZTyHUSivVaf?d^Z=>=@Vaa_PH zo9kCx#D~~k-PUGc3*N^i{AD@*!MFGbFLz^vT{w-qYTd(m?CHh;JMje`YRei{@p?Bz zcnP24fwoN_gJ<wcHxzgazv!3WaJ1_)yoj?{*Iz5x+Vu@~<9ow!9dC4ff&I8+SpLA< zUF&9Fo)g2gh7Y<{;XV9q*w%5PYYpBRLFYdmLOZ_%>>Kc7=XsB#L#_PVnT|q^(LL;~ z?EDvS&A9zsHlR2AWDiy=I{!`lo8Euy*s_NhZalem;Jal8a4KE?ANQBl`8)n+J~o&v zD}Zz9?V<o?s}#oe!PQg%pUr(c<1<;tN7q=tc$)}dI?@@10etnGi-!dUFr5?4%eOXw zcQ?NN=uH+Gz~`gy-r@j$n&Sq>ZnDS~%Ng}74B+4#7Y~aI;ADEYHh>Ji6$kLmoHsCb zlSKtE_DT2h0B+8G3*$CfQ~*O;WZSy{ri+iFFo5a)+t^rs0mbqTD3*UgLk-|+b<4&c zz}M9+>xqm770YPoPy;wn-Ljs@j99VE2^Y(%h+<h6R4gmwie+tRv8;|Rmi+<6vO}g= z_J|eBF3GV3@M<RN3j>&ike%{XJLP8qq*g>_t%z9&sg_bzE#;{YQZJ~gUeGLnRLoLX zF>4k=YQ|Md)x-v*ZfFBiIky3+9o>LbPj5iZ4`@J6&}c-?kZC|pQEG&oBi05vNv{oZ qmSj8RG}X4qdBPD95fKsHCV2!zp^&70(BFpu0000<MNUMnLSTYaZe-N} literal 0 HcmV?d00001 diff --git a/public/loading.html b/public/loading.html index a6dec0e..45bdf5b 100644 --- a/public/loading.html +++ b/public/loading.html @@ -5,8 +5,11 @@ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" /> <meta name="theme-color" content="#fbfaf7" /> <meta name="robots" content="noindex" /> -<title>cobble +{{name}} + + +