Originally created by: kristofferR
Shipping layout themes inside the app adds megabytes to every install and ties theme fixes to app releases. Themes should come from a catalog Chatpane downloads from.
Plan: https://plans.kristofferr.com/d/w5svpa5g4twy
themes/ folder in this repo. Chatpane fetches it straight from GitHub at https://raw.githubusercontent.com/kristofferR/Carrier/main/themes/: no Pages, no new repo or hosting, and a theme fix ships when it merges to main (GitHub's raw cache is about 5 minutes).Layout: themes/<id>.css, themes/previews/<id>-light.png / -dark.png, and themes/index.json:
:::json
{ "version": 1, "themes": [{ "id": "terminal-amber", "name": "Terminal Amber", "author": "darkpiv",
"credit": "Ported from fMess (MIT)", "description": "Amber monochrome, IRC-style lines",
"mode": "dark", "version": 3, "hooks": 1, "css": "terminal-amber.css",
"sha256": "…", "bytes": 114978, "preview": { "light": null, "dark": "previews/terminal-amber-dark.png" } }] }
One checker: a cargo test loads every themes/*.css and runs the app's own parse_header and check_css, so the catalog can never accept what Chatpane would refuse.
bun run build:themes script fills in sha256 and bytes from the files; CI fails if index.json drifts from them, the same way it guards the inject bundles. A theme whose CSS changed without a version bump fails too.themes/LICENSE-fmess); each theme header credits its author.src-tauri/themes/ and ship with the app; the root themes/ folder is only the downloadable catalog.Catalog in a top-level themes/ folder, fetched from raw.githubusercontent.com (decided); HTTPS from one host plus SHA-256 per file, no index signing; automatic updates; screenshot previews.
Part of [#434].