Let each install pick its app icon
Settings > General gets an App icon (super admin): one of the seven stones, or an uploaded image with the picked stone as a top-left corner mark (inside a round launcher's crop, clear of the browser's badge), previewed in both launcher crops before saving. Uploads are decoded and cropped to a stored square (no SVG); the set is drawn into DATA_DIR/install-icon/<version>/ and served publicly and immutable. The manifest, head icon links and push notifications point at it; the ember stone keeps the stock icons. The generator shares the icon renderer. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -8,7 +8,7 @@ This file is a map: it names the rules, the invariants and where things live. Fo
|
||||
|
||||
`assets/handoff/` (gitignored) is the project's foundation, not its design. Never use its layouts, `assets/screens/*.png`, right-hand "working on" panel or PRODUCT/IMPLEMENTATION briefs as reference for the UI, docs, screenshots or marketing. Still authoritative:
|
||||
|
||||
- **Brand assets** (never change): stone icons (`public/brand/icons/*.svg`, mirrored in `src/data/stone-geometry.ts`), coordinator (`public/brand/coordinator/`), app icon (`public/brand/app-icon/`), wordmark (`public/brand/wordmark/`, mirrored in `src/data/wordmark-paths.ts`). The mark is a stone with exactly one flat cut; a bot's colour is its identity (never status); the coordinator is hue-less.
|
||||
- **Brand assets** (never change): stone icons (`public/brand/icons/*.svg`, mirrored in `src/data/stone-geometry.ts`), coordinator (`public/brand/coordinator/`), app icon (`public/brand/app-icon/`), wordmark (`public/brand/wordmark/`, mirrored in `src/data/wordmark-paths.ts`). The mark is a stone with exactly one flat cut; a bot's colour is its identity (never status); the coordinator is hue-less. The one sanctioned override is an install's own app icon (Settings > General): another brand stone, or an uploaded image with a brand stone as its top-left corner mark.
|
||||
- **Tokens:** `src/styles/main.css` is now the source of truth (the handoff `tokens.css` is history).
|
||||
|
||||
For the current UI read `src/layouts/bots/` (rail, workspace rail, user popover), `src/pages/admin/bots/[bot_id]/` (header, thread, composer, modals) and `src/pages/admin/workspaces/` (dashboard).
|
||||
@@ -148,6 +148,7 @@ Set in Settings > Environment (super admin), not `.env`. `envs` (private; encryp
|
||||
|
||||
- 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 `<title>` is the `{{name}}` placeholder. Devices pick up a new name only on reinstall.
|
||||
- **Install icon:** app setting `install_icon` (JSON, `parseInstallIcon`): a stone, or an upload (decoded, cropped to `source.png`, never stored as sent, no SVG) with the stone at `PwaCornerMarkInset`/`PwaCornerMarkScale`, inside a round launcher's crop. `saveInstallIcon` draws the set (`renderInstallIcons`, shared with `gen:favicon` via `renderAppIcon`) into `DATA_DIR/install-icon/<version>/`, served publicly and `immutable` by `handleInstallIconFile`; the manifest, head links and push payloads point at it. Ember stone = stock icons, no set.
|
||||
- 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.
|
||||
|
||||
Reference in New Issue
Block a user