fix: theme color not following system preference
This commit is contained in:
@@ -29,7 +29,7 @@ const getLanguagePackMap = (key: string) =>
|
||||
* custom theme
|
||||
*/
|
||||
export const useCustomTheme = () => {
|
||||
const appWindow: WebviewWindow = getCurrentWebviewWindow();
|
||||
const appWindow: WebviewWindow = useMemo(() => getCurrentWebviewWindow(), []);
|
||||
const { verge } = useVerge();
|
||||
const { i18n } = useTranslation();
|
||||
const { theme_mode, theme_setting } = verge ?? {};
|
||||
@@ -37,45 +37,71 @@ export const useCustomTheme = () => {
|
||||
const setMode = useSetThemeMode();
|
||||
|
||||
useEffect(() => {
|
||||
const themeModeSetting = ["light", "dark", "system"].includes(theme_mode!)
|
||||
? theme_mode!
|
||||
: "light";
|
||||
if (theme_mode === "light" || theme_mode === "dark") {
|
||||
setMode(theme_mode);
|
||||
}
|
||||
}, [theme_mode, setMode]);
|
||||
|
||||
if (themeModeSetting !== "system") {
|
||||
setMode(themeModeSetting as 'light' | 'dark');
|
||||
useEffect(() => {
|
||||
if (theme_mode !== "system") {
|
||||
return;
|
||||
}
|
||||
|
||||
appWindow.theme().then((systemTheme: 'light' | 'dark' | null) => {
|
||||
if (systemTheme) {
|
||||
setMode(systemTheme);
|
||||
let isMounted = true;
|
||||
|
||||
const timerId = setTimeout(() => {
|
||||
if (!isMounted) return;
|
||||
appWindow.theme().then((systemTheme) => {
|
||||
if (isMounted && systemTheme) {
|
||||
setMode(systemTheme);
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error("Failed to get initial system theme:", err);
|
||||
});
|
||||
}, 0);
|
||||
|
||||
const unlistenPromise = appWindow.onThemeChanged(({ payload }) => {
|
||||
if (isMounted) {
|
||||
setMode(payload);
|
||||
}
|
||||
});
|
||||
const unlisten = appWindow.onThemeChanged(({ payload }: { payload: 'light' | 'dark' }) => {
|
||||
setMode(payload);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unlisten.then((fn: () => void) => fn());
|
||||
isMounted = false;
|
||||
clearTimeout(timerId);
|
||||
unlistenPromise.then((unlistenFn) => {
|
||||
if (typeof unlistenFn === 'function') {
|
||||
unlistenFn();
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error("Failed to unlisten from theme changes:", err);
|
||||
});
|
||||
};
|
||||
}, [theme_mode, setMode, i18n, theme_setting, appWindow]);
|
||||
}, [theme_mode, appWindow, setMode]);
|
||||
|
||||
useEffect(() => {
|
||||
if (mode) {
|
||||
appWindow.setTheme(mode as TauriOsTheme).catch((err: any) => {
|
||||
console.error("Failed to set window theme:", err);
|
||||
if (theme_mode === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme_mode === "system") {
|
||||
appWindow.setTheme(null).catch((err) => {
|
||||
console.error("Failed to set window theme to follow system (setTheme(null)):", err);
|
||||
});
|
||||
} else if (mode) {
|
||||
appWindow.setTheme(mode as TauriOsTheme).catch((err) => {
|
||||
console.error(`Failed to set window theme to ${mode}:`, err);
|
||||
});
|
||||
}
|
||||
}, [mode, appWindow]);
|
||||
}, [mode, appWindow, theme_mode]);
|
||||
|
||||
const theme = useMemo(() => {
|
||||
const setting = theme_setting || {};
|
||||
const dt = mode === "light" ? defaultTheme : defaultDarkTheme;
|
||||
|
||||
let theme: MuiTheme;
|
||||
let muiTheme: MuiTheme;
|
||||
|
||||
try {
|
||||
theme = createTheme(
|
||||
muiTheme = createTheme(
|
||||
{
|
||||
breakpoints: {
|
||||
values: { xs: 0, sm: 650, md: 900, lg: 1200, xl: 1536 },
|
||||
@@ -98,7 +124,6 @@ export const useCustomTheme = () => {
|
||||
},
|
||||
shadows: Array(25).fill("none") as Shadows,
|
||||
typography: {
|
||||
// todo
|
||||
fontFamily: setting.font_family
|
||||
? `${setting.font_family}, ${dt.font_family}`
|
||||
: dt.font_family,
|
||||
@@ -106,9 +131,9 @@ export const useCustomTheme = () => {
|
||||
},
|
||||
getLanguagePackMap(i18n.language),
|
||||
);
|
||||
} catch {
|
||||
// fix #294
|
||||
theme = createTheme({
|
||||
} catch (e) {
|
||||
console.error("Error creating MUI theme, falling back to defaults:", e);
|
||||
muiTheme = createTheme({
|
||||
breakpoints: {
|
||||
values: { xs: 0, sm: 650, md: 900, lg: 1200, xl: 1536 },
|
||||
},
|
||||
@@ -126,38 +151,36 @@ export const useCustomTheme = () => {
|
||||
});
|
||||
}
|
||||
|
||||
// css
|
||||
const backgroundColor = mode === "light" ? "#ECECEC" : "#2e303d";
|
||||
const selectColor = mode === "light" ? "#f5f5f5" : "#d5d5d5";
|
||||
const scrollColor = mode === "light" ? "#90939980" : "#3E3E3Eee";
|
||||
const dividerColor =
|
||||
mode === "light" ? "rgba(0, 0, 0, 0.06)" : "rgba(255, 255, 255, 0.06)";
|
||||
|
||||
const rootEle = document.documentElement;
|
||||
rootEle.style.setProperty("--divider-color", dividerColor);
|
||||
rootEle.style.setProperty("--background-color", backgroundColor);
|
||||
rootEle.style.setProperty("--selection-color", selectColor);
|
||||
rootEle.style.setProperty("--scroller-color", scrollColor);
|
||||
rootEle.style.setProperty("--primary-main", theme.palette.primary.main);
|
||||
rootEle.style.setProperty(
|
||||
"--background-color-alpha",
|
||||
alpha(theme.palette.primary.main, 0.1),
|
||||
);
|
||||
if (rootEle) {
|
||||
const backgroundColor = mode === "light" ? "#ECECEC" : "#2e303d";
|
||||
const selectColor = mode === "light" ? "#f5f5f5" : "#d5d5d5";
|
||||
const scrollColor = mode === "light" ? "#90939980" : "#3E3E3Eee";
|
||||
const dividerColor =
|
||||
mode === "light" ? "rgba(0, 0, 0, 0.06)" : "rgba(255, 255, 255, 0.06)";
|
||||
|
||||
rootEle.style.setProperty("--divider-color", dividerColor);
|
||||
rootEle.style.setProperty("--background-color", backgroundColor);
|
||||
rootEle.style.setProperty("--selection-color", selectColor);
|
||||
rootEle.style.setProperty("--scroller-color", scrollColor);
|
||||
rootEle.style.setProperty("--primary-main", muiTheme.palette.primary.main);
|
||||
rootEle.style.setProperty(
|
||||
"--background-color-alpha",
|
||||
alpha(muiTheme.palette.primary.main, 0.1),
|
||||
);
|
||||
}
|
||||
// inject css
|
||||
let style = document.querySelector("style#verge-theme");
|
||||
if (!style) {
|
||||
style = document.createElement("style");
|
||||
style.id = "verge-theme";
|
||||
document.head.appendChild(style!);
|
||||
let styleElement = document.querySelector("style#verge-theme");
|
||||
if (!styleElement) {
|
||||
styleElement = document.createElement("style");
|
||||
styleElement.id = "verge-theme";
|
||||
document.head.appendChild(styleElement!);
|
||||
}
|
||||
if (style) {
|
||||
style.innerHTML = setting.css_injection || "";
|
||||
if (styleElement) {
|
||||
styleElement.innerHTML = setting.css_injection || "";
|
||||
}
|
||||
|
||||
// update svg icon
|
||||
const { palette } = theme;
|
||||
|
||||
const { palette } = muiTheme;
|
||||
setTimeout(() => {
|
||||
const dom = document.querySelector("#Gradient2");
|
||||
if (dom) {
|
||||
@@ -169,7 +192,7 @@ export const useCustomTheme = () => {
|
||||
}
|
||||
}, 0);
|
||||
|
||||
return theme;
|
||||
return muiTheme;
|
||||
}, [mode, theme_setting, i18n.language]);
|
||||
|
||||
return { theme };
|
||||
|
||||
Reference in New Issue
Block a user