feat: implement theme management with system preference detection and early application

pull/5158/head
Claude 7 days ago
parent 3514180721
commit f6e025d583

@ -8,8 +8,12 @@ import "./index.css";
import router from "./router";
import { initialUserStore } from "./store/user";
import { initialWorkspaceStore } from "./store/workspace";
import { applyThemeEarly } from "./utils/theme";
import "leaflet/dist/leaflet.css";
// Apply theme early to prevent flash of wrong theme
applyThemeEarly();
const Main = observer(() => (
<>
<RouterProvider router={router} />

@ -16,6 +16,43 @@ const validateTheme = (theme: string): ValidTheme => {
return VALID_THEMES.includes(theme as ValidTheme) ? (theme as ValidTheme) : "default";
};
/**
* Detects system theme preference
*/
export const getSystemTheme = (): "default" | "default-dark" => {
if (typeof window !== "undefined" && window.matchMedia) {
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "default-dark" : "default";
}
return "default";
};
/**
* Gets the theme that should be applied on initial load
* Priority: stored user preference -> system preference -> default
*/
export const getInitialTheme = (): ValidTheme => {
// Try to get stored theme from localStorage (where user settings might be cached)
try {
const storedTheme = localStorage.getItem("memos-theme");
if (storedTheme && VALID_THEMES.includes(storedTheme as ValidTheme)) {
return storedTheme as ValidTheme;
}
} catch {
// localStorage might not be available
}
// Fall back to system preference
return getSystemTheme();
};
/**
* Applies the theme early to prevent flash of wrong theme
*/
export const applyThemeEarly = (): void => {
const theme = getInitialTheme();
loadTheme(theme);
};
export const loadTheme = (themeName: string): void => {
const validTheme = validateTheme(themeName);
@ -35,4 +72,11 @@ export const loadTheme = (themeName: string): void => {
// Set data attribute
document.documentElement.setAttribute("data-theme", validTheme);
// Store theme preference for future loads
try {
localStorage.setItem("memos-theme", validTheme);
} catch {
// localStorage might not be available
}
};

Loading…
Cancel
Save