54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
|
|
/**
|
||
|
|
* Theme utilities — read / write the dark-mode preference and
|
||
|
|
* apply it to <html>.
|
||
|
|
*
|
||
|
|
* Dark mode is a class-based Tailwind strategy (see
|
||
|
|
* tailwind.config.js). The class is toggled on `<html>` and the
|
||
|
|
* CSS in `app/globals.css` does the heavy lifting via the
|
||
|
|
* `.dark { --surface-XXX }` overrides.
|
||
|
|
*
|
||
|
|
* The settings live in the same `1driver_settings` localStorage
|
||
|
|
* key as the rest of AppSettings — see `lib/pocketbase.ts:231`
|
||
|
|
* for the writer. We don't import the pocketbase module here so
|
||
|
|
* that `applyDarkMode` can run during the pre-hydration
|
||
|
|
* `import` phase in `app/layout.tsx` without dragging PB into
|
||
|
|
* a server-only context.
|
||
|
|
*/
|
||
|
|
|
||
|
|
const SETTINGS_KEY = '1driver_settings';
|
||
|
|
|
||
|
|
function readSettings(): { darkMode?: boolean } {
|
||
|
|
if (typeof window === 'undefined') return {};
|
||
|
|
try {
|
||
|
|
const raw = window.localStorage.getItem(SETTINGS_KEY);
|
||
|
|
if (!raw) return {};
|
||
|
|
return JSON.parse(raw) as { darkMode?: boolean };
|
||
|
|
} catch {
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Apply the persisted dark-mode preference to <html>. */
|
||
|
|
export function applyDarkMode(): void {
|
||
|
|
if (typeof document === 'undefined') return;
|
||
|
|
const { darkMode } = readSettings();
|
||
|
|
document.documentElement.classList.toggle('dark', Boolean(darkMode));
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Toggle the preference, persist it, and apply it. */
|
||
|
|
export function setDarkMode(enabled: boolean): void {
|
||
|
|
if (typeof document === 'undefined') return;
|
||
|
|
document.documentElement.classList.toggle('dark', enabled);
|
||
|
|
|
||
|
|
// Persist alongside the rest of AppSettings — merge with whatever
|
||
|
|
// is already there so we don't blow away locationInterval etc.
|
||
|
|
let current: Record<string, unknown> = {};
|
||
|
|
try {
|
||
|
|
const raw = window.localStorage.getItem(SETTINGS_KEY);
|
||
|
|
if (raw) current = JSON.parse(raw);
|
||
|
|
} catch {
|
||
|
|
/* corrupted JSON — start fresh */
|
||
|
|
}
|
||
|
|
current.darkMode = enabled;
|
||
|
|
window.localStorage.setItem(SETTINGS_KEY, JSON.stringify(current));
|
||
|
|
}
|