mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-04-14 05:51:02 +08:00
fix(proxy): sync system proxy switch state with background highlight #5240, #5439, #5421, #4651, #4536
Fixed race condition where button state and background color would desync during rapid toggles or slow backend responses. Root causes: - Button used actualState while background used configState - toggleSystemProxy returned immediately via setTimeout(0), releasing lock before backend operation completed - 100ms delay in updateProxyStatus caused visual flash Changes: - Unified state source: both button and background now use actualState - Made toggleSystemProxy truly async with proper await chain - Wrapped toggle function with useLockFn to serialize operations - Reduced state refresh delay from 100ms to 50ms - Fixed GuardState lock release timing for async operations - Added proper error rollback with state refresh on failure Resolves issue where proxy toggle button would show as off while background remained green, or vice versa.
This commit is contained in:
parent
ddd24eb3ac
commit
44adf55975
@ -60,6 +60,7 @@ export function GuardState<T>(props: Props<T>) {
|
||||
|
||||
if (waitTime <= 0) {
|
||||
await onGuard(newValue, value!);
|
||||
lockRef.current = false;
|
||||
} else {
|
||||
// debounce guard
|
||||
clearTimeout(timeRef.current);
|
||||
@ -71,6 +72,8 @@ export function GuardState<T>(props: Props<T>) {
|
||||
// 状态回退
|
||||
onChange(saveRef.current!);
|
||||
onCatch(err);
|
||||
} finally {
|
||||
lockRef.current = false;
|
||||
}
|
||||
}, waitTime);
|
||||
}
|
||||
@ -78,8 +81,8 @@ export function GuardState<T>(props: Props<T>) {
|
||||
// 状态回退
|
||||
onChange(saveRef.current!);
|
||||
onCatch(err);
|
||||
lockRef.current = false;
|
||||
}
|
||||
lockRef.current = false;
|
||||
};
|
||||
const { children: nestedChildren, ...restProps } = childProps;
|
||||
|
||||
|
||||
@ -123,7 +123,7 @@ const ProxyControlSwitches = ({
|
||||
const sysproxyRef = useRef<DialogRef>(null);
|
||||
const tunRef = useRef<DialogRef>(null);
|
||||
|
||||
const { enable_tun_mode, enable_system_proxy } = verge ?? {};
|
||||
const { enable_tun_mode } = verge ?? {};
|
||||
|
||||
const showErrorNotice = useCallback(
|
||||
(msg: string) => showNotice.error(msg),
|
||||
@ -175,7 +175,7 @@ const ProxyControlSwitches = ({
|
||||
onInfoClick={() => sysproxyRef.current?.open()}
|
||||
onToggle={(value) => toggleSystemProxy(value)}
|
||||
onError={onError}
|
||||
highlight={enable_system_proxy}
|
||||
highlight={systemProxyActualState}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useLockFn } from "ahooks";
|
||||
import useSWR, { mutate } from "swr";
|
||||
import { closeAllConnections } from "tauri-plugin-mihomo-api";
|
||||
|
||||
@ -41,31 +42,30 @@ export const useSystemProxyState = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const updateProxyStatus = async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
const updateProxyStatus = async (isEnabling: boolean) => {
|
||||
// 关闭时更快响应,开启时等待系统确认
|
||||
const delay = isEnabling ? 20 : 10;
|
||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||
await mutate("getSystemProxy");
|
||||
await mutate("getAutotemProxy");
|
||||
};
|
||||
|
||||
const toggleSystemProxy = (enabled: boolean) => {
|
||||
const toggleSystemProxy = useLockFn(async (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) {
|
||||
console.warn("[useSystemProxyState] toggleSystemProxy failed:", error);
|
||||
mutateVerge({ ...verge, enable_system_proxy: !enabled }, false);
|
||||
try {
|
||||
if (!enabled && verge?.auto_close_connection) {
|
||||
await closeAllConnections();
|
||||
}
|
||||
}, 0);
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
await patchVerge({ enable_system_proxy: enabled });
|
||||
await updateProxyStatus(enabled);
|
||||
} catch (error) {
|
||||
console.warn("[useSystemProxyState] toggleSystemProxy failed:", error);
|
||||
mutateVerge({ ...verge, enable_system_proxy: !enabled }, false);
|
||||
await updateProxyStatus(!enabled);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
actualState: getSystemProxyActualState(),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user