diff --git a/src/config/setting.js b/src/config/setting.js index 75740b8..592f652 100644 --- a/src/config/setting.js +++ b/src/config/setting.js @@ -141,7 +141,7 @@ export const DEFAULT_MOUSE_HOVER_SETTING = { }; export const DEFAULT_SETTING = { - darkMode: false, // 深色模式 + darkMode: "auto", // 深色模式 uiLang: "en", // 界面语言 // fetchLimit: DEFAULT_FETCH_LIMIT, // 最大任务数量(移至rule,作废) // fetchInterval: DEFAULT_FETCH_INTERVAL, // 任务间隔时间(移至rule,作废) diff --git a/src/hooks/ColorMode.js b/src/hooks/ColorMode.js index e99f689..523db9c 100644 --- a/src/hooks/ColorMode.js +++ b/src/hooks/ColorMode.js @@ -12,7 +12,12 @@ export function useDarkMode() { } = useSetting(); const toggleDarkMode = useCallback(() => { - updateSetting({ darkMode: !darkMode }); + const nextMode = { + light: "dark", + dark: "auto", + auto: "light", + }; + updateSetting({ darkMode: nextMode[darkMode] || "light" }); }, [darkMode, updateSetting]); return { darkMode, toggleDarkMode }; diff --git a/src/hooks/Setting.js b/src/hooks/Setting.js index cfcdb81..9c81670 100644 --- a/src/hooks/Setting.js +++ b/src/hooks/Setting.js @@ -33,6 +33,15 @@ export function SettingProvider({ children }) { reload, } = useStorage(STOKEY_SETTING, DEFAULT_SETTING, KV_SETTING_KEY); + useEffect(() => { + if (typeof setting?.darkMode === "boolean") { + update((currentSetting) => ({ + ...currentSetting, + darkMode: currentSetting.darkMode ? "dark" : "light", + })); + } + }, [setting?.darkMode, update]); + useEffect(() => { (async () => { try { diff --git a/src/hooks/Theme.js b/src/hooks/Theme.js index 4f01bd9..bb714ea 100644 --- a/src/hooks/Theme.js +++ b/src/hooks/Theme.js @@ -1,4 +1,4 @@ -import { useMemo } from "react"; +import { useEffect, useMemo, useState } from "react"; import { ThemeProvider, createTheme } from "@mui/material/styles"; import { CssBaseline, GlobalStyles } from "@mui/material"; import { useDarkMode } from "./ColorMode"; @@ -11,6 +11,21 @@ import { THEME_DARK, THEME_LIGHT } from "../config"; */ export default function Theme({ children, options, styles }) { const { darkMode } = useDarkMode(); + const [systemMode, setSystemMode] = useState(THEME_LIGHT); + + useEffect(() => { + if (typeof window.matchMedia !== "function") { + return; + } + const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + const handleChange = () => { + setSystemMode(mediaQuery.matches ? THEME_DARK : THEME_LIGHT); + }; + handleChange(); // Set initial value + mediaQuery.addEventListener("change", handleChange); + return () => mediaQuery.removeEventListener("change", handleChange); + }, []); + const theme = useMemo(() => { let htmlFontSize = 16; try { @@ -23,16 +38,19 @@ export default function Theme({ children, options, styles }) { // } + const isDarkMode = + darkMode === "dark" || (darkMode === "auto" && systemMode === THEME_DARK); + return createTheme({ palette: { - mode: darkMode ? THEME_DARK : THEME_LIGHT, + mode: isDarkMode ? THEME_DARK : THEME_LIGHT, }, typography: { htmlFontSize, }, ...options, }); - }, [darkMode, options]); + }, [darkMode, options, systemMode]); return ( diff --git a/src/views/Options/DarkModeButton.js b/src/views/Options/DarkModeButton.js index 4d8cce3..bea3261 100644 --- a/src/views/Options/DarkModeButton.js +++ b/src/views/Options/DarkModeButton.js @@ -2,12 +2,19 @@ import IconButton from "@mui/material/IconButton"; import { useDarkMode } from "../../hooks/ColorMode"; import LightModeIcon from "@mui/icons-material/LightMode"; import DarkModeIcon from "@mui/icons-material/DarkMode"; +import BrightnessAutoIcon from "@mui/icons-material/BrightnessAuto"; export default function DarkModeButton() { const { darkMode, toggleDarkMode } = useDarkMode(); return ( - - {darkMode ? : } + + {darkMode === "dark" ? ( + + ) : darkMode === "light" ? ( + + ) : ( + + )} ); }