refactor: restructure DNS setting logic
This commit is contained in:
@@ -22,6 +22,7 @@ import yaml from "js-yaml";
|
||||
import MonacoEditor from "react-monaco-editor";
|
||||
import { useThemeMode } from "@/services/states";
|
||||
import getSystem from "@/utils/get-system";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
const Item = styled(ListItem)(({ theme }) => ({
|
||||
padding: "8px 0",
|
||||
@@ -145,11 +146,109 @@ export const DnsViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => {
|
||||
setOpen(true);
|
||||
resetToDefaults();
|
||||
// 获取DNS配置文件并初始化表单
|
||||
initDnsConfig();
|
||||
},
|
||||
close: () => setOpen(false),
|
||||
}));
|
||||
|
||||
// 初始化DNS配置
|
||||
const initDnsConfig = async () => {
|
||||
try {
|
||||
// 尝试从dns_config.yaml文件读取配置
|
||||
const dnsConfigExists = await invoke<boolean>(
|
||||
"check_dns_config_exists",
|
||||
{},
|
||||
);
|
||||
|
||||
if (dnsConfigExists) {
|
||||
// 如果存在配置文件,加载其内容
|
||||
const dnsConfig = await invoke<string>("get_dns_config_content", {});
|
||||
const config = yaml.load(dnsConfig) as any;
|
||||
|
||||
// 更新表单数据
|
||||
updateValuesFromConfig(config);
|
||||
// 更新YAML编辑器内容
|
||||
setYamlContent(dnsConfig);
|
||||
} else {
|
||||
// 如果不存在配置文件,使用默认值
|
||||
resetToDefaults();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to initialize DNS config", err);
|
||||
resetToDefaults();
|
||||
}
|
||||
};
|
||||
|
||||
// 从配置对象更新表单值
|
||||
const updateValuesFromConfig = (config: any) => {
|
||||
if (!config) return;
|
||||
|
||||
const enhancedMode =
|
||||
config["enhanced-mode"] || DEFAULT_DNS_CONFIG["enhanced-mode"];
|
||||
const validEnhancedMode =
|
||||
enhancedMode === "fake-ip" || enhancedMode === "redir-host"
|
||||
? enhancedMode
|
||||
: DEFAULT_DNS_CONFIG["enhanced-mode"];
|
||||
|
||||
const fakeIpFilterMode =
|
||||
config["fake-ip-filter-mode"] ||
|
||||
DEFAULT_DNS_CONFIG["fake-ip-filter-mode"];
|
||||
const validFakeIpFilterMode =
|
||||
fakeIpFilterMode === "blacklist" || fakeIpFilterMode === "whitelist"
|
||||
? fakeIpFilterMode
|
||||
: DEFAULT_DNS_CONFIG["fake-ip-filter-mode"];
|
||||
|
||||
setValues({
|
||||
enable: config.enable ?? DEFAULT_DNS_CONFIG.enable,
|
||||
listen: config.listen ?? DEFAULT_DNS_CONFIG.listen,
|
||||
enhancedMode: validEnhancedMode,
|
||||
fakeIpRange:
|
||||
config["fake-ip-range"] ?? DEFAULT_DNS_CONFIG["fake-ip-range"],
|
||||
fakeIpFilterMode: validFakeIpFilterMode,
|
||||
preferH3: config["prefer-h3"] ?? DEFAULT_DNS_CONFIG["prefer-h3"],
|
||||
respectRules:
|
||||
config["respect-rules"] ?? DEFAULT_DNS_CONFIG["respect-rules"],
|
||||
fakeIpFilter:
|
||||
config["fake-ip-filter"]?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fake-ip-filter"].join(", "),
|
||||
nameserver:
|
||||
config.nameserver?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG.nameserver.join(", "),
|
||||
fallback:
|
||||
config.fallback?.join(", ") ?? DEFAULT_DNS_CONFIG.fallback.join(", "),
|
||||
defaultNameserver:
|
||||
config["default-nameserver"]?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["default-nameserver"].join(", "),
|
||||
useHosts: config["use-hosts"] ?? DEFAULT_DNS_CONFIG["use-hosts"],
|
||||
useSystemHosts:
|
||||
config["use-system-hosts"] ?? DEFAULT_DNS_CONFIG["use-system-hosts"],
|
||||
proxyServerNameserver:
|
||||
config["proxy-server-nameserver"]?.join(", ") ??
|
||||
(DEFAULT_DNS_CONFIG["proxy-server-nameserver"]?.join(", ") || ""),
|
||||
directNameserver:
|
||||
config["direct-nameserver"]?.join(", ") ??
|
||||
(DEFAULT_DNS_CONFIG["direct-nameserver"]?.join(", ") || ""),
|
||||
directNameserverFollowPolicy:
|
||||
config["direct-nameserver-follow-policy"] ??
|
||||
DEFAULT_DNS_CONFIG["direct-nameserver-follow-policy"],
|
||||
fallbackGeoip:
|
||||
config["fallback-filter"]?.geoip ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].geoip,
|
||||
fallbackGeoipCode:
|
||||
config["fallback-filter"]?.["geoip-code"] ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"]["geoip-code"],
|
||||
fallbackIpcidr:
|
||||
config["fallback-filter"]?.ipcidr?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].ipcidr.join(", "),
|
||||
fallbackDomain:
|
||||
config["fallback-filter"]?.domain?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].domain.join(", "),
|
||||
nameserverPolicy:
|
||||
formatNameserverPolicy(config["nameserver-policy"]) || "",
|
||||
});
|
||||
};
|
||||
|
||||
// 重置为默认值
|
||||
const resetToDefaults = () => {
|
||||
setValues({
|
||||
@@ -396,6 +495,7 @@ export const DnsViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
return dnsConfig;
|
||||
};
|
||||
|
||||
// 处理保存操作
|
||||
const onSave = useLockFn(async () => {
|
||||
try {
|
||||
let dnsConfig;
|
||||
@@ -412,8 +512,15 @@ export const DnsViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
dnsConfig = parsedConfig;
|
||||
}
|
||||
|
||||
await patchClash({ dns: dnsConfig });
|
||||
mutateClash();
|
||||
// 不直接应用到clash配置,而是保存到单独文件
|
||||
await invoke("save_dns_config", { dnsConfig });
|
||||
|
||||
// 如果DNS开关当前是打开的,则需要应用新的DNS配置
|
||||
if (clash?.dns?.enable) {
|
||||
await invoke("apply_dns_config", { apply: true });
|
||||
mutateClash(); // 刷新UI
|
||||
}
|
||||
|
||||
setOpen(false);
|
||||
Notice.success(t("DNS settings saved"));
|
||||
} catch (err: any) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useRef } from "react";
|
||||
import { useRef, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TextField, Select, MenuItem, Typography } from "@mui/material";
|
||||
import {
|
||||
@@ -22,6 +22,9 @@ import { updateGeoData } from "@/services/api";
|
||||
import { TooltipIcon } from "@/components/base/base-tooltip-icon";
|
||||
import { NetworkInterfaceViewer } from "./mods/network-interface-viewer";
|
||||
import { DnsViewer } from "./mods/dns-viewer";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { useLockFn } from "ahooks";
|
||||
import { useListen } from "@/hooks/use-listen";
|
||||
|
||||
const isWIN = getSystem() === "windows";
|
||||
|
||||
@@ -45,6 +48,10 @@ const SettingClash = ({ onError }: Props) => {
|
||||
|
||||
const { enable_random_port = false, verge_mixed_port } = verge ?? {};
|
||||
|
||||
// 独立跟踪DNS设置开关状态
|
||||
const [dnsSettingsEnabled, setDnsSettingsEnabled] = useState(false);
|
||||
const { addListener } = useListen();
|
||||
|
||||
const webRef = useRef<DialogRef>(null);
|
||||
const portRef = useRef<DialogRef>(null);
|
||||
const ctrlRef = useRef<DialogRef>(null);
|
||||
@@ -52,6 +59,12 @@ const SettingClash = ({ onError }: Props) => {
|
||||
const networkRef = useRef<DialogRef>(null);
|
||||
const dnsRef = useRef<DialogRef>(null);
|
||||
|
||||
// 初始化时从verge配置中加载DNS设置开关状态
|
||||
useEffect(() => {
|
||||
const dnsSettingsState = verge?.enable_dns_settings ?? false;
|
||||
setDnsSettingsEnabled(dnsSettingsState);
|
||||
}, [verge]);
|
||||
|
||||
const onSwitchFormat = (_e: any, value: boolean) => value;
|
||||
const onChangeData = (patch: Partial<IConfigData>) => {
|
||||
mutateClash((old) => ({ ...(old! || {}), ...patch }), false);
|
||||
@@ -68,6 +81,25 @@ const SettingClash = ({ onError }: Props) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 实现DNS设置开关处理函数
|
||||
const handleDnsToggle = useLockFn(async (enable: boolean) => {
|
||||
try {
|
||||
setDnsSettingsEnabled(enable);
|
||||
await patchVerge({ enable_dns_settings: enable });
|
||||
await invoke("apply_dns_config", { apply: enable });
|
||||
setTimeout(() => {
|
||||
mutateClash();
|
||||
}, 500); // 延迟500ms确保后端完成处理
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
setDnsSettingsEnabled(!enable);
|
||||
await patchVerge({ enable_dns_settings: !enable }).catch(() => {
|
||||
// 忽略恢复状态时的错误
|
||||
});
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<SettingList title={t("Clash Setting")}>
|
||||
<WebUIViewer ref={webRef} />
|
||||
@@ -111,16 +143,12 @@ const SettingClash = ({ onError }: Props) => {
|
||||
/>
|
||||
}
|
||||
>
|
||||
<GuardState
|
||||
value={dns?.enable ?? false}
|
||||
valueProps="checked"
|
||||
onCatch={onError}
|
||||
onFormat={onSwitchFormat}
|
||||
onChange={(e) => onChangeData({ dns: { ...dns, enable: e } })}
|
||||
onGuard={(e) => patchClash({ dns: { enable: e } })}
|
||||
>
|
||||
<Switch edge="end" />
|
||||
</GuardState>
|
||||
{/* 使用独立状态,不再依赖dns?.enable */}
|
||||
<Switch
|
||||
edge="end"
|
||||
checked={dnsSettingsEnabled}
|
||||
onChange={(_, checked) => handleDnsToggle(checked)}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem label={t("IPv6")}>
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
"Test URL": "测试地址",
|
||||
"Settings": "设置",
|
||||
"System Setting": "系统设置",
|
||||
"Tun Mode": "TUN(虚拟网卡)模式",
|
||||
"Tun Mode": "TUN(虚拟网卡)模式",
|
||||
"TUN requires Service Mode": "TUN 模式需要服务",
|
||||
"Install Service": "安装服务",
|
||||
"Reset to Default": "重置为默认值",
|
||||
@@ -502,6 +502,5 @@
|
||||
"Fallback IP CIDR": "回退 IP CIDR",
|
||||
"IP CIDRs not using fallback servers": "不使用回退服务器的 IP CIDR,用逗号分隔",
|
||||
"Fallback Domain": "回退域名",
|
||||
"Domains using fallback servers": "使用回退服务器的域名,用逗号分隔",
|
||||
"Fallback Geosite": "回退 Geosite"
|
||||
"Domains using fallback servers": "使用回退服务器的域名,用逗号分隔"
|
||||
}
|
||||
|
||||
1
src/services/types.d.ts
vendored
1
src/services/types.d.ts
vendored
@@ -739,6 +739,7 @@ interface IVergeConfig {
|
||||
enable_silent_start?: boolean;
|
||||
enable_system_proxy?: boolean;
|
||||
enable_global_hotkey?: boolean;
|
||||
enable_dns_settings?: boolean;
|
||||
proxy_auto_config?: boolean;
|
||||
pac_file_content?: string;
|
||||
enable_random_port?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user