import { create } from 'zustand' import { isDarkTheme } from '../themes' const STORAGE_KEY = 'p3xr-theme' const AUTO = 'auto' function getSystemDark(): boolean { return typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches } function normalizeThemeKey(raw: string): string { // Handle Angular format: p3xrThemeDark → dark, p3xrThemeEnterprise → enterprise if (raw.startsWith('p3xrTheme')) { const name = raw.replace('p3xrTheme', '') return name.charAt(0).toLowerCase() + name.slice(1) } return raw } function readStored(): string { try { const raw = localStorage.getItem(STORAGE_KEY) || AUTO if (raw === AUTO) return AUTO return normalizeThemeKey(raw) } catch { return AUTO } } function applyBodyClasses(resolved: string): void { if (typeof document === 'undefined') return const dark = isDarkTheme(resolved) document.documentElement.setAttribute('data-color-scheme', dark ? 'dark' : 'light') document.body.classList.toggle('p3xr-theme-dark', dark) document.body.classList.toggle('p3xr-theme-light', !dark) } // Same logic as Angular ThemeService function resolveThemeKey(stored: string): string { if (stored === AUTO) return getSystemDark() ? 'dark' : 'enterprise' return stored } interface ThemeState { isAuto: boolean themeKey: string // resolved key: 'dark', 'enterprise', 'light', etc. storedValue: string // raw stored: 'auto' or theme key setTheme: (choice: string) => void // 'auto' or any theme key } export const useThemeStore = create((set) => { const stored = readStored() const isAuto = stored === AUTO const themeKey = resolveThemeKey(stored) // Apply on initial load applyBodyClasses(themeKey) return { isAuto, themeKey, storedValue: stored, setTheme: (choice: string) => { const auto = choice === AUTO const resolved = auto ? resolveThemeKey(AUTO) : choice try { localStorage.setItem(STORAGE_KEY, choice) } catch {} applyBodyClasses(resolved) // Notify Electron parent try { window.parent?.postMessage({ type: 'p3x-theme-change', dark: isDarkTheme(resolved) }, '*') } catch {} set({ isAuto: auto, themeKey: resolved, storedValue: choice }) }, } }) // Listen for system theme changes (auto mode) if (typeof window !== 'undefined' && window.matchMedia) { window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { const { isAuto } = useThemeStore.getState() if (isAuto) { const resolved = getSystemDark() ? 'dark' : 'enterprise' applyBodyClasses(resolved) useThemeStore.setState({ themeKey: resolved }) } }) }