diff --git a/src/components/home/system-info-card.tsx b/src/components/home/system-info-card.tsx index 4198ea88d..29e41081b 100644 --- a/src/components/home/system-info-card.tsx +++ b/src/components/home/system-info-card.tsx @@ -29,7 +29,7 @@ export const SystemInfoCard = () => { const { t } = useTranslation() const { verge, patchVerge } = useVerge() const navigate = useNavigate() - const { isAdminMode, isSidecarMode } = useSystemState() + const { isAdminMode, isSidecarMode, mutateSystemState } = useSystemState() const { installServiceAndRestartCore } = useServiceInstaller() // 自动检查更新逻辑(lastCheckUpdate 由 useUpdate 统一管理) @@ -89,11 +89,17 @@ export const SystemInfoCard = () => { }, [verge, patchVerge]) // 点击运行模式处理,Sidecar或纯管理员模式允许安装服务 - const handleRunningModeClick = useCallback(() => { + const handleRunningModeClick = useCallback(async () => { if (isSidecarMode || (isAdminMode && isSidecarMode)) { - installServiceAndRestartCore() + await installServiceAndRestartCore() + await mutateSystemState() } - }, [isSidecarMode, isAdminMode, installServiceAndRestartCore]) + }, [ + isSidecarMode, + isAdminMode, + installServiceAndRestartCore, + mutateSystemState, + ]) // 检查更新 const onCheckUpdate = useLockFn(async () => { diff --git a/src/hooks/use-service-installer.ts b/src/hooks/use-service-installer.ts index 144e62db4..b24ccc255 100644 --- a/src/hooks/use-service-installer.ts +++ b/src/hooks/use-service-installer.ts @@ -3,8 +3,6 @@ import { useCallback } from 'react' import { installService, restartCore } from '@/services/cmds' import { showNotice } from '@/services/notice-service' -import { useSystemState } from './use-system-state' - const executeWithErrorHandling = async ( operation: () => Promise, loadingKey: string, @@ -23,8 +21,6 @@ const executeWithErrorHandling = async ( } export const useServiceInstaller = () => { - const { mutateSystemState } = useSystemState() - const installServiceAndRestartCore = useCallback(async () => { await executeWithErrorHandling( () => installService(), @@ -37,8 +33,6 @@ export const useServiceInstaller = () => { 'settings.statuses.clash.restarting', 'settings.feedback.notifications.clash.restartSuccess', ) - - await mutateSystemState() - }, [mutateSystemState]) + }, []) return { installServiceAndRestartCore } } diff --git a/src/hooks/use-service-uninstaller.ts b/src/hooks/use-service-uninstaller.ts index 0843967d7..c3ed50027 100644 --- a/src/hooks/use-service-uninstaller.ts +++ b/src/hooks/use-service-uninstaller.ts @@ -3,8 +3,6 @@ import { useCallback } from 'react' import { restartCore, stopCore, uninstallService } from '@/services/cmds' import { showNotice } from '@/services/notice-service' -import { useSystemState } from './use-system-state' - const executeWithErrorHandling = async ( operation: () => Promise, loadingKey: string, @@ -23,8 +21,6 @@ const executeWithErrorHandling = async ( } export const useServiceUninstaller = () => { - const { mutateSystemState } = useSystemState() - const uninstallServiceAndRestartCore = useCallback(async () => { try { await executeWithErrorHandling( @@ -43,9 +39,8 @@ export const useServiceUninstaller = () => { 'settings.statuses.clash.restarting', 'settings.feedback.notifications.clash.restartSuccess', ) - await mutateSystemState() } - }, [mutateSystemState]) + }, []) return { uninstallServiceAndRestartCore } } diff --git a/src/hooks/use-system-state.ts b/src/hooks/use-system-state.ts index 213a4c192..c62fe2ed8 100644 --- a/src/hooks/use-system-state.ts +++ b/src/hooks/use-system-state.ts @@ -27,9 +27,7 @@ const STARTUP_GRACE_MS = 10_000 * 包括运行模式、管理员状态、系统服务是否可用 */ export function useSystemState() { - const { verge, patchVerge } = useVerge() const pageVisible = useVisibility() - const disablingTunRef = useRef(false) const [isStartingUp, setIsStartingUp] = useState(true) useEffect(() => { @@ -60,8 +58,25 @@ export function useSystemState() { const isServiceMode = systemState.runningMode === 'Service' const isTunModeAvailable = systemState.isAdminMode || systemState.isServiceOk - const enable_tun_mode = verge?.enable_tun_mode + return { + runningMode: systemState.runningMode, + isAdminMode: systemState.isAdminMode, + isServiceOk: systemState.isServiceOk, + isSidecarMode, + isServiceMode, + isTunModeAvailable, + mutateSystemState, + isLoading, + isStartingUp, + } +} + +export function useTunAvailabilityGuard() { + const { verge, patchVerge } = useVerge() + const { isTunModeAvailable, isLoading, isStartingUp } = useSystemState() + const disablingTunRef = useRef(false) const cooldownTimerRef = useRef | null>(null) + const enable_tun_mode = verge?.enable_tun_mode useEffect(() => { if (enable_tun_mode === undefined) return @@ -103,15 +118,4 @@ export function useSystemState() { } } }, [enable_tun_mode, isTunModeAvailable, patchVerge, isLoading, isStartingUp]) - - return { - runningMode: systemState.runningMode, - isAdminMode: systemState.isAdminMode, - isServiceOk: systemState.isServiceOk, - isSidecarMode, - isServiceMode, - isTunModeAvailable, - mutateSystemState, - isLoading, - } } diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index 3b6bd61e3..0766bf226 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -41,6 +41,7 @@ import { WindowResizeHandles, } from '@/components/layout/window-controller' import { useI18n } from '@/hooks/use-i18n' +import { useTunAvailabilityGuard } from '@/hooks/use-system-state' import { useVerge } from '@/hooks/use-verge' import { useWindowDecorations } from '@/hooks/use-window' import { useThemeMode } from '@/services/states' @@ -121,6 +122,8 @@ const Layout = () => { const navigate = useNavigate() const themeReady = useMemo(() => Boolean(theme), [theme]) + useTunAvailabilityGuard() + const [menuUnlocked, setMenuUnlocked] = useState(false) const [menuContextPosition, setMenuContextPosition] = useState(null)