61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
import { AUTH_USER_CHANGED_EVENT, getAuthUserKey } from "./auth";
|
|
|
|
export type ThemeModePref = "system" | "light" | "dark";
|
|
export type EffectiveThemeMode = "light" | "dark";
|
|
|
|
export const DEFAULT_THEME_MODE: ThemeModePref = "system";
|
|
const THEME_KEY_PREFIX = "themeMode:";
|
|
|
|
export function getUserKeyFromToken(): string {
|
|
return getAuthUserKey();
|
|
}
|
|
|
|
function k(base: string) {
|
|
return `${base}:${getUserKeyFromToken()}`;
|
|
}
|
|
|
|
function readThemeMode(key: string): ThemeModePref | null {
|
|
try {
|
|
const raw = window.localStorage.getItem(key);
|
|
return raw === "light" || raw === "dark" || raw === "system" ? raw : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function getThemeModePref(): ThemeModePref {
|
|
const userKey = getUserKeyFromToken();
|
|
const savedUserMode = readThemeMode(`${THEME_KEY_PREFIX}${userKey}`);
|
|
if (savedUserMode) return savedUserMode;
|
|
if (userKey !== "anon") {
|
|
const anonymousMode = readThemeMode(`${THEME_KEY_PREFIX}anon`);
|
|
if (anonymousMode) return anonymousMode;
|
|
}
|
|
return DEFAULT_THEME_MODE;
|
|
}
|
|
|
|
export function setThemeModePref(v: ThemeModePref) {
|
|
try {
|
|
window.localStorage.setItem(k("themeMode"), v);
|
|
} catch {
|
|
// Keep the in-memory selection even when storage is unavailable.
|
|
}
|
|
}
|
|
|
|
export function resolveEffectiveThemeMode(preference: ThemeModePref, systemPrefersDark: boolean): EffectiveThemeMode {
|
|
if (preference === "light" || preference === "dark") return preference;
|
|
return systemPrefersDark ? "dark" : "light";
|
|
}
|
|
|
|
export function subscribeToThemePreferenceChanges(sync: () => void) {
|
|
const onStorage = (event: StorageEvent) => {
|
|
if (event.key === "authUserKey" || event.key?.startsWith(THEME_KEY_PREFIX)) sync();
|
|
};
|
|
window.addEventListener(AUTH_USER_CHANGED_EVENT, sync);
|
|
window.addEventListener("storage", onStorage);
|
|
return () => {
|
|
window.removeEventListener(AUTH_USER_CHANGED_EVENT, sync);
|
|
window.removeEventListener("storage", onStorage);
|
|
};
|
|
}
|