import { useQuery } from "@tanstack/react-query"; import type React from "react"; import { lazy, Suspense, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Route, BrowserRouter as Router, Routes } from "react-router-dom"; import { DashCommand } from "./components/DashCommand"; import ErrorBoundary from "./components/ErrorBoundary"; import Footer from "./components/Footer"; import Header, { RefreshToast } from "./components/Header"; import { useBackground } from "./hooks/use-background"; import { useTheme } from "./hooks/use-theme"; import { InjectContext } from "./lib/inject"; import { fetchSetting } from "./lib/nezha-api"; import { cn } from "./lib/utils"; import ErrorPage from "./pages/ErrorPage"; import Server from "./pages/Server"; const NotFound = lazy(() => import("./pages/NotFound")); const loadServerDetail = () => import("./pages/ServerDetail"); const ServerDetail = lazy(loadServerDetail); // Route checker component const RouteChecker: React.FC = () => { return ; }; const toError = (error: unknown) => { if (!error) return null; return error instanceof Error ? error : new Error(String(error)); }; const MainApp: React.FC = () => { const { data: settingData, error } = useQuery({ queryKey: ["setting"], queryFn: () => fetchSetting(), refetchOnMount: true, refetchOnWindowFocus: true, retry: false, }); const { i18n } = useTranslation(); const { setTheme } = useTheme(); const [isCustomCodeInjected, setIsCustomCodeInjected] = useState(false); const { backgroundImage: customBackgroundImage } = useBackground(); useEffect(() => { loadServerDetail(); }, []); useEffect(() => { if (settingData?.data?.config?.custom_code) { InjectContext(settingData?.data?.config?.custom_code); setIsCustomCodeInjected(true); } }, [settingData?.data?.config?.custom_code]); // 检测是否强制指定了主题颜色 const forceTheme = // @ts-expect-error ForceTheme is a global variable (window.ForceTheme as string) !== "" ? window.ForceTheme : undefined; useEffect(() => { if (forceTheme === "dark" || forceTheme === "light") { setTheme(forceTheme); } }, [forceTheme, setTheme]); const initialBackendError = !settingData ? toError(error) : null; if (settingData?.data?.config?.custom_code && !isCustomCodeInjected) { return null; } if ( settingData?.data?.config?.language && !localStorage.getItem("language") ) { i18n.changeLanguage(settingData?.data?.config?.language); } const customMobileBackgroundImage = window.CustomMobileBackgroundImage !== "" ? window.CustomMobileBackgroundImage : undefined; return ( {/* 固定定位的背景层 */} {customBackgroundImage && (
)} {customMobileBackgroundImage && (
)}
} /> } /> } /> } />
); }; // Main App wrapper with router const App: React.FC = () => { return ( ); }; export default App;