mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-02 21:05:36 +00:00
refactor(theme): single-source the HealthChat Light theme
Author the theme once in apps/web/element.io/healthchat/HealthChat-Light-Theme.json
and sync it into the web (apps/web/config.json) and desktop
(apps/desktop/element.io/healthchat/config.json) configs via
scripts/healthchat-sync-theme.mjs, removing the drifted duplicate.
`pnpm healthchat:theme` writes it; `pnpm lint` runs healthchat:theme:check to
fail on drift.
The canonical palette is the reviewed desktop theme, which reverts the web-only
contrast tweak (f64923ea1a) so web and desktop match.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env node
|
||||
/*
|
||||
* HealthChat theme sync.
|
||||
*
|
||||
* Single source of truth for the "HealthChat Light" theme lives in
|
||||
* apps/web/element.io/healthchat/HealthChat-Light-Theme.json
|
||||
* This script injects it into every element-web config that ships the theme, so the palette
|
||||
* is authored once and never drifts between the dev and desktop configs.
|
||||
*
|
||||
* The production web deployment (matrix-docker-ansible-deploy) renders its config.json from
|
||||
* host_vars and carries an inline copy of this theme; re-copy this file there when it changes.
|
||||
*
|
||||
* Usage:
|
||||
* node apps/web/scripts/healthchat-sync-theme.mjs # write the theme into all configs
|
||||
* node apps/web/scripts/healthchat-sync-theme.mjs --check # exit 1 if any config is out of sync
|
||||
*
|
||||
* Run `pnpm --filter element-web healthchat:theme` after editing the canonical theme;
|
||||
* the --check variant runs in lint/CI to catch an un-synced edit.
|
||||
*/
|
||||
import { readFileSync, writeFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import prettier from "prettier";
|
||||
|
||||
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = resolve(scriptDir, "../../..");
|
||||
|
||||
const CANONICAL = resolve(repoRoot, "apps/web/element.io/healthchat/HealthChat-Light-Theme.json");
|
||||
|
||||
// Configs that must carry the theme in setting_defaults.custom_themes.
|
||||
const TARGETS = [
|
||||
"apps/web/config.json", // dev server config (also served by the web Docker image)
|
||||
"apps/desktop/element.io/healthchat/config.json", // desktop variant config bundled into the app
|
||||
];
|
||||
|
||||
const check = process.argv.includes("--check");
|
||||
|
||||
const theme = JSON.parse(readFileSync(CANONICAL, "utf8"));
|
||||
|
||||
let changed = 0;
|
||||
for (const rel of TARGETS) {
|
||||
const path = resolve(repoRoot, rel);
|
||||
const raw = readFileSync(path, "utf8");
|
||||
const config = JSON.parse(raw);
|
||||
config.setting_defaults ??= {};
|
||||
config.setting_defaults.custom_themes = [theme];
|
||||
|
||||
// Format identically to `prettier --write` so the output is byte-for-byte what the
|
||||
// repo's formatting lint expects, keeping --check stable.
|
||||
const options = await prettier.resolveConfig(path);
|
||||
const next = await prettier.format(JSON.stringify(config), { ...options, filepath: path });
|
||||
|
||||
if (next === raw) {
|
||||
continue;
|
||||
}
|
||||
changed++;
|
||||
if (check) {
|
||||
console.error(`out of sync: ${rel} (run: pnpm --filter element-web healthchat:theme)`);
|
||||
} else {
|
||||
writeFileSync(path, next);
|
||||
console.log(`synced theme -> ${rel}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (check) {
|
||||
if (changed > 0) process.exit(1);
|
||||
console.log("all configs in sync with the canonical HealthChat theme");
|
||||
} else if (changed === 0) {
|
||||
console.log("all configs already in sync");
|
||||
}
|
||||
Reference in New Issue
Block a user