import { useTranslation } from "react-i18next"; import { Box, Button, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, FormGroup, FormControlLabel, Checkbox, Tooltip, Grid, Skeleton, } from "@mui/material"; import { useVerge } from "@/hooks/use-verge"; import { useProfiles } from "@/hooks/use-profiles"; import { RouterOutlined, SettingsOutlined, DnsOutlined, SpeedOutlined, HelpOutlineRounded, HistoryEduOutlined, } from "@mui/icons-material"; import { ProxyTunCard } from "@/components/home/proxy-tun-card"; import { ClashModeCard } from "@/components/home/clash-mode-card"; import { EnhancedTrafficStats } from "@/components/home/enhanced-traffic-stats"; import { useState, useMemo, Suspense, lazy, useCallback } from "react"; import { HomeProfileCard } from "@/components/home/home-profile-card"; import { EnhancedCard } from "@/components/home/enhanced-card"; import { CurrentProxyCard } from "@/components/home/current-proxy-card"; import { BasePage } from "@/components/base"; import { useLockFn } from "ahooks"; import { entry_lightweight_mode, openWebUrl } from "@/services/cmds"; const LazyTestCard = lazy(() => import("@/components/home/test-card").then((module) => ({ default: module.TestCard, })), ); const LazyIpInfoCard = lazy(() => import("@/components/home/ip-info-card").then((module) => ({ default: module.IpInfoCard, })), ); const LazyClashInfoCard = lazy(() => import("@/components/home/clash-info-card").then((module) => ({ default: module.ClashInfoCard, })), ); const LazySystemInfoCard = lazy(() => import("@/components/home/system-info-card").then((module) => ({ default: module.SystemInfoCard, })), ); // 定义首页卡片设置接口 interface HomeCardsSettings { profile: boolean; proxy: boolean; network: boolean; mode: boolean; traffic: boolean; info: boolean; clashinfo: boolean; systeminfo: boolean; test: boolean; ip: boolean; [key: string]: boolean; } // 首页设置对话框组件接口 interface HomeSettingsDialogProps { open: boolean; onClose: () => void; homeCards: HomeCardsSettings; onSave: (cards: HomeCardsSettings) => void; } // 首页设置对话框组件 const HomeSettingsDialog = ({ open, onClose, homeCards, onSave, }: HomeSettingsDialogProps) => { const { t } = useTranslation(); const [cards, setCards] = useState(homeCards); const { patchVerge } = useVerge(); const handleToggle = (key: string) => { setCards((prev: HomeCardsSettings) => ({ ...prev, [key]: !prev[key], })); }; const handleSave = async () => { await patchVerge({ home_cards: cards }); onSave(cards); onClose(); }; return ( {t("Home Settings")} handleToggle("profile")} /> } label={t("Profile Card")} /> handleToggle("proxy")} /> } label={t("Current Proxy Card")} /> handleToggle("network")} /> } label={t("Network Settings Card")} /> handleToggle("mode")} /> } label={t("Proxy Mode Card")} /> handleToggle("traffic")} /> } label={t("Traffic Stats Card")} /> handleToggle("test")} /> } label={t("Website Tests Card")} /> handleToggle("ip")} /> } label={t("IP Information Card")} /> handleToggle("clashinfo")} /> } label={t("Clash Info Cards")} /> handleToggle("systeminfo")} /> } label={t("System Info Cards")} /> ); }; export const HomePage = () => { const { t } = useTranslation(); const { verge } = useVerge(); const { current, mutateProfiles } = useProfiles(); // 设置弹窗的状态 const [settingsOpen, setSettingsOpen] = useState(false); // 卡片显示状态 const defaultCards = useMemo( () => ({ info: false, profile: true, proxy: true, network: true, mode: true, traffic: true, clashinfo: true, systeminfo: true, test: true, ip: true, }), [], ); const [homeCards, setHomeCards] = useState(() => { return (verge?.home_cards as HomeCardsSettings) || defaultCards; }); // 文档链接函数 const toGithubDoc = useLockFn(() => { return openWebUrl("https://clash-verge-rev.github.io/index.html"); }); // 新增:打开设置弹窗 const openSettings = useCallback(() => { setSettingsOpen(true); }, []); const renderCard = useCallback( (cardKey: string, component: React.ReactNode, size: number = 6) => { if (!homeCards[cardKey]) return null; return ( {component} ); }, [homeCards], ); const criticalCards = useMemo( () => [ renderCard( "profile", , ), renderCard("proxy", ), renderCard("network", ), renderCard("mode", ), ], [homeCards, current, mutateProfiles, renderCard], ); // 新增:保存设置时用requestIdleCallback/setTimeout const handleSaveSettings = (newCards: HomeCardsSettings) => { if (window.requestIdleCallback) { window.requestIdleCallback(() => setHomeCards(newCards)); } else { setTimeout(() => setHomeCards(newCards), 0); } }; const nonCriticalCards = useMemo( () => [ renderCard( "traffic", } iconColor="secondary" > , 12, ), renderCard( "test", }> , ), renderCard( "ip", }> , ), renderCard( "clashinfo", }> , ), renderCard( "systeminfo", }> , ), ], [homeCards, t, renderCard], ); return ( await entry_lightweight_mode()} size="small" color="inherit" > } > {criticalCards} {nonCriticalCards} {/* 首页设置弹窗 */} setSettingsOpen(false)} homeCards={homeCards} onSave={handleSaveSettings} /> ); }; // 增强版网络设置卡片组件 const NetworkSettingsCard = () => { const { t } = useTranslation(); return ( } iconColor="primary" action={null} > ); }; // 增强版 Clash 模式卡片组件 const ClashModeEnhancedCard = () => { const { t } = useTranslation(); return ( } iconColor="info" action={null} > ); }; export default HomePage;