mirror of https://github.com/usememos/memos
feat: update appearance selector (#645)
parent
eaebc6dcef
commit
7c6d7226f5
@ -0,0 +1,65 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
import { useColorScheme } from "@mui/joy/styles";
|
||||||
|
import { useAppSelector } from "../store";
|
||||||
|
import { globalService } from "../services";
|
||||||
|
|
||||||
|
const getSystemColorScheme = () => {
|
||||||
|
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
|
return "dark";
|
||||||
|
} else {
|
||||||
|
return "light";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const useAppearance = () => {
|
||||||
|
const user = useAppSelector((state) => state.user.user);
|
||||||
|
const appearance = useAppSelector((state) => state.global.appearance);
|
||||||
|
const { mode, setMode } = useColorScheme();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (user) {
|
||||||
|
globalService.setAppearance(user.setting.appearance);
|
||||||
|
}
|
||||||
|
}, [user]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let mode = appearance;
|
||||||
|
if (appearance === "system") {
|
||||||
|
mode = getSystemColorScheme();
|
||||||
|
}
|
||||||
|
setMode(mode);
|
||||||
|
}, [appearance]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const colorSchemeChangeHandler = (event: MediaQueryListEvent) => {
|
||||||
|
const newColorScheme = event.matches ? "dark" : "light";
|
||||||
|
if (globalService.getState().appearance === "system") {
|
||||||
|
setMode(newColorScheme);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (appearance !== "system") {
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", colorSchemeChangeHandler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", colorSchemeChangeHandler);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", colorSchemeChangeHandler);
|
||||||
|
};
|
||||||
|
}, [appearance]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const root = document.documentElement;
|
||||||
|
if (mode === "dark") {
|
||||||
|
root.classList.add("dark");
|
||||||
|
} else if (mode === "light") {
|
||||||
|
root.classList.remove("dark");
|
||||||
|
}
|
||||||
|
}, [mode]);
|
||||||
|
|
||||||
|
return [appearance, globalService.setAppearance] as const;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useAppearance;
|
@ -1,30 +0,0 @@
|
|||||||
import { useEffect } from "react";
|
|
||||||
import { useColorScheme } from "@mui/joy/styles";
|
|
||||||
|
|
||||||
import { APPERANCE_OPTIONS, APPERANCE_OPTIONS_STORAGE_KEY } from "../helpers/consts";
|
|
||||||
import useLocalStorage from "./useLocalStorage";
|
|
||||||
import useMediaQuery from "./useMediaQuery";
|
|
||||||
|
|
||||||
export type Apperance = typeof APPERANCE_OPTIONS[number];
|
|
||||||
|
|
||||||
const useApperance = () => {
|
|
||||||
const [apperance, setApperance] = useLocalStorage<Apperance>(APPERANCE_OPTIONS_STORAGE_KEY, APPERANCE_OPTIONS[0]);
|
|
||||||
const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
|
|
||||||
|
|
||||||
const { setMode } = useColorScheme();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const root = document.documentElement;
|
|
||||||
if (apperance === "dark" || (apperance === "auto" && prefersDarkMode)) {
|
|
||||||
root.classList.add("dark");
|
|
||||||
setMode("dark");
|
|
||||||
} else {
|
|
||||||
root.classList.remove("dark");
|
|
||||||
setMode("light");
|
|
||||||
}
|
|
||||||
}, [apperance, prefersDarkMode]);
|
|
||||||
|
|
||||||
return [apperance, setApperance] as const;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useApperance;
|
|
@ -1,26 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
const useLocalStorage = <T>(key: string, initialValue: T) => {
|
|
||||||
const [storedValue, setStoredValue] = useState<T>(() => {
|
|
||||||
try {
|
|
||||||
const item = window.localStorage.getItem(key);
|
|
||||||
return item ? JSON.parse(item) : initialValue;
|
|
||||||
} catch (error) {
|
|
||||||
return initialValue;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const setValue = (value: T | ((val: T) => T)) => {
|
|
||||||
try {
|
|
||||||
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
||||||
setStoredValue(valueToStore);
|
|
||||||
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return [storedValue, setValue] as const;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useLocalStorage;
|
|
Loading…
Reference in New Issue