diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index f10ab424..fe1a98df 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -4,13 +4,7 @@ import { listen } from "@tauri-apps/api/event"; import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"; import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; -import React, { - useCallback, - useEffect, - useMemo, - useReducer, - useRef, -} from "react"; +import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate, useRoutes } from "react-router-dom"; import { SWRConfig, mutate } from "swr"; @@ -19,7 +13,6 @@ import iconDark from "@/assets/image/icon_dark.svg?react"; import iconLight from "@/assets/image/icon_light.svg?react"; import LogoSvg from "@/assets/image/logo.svg?react"; import { NoticeManager } from "@/components/base/NoticeManager"; -import { WindowControls } from "@/components/controller/window-controller"; import { LayoutItem } from "@/components/layout/layout-item"; import { LayoutTraffic } from "@/components/layout/layout-traffic"; import { UpdateButton } from "@/components/layout/update-button"; @@ -43,6 +36,9 @@ import { routers } from "./_routers"; import "dayjs/locale/ru"; import "dayjs/locale/zh-cn"; +import { WindowControls } from "@/components/controller/window-controller"; +// 删除重复导入 + const appWindow = getCurrentWebviewWindow(); export const portableFlag = false; @@ -164,12 +160,15 @@ const Layout = () => { useConnectionData(); useLogData(); const mode = useThemeMode(); - const isDark = mode !== "light"; + const isDark = mode === "light" ? false : true; const { t } = useTranslation(); const { theme } = useCustomTheme(); const { verge } = useVerge(); - useClashInfo(); - useClashLog(); + const { clashInfo } = useClashInfo(); + const [clashLog] = useClashLog(); + const enableLog = clashLog.enable; + const logLevel = clashLog.logLevel; + // const [logLevel] = useLocalStorage("log:log-level", "info"); const { language, start_page } = verge ?? {}; const { switchLanguage } = useI18n(); const navigate = useNavigate(); @@ -177,7 +176,7 @@ const Layout = () => { const routersEles = useRoutes(routers); const { addListener } = useListen(); const initRef = useRef(false); - const [themeReady, activateTheme] = useReducer(() => true, false); + const [themeReady, setThemeReady] = useState(false); const windowControls = useRef(null); const { decorated } = useWindowDecorations(); @@ -188,8 +187,6 @@ const Layout = () => { decorated, "| showing:", !decorated, - "| theme mode:", - mode, ); if (!decorated) { return ( @@ -199,22 +196,22 @@ const Layout = () => { ); } return null; - }, [decorated, mode]); + }, [decorated]); useEffect(() => { - activateTheme(); + setThemeReady(true); }, [theme]); const handleNotice = useCallback( (payload: [string, string]) => { const [status, msg] = payload; - queueMicrotask(() => { + setTimeout(() => { try { handleNoticeMessage(status, msg, t, navigate); } catch (error) { console.error("[Layout] 处理通知消息失败:", error); } - }); + }, 0); }, [t, navigate], ); @@ -263,10 +260,10 @@ const Layout = () => { }; }; - const cleanupWindowPromise = setupWindowListeners(); + const cleanupWindow = setupWindowListeners(); return () => { - queueMicrotask(() => { + setTimeout(() => { listeners.forEach((listener) => { if (typeof listener.then === "function") { listener @@ -283,7 +280,7 @@ const Layout = () => { } }); - cleanupWindowPromise + cleanupWindow .then((cleanup) => { try { cleanup(); @@ -294,9 +291,9 @@ const Layout = () => { .catch((error) => { console.error("[Layout] 获取cleanup函数失败:", error); }); - }); + }, 0); }; - }, [addListener, handleNotice]); + }, [handleNotice]); useEffect(() => { if (initRef.current) { @@ -306,16 +303,6 @@ const Layout = () => { console.log("[Layout] 开始执行初始化代码"); initRef.current = true; - const timers = new Set(); - const scheduleTimeout = (callback: () => void, delay = 0) => { - const timeoutId = window.setTimeout(() => { - timers.delete(timeoutId); - callback(); - }, delay); - timers.add(timeoutId); - return timeoutId; - }; - let isInitialized = false; let initializationAttempts = 0; const maxAttempts = 3; @@ -339,7 +326,7 @@ const Layout = () => { if (initialOverlay) { console.log("[Layout] 移除加载指示器"); initialOverlay.style.opacity = "0"; - scheduleTimeout(() => { + setTimeout(() => { try { initialOverlay.remove(); } catch { @@ -370,13 +357,13 @@ const Layout = () => { console.log("[Layout] React组件已挂载"); resolve(); } else { - scheduleTimeout(checkReactMount, 50); + setTimeout(checkReactMount, 50); } }; checkReactMount(); - scheduleTimeout(() => { + setTimeout(() => { console.log("[Layout] React组件挂载检查超时,继续执行"); resolve(); }, 2000); @@ -404,7 +391,7 @@ const Layout = () => { console.log( `[Layout] 将在500ms后进行第 ${initializationAttempts + 1} 次重试`, ); - scheduleTimeout(performInitialization, 500); + setTimeout(performInitialization, 500); } else { console.error("[Layout] 所有初始化尝试都失败,执行紧急初始化"); @@ -421,6 +408,15 @@ const Layout = () => { let hasEventTriggered = false; + const setupEventListener = async () => { + try { + console.log("[Layout] 开始监听启动完成事件"); + } catch (err) { + console.error("[Layout] 监听启动完成事件失败:", err); + return () => { }; + } + }; + const checkImmediateInitialization = async () => { try { console.log("[Layout] 检查后端是否已就绪"); @@ -436,7 +432,7 @@ const Layout = () => { } }; - const backupInitialization = scheduleTimeout(() => { + const backupInitialization = setTimeout(() => { if (!hasEventTriggered && !isInitialized) { console.warn("[Layout] 备用初始化触发:1.5秒内未开始初始化"); hasEventTriggered = true; @@ -444,28 +440,20 @@ const Layout = () => { } }, 1500); - const emergencyInitialization = scheduleTimeout(() => { + const emergencyInitialization = setTimeout(() => { if (!isInitialized) { console.error("[Layout] 紧急初始化触发:5秒内未完成初始化"); removeLoadingOverlay(); - notifyBackend("UI就绪").catch(() => {}); + notifyBackend("UI就绪").catch(() => { }); isInitialized = true; } }, 5000); - const immediateInitialization = scheduleTimeout( - checkImmediateInitialization, - 100, - ); + setTimeout(checkImmediateInitialization, 100); return () => { - window.clearTimeout(backupInitialization); - window.clearTimeout(emergencyInitialization); - window.clearTimeout(immediateInitialization); - timers.forEach((timeoutId) => { - window.clearTimeout(timeoutId); - }); - timers.clear(); + clearTimeout(backupInitialization); + clearTimeout(emergencyInitialization); }; }, []); @@ -481,7 +469,7 @@ const Layout = () => { if (start_page) { navigate(start_page, { replace: true }); } - }, [navigate, start_page]); + }, [start_page]); if (!themeReady) { return ( @@ -555,27 +543,27 @@ const Layout = () => { borderTopLeftRadius: "0px", borderTopRightRadius: "0px", }} - onContextMenu={() => { + onContextMenu={(e) => { // TODO: 禁止右键菜单 // if ( // OS === "windows" && // !["input", "textarea"].includes( - // event.currentTarget.tagName.toLowerCase(), + // e.currentTarget.tagName.toLowerCase(), // ) && - // !event.currentTarget.isContentEditable + // !e.currentTarget.isContentEditable // ) { - // event.preventDefault(); + // e.preventDefault(); // } }} sx={[ ({ palette }) => ({ bgcolor: palette.background.paper }), OS === "linux" ? { - borderRadius: "8px", - border: "1px solid var(--divider-color)", - width: "100vw", - height: "100vh", - } + borderRadius: "8px", + border: "1px solid var(--divider-color)", + width: "100vw", + height: "100vh", + } : {}, ]} > @@ -629,11 +617,7 @@ const Layout = () => {
- {routersEles ? ( - - {routersEles} - - ) : null} + {React.cloneElement(routersEles, { key: location.pathname })}