Files
cc-switch/src/hooks/useDarkMode.ts

83 lines
2.6 KiB
TypeScript
Raw Normal View History

import { useState, useEffect } from "react";
export function useDarkMode() {
// 初始设为 false挂载后在 useEffect 中加载真实值
const [isDarkMode, setIsDarkMode] = useState<boolean>(false);
const [isInitialized, setIsInitialized] = useState(false);
// 组件挂载后加载初始值(兼容 Tauri 环境)
useEffect(() => {
if (typeof window === "undefined") return;
try {
// 尝试读取已保存的偏好
const saved = localStorage.getItem("darkMode");
if (saved !== null) {
const savedBool = saved === "true";
setIsDarkMode(savedBool);
console.log("[DarkMode] Loaded from localStorage:", savedBool);
} else {
// 回退到系统偏好
const prefersDark =
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
setIsDarkMode(prefersDark);
console.log("[DarkMode] Using system preference:", prefersDark);
}
} catch (error) {
console.error("[DarkMode] Error loading preference:", error);
setIsDarkMode(false);
}
setIsInitialized(true);
}, []); // 仅在首次挂载时运行
// 将 dark 类应用到文档根节点
useEffect(() => {
if (!isInitialized) return;
// 添加短暂延迟以确保 Tauri 中 DOM 已就绪
const timer = setTimeout(() => {
try {
if (isDarkMode) {
document.documentElement.classList.add("dark");
console.log("[DarkMode] Added dark class to document");
} else {
document.documentElement.classList.remove("dark");
console.log("[DarkMode] Removed dark class from document");
}
// 检查类名是否已成功应用
const hasClass = document.documentElement.classList.contains("dark");
console.log("[DarkMode] Document has dark class:", hasClass);
} catch (error) {
console.error("[DarkMode] Error applying dark class:", error);
}
}, 0);
return () => clearTimeout(timer);
}, [isDarkMode, isInitialized]);
// 将偏好保存到 localStorage
useEffect(() => {
if (!isInitialized) return;
try {
localStorage.setItem("darkMode", isDarkMode.toString());
console.log("[DarkMode] Saved to localStorage:", isDarkMode);
} catch (error) {
console.error("[DarkMode] Error saving preference:", error);
}
}, [isDarkMode, isInitialized]);
const toggleDarkMode = () => {
setIsDarkMode((prev) => {
const newValue = !prev;
console.log("[DarkMode] Toggling from", prev, "to", newValue);
return newValue;
});
};
return { isDarkMode, toggleDarkMode };
}