diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f30b6b4..34fe7cc 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -24,7 +24,7 @@ export default function RootLayout({ return ( diff --git a/src/components/settings-dialog.tsx b/src/components/settings-dialog.tsx index 6ffa439..201bf4d 100644 --- a/src/components/settings-dialog.tsx +++ b/src/components/settings-dialog.tsx @@ -187,6 +187,17 @@ export function SettingsDialog({ isOpen, onClose }: SettingsDialogProps) { } }, []); + // Apply or clear custom theme live without restart + // Defer application until Save + const _applyCustomTheme = useCallback((vars: Record) => { + const root = document.documentElement; + Object.entries(vars).forEach(([k, v]) => root.style.setProperty(k, v)); + }, []); + const _clearCustomTheme = useCallback(() => { + const root = document.documentElement; + THEME_VARIABLES.forEach(({ key }) => root.style.removeProperty(key)); + }, []); + const loadPermissions = useCallback(async () => { setIsLoadingPermissions(true); try { @@ -281,6 +292,26 @@ export function SettingsDialog({ isOpen, onClose }: SettingsDialogProps) { try { await invoke("save_app_settings", { settings }); setTheme(settings.theme === "custom" ? "dark" : settings.theme); + // Apply or clear custom variables only on Save + if (settings.theme === "custom") { + if (settings.custom_theme) { + try { + const root = document.documentElement; + // Clear any previous custom vars first + THEME_VARIABLES.forEach(({ key }) => + root.style.removeProperty(key), + ); + Object.entries(settings.custom_theme).forEach(([k, v]) => + root.style.setProperty(k, v), + ); + } catch {} + } + } else { + try { + const root = document.documentElement; + THEME_VARIABLES.forEach(({ key }) => root.style.removeProperty(key)); + } catch {} + } setOriginalSettings(settings); onClose(); } catch (error) { @@ -418,7 +449,7 @@ export function SettingsDialog({ isOpen, onClose }: SettingsDialogProps) {