You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

56 lines
1.7 KiB

import { REFETCH_LOGO_EVENT } from "@/LogoContext";
import { useState, useEffect } from "react";
const availableThemes = {
default: "默认",
light: "高亮",
};
/**
* Determines the current theme of the application
* @returns {{theme: ('default' | 'light'), setTheme: function, availableThemes: object}} The current theme, a function to set the theme, and the available themes
*/
export function useTheme() {
const [theme, _setTheme] = useState(() => {
return localStorage.getItem("theme") || "default";
});
useEffect(() => {
if (localStorage.getItem("theme") !== null) return;
if (!window.matchMedia) return;
if (window.matchMedia("(prefers-color-scheme: light)").matches)
return _setTheme("light");
_setTheme("default");
}, []);
useEffect(() => {
document.documentElement.setAttribute("data-theme", theme);
document.body.classList.toggle("light", theme === "light");
localStorage.setItem("theme", theme);
window.dispatchEvent(new Event(REFETCH_LOGO_EVENT));
}, [theme]);
// In development, attach keybind combinations to toggle theme
useEffect(() => {
if (!import.meta.env.DEV) return;
function toggleOnKeybind(e) {
if (e.metaKey && e.key === ".") {
e.preventDefault();
setTheme((prev) => (prev === "light" ? "default" : "light"));
}
}
document.addEventListener("keydown", toggleOnKeybind);
return () => document.removeEventListener("keydown", toggleOnKeybind);
}, []);
/**
* Sets the theme of the application and runs any
* other necessary side effects
* @param {string} newTheme The new theme to set
*/
function setTheme(newTheme) {
_setTheme(newTheme);
}
return { theme, setTheme, availableThemes };
}