import { computed, reactive } from "vue"; type ThemeMode = "light" | "dark" | "system"; type DensityMode = "comfortable" | "compact"; const STORAGE_KEYS = { themeMode: "live-recorder-ui-theme", density: "live-recorder-ui-density", sidebarCollapsed: "live-recorder-ui-sidebar-collapsed" } as const; const state = reactive({ themeMode: "system" as ThemeMode, density: "comfortable" as DensityMode, sidebarCollapsed: false, systemTheme: "light" as "light" | "dark", initialized: false }); let mediaQueryList: MediaQueryList | null = null; function readStoredThemeMode(): ThemeMode { const stored = window.localStorage.getItem(STORAGE_KEYS.themeMode); return stored === "light" || stored === "dark" || stored === "system" ? stored : "system"; } function readStoredDensity(): DensityMode { return window.localStorage.getItem(STORAGE_KEYS.density) === "compact" ? "compact" : "comfortable"; } function readStoredSidebarCollapsed() { return window.localStorage.getItem(STORAGE_KEYS.sidebarCollapsed) === "true"; } function resolveTheme(): "light" | "dark" { return state.themeMode === "system" ? state.systemTheme : state.themeMode; } function applyDocumentPreferences() { if (typeof document === "undefined") { return; } const resolvedTheme = resolveTheme(); document.documentElement.dataset.theme = resolvedTheme; document.documentElement.dataset.themeMode = state.themeMode; document.documentElement.dataset.density = state.density; } function syncSystemTheme() { state.systemTheme = mediaQueryList?.matches ? "dark" : "light"; applyDocumentPreferences(); } function ensureInitialized() { if (state.initialized || typeof window === "undefined") { return; } state.themeMode = readStoredThemeMode(); state.density = readStoredDensity(); state.sidebarCollapsed = readStoredSidebarCollapsed(); mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); if (typeof mediaQueryList.addEventListener === "function") { mediaQueryList.addEventListener("change", syncSystemTheme); } else { mediaQueryList.addListener(syncSystemTheme); } syncSystemTheme(); state.initialized = true; } function persistPreferences() { if (typeof window === "undefined") { return; } window.localStorage.setItem(STORAGE_KEYS.themeMode, state.themeMode); window.localStorage.setItem(STORAGE_KEYS.density, state.density); window.localStorage.setItem(STORAGE_KEYS.sidebarCollapsed, String(state.sidebarCollapsed)); } export function useUiPreferences() { ensureInitialized(); const resolvedTheme = computed(() => resolveTheme()); function setThemeMode(value: ThemeMode) { state.themeMode = value; persistPreferences(); applyDocumentPreferences(); } function cycleThemeMode() { const nextValue = state.themeMode === "light" ? "dark" : state.themeMode === "dark" ? "system" : "light"; setThemeMode(nextValue); } function setDensity(value: DensityMode) { state.density = value; persistPreferences(); applyDocumentPreferences(); } function setSidebarCollapsed(value: boolean) { state.sidebarCollapsed = value; persistPreferences(); } function toggleSidebarCollapsed() { setSidebarCollapsed(!state.sidebarCollapsed); } return { themeMode: computed({ get: () => state.themeMode, set: (value: ThemeMode) => setThemeMode(value) }), resolvedTheme, density: computed({ get: () => state.density, set: (value: DensityMode) => setDensity(value) }), sidebarCollapsed: computed({ get: () => state.sidebarCollapsed, set: (value: boolean) => setSidebarCollapsed(value) }), cycleThemeMode, toggleSidebarCollapsed }; }