mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-10-31 16:23:03 +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:
+22
-42
@@ -8,44 +8,25 @@
|
||||
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
|
||||
"default_country_code": "GB",
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://matrix.healthchat.ch",
|
||||
"server_name": "healthchat.ch"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": ""
|
||||
}
|
||||
"m.homeserver": { "base_url": "https://matrix.healthchat.ch", "server_name": "healthchat.ch" },
|
||||
"m.identity_server": { "base_url": "" }
|
||||
},
|
||||
"default_theme": "custom-HealthChat Light",
|
||||
"disable_custom_urls": true,
|
||||
"disable_guests": true,
|
||||
"element_call": {},
|
||||
"embedded_pages": {
|
||||
"homeUrl": ""
|
||||
},
|
||||
"embedded_pages": { "homeUrl": "" },
|
||||
"enable_presence_by_hs_url": "",
|
||||
"features": {},
|
||||
"integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_widgets_urls": [
|
||||
"https://scalar.vector.im/api"
|
||||
],
|
||||
"jitsi": {
|
||||
"preferred_domain": "jitsi.healthchat.ch"
|
||||
},
|
||||
"integrations_widgets_urls": ["https://scalar.vector.im/api"],
|
||||
"jitsi": { "preferred_domain": "jitsi.healthchat.ch" },
|
||||
"logout_redirect_url": "",
|
||||
"matrix_to_url": "https://to.healthchat.ch",
|
||||
"room_directory": {
|
||||
"servers": [
|
||||
"matrix.org"
|
||||
]
|
||||
},
|
||||
"sso_redirect_options": {
|
||||
"immediate": true,
|
||||
"on_welcome_page": true,
|
||||
"on_login_page": true
|
||||
},
|
||||
"room_directory": { "servers": ["matrix.org"] },
|
||||
"sso_redirect_options": { "immediate": true, "on_welcome_page": true, "on_login_page": true },
|
||||
"setting_defaults": {
|
||||
"UIFeature.deactivate": false,
|
||||
"UIFeature.advancedEncryption": false,
|
||||
@@ -55,7 +36,6 @@
|
||||
"UIFeature.advancedSettings": false,
|
||||
"UIFeature.feedback": false,
|
||||
"custom_themes": [
|
||||
"HealthChat Light",
|
||||
{
|
||||
"name": "HealthChat Light",
|
||||
"is_dark": false,
|
||||
@@ -74,8 +54,8 @@
|
||||
"timeline-highlights-color": "#d9d9d9",
|
||||
"timeline-text-color": "#473e3e",
|
||||
"timeline-text-secondary-color": "#9b9898",
|
||||
"secondary-content": "#6e6a6a",
|
||||
"tertiary-content": "#6e6a6a",
|
||||
"secondary-content": "#9b9898",
|
||||
"tertiary-content": "#9b9898",
|
||||
"focus-bg-color": "#d9d9d9",
|
||||
"menu-selected-color": "#d9d9d9",
|
||||
"other-user-pill-bg-color": "#376A91",
|
||||
@@ -83,30 +63,30 @@
|
||||
"reaction-row-button-selected-bg-color": "#d9d9d9",
|
||||
"togglesw-off-color": "#9b9898",
|
||||
"avatar-background-colors": ["#12325c", "#1f4d85", "#376A91"],
|
||||
"username-colors": ["#12325c", "#2a4063", "#1f4d85", "#376A91", "#473e3e", "#1f4d85", "#2a4063", "#12325c"]
|
||||
},
|
||||
"fonts": {
|
||||
"general": "\"Century Gothic\", \"Futura\", \"Trebuchet MS\", \"Arial\", sans-serif"
|
||||
"username-colors": [
|
||||
"#12325c",
|
||||
"#2a4063",
|
||||
"#1f4d85",
|
||||
"#376A91",
|
||||
"#473e3e",
|
||||
"#1f4d85",
|
||||
"#2a4063",
|
||||
"#12325c"
|
||||
]
|
||||
},
|
||||
"fonts": { "general": "\"Century Gothic\", \"Futura\", \"Trebuchet MS\", \"Arial\", sans-serif" },
|
||||
"compound": {
|
||||
"--cpd-color-text-action-accent": "#1f4d85",
|
||||
"--cpd-color-bg-action-primary-rest": "#1f4d85",
|
||||
"--cpd-color-bg-action-primary-hovered": "#2a4063",
|
||||
"--cpd-color-bg-action-primary-pressed": "#12325c",
|
||||
"--cpd-color-text-link-external": "#1f4d85",
|
||||
"--cpd-color-icon-accent-tertiary": "#376A91",
|
||||
"--cpd-color-icon-tertiary": "#5c6470",
|
||||
"--cpd-color-icon-quaternary": "#7c8591",
|
||||
"--cpd-color-icon-accent-primary": "#1f4d85",
|
||||
"--cpd-color-icon-info-primary": "#1f4d85"
|
||||
"--cpd-color-icon-accent-tertiary": "#376A91"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"show_labs_settings": false,
|
||||
"modules": ["/modules/healthchat-module.js"],
|
||||
"ch.healthchat": {
|
||||
"api_base_url": "http://localhost:5001",
|
||||
"elements_base_url": "/modules/elements"
|
||||
}
|
||||
"ch.healthchat": { "api_base_url": "http://localhost:5001", "elements_base_url": "/modules/elements" }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "HealthChat Light",
|
||||
"is_dark": false,
|
||||
"colors": {
|
||||
"accent-color": "#1f4d85",
|
||||
"primary-color": "#1f4d85",
|
||||
"alert": "#df8e1d",
|
||||
"warning-color": "#d20f39",
|
||||
"sidebar-color": "#12325c",
|
||||
"roomlist-background-color": "#f5f5f5",
|
||||
"roomlist-highlights-color": "#d9d9d9",
|
||||
"roomlist-separator-color": "#9b9898",
|
||||
"roomlist-text-color": "#473e3e",
|
||||
"roomlist-text-secondary-color": "#9b9898",
|
||||
"timeline-background-color": "#ffffff",
|
||||
"timeline-highlights-color": "#d9d9d9",
|
||||
"timeline-text-color": "#473e3e",
|
||||
"timeline-text-secondary-color": "#9b9898",
|
||||
"secondary-content": "#9b9898",
|
||||
"tertiary-content": "#9b9898",
|
||||
"focus-bg-color": "#d9d9d9",
|
||||
"menu-selected-color": "#d9d9d9",
|
||||
"other-user-pill-bg-color": "#376A91",
|
||||
"room-highlight-color": "#376A91",
|
||||
"reaction-row-button-selected-bg-color": "#d9d9d9",
|
||||
"togglesw-off-color": "#9b9898",
|
||||
"avatar-background-colors": ["#12325c", "#1f4d85", "#376A91"],
|
||||
"username-colors": ["#12325c", "#2a4063", "#1f4d85", "#376A91", "#473e3e", "#1f4d85", "#2a4063", "#12325c"]
|
||||
},
|
||||
"fonts": {
|
||||
"general": "\"Century Gothic\", \"Futura\", \"Trebuchet MS\", \"Arial\", sans-serif"
|
||||
},
|
||||
"compound": {
|
||||
"--cpd-color-text-action-accent": "#1f4d85",
|
||||
"--cpd-color-bg-action-primary-rest": "#1f4d85",
|
||||
"--cpd-color-bg-action-primary-hovered": "#2a4063",
|
||||
"--cpd-color-bg-action-primary-pressed": "#12325c",
|
||||
"--cpd-color-text-link-external": "#1f4d85",
|
||||
"--cpd-color-icon-accent-tertiary": "#376A91"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
HealthChat theme — single source of truth
|
||||
=========================================
|
||||
|
||||
HealthChat-Light-Theme.json The canonical "HealthChat Light" theme.
|
||||
|
||||
Edit the palette HERE and nowhere else. apps/web/scripts/healthchat-sync-theme.mjs injects
|
||||
it into the element-web configs that ship it:
|
||||
|
||||
- apps/web/config.json (dev server; also baked into the web image)
|
||||
- apps/desktop/element.io/healthchat/config.json (desktop variant, bundled into the app)
|
||||
|
||||
After editing, run:
|
||||
pnpm --filter element-web healthchat:theme
|
||||
`pnpm lint` runs `healthchat:theme:check`, which fails if a config is out of sync — so an
|
||||
un-propagated edit is caught in CI.
|
||||
|
||||
Production web deployment
|
||||
-------------------------
|
||||
The production web client is deployed by matrix-docker-ansible-deploy, whose
|
||||
matrix-client-element role renders config.json from host_vars (no upstream role change).
|
||||
It carries an INLINE copy of this theme in
|
||||
inventory/host_vars/matrix.healthchat.ch/vars.yml
|
||||
(matrix_client_element_setting_defaults_custom_themes)
|
||||
When you change the theme here, re-copy it into that host_vars block. themes_enabled is off
|
||||
there, so the (stale) Novaloop-AG/element-themes repo does not append an older theme.
|
||||
@@ -18,13 +18,15 @@
|
||||
"i18n:lint": "matrix-i18n-lint && prettier --log-level=silent --write src/i18n/strings/ --ignore-path /dev/null",
|
||||
"i18n:diff": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && pnpm i18n && matrix-compare-i18n-files src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
|
||||
"rethemendex": "sh ./res/css/rethemendex.sh",
|
||||
"healthchat:theme": "node scripts/healthchat-sync-theme.mjs",
|
||||
"healthchat:theme:check": "node scripts/healthchat-sync-theme.mjs --check",
|
||||
"build": "nx build",
|
||||
"build-stats": "nx build --json=webpack-stats.json",
|
||||
"vendor:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js && mv src/vector/modernizr.js src/vector/modernizr.cjs",
|
||||
"vendor:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js",
|
||||
"dist": "./scripts/package.sh",
|
||||
"start": "nx start",
|
||||
"lint": "pnpm lint:types && pnpm lint:js && pnpm lint:style",
|
||||
"lint": "pnpm healthchat:theme:check && pnpm lint:types && pnpm lint:js && pnpm lint:style",
|
||||
"lint:js": "eslint --max-warnings 0 src test playwright module_system",
|
||||
"lint:js-fix": "eslint --fix src test playwright module_system",
|
||||
"lint:types": "nx lint:types",
|
||||
|
||||
@@ -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