fix(themes): apply Theme Store themes in production release builds (#1070)

Release CSP blocked runtime <style> injection for community themes; add
explicit style-src/style-src-elem and font-src. Derive the effective theme
synchronously in useThemeScheduler so data-theme updates on the same commit.
This commit is contained in:
cucadmuh
2026-06-12 03:13:18 +03:00
committed by GitHub
parent 4902c0e25b
commit 80822fd742
2 changed files with 26 additions and 10 deletions
+1 -1
View File
@@ -28,7 +28,7 @@
}
],
"security": {
"csp": "default-src 'self' 'unsafe-inline' 'unsafe-eval' ipc: http://ipc.localhost tauri:; connect-src 'self' ipc: http://ipc.localhost tauri: https: http: ws: wss:; img-src 'self' asset: http://asset.localhost https: http: data: blob:; media-src 'self' asset: http://asset.localhost https: http: data: blob:;",
"csp": "default-src 'self' 'unsafe-inline' 'unsafe-eval' ipc: http://ipc.localhost tauri:; style-src 'self' 'unsafe-inline' asset: http://asset.localhost https://asset.localhost tauri: blob:; style-src-elem 'self' 'unsafe-inline' asset: http://asset.localhost https://asset.localhost tauri: blob:; font-src 'self' data: asset: http://asset.localhost https://asset.localhost; connect-src 'self' ipc: http://ipc.localhost tauri: https: http: ws: wss:; img-src 'self' asset: http://asset.localhost https: http: data: blob:; media-src 'self' asset: http://asset.localhost https: http: data: blob:;",
"assetProtocol": {
"enable": true,
"scope": [
+25 -9
View File
@@ -1,18 +1,34 @@
import { useEffect, useState } from 'react';
import { useThemeStore, getScheduledTheme } from '../store/themeStore';
/**
* Effective theme id for `data-theme` — scheduler-aware when enabled.
* Derived synchronously from the store so `App.tsx` never paints a stale id
* (the previous useState+mirror lag could leave `data-theme` on Mocha for a
* commit cycle in production React).
*/
export function useThemeScheduler(): string {
const state = useThemeStore();
const [effectiveTheme, setEffectiveTheme] = useState(() => getScheduledTheme(state));
const enableScheduler = useThemeStore(s => s.enableThemeScheduler);
const theme = useThemeStore(s => s.theme);
const themeDay = useThemeStore(s => s.themeDay);
const themeNight = useThemeStore(s => s.themeNight);
const timeDayStart = useThemeStore(s => s.timeDayStart);
const timeNightStart = useThemeStore(s => s.timeNightStart);
const [tick, setTick] = useState(0);
useEffect(() => {
setEffectiveTheme(getScheduledTheme(useThemeStore.getState()));
if (!state.enableThemeScheduler) return;
const id = setInterval(() => {
setEffectiveTheme(getScheduledTheme(useThemeStore.getState()));
}, 60_000);
if (!enableScheduler) return;
const id = setInterval(() => setTick(n => n + 1), 60_000);
return () => clearInterval(id);
}, [state.enableThemeScheduler, state.theme, state.themeDay, state.themeNight, state.timeDayStart, state.timeNightStart]);
}, [enableScheduler, themeDay, themeNight, timeDayStart, timeNightStart]);
return effectiveTheme;
void tick;
return getScheduledTheme({
enableThemeScheduler: enableScheduler,
theme,
themeDay,
themeNight,
timeDayStart,
timeNightStart,
});
}