Enable runtime theme accent overrides

This commit is contained in:
thePR0M3TH3AN committed 2025-10-19 13:51:46 -04:00
1 parent aaec3ab3a6
commit bfb980c1c1
3 files changed
+93 -8

No files matched your search

+60 -6
View File
@@ -1,4 +1,4 @@
import { THEME_ACCENT_OVERRIDES } from "../config/instance-config.js";
import { THEME_ACCENT_OVERRIDES as CONFIG_THEME_ACCENT_OVERRIDES } from "../config/instance-config.js";
import { userLogger } from "./utils/logger.js";
const STORAGE_KEY = "bitvid:theme";
const FALLBACK_THEME = "dark";
@@ -24,6 +24,7 @@ const boundToggles = new WeakSet();
const registeredToggles = new Set();
let currentTheme = null;
let storageListenerBound = false;
let accentOverrides = null;
const isBrowser = () =>
typeof window !== "undefined" && typeof document !== "undefined";
@@ -80,17 +81,56 @@ const getRootElement = () => {
const normalizeAccentValue = (value) =>
typeof value === "string" ? value.trim() : "";
const cloneAccentOverrides = (overrides) => {
if (!overrides || typeof overrides !== "object") {
return null;
}
const sanitized = Object.entries(overrides).reduce((accumulator, [themeKey, themeOverrides]) => {
if (!themeOverrides || typeof themeOverrides !== "object") {
return accumulator;
}
const nextThemeOverrides = Object.entries(themeOverrides).reduce(
(themeAccumulator, [token, value]) => {
if (Object.prototype.hasOwnProperty.call(ACCENT_CSS_VARIABLES, token)) {
themeAccumulator[token] = value;
}
return themeAccumulator;
},
{},
);
if (Object.keys(nextThemeOverrides).length > 0) {
accumulator[themeKey] = nextThemeOverrides;
}
return accumulator;
}, {});
return Object.keys(sanitized).length > 0 ? sanitized : null;
};
const setAccentOverrides = (overrides) => {
accentOverrides = cloneAccentOverrides(overrides);
};
setAccentOverrides(
typeof CONFIG_THEME_ACCENT_OVERRIDES !== "undefined"
? CONFIG_THEME_ACCENT_OVERRIDES
: null,
);
const applyAccentOverrides = (root, theme) => {
if (!root) {
return;
}
const themeOverrides =
THEME_ACCENT_OVERRIDES &&
typeof THEME_ACCENT_OVERRIDES === "object" &&
THEME_ACCENT_OVERRIDES[theme] &&
typeof THEME_ACCENT_OVERRIDES[theme] === "object"
? THEME_ACCENT_OVERRIDES[theme]
accentOverrides &&
typeof accentOverrides === "object" &&
accentOverrides[theme] &&
typeof accentOverrides[theme] === "object"
? accentOverrides[theme]
: null;
Object.entries(ACCENT_CSS_VARIABLES).forEach(([token, cssVariable]) => {
@@ -258,6 +298,20 @@ const applyTheme = (theme, { persist = true } = {}) => {
return normalized;
};
export const setThemeAccentOverrides = (overrides) => {
setAccentOverrides(overrides);
const root = getRootElement();
if (!root) {
return;
}
const theme = currentTheme || FALLBACK_THEME;
applyAccentOverrides(root, theme);
};
export const getThemeAccentOverrides = () => cloneAccentOverrides(accentOverrides);
export const setTheme = (theme) => {
if (!isBrowser()) {
currentTheme = normalizeTheme(theme) || FALLBACK_THEME;
+1
View File
@@ -40,6 +40,7 @@ await build({
target: ["es2020"],
minify: true,
sourcemap: false,
external: ["../config/instance-config.js", "../../config/instance-config.js"],
loader: {
".css": "css",
".woff": "dataurl",
+32 -2
View File
@@ -1,7 +1,12 @@
import { devLogger, userLogger } from "../js/utils/logger.js";
import { initThemeController } from "../../js/themeController.js";
import {
initThemeController,
setThemeAccentOverrides,
} from "../../js/themeController.js";
import { createBeaconApp } from "../app.js";
const CONFIG_MODULE_ID = "../../config/instance-config.js";
function resolveGlobalScope() {
return (
(typeof window !== "undefined" && window) ||
@@ -22,7 +27,32 @@ function resolveWebTorrent() {
let appInstance = null;
const initializeThemeController = () => {
const loadThemeAccentOverrides = async () => {
try {
const configModule = await import(CONFIG_MODULE_ID);
if (configModule && typeof configModule.THEME_ACCENT_OVERRIDES !== "undefined") {
return configModule.THEME_ACCENT_OVERRIDES;
}
} catch (error) {
devLogger.warn(
`[beacon] Failed to load theme accent overrides from ${CONFIG_MODULE_ID}`,
error,
);
}
return null;
};
const initializeThemeController = async () => {
try {
const overrides = await loadThemeAccentOverrides();
if (overrides) {
setThemeAccentOverrides(overrides);
}
} catch (error) {
devLogger.warn("[beacon] Unable to hydrate theme accent overrides", error);
}
try {
initThemeController();
} catch (error) {