perf: improve proxy status indicator and toggle responsiveness

This commit is contained in:
wonfen
2025-06-23 12:59:24 +08:00
parent 628de70e89
commit d5a174c71b
5 changed files with 110 additions and 104 deletions

View File

@@ -19,6 +19,7 @@ import {
} from "@mui/icons-material";
import { useVerge } from "@/hooks/use-verge";
import { useSystemState } from "@/hooks/use-system-state";
import { useSystemProxyState } from "@/hooks/use-system-proxy-state";
import { showNotice } from "@/services/noticeService";
import { getRunningMode } from "@/services/cmds";
import { mutate } from "swr";
@@ -145,8 +146,9 @@ export const ProxyTunCard: FC = () => {
const { verge } = useVerge();
const { isAdminMode } = useSystemState();
const { indicator: systemProxyIndicator } = useSystemProxyState();
const { enable_system_proxy, enable_tun_mode } = verge ?? {};
const { enable_tun_mode } = verge ?? {};
const updateLocalStatus = async () => {
try {
@@ -180,7 +182,7 @@ export const ProxyTunCard: FC = () => {
const tabDescription = useMemo(() => {
if (activeTab === "system") {
return {
text: enable_system_proxy
text: systemProxyIndicator
? t("System Proxy Enabled")
: t("System Proxy Disabled"),
tooltip: t("System Proxy Info"),
@@ -195,7 +197,7 @@ export const ProxyTunCard: FC = () => {
tooltip: t("TUN Mode Intercept Info"),
};
}
}, [activeTab, enable_system_proxy, enable_tun_mode, isTunAvailable, t]);
}, [activeTab, systemProxyIndicator, enable_tun_mode, isTunAvailable, t]);
return (
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
@@ -214,7 +216,7 @@ export const ProxyTunCard: FC = () => {
onClick={() => handleTabChange("system")}
icon={ComputerRounded}
label={t("System Proxy")}
hasIndicator={enable_system_proxy}
hasIndicator={systemProxyIndicator}
/>
<TabButton
isActive={activeTab === "tun"}

View File

@@ -1,4 +1,4 @@
import useSWR, { mutate } from "swr";
import { mutate } from "swr";
import { useRef } from "react";
import { useTranslation } from "react-i18next";
import {
@@ -10,23 +10,18 @@ import {
DeleteForeverRounded,
} from "@mui/icons-material";
import { useVerge } from "@/hooks/use-verge";
import { useSystemProxyState } from "@/hooks/use-system-proxy-state";
import { DialogRef, Switch } from "@/components/base";
import { SettingList, SettingItem } from "./mods/setting-comp";
import { GuardState } from "./mods/guard-state";
import { SysproxyViewer } from "./mods/sysproxy-viewer";
import { TunViewer } from "./mods/tun-viewer";
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
import {
getSystemProxy,
getAutotemProxy,
uninstallService,
restartCore,
stopCore,
} from "@/services/cmds";
import { uninstallService, restartCore, stopCore } from "@/services/cmds";
import { useLockFn } from "ahooks";
import { Button, Tooltip } from "@mui/material";
import { useSystemState } from "@/hooks/use-system-state";
import { closeAllConnections } from "@/services/api";
import { showNotice } from "@/services/noticeService";
import { useServiceInstaller } from "@/hooks/useServiceInstaller";
@@ -39,9 +34,11 @@ const SettingSystem = ({ onError }: Props) => {
const { verge, mutateVerge, patchVerge } = useVerge();
const { installServiceAndRestartCore } = useServiceInstaller();
const { data: sysproxy } = useSWR("getSystemProxy", getSystemProxy);
const { data: autoproxy } = useSWR("getAutotemProxy", getAutotemProxy);
const {
actualState: systemProxyActualState,
indicator: systemProxyIndicator,
toggleSystemProxy,
} = useSystemProxyState();
const { isAdminMode, isServiceMode, mutateRunningMode } = useSystemState();
@@ -51,26 +48,14 @@ const SettingSystem = ({ onError }: Props) => {
const sysproxyRef = useRef<DialogRef>(null);
const tunRef = useRef<DialogRef>(null);
const {
enable_tun_mode,
enable_auto_launch,
enable_silent_start,
enable_system_proxy,
proxy_auto_config,
enable_hover_jump_navigator,
} = verge ?? {};
const { enable_tun_mode, enable_auto_launch, enable_silent_start } =
verge ?? {};
const onSwitchFormat = (_e: any, value: boolean) => value;
const onChangeData = (patch: Partial<IVergeConfig>) => {
mutateVerge({ ...verge, ...patch }, false);
};
const updateProxyStatus = async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
await mutate("getSystemProxy");
await mutate("getAutotemProxy");
};
// 抽象服务操作逻辑
const handleServiceOperation = useLockFn(
async ({
@@ -194,13 +179,7 @@ const SettingSystem = ({ onError }: Props) => {
icon={SettingsRounded}
onClick={() => sysproxyRef.current?.open()}
/>
{proxy_auto_config ? (
autoproxy?.enable ? (
<PlayArrowRounded sx={{ color: "success.main", mr: 1 }} />
) : (
<PauseRounded sx={{ color: "error.main", mr: 1 }} />
)
) : sysproxy?.enable ? (
{systemProxyIndicator ? (
<PlayArrowRounded sx={{ color: "success.main", mr: 1 }} />
) : (
<PauseRounded sx={{ color: "error.main", mr: 1 }} />
@@ -209,44 +188,13 @@ const SettingSystem = ({ onError }: Props) => {
}
>
<GuardState
value={
// 此行为跟随代理状态,异常关闭时按钮应当也关闭
// 如果 autoproxy.enable 和 sysproxy.enable 都为 false则强制为 false
autoproxy?.enable === false && sysproxy?.enable === false
? false
: (enable_system_proxy ?? false)
}
value={systemProxyActualState}
valueProps="checked"
onCatch={onError}
onFormat={onSwitchFormat}
onChange={(e) => {
if (autoproxy?.enable === false && sysproxy?.enable === false) {
onChangeData({ enable_system_proxy: !enable_system_proxy });
} else {
onChangeData({ enable_system_proxy: e });
}
}}
onGuard={async (e) => {
if (autoproxy?.enable === false && sysproxy?.enable === false) {
await patchVerge({ enable_system_proxy: !enable_system_proxy });
await updateProxyStatus();
return;
}
if (!e && verge?.auto_close_connection) {
closeAllConnections();
}
await patchVerge({ enable_system_proxy: e });
await updateProxyStatus();
}}
onGuard={(e) => toggleSystemProxy(e)}
>
<Switch
edge="end"
checked={
autoproxy?.enable === false && sysproxy?.enable === false
? false
: (enable_system_proxy ?? false)
}
/>
<Switch edge="end" checked={systemProxyActualState} />
</GuardState>
</SettingItem>

View File

@@ -1,6 +1,6 @@
import { useRef } from "react";
import { useTranslation } from "react-i18next";
import useSWR, { mutate } from "swr";
import useSWR from "swr";
import {
SettingsRounded,
PlayCircleOutlineRounded,
@@ -20,12 +20,8 @@ import { GuardState } from "@/components/setting/mods/guard-state";
import { SysproxyViewer } from "@/components/setting/mods/sysproxy-viewer";
import { TunViewer } from "@/components/setting/mods/tun-viewer";
import { useVerge } from "@/hooks/use-verge";
import {
getSystemProxy,
getAutotemProxy,
getRunningMode,
} from "@/services/cmds";
import { closeAllConnections } from "@/services/api";
import { useSystemProxyState } from "@/hooks/use-system-proxy-state";
import { getRunningMode } from "@/services/cmds";
import { showNotice } from "@/services/noticeService";
import { useServiceInstaller } from "@/hooks/useServiceInstaller";
@@ -44,12 +40,13 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
const theme = useTheme();
const { installServiceAndRestartCore } = useServiceInstaller();
const { data: sysproxy } = useSWR("getSystemProxy", getSystemProxy);
const { data: autoproxy } = useSWR("getAutotemProxy", getAutotemProxy);
const { data: runningMode, mutate: mutateRunningMode } = useSWR(
"getRunningMode",
getRunningMode,
);
const {
actualState: systemProxyActualState,
indicator: systemProxyIndicator,
toggleSystemProxy,
} = useSystemProxyState();
const { data: runningMode } = useSWR("getRunningMode", getRunningMode);
// 是否以sidecar模式运行
const isSidecarMode = runningMode === "Sidecar";
@@ -57,8 +54,7 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
const sysproxyRef = useRef<DialogRef>(null);
const tunRef = useRef<DialogRef>(null);
const { enable_tun_mode, enable_system_proxy, proxy_auto_config } =
verge ?? {};
const { enable_tun_mode, enable_system_proxy } = verge ?? {};
// 确定当前显示哪个开关
const isSystemProxyMode = label === t("System Proxy") || !label;
@@ -69,12 +65,6 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
mutateVerge({ ...verge, ...patch }, false);
};
const updateProxyStatus = async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
await mutate("getSystemProxy");
await mutate("getAutotemProxy");
};
// 安装系统服务
const onInstallService = installServiceAndRestartCore;
@@ -109,7 +99,7 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
}}
>
<Box sx={{ display: "flex", alignItems: "center" }}>
{enable_system_proxy ? (
{systemProxyIndicator ? (
<PlayCircleOutlineRounded
sx={{ color: "success.main", mr: 1.5, fontSize: 28 }}
/>
@@ -151,18 +141,11 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
</Tooltip>
<GuardState
value={enable_system_proxy ?? false}
value={systemProxyActualState}
valueProps="checked"
onCatch={onError}
onFormat={onSwitchFormat}
onChange={(e) => onChangeData({ enable_system_proxy: e })}
onGuard={async (e) => {
if (!e && verge?.auto_close_connection) {
closeAllConnections();
}
await patchVerge({ enable_system_proxy: e });
await updateProxyStatus();
}}
onGuard={(e) => toggleSystemProxy(e)}
>
<Switch edge="end" />
</GuardState>

View File

@@ -0,0 +1,72 @@
import useSWR, { mutate } from "swr";
import { useVerge } from "@/hooks/use-verge";
import { getAutotemProxy } from "@/services/cmds";
import { useAppData } from "@/providers/app-data-provider";
import { closeAllConnections } from "@/services/api";
// 系统代理状态检测统一逻辑
export const useSystemProxyState = () => {
const { verge, mutateVerge, patchVerge } = useVerge();
const { sysproxy } = useAppData();
const { data: autoproxy } = useSWR("getAutotemProxy", getAutotemProxy, {
revalidateOnFocus: true,
revalidateOnReconnect: true,
});
const { enable_system_proxy, proxy_auto_config } = verge ?? {};
const getSystemProxyActualState = () => {
const userEnabled = enable_system_proxy ?? false;
if (userEnabled) {
return true;
}
return autoproxy?.enable === false && sysproxy?.enable === false
? false
: userEnabled;
};
const getSystemProxyIndicator = () => {
if (proxy_auto_config) {
return autoproxy?.enable ?? false;
} else {
return sysproxy?.enable ?? false;
}
};
const updateProxyStatus = async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
await mutate("getSystemProxy");
await mutate("getAutotemProxy");
};
const toggleSystemProxy = (enabled: boolean) => {
mutateVerge({ ...verge, enable_system_proxy: enabled }, false);
setTimeout(async () => {
try {
if (!enabled && verge?.auto_close_connection) {
closeAllConnections();
}
await patchVerge({ enable_system_proxy: enabled });
updateProxyStatus();
} catch (error) {
mutateVerge({ ...verge, enable_system_proxy: !enabled }, false);
}
}, 0);
return Promise.resolve();
};
return {
actualState: getSystemProxyActualState(),
indicator: getSystemProxyIndicator(),
configState: enable_system_proxy ?? false,
sysproxy,
autoproxy,
proxy_auto_config,
toggleSystemProxy,
};
};

View File

@@ -68,7 +68,7 @@ export const AppDataProvider = ({
getProxies,
{
refreshInterval: 5000,
revalidateOnFocus: false,
revalidateOnFocus: true,
suspense: false,
errorRetryCount: 3,
},
@@ -243,7 +243,8 @@ export const AppDataProvider = ({
"getSystemProxy",
getSystemProxy,
{
revalidateOnFocus: false,
revalidateOnFocus: true,
revalidateOnReconnect: true,
suspense: false,
errorRetryCount: 3,
},