123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- import { useEffect, useMemo } from "react";
- import { useRecoilState } from "recoil";
- import { createTheme, Theme } from "@mui/material";
- import { appWindow } from "@tauri-apps/api/window";
- import { atomThemeMode } from "@/services/states";
- import { defaultTheme, defaultDarkTheme } from "@/pages/_theme";
- import { useVerge } from "@/hooks/use-verge";
- /**
- * custom theme
- */
- export const useCustomTheme = () => {
- const { verge } = useVerge();
- const { theme_mode, theme_setting } = verge ?? {};
- const [mode, setMode] = useRecoilState(atomThemeMode);
- useEffect(() => {
- const themeMode = ["light", "dark", "system"].includes(theme_mode!)
- ? theme_mode!
- : "light";
- if (themeMode !== "system") {
- setMode(themeMode);
- return;
- }
- appWindow.theme().then((m) => m && setMode(m));
- const unlisten = appWindow.onThemeChanged((e) => setMode(e.payload));
- return () => {
- unlisten.then((fn) => fn());
- };
- }, [theme_mode]);
- const theme = useMemo(() => {
- const setting = theme_setting || {};
- const dt = mode === "light" ? defaultTheme : defaultDarkTheme;
- let theme: Theme;
- try {
- theme = createTheme({
- breakpoints: {
- values: { xs: 0, sm: 650, md: 900, lg: 1200, xl: 1536 },
- },
- palette: {
- mode,
- primary: { main: setting.primary_color || dt.primary_color },
- secondary: { main: setting.secondary_color || dt.secondary_color },
- info: { main: setting.info_color || dt.info_color },
- error: { main: setting.error_color || dt.error_color },
- warning: { main: setting.warning_color || dt.warning_color },
- success: { main: setting.success_color || dt.success_color },
- text: {
- primary: setting.primary_text || dt.primary_text,
- secondary: setting.secondary_text || dt.secondary_text,
- },
- },
- typography: {
- // todo
- fontFamily: setting.font_family
- ? `${setting.font_family}, ${dt.font_family}`
- : dt.font_family,
- },
- });
- } catch {
- // fix #294
- theme = createTheme({
- breakpoints: {
- values: { xs: 0, sm: 650, md: 900, lg: 1200, xl: 1536 },
- },
- palette: {
- mode,
- primary: { main: dt.primary_color },
- secondary: { main: dt.secondary_color },
- info: { main: dt.info_color },
- error: { main: dt.error_color },
- warning: { main: dt.warning_color },
- success: { main: dt.success_color },
- text: { primary: dt.primary_text, secondary: dt.secondary_text },
- },
- typography: { fontFamily: dt.font_family },
- });
- }
- // css
- const backgroundColor = mode === "light" ? "#ffffff" : "#121212";
- const selectColor = mode === "light" ? "#f5f5f5" : "#d5d5d5";
- const scrollColor = mode === "light" ? "#90939980" : "#54545480";
- const rootEle = document.documentElement;
- 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);
- // inject css
- let style = document.querySelector("style#verge-theme");
- if (!style) {
- style = document.createElement("style");
- style.id = "verge-theme";
- document.head.appendChild(style!);
- }
- if (style) {
- style.innerHTML = setting.css_injection || "";
- }
- // update svg icon
- const { palette } = theme;
- setTimeout(() => {
- const dom = document.querySelector("#Gradient2");
- if (dom) {
- dom.innerHTML = `
- <stop offset="0%" stop-color="${palette.primary.main}" />
- <stop offset="80%" stop-color="${palette.primary.dark}" />
- <stop offset="100%" stop-color="${palette.primary.dark}" />
- `;
- }
- }, 0);
- return theme;
- }, [mode, theme_setting]);
- return { theme };
- };
|