perf: improve proxy status indicator and toggle responsiveness
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
|||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
import { useVerge } from "@/hooks/use-verge";
|
import { useVerge } from "@/hooks/use-verge";
|
||||||
import { useSystemState } from "@/hooks/use-system-state";
|
import { useSystemState } from "@/hooks/use-system-state";
|
||||||
|
import { useSystemProxyState } from "@/hooks/use-system-proxy-state";
|
||||||
import { showNotice } from "@/services/noticeService";
|
import { showNotice } from "@/services/noticeService";
|
||||||
import { getRunningMode } from "@/services/cmds";
|
import { getRunningMode } from "@/services/cmds";
|
||||||
import { mutate } from "swr";
|
import { mutate } from "swr";
|
||||||
@@ -145,8 +146,9 @@ export const ProxyTunCard: FC = () => {
|
|||||||
|
|
||||||
const { verge } = useVerge();
|
const { verge } = useVerge();
|
||||||
const { isAdminMode } = useSystemState();
|
const { isAdminMode } = useSystemState();
|
||||||
|
const { indicator: systemProxyIndicator } = useSystemProxyState();
|
||||||
|
|
||||||
const { enable_system_proxy, enable_tun_mode } = verge ?? {};
|
const { enable_tun_mode } = verge ?? {};
|
||||||
|
|
||||||
const updateLocalStatus = async () => {
|
const updateLocalStatus = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -180,7 +182,7 @@ export const ProxyTunCard: FC = () => {
|
|||||||
const tabDescription = useMemo(() => {
|
const tabDescription = useMemo(() => {
|
||||||
if (activeTab === "system") {
|
if (activeTab === "system") {
|
||||||
return {
|
return {
|
||||||
text: enable_system_proxy
|
text: systemProxyIndicator
|
||||||
? t("System Proxy Enabled")
|
? t("System Proxy Enabled")
|
||||||
: t("System Proxy Disabled"),
|
: t("System Proxy Disabled"),
|
||||||
tooltip: t("System Proxy Info"),
|
tooltip: t("System Proxy Info"),
|
||||||
@@ -195,7 +197,7 @@ export const ProxyTunCard: FC = () => {
|
|||||||
tooltip: t("TUN Mode Intercept Info"),
|
tooltip: t("TUN Mode Intercept Info"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [activeTab, enable_system_proxy, enable_tun_mode, isTunAvailable, t]);
|
}, [activeTab, systemProxyIndicator, enable_tun_mode, isTunAvailable, t]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
||||||
@@ -214,7 +216,7 @@ export const ProxyTunCard: FC = () => {
|
|||||||
onClick={() => handleTabChange("system")}
|
onClick={() => handleTabChange("system")}
|
||||||
icon={ComputerRounded}
|
icon={ComputerRounded}
|
||||||
label={t("System Proxy")}
|
label={t("System Proxy")}
|
||||||
hasIndicator={enable_system_proxy}
|
hasIndicator={systemProxyIndicator}
|
||||||
/>
|
/>
|
||||||
<TabButton
|
<TabButton
|
||||||
isActive={activeTab === "tun"}
|
isActive={activeTab === "tun"}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import useSWR, { mutate } from "swr";
|
import { mutate } from "swr";
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
@@ -10,23 +10,18 @@ import {
|
|||||||
DeleteForeverRounded,
|
DeleteForeverRounded,
|
||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
import { useVerge } from "@/hooks/use-verge";
|
import { useVerge } from "@/hooks/use-verge";
|
||||||
|
import { useSystemProxyState } from "@/hooks/use-system-proxy-state";
|
||||||
import { DialogRef, Switch } from "@/components/base";
|
import { DialogRef, Switch } from "@/components/base";
|
||||||
import { SettingList, SettingItem } from "./mods/setting-comp";
|
import { SettingList, SettingItem } from "./mods/setting-comp";
|
||||||
import { GuardState } from "./mods/guard-state";
|
import { GuardState } from "./mods/guard-state";
|
||||||
import { SysproxyViewer } from "./mods/sysproxy-viewer";
|
import { SysproxyViewer } from "./mods/sysproxy-viewer";
|
||||||
import { TunViewer } from "./mods/tun-viewer";
|
import { TunViewer } from "./mods/tun-viewer";
|
||||||
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
|
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
|
||||||
import {
|
import { uninstallService, restartCore, stopCore } from "@/services/cmds";
|
||||||
getSystemProxy,
|
|
||||||
getAutotemProxy,
|
|
||||||
uninstallService,
|
|
||||||
restartCore,
|
|
||||||
stopCore,
|
|
||||||
} from "@/services/cmds";
|
|
||||||
import { useLockFn } from "ahooks";
|
import { useLockFn } from "ahooks";
|
||||||
import { Button, Tooltip } from "@mui/material";
|
import { Button, Tooltip } from "@mui/material";
|
||||||
import { useSystemState } from "@/hooks/use-system-state";
|
import { useSystemState } from "@/hooks/use-system-state";
|
||||||
import { closeAllConnections } from "@/services/api";
|
|
||||||
import { showNotice } from "@/services/noticeService";
|
import { showNotice } from "@/services/noticeService";
|
||||||
import { useServiceInstaller } from "@/hooks/useServiceInstaller";
|
import { useServiceInstaller } from "@/hooks/useServiceInstaller";
|
||||||
|
|
||||||
@@ -39,9 +34,11 @@ const SettingSystem = ({ onError }: Props) => {
|
|||||||
|
|
||||||
const { verge, mutateVerge, patchVerge } = useVerge();
|
const { verge, mutateVerge, patchVerge } = useVerge();
|
||||||
const { installServiceAndRestartCore } = useServiceInstaller();
|
const { installServiceAndRestartCore } = useServiceInstaller();
|
||||||
|
const {
|
||||||
const { data: sysproxy } = useSWR("getSystemProxy", getSystemProxy);
|
actualState: systemProxyActualState,
|
||||||
const { data: autoproxy } = useSWR("getAutotemProxy", getAutotemProxy);
|
indicator: systemProxyIndicator,
|
||||||
|
toggleSystemProxy,
|
||||||
|
} = useSystemProxyState();
|
||||||
|
|
||||||
const { isAdminMode, isServiceMode, mutateRunningMode } = useSystemState();
|
const { isAdminMode, isServiceMode, mutateRunningMode } = useSystemState();
|
||||||
|
|
||||||
@@ -51,26 +48,14 @@ const SettingSystem = ({ onError }: Props) => {
|
|||||||
const sysproxyRef = useRef<DialogRef>(null);
|
const sysproxyRef = useRef<DialogRef>(null);
|
||||||
const tunRef = useRef<DialogRef>(null);
|
const tunRef = useRef<DialogRef>(null);
|
||||||
|
|
||||||
const {
|
const { enable_tun_mode, enable_auto_launch, enable_silent_start } =
|
||||||
enable_tun_mode,
|
verge ?? {};
|
||||||
enable_auto_launch,
|
|
||||||
enable_silent_start,
|
|
||||||
enable_system_proxy,
|
|
||||||
proxy_auto_config,
|
|
||||||
enable_hover_jump_navigator,
|
|
||||||
} = verge ?? {};
|
|
||||||
|
|
||||||
const onSwitchFormat = (_e: any, value: boolean) => value;
|
const onSwitchFormat = (_e: any, value: boolean) => value;
|
||||||
const onChangeData = (patch: Partial<IVergeConfig>) => {
|
const onChangeData = (patch: Partial<IVergeConfig>) => {
|
||||||
mutateVerge({ ...verge, ...patch }, false);
|
mutateVerge({ ...verge, ...patch }, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateProxyStatus = async () => {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
||||||
await mutate("getSystemProxy");
|
|
||||||
await mutate("getAutotemProxy");
|
|
||||||
};
|
|
||||||
|
|
||||||
// 抽象服务操作逻辑
|
// 抽象服务操作逻辑
|
||||||
const handleServiceOperation = useLockFn(
|
const handleServiceOperation = useLockFn(
|
||||||
async ({
|
async ({
|
||||||
@@ -194,13 +179,7 @@ const SettingSystem = ({ onError }: Props) => {
|
|||||||
icon={SettingsRounded}
|
icon={SettingsRounded}
|
||||||
onClick={() => sysproxyRef.current?.open()}
|
onClick={() => sysproxyRef.current?.open()}
|
||||||
/>
|
/>
|
||||||
{proxy_auto_config ? (
|
{systemProxyIndicator ? (
|
||||||
autoproxy?.enable ? (
|
|
||||||
<PlayArrowRounded sx={{ color: "success.main", mr: 1 }} />
|
|
||||||
) : (
|
|
||||||
<PauseRounded sx={{ color: "error.main", mr: 1 }} />
|
|
||||||
)
|
|
||||||
) : sysproxy?.enable ? (
|
|
||||||
<PlayArrowRounded sx={{ color: "success.main", mr: 1 }} />
|
<PlayArrowRounded sx={{ color: "success.main", mr: 1 }} />
|
||||||
) : (
|
) : (
|
||||||
<PauseRounded sx={{ color: "error.main", mr: 1 }} />
|
<PauseRounded sx={{ color: "error.main", mr: 1 }} />
|
||||||
@@ -209,44 +188,13 @@ const SettingSystem = ({ onError }: Props) => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<GuardState
|
<GuardState
|
||||||
value={
|
value={systemProxyActualState}
|
||||||
// 此行为跟随代理状态,异常关闭时按钮应当也关闭
|
|
||||||
// 如果 autoproxy.enable 和 sysproxy.enable 都为 false,则强制为 false
|
|
||||||
autoproxy?.enable === false && sysproxy?.enable === false
|
|
||||||
? false
|
|
||||||
: (enable_system_proxy ?? false)
|
|
||||||
}
|
|
||||||
valueProps="checked"
|
valueProps="checked"
|
||||||
onCatch={onError}
|
onCatch={onError}
|
||||||
onFormat={onSwitchFormat}
|
onFormat={onSwitchFormat}
|
||||||
onChange={(e) => {
|
onGuard={(e) => toggleSystemProxy(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();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Switch
|
<Switch edge="end" checked={systemProxyActualState} />
|
||||||
edge="end"
|
|
||||||
checked={
|
|
||||||
autoproxy?.enable === false && sysproxy?.enable === false
|
|
||||||
? false
|
|
||||||
: (enable_system_proxy ?? false)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</GuardState>
|
</GuardState>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR from "swr";
|
||||||
import {
|
import {
|
||||||
SettingsRounded,
|
SettingsRounded,
|
||||||
PlayCircleOutlineRounded,
|
PlayCircleOutlineRounded,
|
||||||
@@ -20,12 +20,8 @@ import { GuardState } from "@/components/setting/mods/guard-state";
|
|||||||
import { SysproxyViewer } from "@/components/setting/mods/sysproxy-viewer";
|
import { SysproxyViewer } from "@/components/setting/mods/sysproxy-viewer";
|
||||||
import { TunViewer } from "@/components/setting/mods/tun-viewer";
|
import { TunViewer } from "@/components/setting/mods/tun-viewer";
|
||||||
import { useVerge } from "@/hooks/use-verge";
|
import { useVerge } from "@/hooks/use-verge";
|
||||||
import {
|
import { useSystemProxyState } from "@/hooks/use-system-proxy-state";
|
||||||
getSystemProxy,
|
import { getRunningMode } from "@/services/cmds";
|
||||||
getAutotemProxy,
|
|
||||||
getRunningMode,
|
|
||||||
} from "@/services/cmds";
|
|
||||||
import { closeAllConnections } from "@/services/api";
|
|
||||||
import { showNotice } from "@/services/noticeService";
|
import { showNotice } from "@/services/noticeService";
|
||||||
import { useServiceInstaller } from "@/hooks/useServiceInstaller";
|
import { useServiceInstaller } from "@/hooks/useServiceInstaller";
|
||||||
|
|
||||||
@@ -44,12 +40,13 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { installServiceAndRestartCore } = useServiceInstaller();
|
const { installServiceAndRestartCore } = useServiceInstaller();
|
||||||
|
|
||||||
const { data: sysproxy } = useSWR("getSystemProxy", getSystemProxy);
|
const {
|
||||||
const { data: autoproxy } = useSWR("getAutotemProxy", getAutotemProxy);
|
actualState: systemProxyActualState,
|
||||||
const { data: runningMode, mutate: mutateRunningMode } = useSWR(
|
indicator: systemProxyIndicator,
|
||||||
"getRunningMode",
|
toggleSystemProxy,
|
||||||
getRunningMode,
|
} = useSystemProxyState();
|
||||||
);
|
|
||||||
|
const { data: runningMode } = useSWR("getRunningMode", getRunningMode);
|
||||||
|
|
||||||
// 是否以sidecar模式运行
|
// 是否以sidecar模式运行
|
||||||
const isSidecarMode = runningMode === "Sidecar";
|
const isSidecarMode = runningMode === "Sidecar";
|
||||||
@@ -57,8 +54,7 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
|
|||||||
const sysproxyRef = useRef<DialogRef>(null);
|
const sysproxyRef = useRef<DialogRef>(null);
|
||||||
const tunRef = useRef<DialogRef>(null);
|
const tunRef = useRef<DialogRef>(null);
|
||||||
|
|
||||||
const { enable_tun_mode, enable_system_proxy, proxy_auto_config } =
|
const { enable_tun_mode, enable_system_proxy } = verge ?? {};
|
||||||
verge ?? {};
|
|
||||||
|
|
||||||
// 确定当前显示哪个开关
|
// 确定当前显示哪个开关
|
||||||
const isSystemProxyMode = label === t("System Proxy") || !label;
|
const isSystemProxyMode = label === t("System Proxy") || !label;
|
||||||
@@ -69,12 +65,6 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
|
|||||||
mutateVerge({ ...verge, ...patch }, false);
|
mutateVerge({ ...verge, ...patch }, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateProxyStatus = async () => {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
||||||
await mutate("getSystemProxy");
|
|
||||||
await mutate("getAutotemProxy");
|
|
||||||
};
|
|
||||||
|
|
||||||
// 安装系统服务
|
// 安装系统服务
|
||||||
const onInstallService = installServiceAndRestartCore;
|
const onInstallService = installServiceAndRestartCore;
|
||||||
|
|
||||||
@@ -109,7 +99,7 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
{enable_system_proxy ? (
|
{systemProxyIndicator ? (
|
||||||
<PlayCircleOutlineRounded
|
<PlayCircleOutlineRounded
|
||||||
sx={{ color: "success.main", mr: 1.5, fontSize: 28 }}
|
sx={{ color: "success.main", mr: 1.5, fontSize: 28 }}
|
||||||
/>
|
/>
|
||||||
@@ -151,18 +141,11 @@ const ProxyControlSwitches = ({ label, onError }: ProxySwitchProps) => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<GuardState
|
<GuardState
|
||||||
value={enable_system_proxy ?? false}
|
value={systemProxyActualState}
|
||||||
valueProps="checked"
|
valueProps="checked"
|
||||||
onCatch={onError}
|
onCatch={onError}
|
||||||
onFormat={onSwitchFormat}
|
onFormat={onSwitchFormat}
|
||||||
onChange={(e) => onChangeData({ enable_system_proxy: e })}
|
onGuard={(e) => toggleSystemProxy(e)}
|
||||||
onGuard={async (e) => {
|
|
||||||
if (!e && verge?.auto_close_connection) {
|
|
||||||
closeAllConnections();
|
|
||||||
}
|
|
||||||
await patchVerge({ enable_system_proxy: e });
|
|
||||||
await updateProxyStatus();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Switch edge="end" />
|
<Switch edge="end" />
|
||||||
</GuardState>
|
</GuardState>
|
||||||
|
|||||||
72
src/hooks/use-system-proxy-state.ts
Normal file
72
src/hooks/use-system-proxy-state.ts
Normal 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,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -68,7 +68,7 @@ export const AppDataProvider = ({
|
|||||||
getProxies,
|
getProxies,
|
||||||
{
|
{
|
||||||
refreshInterval: 5000,
|
refreshInterval: 5000,
|
||||||
revalidateOnFocus: false,
|
revalidateOnFocus: true,
|
||||||
suspense: false,
|
suspense: false,
|
||||||
errorRetryCount: 3,
|
errorRetryCount: 3,
|
||||||
},
|
},
|
||||||
@@ -243,7 +243,8 @@ export const AppDataProvider = ({
|
|||||||
"getSystemProxy",
|
"getSystemProxy",
|
||||||
getSystemProxy,
|
getSystemProxy,
|
||||||
{
|
{
|
||||||
revalidateOnFocus: false,
|
revalidateOnFocus: true,
|
||||||
|
revalidateOnReconnect: true,
|
||||||
suspense: false,
|
suspense: false,
|
||||||
errorRetryCount: 3,
|
errorRetryCount: 3,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user