diff --git a/src-tauri/src/core/manager/config.rs b/src-tauri/src/core/manager/config.rs index 56e725d61..82496fc93 100644 --- a/src-tauri/src/core/manager/config.rs +++ b/src-tauri/src/core/manager/config.rs @@ -19,6 +19,7 @@ use smartstring::alias::String; use std::{ collections::HashSet, path::PathBuf, + sync::Arc, time::{Duration, Instant}, }; use tauri_plugin_mihomo::Error as MihomoError; @@ -259,6 +260,7 @@ impl CoreManager { let outcome = self.perform_config_update(Some(profiles)).await?; if outcome.is_valid() { crate::config::profiles::restore_selected_nodes().await; + handle::Handle::refresh_clash(); Ok(()) } else { Err(anyhow!("failed to restore previous Core configuration: {outcome}")) @@ -324,7 +326,18 @@ impl CoreManager { /// Commits the applied runtime even if restoring the system proxy subsequently fails. async fn validate_and_apply(&self, transaction: DraftTransaction<'_>) -> Result { - let outcome = self.validate_and_apply_draft().await?; + let runtime = Config::runtime().await; + let original_runtime = runtime.data_arc(); + let outcome = match self.validate_and_apply_draft().await { + Ok(outcome) => outcome, + Err(error) => { + transaction.rollback(); + if !Arc::ptr_eq(&original_runtime, &runtime.data_arc()) { + handle::Handle::refresh_clash(); + } + return Err(error); + } + }; if outcome.is_valid() { transaction.commit(); } diff --git a/src-tauri/src/feat/effects.rs b/src-tauri/src/feat/effects.rs index e273bb8da..e1ac370fb 100644 --- a/src-tauri/src/feat/effects.rs +++ b/src-tauri/src/feat/effects.rs @@ -77,12 +77,12 @@ verge_registry! { enable_bypass_check => NoEffect; enable_dns_settings => NoEffect; profile_dns_settings => NoEffect; - use_default_bypass => NoEffect; + use_default_bypass => [SystemProxy]; system_proxy_bypass => [SystemProxy]; proxy_guard_duration => [SystemProxy]; proxy_auto_config => [SystemProxy]; pac_file_content => [SystemProxy]; - proxy_host => NoEffect; + proxy_host => [SystemProxy]; theme_setting => NoEffect; web_ui_list => NoEffect; clash_core => NoEffect; @@ -173,7 +173,7 @@ mod tests { fn representative_verge_patches_map_to_frozen_effects() { assert_eq!(verge_effects(&IVerge::default()), Effects::new()); - let cases: [(IVerge, &[Effect]); 7] = [ + let cases: [(IVerge, &[Effect]); 9] = [ ( verge_patch(|p| p.verge_mixed_port = Some(27899)), &[Effect::RestartCore], @@ -199,6 +199,14 @@ mod tests { verge_patch(|p| p.system_proxy_bypass = Some("localhost".into())), &[Effect::SystemProxy], ), + ( + verge_patch(|p| p.use_default_bypass = Some(false)), + &[Effect::SystemProxy], + ), + ( + verge_patch(|p| p.proxy_host = Some("localhost".into())), + &[Effect::SystemProxy], + ), ( verge_patch(|p| p.tray_event = Some("show_main_window".into())), &[Effect::TrayClick], diff --git a/src/components/setting/mods/sysproxy-viewer.tsx b/src/components/setting/mods/sysproxy-viewer.tsx index 8c4db006c..e96a96bc4 100644 --- a/src/components/setting/mods/sysproxy-viewer.tsx +++ b/src/components/setting/mods/sysproxy-viewer.tsx @@ -36,23 +36,14 @@ import { useSystemProxyState } from '@/hooks/use-system-proxy-state' import { useVerge } from '@/hooks/use-verge' import { useSystemData } from '@/providers/app-data-context' import { - getAutotemProxy, getEmbeddedServerPort, getNetworkInterfacesInfo, getSystemHostname, - getSystemProxy, - patchVergeConfig, } from '@/services/cmds' -import { mutate } from '@/services/mutate' import { showNotice } from '@/services/notice-service' import { debugLog } from '@/utils/debug' import getSystem from '@/utils/get-system' -const sleep = (ms: number) => - new Promise((resolve) => { - setTimeout(resolve, ms) - }) - const DEFAULT_PAC = `function FindProxyForURL(url, host) { return "PROXY %proxy_host%:%mixed-port%; SOCKS5 %proxy_host%:%mixed-port%; DIRECT;"; }` @@ -345,13 +336,6 @@ export const SysproxyViewer = forwardRef((props, ref) => { patch.proxy_host = proxyHost } - const needResetProxy = - value.pac !== proxy_auto_config || - proxyHost !== proxy_host || - pacContent !== pac_file_content || - value.bypass !== system_proxy_bypass || - value.use_default !== use_default_bypass - Promise.resolve().then(async () => { try { if (Object.keys(patch).length > 0) { @@ -360,36 +344,11 @@ export const SysproxyViewer = forwardRef((props, ref) => { if (Object.keys(patch).length > 0) { await patchVerge(patch) } - setTimeout(async () => { - try { - await invalidateProxyState() - - if (needResetProxy && enabled) { - const [currentSysProxy, currentAutoProxy] = await Promise.all([ - getSystemProxy(), - getAutotemProxy(), - ]) - - const isProxyActive = value.pac - ? currentAutoProxy?.enable - : currentSysProxy?.enable - - if (isProxyActive) { - await mutate( - async () => { - await patchVergeConfig({ enable_system_proxy: false }) - await sleep(50) - await patchVergeConfig({ enable_system_proxy: true }) - }, - { id: 'patch-verge-config', errorNotice: false }, - ) - await invalidateProxyState() - } - } - } catch (err) { - console.warn('代理状态更新失败:', err) - } - }, 50) + try { + await invalidateProxyState() + } catch (err) { + console.warn('代理状态更新失败:', err) + } } catch (err) { console.error('配置保存失败:', err) mutateVerge()