import { InfoOutlined, SettingsOutlined, AdminPanelSettingsOutlined, DnsOutlined, ExtensionOutlined, } from '@mui/icons-material' import { Typography, Stack, Divider, Chip, IconButton } from '@mui/material' import { useLockFn } from 'ahooks' import { useCallback, useEffect, useMemo, useReducer } from 'react' import { useTranslation } from 'react-i18next' import { useNavigate } from 'react-router' import { useServiceInstaller } from '@/hooks/use-service-installer' import { useSystemState } from '@/hooks/use-system-state' import { useUpdate } from '@/hooks/use-update' import { useVerge } from '@/hooks/use-verge' import { getSystemInfo } from '@/services/cmds' import { showNotice } from '@/services/notice-service' import { version as appVersion } from '@root/package.json' import { EnhancedCard } from './enhanced-card' interface SystemState { osInfo: string lastCheckUpdate: string } type SystemStateAction = | { type: 'set-os-info'; payload: string } | { type: 'set-last-check-update'; payload: string } const systemStateReducer = ( state: SystemState, action: SystemStateAction, ): SystemState => { switch (action.type) { case 'set-os-info': return { ...state, osInfo: action.payload } case 'set-last-check-update': return { ...state, lastCheckUpdate: action.payload } default: return state } } export const SystemInfoCard = () => { const { t } = useTranslation() const { verge, patchVerge } = useVerge() const navigate = useNavigate() const { isAdminMode, isSidecarMode } = useSystemState() const { installServiceAndRestartCore } = useServiceInstaller() // 自动检查更新逻辑 const { checkUpdate: triggerCheckUpdate } = useUpdate(true, { onSuccess: () => { const now = Date.now() localStorage.setItem('last_check_update', now.toString()) dispatchSystemState({ type: 'set-last-check-update', payload: new Date(now).toLocaleString(), }) }, }) // 系统信息状态 const [systemState, dispatchSystemState] = useReducer(systemStateReducer, { osInfo: '', lastCheckUpdate: '-', }) // 初始化系统信息 useEffect(() => { let timeoutId: number | undefined getSystemInfo() .then((info) => { const lines = info.split('\n') if (lines.length > 0) { const sysName = lines[0].split(': ')[1] || '' let sysVersion = lines[1].split(': ')[1] || '' if ( sysName && sysVersion.toLowerCase().startsWith(sysName.toLowerCase()) ) { sysVersion = sysVersion.substring(sysName.length).trim() } dispatchSystemState({ type: 'set-os-info', payload: `${sysName} ${sysVersion}`, }) } }) .catch(console.error) // 获取最后检查更新时间 const lastCheck = localStorage.getItem('last_check_update') if (lastCheck) { try { const timestamp = parseInt(lastCheck, 10) if (!isNaN(timestamp)) { dispatchSystemState({ type: 'set-last-check-update', payload: new Date(timestamp).toLocaleString(), }) } } catch (e) { console.error('Error parsing last check update time', e) } } else if (verge?.auto_check_update) { // 如果启用了自动检查更新但没有记录,设置当前时间并延迟检查 const now = Date.now() localStorage.setItem('last_check_update', now.toString()) dispatchSystemState({ type: 'set-last-check-update', payload: new Date(now).toLocaleString(), }) timeoutId = window.setTimeout(() => { if (verge?.auto_check_update) { triggerCheckUpdate().catch(console.error) } }, 5000) } return () => { if (timeoutId !== undefined) { window.clearTimeout(timeoutId) } } }, [verge?.auto_check_update, dispatchSystemState, triggerCheckUpdate]) // 导航到设置页面 const goToSettings = useCallback(() => { navigate('/settings') }, [navigate]) // 切换自启动状态 const toggleAutoLaunch = useCallback(async () => { if (!verge) return try { await patchVerge({ enable_auto_launch: !verge.enable_auto_launch }) } catch (err) { console.error('切换开机自启动状态失败:', err) } }, [verge, patchVerge]) // 点击运行模式处理,Sidecar或纯管理员模式允许安装服务 const handleRunningModeClick = useCallback(() => { if (isSidecarMode || (isAdminMode && isSidecarMode)) { installServiceAndRestartCore() } }, [isSidecarMode, isAdminMode, installServiceAndRestartCore]) // 检查更新 const onCheckUpdate = useLockFn(async () => { try { const info = await triggerCheckUpdate() const now = Date.now() localStorage.setItem('last_check_update', now.toString()) dispatchSystemState({ type: 'set-last-check-update', payload: new Date(now).toLocaleString(), }) if (!info?.available) { showNotice.success( 'settings.components.verge.advanced.notifications.latestVersion', ) } else { showNotice.info('shared.feedback.notifications.updateAvailable', 2000) goToSettings() } } catch (err) { showNotice.error(err) } }) // 是否启用自启动 const autoLaunchEnabled = useMemo( () => verge?.enable_auto_launch || false, [verge], ) // 运行模式样式 const runningModeStyle = useMemo( () => ({ // Sidecar或纯管理员模式允许安装服务 cursor: isSidecarMode || (isAdminMode && isSidecarMode) ? 'pointer' : 'default', textDecoration: isSidecarMode || (isAdminMode && isSidecarMode) ? 'underline' : 'none', display: 'flex', alignItems: 'center', gap: 0.5, '&:hover': { opacity: isSidecarMode || (isAdminMode && isSidecarMode) ? 0.7 : 1, }, }), [isSidecarMode, isAdminMode], ) // 获取模式图标和文本 const getModeIcon = () => { if (isAdminMode) { // 判断是否为组合模式(管理员+服务) if (!isSidecarMode) { return ( <> ) } return ( ) } else if (isSidecarMode) { return ( ) } else { return ( ) } } // 获取模式文本 const getModeText = () => { if (isAdminMode) { // 判断是否同时处于服务模式 if (!isSidecarMode) { return t('home.components.systemInfo.badges.adminServiceMode') } return t('home.components.systemInfo.badges.adminMode') } else if (isSidecarMode) { return t('home.components.systemInfo.badges.sidecarMode') } else { return t('home.components.systemInfo.badges.serviceMode') } } // 只有当verge存在时才渲染内容 if (!verge) return null return ( } iconColor="error" action={ } > {t('home.components.systemInfo.fields.osInfo')} {systemState.osInfo} {t('home.components.systemInfo.fields.autoLaunch')} {t('home.components.systemInfo.fields.runningMode')} {getModeIcon()} {getModeText()} {t('home.components.systemInfo.fields.lastCheckUpdate')} {systemState.lastCheckUpdate} {t('home.components.systemInfo.fields.vergeVersion')} v{appVersion} ) }