refactor: frontend (#5068)
* refactor: setting components * refactor: frontend * fix: settings router
This commit is contained in:
@@ -16,7 +16,14 @@ import { invoke } from "@tauri-apps/api/core";
|
||||
import { useLockFn } from "ahooks";
|
||||
import yaml from "js-yaml";
|
||||
import type { Ref } from "react";
|
||||
import { useEffect, useImperativeHandle, useState } from "react";
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import MonacoEditor from "react-monaco-editor";
|
||||
|
||||
@@ -35,6 +42,91 @@ const Item = styled(ListItem)(() => ({
|
||||
},
|
||||
}));
|
||||
|
||||
type NameserverPolicy = Record<string, any>;
|
||||
|
||||
function parseNameserverPolicy(str: string): NameserverPolicy {
|
||||
const result: NameserverPolicy = {};
|
||||
if (!str) return result;
|
||||
|
||||
const ruleRegex = /\s*([^=]+?)\s*=\s*([^,]+)(?:,|$)/g;
|
||||
let match: RegExpExecArray | null;
|
||||
|
||||
while ((match = ruleRegex.exec(str)) !== null) {
|
||||
const [, domainsPart, serversPart] = match;
|
||||
|
||||
const domains = [domainsPart.trim()];
|
||||
const servers = serversPart.split(";").map((s) => s.trim());
|
||||
|
||||
domains.forEach((domain) => {
|
||||
result[domain] = servers;
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function formatNameserverPolicy(policy: unknown): string {
|
||||
if (!policy || typeof policy !== "object") return "";
|
||||
|
||||
return Object.entries(policy as Record<string, unknown>)
|
||||
.map(([domain, servers]) => {
|
||||
const serversStr = Array.isArray(servers) ? servers.join(";") : servers;
|
||||
return `${domain}=${serversStr}`;
|
||||
})
|
||||
.join(", ");
|
||||
}
|
||||
|
||||
function formatHosts(hosts: unknown): string {
|
||||
if (!hosts || typeof hosts !== "object") return "";
|
||||
|
||||
const result: string[] = [];
|
||||
|
||||
Object.entries(hosts as Record<string, unknown>).forEach(
|
||||
([domain, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
const ipsStr = value.join(";");
|
||||
result.push(`${domain}=${ipsStr}`);
|
||||
} else {
|
||||
result.push(`${domain}=${value}`);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return result.join(", ");
|
||||
}
|
||||
|
||||
function parseHosts(str: string): NameserverPolicy {
|
||||
const result: NameserverPolicy = {};
|
||||
if (!str) return result;
|
||||
|
||||
str.split(",").forEach((item) => {
|
||||
const parts = item.trim().split("=");
|
||||
if (parts.length < 2) return;
|
||||
|
||||
const domain = parts[0].trim();
|
||||
const valueStr = parts.slice(1).join("=").trim();
|
||||
|
||||
if (valueStr.includes(";")) {
|
||||
result[domain] = valueStr
|
||||
.split(";")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
} else {
|
||||
result[domain] = valueStr;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseList(str: string): string[] {
|
||||
if (!str?.trim()) return [];
|
||||
return str
|
||||
.split(",")
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
// 默认DNS配置
|
||||
const DEFAULT_DNS_CONFIG = {
|
||||
enable: true,
|
||||
@@ -95,6 +187,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [visualization, setVisualization] = useState(true);
|
||||
const skipYamlSyncRef = useRef(false);
|
||||
const [values, setValues] = useState<{
|
||||
enable: boolean;
|
||||
listen: string;
|
||||
@@ -150,304 +243,91 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
});
|
||||
|
||||
// 用于YAML编辑模式
|
||||
const [yamlContent, setYamlContent] = useState("");
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => {
|
||||
setOpen(true);
|
||||
// 获取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 [yamlContent, setYamlContent] = useReducer(
|
||||
(_: string, next: string) => next,
|
||||
"",
|
||||
);
|
||||
|
||||
// 从配置对象更新表单值
|
||||
const updateValuesFromConfig = (config: any) => {
|
||||
if (!config) return;
|
||||
const updateValuesFromConfig = useCallback(
|
||||
(config: any) => {
|
||||
if (!config) return;
|
||||
|
||||
// 提取dns配置
|
||||
const dnsConfig = config.dns || {};
|
||||
// 提取hosts配置(与dns同级)
|
||||
const hostsConfig = config.hosts || {};
|
||||
const dnsConfig = config.dns || {};
|
||||
const hostsConfig = config.hosts || {};
|
||||
|
||||
const enhancedMode =
|
||||
dnsConfig["enhanced-mode"] || DEFAULT_DNS_CONFIG["enhanced-mode"];
|
||||
const validEnhancedMode =
|
||||
enhancedMode === "fake-ip" || enhancedMode === "redir-host"
|
||||
? enhancedMode
|
||||
: DEFAULT_DNS_CONFIG["enhanced-mode"];
|
||||
const enhancedMode =
|
||||
dnsConfig["enhanced-mode"] || DEFAULT_DNS_CONFIG["enhanced-mode"];
|
||||
const validEnhancedMode =
|
||||
enhancedMode === "fake-ip" || enhancedMode === "redir-host"
|
||||
? enhancedMode
|
||||
: DEFAULT_DNS_CONFIG["enhanced-mode"];
|
||||
|
||||
const fakeIpFilterMode =
|
||||
dnsConfig["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"];
|
||||
const fakeIpFilterMode =
|
||||
dnsConfig["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: dnsConfig.enable ?? DEFAULT_DNS_CONFIG.enable,
|
||||
listen: dnsConfig.listen ?? DEFAULT_DNS_CONFIG.listen,
|
||||
enhancedMode: validEnhancedMode,
|
||||
fakeIpRange:
|
||||
dnsConfig["fake-ip-range"] ?? DEFAULT_DNS_CONFIG["fake-ip-range"],
|
||||
fakeIpFilterMode: validFakeIpFilterMode,
|
||||
preferH3: dnsConfig["prefer-h3"] ?? DEFAULT_DNS_CONFIG["prefer-h3"],
|
||||
respectRules:
|
||||
dnsConfig["respect-rules"] ?? DEFAULT_DNS_CONFIG["respect-rules"],
|
||||
useHosts: dnsConfig["use-hosts"] ?? DEFAULT_DNS_CONFIG["use-hosts"],
|
||||
useSystemHosts:
|
||||
dnsConfig["use-system-hosts"] ?? DEFAULT_DNS_CONFIG["use-system-hosts"],
|
||||
ipv6: dnsConfig.ipv6 ?? DEFAULT_DNS_CONFIG.ipv6,
|
||||
fakeIpFilter:
|
||||
dnsConfig["fake-ip-filter"]?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fake-ip-filter"].join(", "),
|
||||
nameserver:
|
||||
dnsConfig.nameserver?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG.nameserver.join(", "),
|
||||
fallback:
|
||||
dnsConfig.fallback?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG.fallback.join(", "),
|
||||
defaultNameserver:
|
||||
dnsConfig["default-nameserver"]?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["default-nameserver"].join(", "),
|
||||
proxyServerNameserver:
|
||||
dnsConfig["proxy-server-nameserver"]?.join(", ") ??
|
||||
(DEFAULT_DNS_CONFIG["proxy-server-nameserver"]?.join(", ") || ""),
|
||||
directNameserver:
|
||||
dnsConfig["direct-nameserver"]?.join(", ") ??
|
||||
(DEFAULT_DNS_CONFIG["direct-nameserver"]?.join(", ") || ""),
|
||||
directNameserverFollowPolicy:
|
||||
dnsConfig["direct-nameserver-follow-policy"] ??
|
||||
DEFAULT_DNS_CONFIG["direct-nameserver-follow-policy"],
|
||||
fallbackGeoip:
|
||||
dnsConfig["fallback-filter"]?.geoip ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].geoip,
|
||||
fallbackGeoipCode:
|
||||
dnsConfig["fallback-filter"]?.["geoip-code"] ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"]["geoip-code"],
|
||||
fallbackIpcidr:
|
||||
dnsConfig["fallback-filter"]?.ipcidr?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].ipcidr.join(", "),
|
||||
fallbackDomain:
|
||||
dnsConfig["fallback-filter"]?.domain?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].domain.join(", "),
|
||||
nameserverPolicy:
|
||||
formatNameserverPolicy(dnsConfig["nameserver-policy"]) || "",
|
||||
hosts: formatHosts(hostsConfig) || "",
|
||||
});
|
||||
};
|
||||
|
||||
// 重置为默认值
|
||||
const resetToDefaults = () => {
|
||||
setValues({
|
||||
enable: DEFAULT_DNS_CONFIG.enable,
|
||||
listen: DEFAULT_DNS_CONFIG.listen,
|
||||
enhancedMode: DEFAULT_DNS_CONFIG["enhanced-mode"],
|
||||
fakeIpRange: DEFAULT_DNS_CONFIG["fake-ip-range"],
|
||||
fakeIpFilterMode: DEFAULT_DNS_CONFIG["fake-ip-filter-mode"],
|
||||
preferH3: DEFAULT_DNS_CONFIG["prefer-h3"],
|
||||
respectRules: DEFAULT_DNS_CONFIG["respect-rules"],
|
||||
useHosts: DEFAULT_DNS_CONFIG["use-hosts"],
|
||||
useSystemHosts: DEFAULT_DNS_CONFIG["use-system-hosts"],
|
||||
ipv6: DEFAULT_DNS_CONFIG.ipv6,
|
||||
fakeIpFilter: DEFAULT_DNS_CONFIG["fake-ip-filter"].join(", "),
|
||||
defaultNameserver: DEFAULT_DNS_CONFIG["default-nameserver"].join(", "),
|
||||
nameserver: DEFAULT_DNS_CONFIG.nameserver.join(", "),
|
||||
fallback: DEFAULT_DNS_CONFIG.fallback.join(", "),
|
||||
proxyServerNameserver:
|
||||
DEFAULT_DNS_CONFIG["proxy-server-nameserver"]?.join(", ") || "",
|
||||
directNameserver:
|
||||
DEFAULT_DNS_CONFIG["direct-nameserver"]?.join(", ") || "",
|
||||
directNameserverFollowPolicy:
|
||||
DEFAULT_DNS_CONFIG["direct-nameserver-follow-policy"] || false,
|
||||
fallbackGeoip: DEFAULT_DNS_CONFIG["fallback-filter"].geoip,
|
||||
fallbackGeoipCode: DEFAULT_DNS_CONFIG["fallback-filter"]["geoip-code"],
|
||||
fallbackIpcidr:
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].ipcidr?.join(", ") || "",
|
||||
fallbackDomain:
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].domain?.join(", ") || "",
|
||||
nameserverPolicy: "",
|
||||
hosts: "",
|
||||
});
|
||||
|
||||
// 更新YAML编辑器内容
|
||||
updateYamlFromValues();
|
||||
};
|
||||
|
||||
// 从表单值更新YAML内容
|
||||
const updateYamlFromValues = () => {
|
||||
const config: Record<string, any> = {};
|
||||
|
||||
const dnsConfig = generateDnsConfig();
|
||||
if (Object.keys(dnsConfig).length > 0) {
|
||||
config.dns = dnsConfig;
|
||||
}
|
||||
|
||||
const hosts = parseHosts(values.hosts);
|
||||
if (Object.keys(hosts).length > 0) {
|
||||
config.hosts = hosts;
|
||||
}
|
||||
|
||||
setYamlContent(yaml.dump(config, { forceQuotes: true }));
|
||||
};
|
||||
|
||||
// 从YAML更新表单值
|
||||
const updateValuesFromYaml = () => {
|
||||
try {
|
||||
const parsedYaml = yaml.load(yamlContent) as any;
|
||||
if (!parsedYaml) return;
|
||||
|
||||
updateValuesFromConfig(parsedYaml);
|
||||
} catch {
|
||||
showNotice("error", t("Invalid YAML format"));
|
||||
}
|
||||
};
|
||||
|
||||
// 解析nameserver-policy为对象
|
||||
const parseNameserverPolicy = (str: string): Record<string, any> => {
|
||||
const result: Record<string, any> = {};
|
||||
if (!str) return result;
|
||||
|
||||
// 处理geosite:xxx,yyy格式
|
||||
const ruleRegex = /\s*([^=]+?)\s*=\s*([^,]+)(?:,|$)/g;
|
||||
let match;
|
||||
|
||||
while ((match = ruleRegex.exec(str)) !== null) {
|
||||
const [, domainsPart, serversPart] = match;
|
||||
|
||||
// 处理域名部分
|
||||
let domains;
|
||||
if (domainsPart.startsWith("geosite:")) {
|
||||
domains = [domainsPart.trim()];
|
||||
} else {
|
||||
domains = [domainsPart.trim()];
|
||||
}
|
||||
|
||||
// 处理服务器部分
|
||||
const servers = serversPart.split(";").map((s) => s.trim());
|
||||
|
||||
// 为每个域名组分配相同的服务器列表
|
||||
domains.forEach((domain) => {
|
||||
result[domain] = servers;
|
||||
setValues({
|
||||
enable: dnsConfig.enable ?? DEFAULT_DNS_CONFIG.enable,
|
||||
listen: dnsConfig.listen ?? DEFAULT_DNS_CONFIG.listen,
|
||||
enhancedMode: validEnhancedMode,
|
||||
fakeIpRange:
|
||||
dnsConfig["fake-ip-range"] ?? DEFAULT_DNS_CONFIG["fake-ip-range"],
|
||||
fakeIpFilterMode: validFakeIpFilterMode,
|
||||
preferH3: dnsConfig["prefer-h3"] ?? DEFAULT_DNS_CONFIG["prefer-h3"],
|
||||
respectRules:
|
||||
dnsConfig["respect-rules"] ?? DEFAULT_DNS_CONFIG["respect-rules"],
|
||||
useHosts: dnsConfig["use-hosts"] ?? DEFAULT_DNS_CONFIG["use-hosts"],
|
||||
useSystemHosts:
|
||||
dnsConfig["use-system-hosts"] ??
|
||||
DEFAULT_DNS_CONFIG["use-system-hosts"],
|
||||
ipv6: dnsConfig.ipv6 ?? DEFAULT_DNS_CONFIG.ipv6,
|
||||
fakeIpFilter:
|
||||
dnsConfig["fake-ip-filter"]?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fake-ip-filter"].join(", "),
|
||||
nameserver:
|
||||
dnsConfig.nameserver?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG.nameserver.join(", "),
|
||||
fallback:
|
||||
dnsConfig.fallback?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG.fallback.join(", "),
|
||||
defaultNameserver:
|
||||
dnsConfig["default-nameserver"]?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["default-nameserver"].join(", "),
|
||||
proxyServerNameserver:
|
||||
dnsConfig["proxy-server-nameserver"]?.join(", ") ??
|
||||
(DEFAULT_DNS_CONFIG["proxy-server-nameserver"]?.join(", ") || ""),
|
||||
directNameserver:
|
||||
dnsConfig["direct-nameserver"]?.join(", ") ??
|
||||
(DEFAULT_DNS_CONFIG["direct-nameserver"]?.join(", ") || ""),
|
||||
directNameserverFollowPolicy:
|
||||
dnsConfig["direct-nameserver-follow-policy"] ??
|
||||
DEFAULT_DNS_CONFIG["direct-nameserver-follow-policy"],
|
||||
fallbackGeoip:
|
||||
dnsConfig["fallback-filter"]?.geoip ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].geoip,
|
||||
fallbackGeoipCode:
|
||||
dnsConfig["fallback-filter"]?.["geoip-code"] ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"]["geoip-code"],
|
||||
fallbackIpcidr:
|
||||
dnsConfig["fallback-filter"]?.ipcidr?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].ipcidr.join(", "),
|
||||
fallbackDomain:
|
||||
dnsConfig["fallback-filter"]?.domain?.join(", ") ??
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].domain.join(", "),
|
||||
nameserverPolicy:
|
||||
formatNameserverPolicy(dnsConfig["nameserver-policy"]) || "",
|
||||
hosts: formatHosts(hostsConfig) || "",
|
||||
});
|
||||
}
|
||||
},
|
||||
[setValues],
|
||||
);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// 格式化nameserver-policy为字符串
|
||||
const formatNameserverPolicy = (policy: any): string => {
|
||||
if (!policy || typeof policy !== "object") return "";
|
||||
|
||||
// 直接将对象转换为字符串格式
|
||||
return Object.entries(policy)
|
||||
.map(([domain, servers]) => {
|
||||
const serversStr = Array.isArray(servers) ? servers.join(";") : servers;
|
||||
return `${domain}=${serversStr}`;
|
||||
})
|
||||
.join(", ");
|
||||
};
|
||||
|
||||
// 格式化hosts为字符串
|
||||
const formatHosts = (hosts: any): string => {
|
||||
if (!hosts || typeof hosts !== "object") return "";
|
||||
|
||||
const result: string[] = [];
|
||||
|
||||
Object.entries(hosts).forEach(([domain, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
// 处理数组格式的IP
|
||||
const ipsStr = value.join(";");
|
||||
result.push(`${domain}=${ipsStr}`);
|
||||
} else {
|
||||
// 处理单个IP或域名
|
||||
result.push(`${domain}=${value}`);
|
||||
}
|
||||
});
|
||||
|
||||
return result.join(", ");
|
||||
};
|
||||
|
||||
// 解析hosts字符串为对象
|
||||
const parseHosts = (str: string): Record<string, any> => {
|
||||
const result: Record<string, any> = {};
|
||||
if (!str) return result;
|
||||
|
||||
str.split(",").forEach((item) => {
|
||||
const parts = item.trim().split("=");
|
||||
if (parts.length < 2) return;
|
||||
|
||||
const domain = parts[0].trim();
|
||||
const valueStr = parts.slice(1).join("=").trim();
|
||||
|
||||
// 检查是否包含多个分号分隔的IP
|
||||
if (valueStr.includes(";")) {
|
||||
result[domain] = valueStr
|
||||
.split(";")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
} else {
|
||||
result[domain] = valueStr;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// 初始化时设置默认YAML
|
||||
useEffect(() => {
|
||||
updateYamlFromValues();
|
||||
}, []);
|
||||
|
||||
// 切换编辑模式时的处理
|
||||
useEffect(() => {
|
||||
if (visualization) {
|
||||
updateValuesFromYaml();
|
||||
} else {
|
||||
updateYamlFromValues();
|
||||
}
|
||||
}, [visualization]);
|
||||
|
||||
// 解析列表字符串为数组
|
||||
const parseList = (str: string): string[] => {
|
||||
if (!str?.trim()) return [];
|
||||
return str
|
||||
.split(",")
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean);
|
||||
};
|
||||
|
||||
// 生成DNS配置对象
|
||||
const generateDnsConfig = () => {
|
||||
const generateDnsConfig = useCallback(() => {
|
||||
const dnsConfig: any = {
|
||||
enable: values.enable,
|
||||
listen: values.listen,
|
||||
@@ -481,8 +361,132 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
}
|
||||
|
||||
return dnsConfig;
|
||||
};
|
||||
}, [values]);
|
||||
|
||||
const updateYamlFromValues = useCallback(() => {
|
||||
const config: Record<string, any> = {};
|
||||
|
||||
const dnsConfig = generateDnsConfig();
|
||||
if (Object.keys(dnsConfig).length > 0) {
|
||||
config.dns = dnsConfig;
|
||||
}
|
||||
|
||||
const hosts = parseHosts(values.hosts);
|
||||
if (Object.keys(hosts).length > 0) {
|
||||
config.hosts = hosts;
|
||||
}
|
||||
|
||||
setYamlContent(yaml.dump(config, { forceQuotes: true }));
|
||||
}, [generateDnsConfig, setYamlContent, values.hosts]);
|
||||
|
||||
// 重置为默认值
|
||||
const resetToDefaults = useCallback(() => {
|
||||
setValues({
|
||||
enable: DEFAULT_DNS_CONFIG.enable,
|
||||
listen: DEFAULT_DNS_CONFIG.listen,
|
||||
enhancedMode: DEFAULT_DNS_CONFIG["enhanced-mode"],
|
||||
fakeIpRange: DEFAULT_DNS_CONFIG["fake-ip-range"],
|
||||
fakeIpFilterMode: DEFAULT_DNS_CONFIG["fake-ip-filter-mode"],
|
||||
preferH3: DEFAULT_DNS_CONFIG["prefer-h3"],
|
||||
respectRules: DEFAULT_DNS_CONFIG["respect-rules"],
|
||||
useHosts: DEFAULT_DNS_CONFIG["use-hosts"],
|
||||
useSystemHosts: DEFAULT_DNS_CONFIG["use-system-hosts"],
|
||||
ipv6: DEFAULT_DNS_CONFIG.ipv6,
|
||||
fakeIpFilter: DEFAULT_DNS_CONFIG["fake-ip-filter"].join(", "),
|
||||
defaultNameserver: DEFAULT_DNS_CONFIG["default-nameserver"].join(", "),
|
||||
nameserver: DEFAULT_DNS_CONFIG.nameserver.join(", "),
|
||||
fallback: DEFAULT_DNS_CONFIG.fallback.join(", "),
|
||||
proxyServerNameserver:
|
||||
DEFAULT_DNS_CONFIG["proxy-server-nameserver"]?.join(", ") || "",
|
||||
directNameserver:
|
||||
DEFAULT_DNS_CONFIG["direct-nameserver"]?.join(", ") || "",
|
||||
directNameserverFollowPolicy:
|
||||
DEFAULT_DNS_CONFIG["direct-nameserver-follow-policy"] || false,
|
||||
fallbackGeoip: DEFAULT_DNS_CONFIG["fallback-filter"].geoip,
|
||||
fallbackGeoipCode: DEFAULT_DNS_CONFIG["fallback-filter"]["geoip-code"],
|
||||
fallbackIpcidr:
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].ipcidr?.join(", ") || "",
|
||||
fallbackDomain:
|
||||
DEFAULT_DNS_CONFIG["fallback-filter"].domain?.join(", ") || "",
|
||||
nameserverPolicy: "",
|
||||
hosts: "",
|
||||
});
|
||||
|
||||
updateYamlFromValues();
|
||||
}, [setValues, updateYamlFromValues]);
|
||||
|
||||
// 从YAML更新表单值
|
||||
const updateValuesFromYaml = useCallback(() => {
|
||||
try {
|
||||
const parsedYaml = yaml.load(yamlContent) as any;
|
||||
if (!parsedYaml) return;
|
||||
|
||||
skipYamlSyncRef.current = true;
|
||||
updateValuesFromConfig(parsedYaml);
|
||||
} catch {
|
||||
showNotice("error", t("Invalid YAML format"));
|
||||
}
|
||||
}, [yamlContent, t, updateValuesFromConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (skipYamlSyncRef.current) {
|
||||
skipYamlSyncRef.current = false;
|
||||
return;
|
||||
}
|
||||
updateYamlFromValues();
|
||||
}, [updateYamlFromValues]);
|
||||
|
||||
const latestUpdateValuesFromYamlRef = useRef(updateValuesFromYaml);
|
||||
const latestUpdateYamlFromValuesRef = useRef(updateYamlFromValues);
|
||||
|
||||
useEffect(() => {
|
||||
latestUpdateValuesFromYamlRef.current = updateValuesFromYaml;
|
||||
latestUpdateYamlFromValuesRef.current = updateYamlFromValues;
|
||||
}, [updateValuesFromYaml, updateYamlFromValues]);
|
||||
|
||||
useEffect(() => {
|
||||
if (visualization) {
|
||||
latestUpdateValuesFromYamlRef.current();
|
||||
} else {
|
||||
latestUpdateYamlFromValuesRef.current();
|
||||
}
|
||||
}, [visualization]);
|
||||
|
||||
const initDnsConfig = useCallback(async () => {
|
||||
try {
|
||||
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);
|
||||
setYamlContent(dnsConfig);
|
||||
} else {
|
||||
resetToDefaults();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to initialize DNS config", err);
|
||||
resetToDefaults();
|
||||
}
|
||||
}, [resetToDefaults, setYamlContent, updateValuesFromConfig]);
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
open: () => {
|
||||
setOpen(true);
|
||||
void initDnsConfig();
|
||||
},
|
||||
close: () => setOpen(false),
|
||||
}),
|
||||
[initDnsConfig],
|
||||
);
|
||||
|
||||
// 生成DNS配置对象
|
||||
// 处理保存操作
|
||||
const onSave = useLockFn(async () => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user