feat(theme+comments): runtime colour theme and COMMENTS_ENABLED switch
Colour theme is configurable at runtime from two seed colours (brand + accent); neutrals stay fixed for contrast safety. Tailwind v4 var()-based tokens let a :root:root override recolour everything with no rebuild; the 50->950 ramps are derived via a color-mix ladder. Config lives in the DB config table (admin UI: Config > Farbschema, presets + custom pickers + live preview), served on the public /event endpoint with env defaults (THEME_PRESET/PRIMARY/ACCENT), propagated live via event-updated SSE, and cached in localStorage for a no-flash boot. The keepsake export mirrors the same ladder in Rust so offline archives match the event theme. COMMENTS_ENABLED (env, default true) is a boot-time kill-switch: the backend rejects new comments with 403 and the frontend hides the comment button (feed card) and panel/composer (lightbox). Existing comments stay in the DB, hidden, and return when re-enabled. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -63,8 +63,25 @@ pub struct AppConfig {
|
||||
pub app_port: u16,
|
||||
/// Number of concurrent media compression workers (read once at boot).
|
||||
pub compression_concurrency: usize,
|
||||
/// Master switch for the comment feature (env `COMMENTS_ENABLED`, default true).
|
||||
/// When false the backend rejects new comments and the frontend hides the whole
|
||||
/// comment UI. Existing comments stay in the DB (hidden), so flipping it back
|
||||
/// restores them. Boot-time immutable, like `compression_concurrency`.
|
||||
pub comments_enabled: bool,
|
||||
/// Default colour theme, used as the fallback when the DB config keys are unset.
|
||||
/// Runtime overrides live in the `config` table (admin UI); these env vars only
|
||||
/// seed the initial default. `preset` is an id the frontend knows (e.g.
|
||||
/// "champagne-gold", "rose", … or "custom"); the two seeds are `#rrggbb` brand +
|
||||
/// accent colours the whole palette is derived from.
|
||||
pub default_theme_preset: String,
|
||||
pub default_theme_primary: String,
|
||||
pub default_theme_accent: String,
|
||||
}
|
||||
|
||||
/// The shipped default brand/accent seed (champagne gold — matches the hand-tuned
|
||||
/// ramp in tailwind-theme.css). Kept here so an unset env still yields the current look.
|
||||
const DEFAULT_THEME_SEED: &str = "#8a6a2b";
|
||||
|
||||
impl AppConfig {
|
||||
pub fn from_env() -> Result<Self> {
|
||||
let app_env = std::env::var("APP_ENV").unwrap_or_else(|_| "development".to_string());
|
||||
@@ -100,6 +117,20 @@ impl AppConfig {
|
||||
.and_then(|v| v.parse().ok())
|
||||
.filter(|&n| n >= 1)
|
||||
.unwrap_or(2),
|
||||
comments_enabled: std::env::var("COMMENTS_ENABLED")
|
||||
.map(|v| {
|
||||
!matches!(
|
||||
v.trim().to_ascii_lowercase().as_str(),
|
||||
"false" | "0" | "no" | "off"
|
||||
)
|
||||
})
|
||||
.unwrap_or(true),
|
||||
default_theme_preset: std::env::var("THEME_PRESET")
|
||||
.unwrap_or_else(|_| "champagne-gold".to_string()),
|
||||
default_theme_primary: std::env::var("THEME_PRIMARY")
|
||||
.unwrap_or_else(|_| DEFAULT_THEME_SEED.to_string()),
|
||||
default_theme_accent: std::env::var("THEME_ACCENT")
|
||||
.unwrap_or_else(|_| DEFAULT_THEME_SEED.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user