From baa993e5863529bec022a88a575aa1052389530a Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Thu, 17 Sep 2026 19:17:00 +0000 Subject: [PATCH] Theme precedence: URL param, then localStorage, then browser default The restricted page's early script now honors the URL theme parameter before the cached profile theme, so a fresh server-provided override wins and the host color scheme applies without a flash. After session load, an empty profile theme clears the cache but keeps the URL parameter in effect instead of reverting to the system default. --- frontend/auth/restricted/index.html | 2 +- frontend/src/utils/theme.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/frontend/auth/restricted/index.html b/frontend/auth/restricted/index.html index a71e29b..c5a0fd9 100644 --- a/frontend/auth/restricted/index.html +++ b/frontend/auth/restricted/index.html @@ -3,7 +3,7 @@ - + diff --git a/frontend/src/utils/theme.js b/frontend/src/utils/theme.js index 51958cb..76ad726 100644 --- a/frontend/src/utils/theme.js +++ b/frontend/src/utils/theme.js @@ -38,9 +38,20 @@ export function initThemeFromCache() { applyTheme(getCachedTheme()) } +/** Theme default from the URL hash (restricted iframe/forward pages only) */ +function getHashTheme() { + const theme = new URLSearchParams(window.location.hash.slice(1)).get('theme') + return theme === 'light' || theme === 'dark' ? theme : '' +} + /** Update theme from session context (call after login/session load) */ export function updateThemeFromSession(ctx, animate = false) { const theme = ctx?.user?.theme || '' + // Always keep the cache in sync with the profile: empty override clears it + // so stale values never mask future server-provided themes. setCachedTheme(theme) - applyTheme(theme, document.documentElement, animate) + // Without a profile override, stay consistent with the initial paint: a + // theme parameter on the URL (e.g. host page color scheme injected by + // paskia-js) remains in effect before the browser/desktop default. + applyTheme(theme || getHashTheme(), document.documentElement, animate) }