fix(web): tolerate unavailable theme storage

This commit is contained in:
Saravana Achu Mac 2026-05-05 22:23:06 -07:00
parent 75a3ac4ecf
commit a436fa61e5

View File

@ -19,10 +19,33 @@ function applyTheme(theme: Theme) {
root.dataset.theme = theme;
}
function readStoredTheme(): Theme | null {
if (typeof window === 'undefined') return null;
try {
const storage = window.localStorage;
if (typeof storage?.getItem !== 'function') return null;
const stored = storage.getItem(STORAGE_KEY);
return stored === 'light' || stored === 'dark' ? stored : null;
} catch {
return null;
}
}
function writeStoredTheme(theme: Theme) {
try {
const storage = window.localStorage;
if (typeof storage?.setItem === 'function') {
storage.setItem(STORAGE_KEY, theme);
}
} catch {
// Theme persistence is best-effort; restricted storage should not break UI.
}
}
function resolveInitialTheme(): Theme {
if (typeof window === 'undefined') return 'light';
const stored = window.localStorage.getItem(STORAGE_KEY);
if (stored === 'light' || stored === 'dark') return stored;
const stored = readStoredTheme();
if (stored) return stored;
return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
@ -31,15 +54,14 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
useEffect(() => {
applyTheme(theme);
window.localStorage.setItem(STORAGE_KEY, theme);
writeStoredTheme(theme);
}, [theme]);
useEffect(() => {
const media = window.matchMedia?.('(prefers-color-scheme: dark)');
if (!media) return;
const handleChange = () => {
const stored = window.localStorage.getItem(STORAGE_KEY);
if (stored === 'light' || stored === 'dark') return;
if (readStoredTheme()) return;
setThemeState(media.matches ? 'dark' : 'light');
};
media.addEventListener?.('change', handleChange);