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 <[email protected]>
This commit is contained in:
2026-10-25 10:17:40 +01:00
co-authored by Claude Opus 5.5
parent 89c4e26d06
commit 3b7c05bfa0
23 changed files with 440 additions and 16 deletions
@@ -1,6 +1,9 @@
import path from "path";
import { AppData } from "@/src/data/app-data";
import { PwaLoadingPath } from "@/src/data/pwa-data";
import { PwaLoadingNamePlaceholder, PwaLoadingPath } from "@/src/data/pwa-data";
import grabInstallName from "@/src/functions/backend/db/app-settings/grab-install-name";
import installDisplayName from "@/src/utils/install-display-name";
import escapeHtml from "@/src/utils/escape-html";
import { getCookie } from "@/src/utils/cookies";
import needsPrecachePage from "@/src/utils/needs-precache-page";
import grabPrecacheManifest from "./grab-precache-manifest";
@@ -53,7 +56,15 @@ export default async function handlePrecacheGate({
total: manifest.files.length,
}).replace(/</g, "\\u003c");
return new Response((await file.text()).replace(BuildPlaceholder, build), {
const name = escapeHtml({
text: installDisplayName({ install_name: await grabInstallName().catch(() => "") }),
});
const page = (await file.text())
.replace(BuildPlaceholder, build)
.replace(PwaLoadingNamePlaceholder, name);
return new Response(page, {
headers: {
"Content-Type": "text/html; charset=utf-8",
"Cache-Control": "no-store, max-age=0, must-revalidate",