Compare commits

...

3 Commits

Author SHA1 Message Date
ezequielnick
0a969e9e38 fix: incompatible CSS style 2025-08-04 23:04:06 +08:00
ezequielnick
f62b8cff67 1.8.1 Released 2025-08-04 18:49:13 +08:00
ezequielnick
1b7c2ee01e refactor: rewrite DNS control module with override logic 2025-08-04 18:49:13 +08:00
17 changed files with 106 additions and 64 deletions

View File

@ -8,5 +8,7 @@
<true/> <true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key> <key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/> <true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@ -1,28 +1,21 @@
## 1.8.1
### 新功能 (Feat)
- 重构 DNS 控制模块改为“覆写”逻辑当开关打开后使用DNS 设置中的配置覆盖订阅原始配置,关闭开关恢复订阅原始配置
### 性能提升(Perf)
- 更新依赖,提升页面响应性
- 优化订阅切换逻辑,大幅提升切换速度和稳定性
### 修复 (Fix)
- “使用自动 Smart 规则覆写”没有覆盖兜底的 MATCH 规则
- 移除默认的 Smart "policy-priority" 规则
-
## 1.8.0 ## 1.8.0
### 新功能 (Feat) ### 新功能 (Feat)
**重大更新:本次更新增加了 Smart Core可以根据用户使用习惯和节点质量自动选择符合您的最优节点。并内置了“一键开启”适合不想折腾自定义规则的用户 **重大更新:本次更新增加了 Smart Core可以根据用户使用习惯和节点质量自动选择符合您的最优节点。并内置了“一键开启”适合不想折腾自定义规则的用户
“一键开启”内置 Smart规则的功能在“内核设置”下的“使用自动 Smart 规则覆写”,原理:当开关开启后,自动载入覆写脚本,新增 Smart Group并替换当前配置文件下的默认出站规则为"Smart Group",您的所有代理流量都将从此分组下的节点流出。如果使用“全局模式”请选择名称为"Smart Group"的节点,以使用该功能。** “一键开启”内置 Smart规则的功能在“内核设置”下的“使用自动 Smart 规则覆写”,原理:当开关开启后,自动载入覆写脚本,新增 Smart Group并替换当前配置文件下的默认出站规则为"Smart Group",您的所有代理流量都将从此分组下的节点流出。如果使用“全局模式”请选择名称为"Smart Group"的节点,以使用该功能。**
注意:本功能还在测试中,如遇到问题请发 issue 反馈 注意:本功能还在测试中,如遇到问题请发 issue 反馈
## 1.7.7
### 新功能 (Feat)
- Mihomo 内核升级 v1.19.12
- 新增 Webdav 最大备数设置和清理逻辑
### 修复 (Fix)
- 修复 MacOS 下无法启动的问题(重置工作目录权限)
- 尝试修复不同版本 MacOS 下安装软件时候的报错Input/output error
- 部分遗漏的多国语言翻译
## 1.7.6
**此版本修复了 1.7.5 中的几个严重 bug推荐所有人更新**
### 修复 (Fix)
- 修复了内核1.19.8更新后gist同步失效的问题(#780)
- 部分遗漏的多国语言翻译
- MacOS 下启动Error: EACCES: permission denied
- MacOS 系统代理 bypass 不生效
- MacOS 系统代理开启时 500 报错

View File

@ -39,12 +39,14 @@ mac:
target: target:
- pkg - pkg
entitlementsInherit: build/entitlements.mac.plist entitlementsInherit: build/entitlements.mac.plist
hardenedRuntime: true
gatekeeperAssess: false
extendInfo: extendInfo:
- NSCameraUsageDescription: Application requests access to the device's camera. - NSCameraUsageDescription: Application requests access to the device's camera.
- NSMicrophoneUsageDescription: Application requests access to the device's microphone. - NSMicrophoneUsageDescription: Application requests access to the device's microphone.
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
notarize: true notarize: false
artifactName: ${name}-macos-${version}-${arch}.${ext} artifactName: ${name}-macos-${version}-${arch}.${ext}
pkg: pkg:
allowAnywhere: false allowAnywhere: false

View File

@ -1,6 +1,6 @@
{ {
"name": "mihomo-party", "name": "mihomo-party",
"version": "1.8.0", "version": "1.8.1",
"description": "Mihomo Party", "description": "Mihomo Party",
"main": "./out/main/index.js", "main": "./out/main/index.js",
"author": "mihomo-party-org", "author": "mihomo-party-org",

View File

@ -20,15 +20,22 @@ export async function getControledMihomoConfig(force = false): Promise<Partial<I
export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> { export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
const { useNameserverPolicy, controlDns = true, controlSniff = true } = await getAppConfig() const { useNameserverPolicy, controlDns = true, controlSniff = true } = await getAppConfig()
if (!controlDns) {
// DNS 配置覆写逻辑
if (controlDns) {
if (!controledMihomoConfig.dns || controledMihomoConfig.dns?.ipv6 === undefined) {
controledMihomoConfig.dns = { ...defaultControledMihomoConfig.dns }
}
const originalEnable = controledMihomoConfig.dns?.enable
controledMihomoConfig.dns = deepMerge(controledMihomoConfig.dns || {}, defaultControledMihomoConfig.dns || {})
if (originalEnable !== undefined) {
controledMihomoConfig.dns.enable = originalEnable
}
} else {
delete controledMihomoConfig.dns delete controledMihomoConfig.dns
delete controledMihomoConfig.hosts delete controledMihomoConfig.hosts
} else {
// 从不接管状态恢复
if (controledMihomoConfig.dns?.ipv6 === undefined) {
controledMihomoConfig.dns = defaultControledMihomoConfig.dns
}
} }
if (!controlSniff) { if (!controlSniff) {
delete controledMihomoConfig.sniffer delete controledMihomoConfig.sniffer
} else { } else {
@ -37,6 +44,7 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
controledMihomoConfig.sniffer = defaultControledMihomoConfig.sniffer controledMihomoConfig.sniffer = defaultControledMihomoConfig.sniffer
} }
} }
if (patch.hosts) { if (patch.hosts) {
controledMihomoConfig.hosts = patch.hosts controledMihomoConfig.hosts = patch.hosts
} }
@ -44,7 +52,9 @@ export async function patchControledMihomoConfig(patch: Partial<IMihomoConfig>):
controledMihomoConfig.dns = controledMihomoConfig.dns || {} controledMihomoConfig.dns = controledMihomoConfig.dns || {}
controledMihomoConfig.dns['nameserver-policy'] = patch.dns['nameserver-policy'] controledMihomoConfig.dns['nameserver-policy'] = patch.dns['nameserver-policy']
} }
controledMihomoConfig = deepMerge(controledMihomoConfig, patch) controledMihomoConfig = deepMerge(controledMihomoConfig, patch)
if (!useNameserverPolicy) { if (!useNameserverPolicy) {
delete controledMihomoConfig?.dns?.['nameserver-policy'] delete controledMihomoConfig?.dns?.['nameserver-policy']
} }

View File

@ -79,8 +79,10 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
'fake-ip-filter': ['*', '+.lan', '+.local', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com'], 'fake-ip-filter': ['*', '+.lan', '+.local', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com'],
'use-hosts': false, 'use-hosts': false,
'use-system-hosts': false, 'use-system-hosts': false,
nameserver: ['https://120.53.53.53/dns-query', 'https://223.5.5.5/dns-query'], 'respect-rules': false,
'proxy-server-nameserver': ['https://120.53.53.53/dns-query', 'https://223.5.5.5/dns-query'], 'default-nameserver': ['tls://223.5.5.5'],
nameserver: ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
'direct-nameserver': [] 'direct-nameserver': []
}, },
sniffer: { sniffer: {

View File

@ -39,7 +39,7 @@ const ConnectionItem: React.FC<Props> = (props) => {
<Chip <Chip
color={`${info.isActive ? 'primary' : 'danger'}`} color={`${info.isActive ? 'primary' : 'danger'}`}
size="sm" size="sm"
radius="xs" radius="sm"
variant="dot" variant="dot"
> >
{info.metadata.type}({info.metadata.network.toUpperCase()}) {info.metadata.type}({info.metadata.network.toUpperCase()})
@ -65,16 +65,16 @@ const ConnectionItem: React.FC<Props> = (props) => {
<Chip <Chip
className="flag-emoji text-ellipsis whitespace-nowrap overflow-hidden" className="flag-emoji text-ellipsis whitespace-nowrap overflow-hidden"
size="sm" size="sm"
radius="xs" radius="sm"
variant="bordered" variant="bordered"
> >
{info.chains[0]} {info.chains[0]}
</Chip> </Chip>
<Chip size="sm" radius="xs" variant="bordered"> <Chip size="sm" radius="sm" variant="bordered">
{calcTraffic(info.upload)} {calcTraffic(info.download)} {calcTraffic(info.upload)} {calcTraffic(info.download)}
</Chip> </Chip>
{info.uploadSpeed !== 0 || info.downloadSpeed !== 0 ? ( {info.uploadSpeed !== 0 || info.downloadSpeed !== 0 ? (
<Chip color="primary" size="sm" radius="xs" variant="bordered"> <Chip color="primary" size="sm" radius="sm" variant="bordered">
{calcTraffic(info.uploadSpeed || 0)}/s {calcTraffic(info.downloadSpeed || 0)} {calcTraffic(info.uploadSpeed || 0)}/s {calcTraffic(info.downloadSpeed || 0)}
/s /s
</Chip> </Chip>

View File

@ -68,7 +68,7 @@ const ProxyItem: React.FC<Props> = (props) => {
? 'bg-primary/30 border-r-2 border-r-primary border-l-2 border-l-primary' ? 'bg-primary/30 border-r-2 border-r-primary border-l-2 border-l-primary'
: 'bg-content2' : 'bg-content2'
}`} }`}
radius="xs" radius="sm"
> >
<CardBody className="p-1"> <CardBody className="p-1">
{proxyDisplayMode === 'full' ? ( {proxyDisplayMode === 'full' ? (

View File

@ -3,7 +3,7 @@ import { useControledMihomoConfig } from '@renderer/hooks/use-controled-mihomo-c
import BorderSwitch from '@renderer/components/base/border-swtich' import BorderSwitch from '@renderer/components/base/border-swtich'
import { LuServer } from 'react-icons/lu' import { LuServer } from 'react-icons/lu'
import { useLocation, useNavigate } from 'react-router-dom' import { useLocation, useNavigate } from 'react-router-dom'
import { patchMihomoConfig } from '@renderer/utils/ipc' import { restartCore } from '@renderer/utils/ipc'
import { useSortable } from '@dnd-kit/sortable' import { useSortable } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities' import { CSS } from '@dnd-kit/utilities'
import { useAppConfig } from '@renderer/hooks/use-app-config' import { useAppConfig } from '@renderer/hooks/use-app-config'
@ -15,15 +15,14 @@ interface Props {
} }
const DNSCard: React.FC<Props> = (props) => { const DNSCard: React.FC<Props> = (props) => {
const { t } = useTranslation() const { t } = useTranslation()
const { appConfig } = useAppConfig() const { appConfig, patchAppConfig } = useAppConfig()
const { iconOnly } = props const { iconOnly } = props
const { dnsCardStatus = 'col-span-1', controlDns = true } = appConfig || {} const { dnsCardStatus = 'col-span-1', controlDns = true } = appConfig || {}
const location = useLocation() const location = useLocation()
const navigate = useNavigate() const navigate = useNavigate()
const match = location.pathname.includes('/dns') const match = location.pathname.includes('/dns')
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig() const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
const { dns, tun } = controledMihomoConfig || {} const { tun } = controledMihomoConfig || {}
const { enable = true } = dns || {}
const { const {
attributes, attributes,
listeners, listeners,
@ -35,20 +34,33 @@ const DNSCard: React.FC<Props> = (props) => {
id: 'dns' id: 'dns'
}) })
const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null
const onChange = async (enable: boolean): Promise<void> => { const onChange = async (controlDnsEnabled: boolean): Promise<void> => {
await patchControledMihomoConfig({ dns: { enable } }) try {
await patchMihomoConfig({ dns: { enable } }) await patchAppConfig({ controlDns: controlDnsEnabled })
await patchControledMihomoConfig({})
await restartCore()
} catch (e) {
alert(e)
}
} }
if (iconOnly) { if (iconOnly) {
return ( return (
<div className={`${dnsCardStatus} ${!controlDns ? 'hidden' : ''} flex justify-center`}> <div className={`${dnsCardStatus} flex justify-center`}>
<Tooltip content={t('sider.cards.dns')} placement="right"> <Tooltip
content={
controlDns
? `${t('sider.cards.dns')} (${t('sider.cards.dns.overrideMode')})`
: `${t('sider.cards.dns')} (${t('sider.cards.dns.originalConfig')})`
}
placement="right"
>
<Button <Button
size="sm" size="sm"
isIconOnly isIconOnly
color={match ? 'primary' : 'default'} color={match ? 'primary' : 'default'}
variant={match ? 'solid' : 'light'} variant={match ? 'solid' : 'light'}
className={!controlDns ? 'opacity-60' : ''}
onPress={() => { onPress={() => {
navigate('/dns') navigate('/dns')
}} }}
@ -68,14 +80,14 @@ const DNSCard: React.FC<Props> = (props) => {
transition, transition,
zIndex: isDragging ? 'calc(infinity)' : undefined zIndex: isDragging ? 'calc(infinity)' : undefined
}} }}
className={`${dnsCardStatus} ${!controlDns ? 'hidden' : ''} dns-card`} className={`${dnsCardStatus} dns-card`}
> >
<Card <Card
fullWidth fullWidth
ref={setNodeRef} ref={setNodeRef}
{...attributes} {...attributes}
{...listeners} {...listeners}
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''}`} className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''} ${!controlDns ? 'opacity-60' : ''}`}
> >
<CardBody className="pb-1 pt-0 px-0"> <CardBody className="pb-1 pt-0 px-0">
<div className="flex justify-between"> <div className="flex justify-between">
@ -90,8 +102,8 @@ const DNSCard: React.FC<Props> = (props) => {
/> />
</Button> </Button>
<BorderSwitch <BorderSwitch
isShowBorder={match && enable} isShowBorder={match && controlDns}
isSelected={enable} isSelected={controlDns}
isDisabled={tun?.enable} isDisabled={tun?.enable}
onValueChange={onChange} onValueChange={onChange}
/> />

View File

@ -42,13 +42,14 @@ const SniffCard: React.FC<Props> = (props) => {
if (iconOnly) { if (iconOnly) {
return ( return (
<div className={`${sniffCardStatus} ${!controlSniff ? 'hidden' : ''} flex justify-center`}> <div className={`${sniffCardStatus} flex justify-center`}>
<Tooltip content={t('sider.cards.sniff')} placement="right"> <Tooltip content={t('sider.cards.sniff')} placement="right">
<Button <Button
size="sm" size="sm"
isIconOnly isIconOnly
color={match ? 'primary' : 'default'} color={match ? 'primary' : 'default'}
variant={match ? 'solid' : 'light'} variant={match ? 'solid' : 'light'}
className={!enable ? 'opacity-60' : ''}
onPress={() => { onPress={() => {
navigate('/sniffer') navigate('/sniffer')
}} }}
@ -68,14 +69,14 @@ const SniffCard: React.FC<Props> = (props) => {
transition, transition,
zIndex: isDragging ? 'calc(infinity)' : undefined zIndex: isDragging ? 'calc(infinity)' : undefined
}} }}
className={`${sniffCardStatus} ${!controlSniff ? 'hidden' : ''} sniff-card`} className={`${sniffCardStatus} sniff-card`}
> >
<Card <Card
fullWidth fullWidth
ref={setNodeRef} ref={setNodeRef}
{...attributes} {...attributes}
{...listeners} {...listeners}
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''}`} className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''} ${!enable ? 'opacity-60' : ''}`}
> >
<CardBody className="pb-1 pt-0 px-0"> <CardBody className="pb-1 pt-0 px-0">
<div className="flex justify-between"> <div className="flex justify-between">

View File

@ -58,6 +58,7 @@ const SysproxySwitcher: React.FC<Props> = (props) => {
isIconOnly isIconOnly
color={match ? 'primary' : 'default'} color={match ? 'primary' : 'default'}
variant={match ? 'solid' : 'light'} variant={match ? 'solid' : 'light'}
className={!enable ? 'opacity-60' : ''}
onPress={() => { onPress={() => {
navigate('/sysproxy') navigate('/sysproxy')
}} }}
@ -84,7 +85,7 @@ const SysproxySwitcher: React.FC<Props> = (props) => {
ref={setNodeRef} ref={setNodeRef}
{...attributes} {...attributes}
{...listeners} {...listeners}
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''}`} className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''} ${!enable ? 'opacity-60' : ''}`}
> >
<CardBody className="pb-1 pt-0 px-0"> <CardBody className="pb-1 pt-0 px-0">
<div className="flex justify-between"> <div className="flex justify-between">

View File

@ -56,6 +56,7 @@ const TunSwitcher: React.FC<Props> = (props) => {
isIconOnly isIconOnly
color={match ? 'primary' : 'default'} color={match ? 'primary' : 'default'}
variant={match ? 'solid' : 'light'} variant={match ? 'solid' : 'light'}
className={!enable ? 'opacity-60' : ''}
onPress={() => { onPress={() => {
navigate('/tun') navigate('/tun')
}} }}
@ -82,7 +83,7 @@ const TunSwitcher: React.FC<Props> = (props) => {
ref={setNodeRef} ref={setNodeRef}
{...attributes} {...attributes}
{...listeners} {...listeners}
className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''}`} className={`${match ? 'bg-primary' : 'hover:bg-primary/30'} ${isDragging ? 'scale-[0.97] tap-highlight-transparent' : ''} ${!enable ? 'opacity-60' : ''}`}
> >
<CardBody className="pb-1 pt-0 px-0"> <CardBody className="pb-1 pt-0 px-0">
<div className="flex justify-between"> <div className="flex justify-between">

View File

@ -98,7 +98,7 @@
"mihomo.cpuPriority.low": "Low", "mihomo.cpuPriority.low": "Low",
"mihomo.workDir.title": "Separate Work Directory for Different Subscriptions", "mihomo.workDir.title": "Separate Work Directory for Different Subscriptions",
"mihomo.workDir.tooltip": "Enable to avoid conflicts when different subscriptions have proxy groups with the same name", "mihomo.workDir.tooltip": "Enable to avoid conflicts when different subscriptions have proxy groups with the same name",
"mihomo.controlDns": "Control DNS Settings", "mihomo.controlDns": "Override DNS Settings",
"mihomo.controlSniff": "Control Domain Sniffing", "mihomo.controlSniff": "Control Domain Sniffing",
"mihomo.autoCloseConnection": "Auto Close Connection", "mihomo.autoCloseConnection": "Auto Close Connection",
"mihomo.pauseSSID.title": "Direct Connection for Specific WiFi SSIDs", "mihomo.pauseSSID.title": "Direct Connection for Specific WiFi SSIDs",
@ -216,7 +216,9 @@
"sider.cards.override": "Override", "sider.cards.override": "Override",
"sider.cards.connections": "Connections", "sider.cards.connections": "Connections",
"sider.cards.core": "Core Settings", "sider.cards.core": "Core Settings",
"sider.cards.dns": "DNS", "sider.cards.dns": "DNS OVR",
"sider.cards.dns.originalConfig": "Using Original Config",
"sider.cards.dns.overrideMode": "Override Mode",
"sider.cards.sniff": "Sniffing", "sider.cards.sniff": "Sniffing",
"sider.cards.logs": "Logs", "sider.cards.logs": "Logs",
"sider.cards.substore": "Sub-Store", "sider.cards.substore": "Sub-Store",
@ -316,6 +318,7 @@
"tun.notifications.firewallResetSuccess": "Firewall Reset Successful", "tun.notifications.firewallResetSuccess": "Firewall Reset Successful",
"tun.error.tunPermissionDenied": "TUN interface start failed, please try to manually grant core permissions", "tun.error.tunPermissionDenied": "TUN interface start failed, please try to manually grant core permissions",
"dns.title": "DNS Settings", "dns.title": "DNS Settings",
"dns.enable.title": "Enable DNS",
"dns.enhancedMode.title": "Domain Mapping Mode", "dns.enhancedMode.title": "Domain Mapping Mode",
"dns.enhancedMode.fakeIp": "Fake IP", "dns.enhancedMode.fakeIp": "Fake IP",
"dns.enhancedMode.redirHost": "Real IP", "dns.enhancedMode.redirHost": "Real IP",
@ -513,7 +516,7 @@
"guide.override.title": "Override", "guide.override.title": "Override",
"guide.override.description": "Mihomo Party provides powerful override functionality to customize your imported subscription configurations, such as adding rules and customizing proxy groups. You can directly import override files written by others or write your own. <b>Remember to enable the override file on the subscription you want to override</b>. For override file syntax, please refer to the <a href=\"https://mihomo.party/docs/guide/override\" target=\"_blank\">official documentation</a>.", "guide.override.description": "Mihomo Party provides powerful override functionality to customize your imported subscription configurations, such as adding rules and customizing proxy groups. You can directly import override files written by others or write your own. <b>Remember to enable the override file on the subscription you want to override</b>. For override file syntax, please refer to the <a href=\"https://mihomo.party/docs/guide/override\" target=\"_blank\">official documentation</a>.",
"guide.dns.title": "DNS", "guide.dns.title": "DNS",
"guide.dns.description": "The software takes control of the core's DNS settings by default. If you need to use the DNS settings from your subscription configuration, you can disable 'Control DNS Settings' in the application settings. The same applies to domain sniffing.", "guide.dns.description": "The software overrides subscription DNS settings with application DNS settings by default. If you need to use the DNS settings from your subscription configuration, you can disable 'Override DNS Settings' in the application settings. The same applies to domain sniffing.",
"guide.end.title": "Tutorial Complete", "guide.end.title": "Tutorial Complete",
"guide.end.description": "Now that you understand the basic usage of the software, import your subscription and start using it. Enjoy!\nYou can also join our official <a href=\"https://t.me/mihomo_party_group\" target=\"_blank\">Telegram group</a> for the latest news." "guide.end.description": "Now that you understand the basic usage of the software, import your subscription and start using it. Enjoy!\nYou can also join our official <a href=\"https://t.me/mihomo_party_group\" target=\"_blank\">Telegram group</a> for the latest news."
} }

View File

@ -101,7 +101,7 @@
"mihomo.cpuPriority.low": "低", "mihomo.cpuPriority.low": "低",
"mihomo.workDir.title": "不同订阅使用独立工作目录", "mihomo.workDir.title": "不同订阅使用独立工作目录",
"mihomo.workDir.tooltip": "启用后可避免不同订阅中存在相同名称的代理组时发生冲突", "mihomo.workDir.tooltip": "启用后可避免不同订阅中存在相同名称的代理组时发生冲突",
"mihomo.controlDns": "控制 DNS 设置", "mihomo.controlDns": "覆写 DNS 设置",
"mihomo.controlSniff": "控制域名嗅探", "mihomo.controlSniff": "控制域名嗅探",
"mihomo.autoCloseConnection": "自动关闭连接", "mihomo.autoCloseConnection": "自动关闭连接",
"mihomo.pauseSSID.title": "指定 WiFi SSID 直连", "mihomo.pauseSSID.title": "指定 WiFi SSID 直连",
@ -216,7 +216,9 @@
"sider.cards.override": "覆写", "sider.cards.override": "覆写",
"sider.cards.connections": "连接", "sider.cards.connections": "连接",
"sider.cards.core": "内核设置", "sider.cards.core": "内核设置",
"sider.cards.dns": "DNS", "sider.cards.dns": "DNS覆写",
"sider.cards.dns.originalConfig": "使用原始配置",
"sider.cards.dns.overrideMode": "覆写模式",
"sider.cards.sniff": "域名嗅探", "sider.cards.sniff": "域名嗅探",
"sider.cards.logs": "日志", "sider.cards.logs": "日志",
"sider.cards.substore": "Sub-Store", "sider.cards.substore": "Sub-Store",
@ -316,6 +318,7 @@
"tun.notifications.firewallResetSuccess": "防火墙重设成功", "tun.notifications.firewallResetSuccess": "防火墙重设成功",
"tun.error.tunPermissionDenied": "虚拟网卡启动失败,请尝试手动授予内核权限", "tun.error.tunPermissionDenied": "虚拟网卡启动失败,请尝试手动授予内核权限",
"dns.title": "DNS 设置", "dns.title": "DNS 设置",
"dns.enable.title": "启用 DNS",
"dns.enhancedMode.title": "域名映射模式", "dns.enhancedMode.title": "域名映射模式",
"dns.enhancedMode.fakeIp": "虚假 IP", "dns.enhancedMode.fakeIp": "虚假 IP",
"dns.enhancedMode.redirHost": "真实 IP", "dns.enhancedMode.redirHost": "真实 IP",
@ -513,7 +516,7 @@
"guide.override.title": "覆写", "guide.override.title": "覆写",
"guide.override.description": "Mihomo Party 提供强大的覆写功能,可以对您导入的订阅配置进行个性化修改,如添加规则、自定义代理组等,您可以直接导入别人写好的覆写文件,也可以自己动手编写,<b>编辑好覆写文件一定要记得在需要覆写的订阅上启用</b>,覆写文件的语法请参考 <a href=\"https://mihomo.party/docs/guide/override\" target=\"_blank\">官方文档</a>", "guide.override.description": "Mihomo Party 提供强大的覆写功能,可以对您导入的订阅配置进行个性化修改,如添加规则、自定义代理组等,您可以直接导入别人写好的覆写文件,也可以自己动手编写,<b>编辑好覆写文件一定要记得在需要覆写的订阅上启用</b>,覆写文件的语法请参考 <a href=\"https://mihomo.party/docs/guide/override\" target=\"_blank\">官方文档</a>",
"guide.dns.title": "DNS", "guide.dns.title": "DNS",
"guide.dns.description": "软件默认接管了内核的 DNS 设置,如果您需要使用订阅配置中的 DNS 设置,可以到应用设置中关闭\"接管 DNS 设置\",域名嗅探同理", "guide.dns.description": "软件默认使用应用的 DNS 设置覆写订阅配置,如果您需要使用订阅配置中的 DNS 设置,可以到应用设置中关闭\"覆写 DNS 设置\",域名嗅探同理",
"guide.end.title": "教程结束", "guide.end.title": "教程结束",
"guide.end.description": "现在您已经了解了软件的基本用法,导入您的订阅开始使用吧,祝您使用愉快!\n您还可以加入我们的官方 <a href=\"https://t.me/mihomo_party_group\" target=\"_blank\">Telegram 群组</a> 获取最新资讯" "guide.end.description": "现在您已经了解了软件的基本用法,导入您的订阅开始使用吧,祝您使用愉快!\n您还可以加入我们的官方 <a href=\"https://t.me/mihomo_party_group\" target=\"_blank\">Telegram 群组</a> 获取最新资讯"
} }

View File

@ -16,6 +16,7 @@ const DNS: React.FC = () => {
const { nameserverPolicy, useNameserverPolicy } = appConfig || {} const { nameserverPolicy, useNameserverPolicy } = appConfig || {}
const { dns, hosts } = controledMihomoConfig || {} const { dns, hosts } = controledMihomoConfig || {}
const { const {
enable = true,
ipv6 = false, ipv6 = false,
'fake-ip-range': fakeIPRange = '198.18.0.1/16', 'fake-ip-range': fakeIPRange = '198.18.0.1/16',
'fake-ip-filter': fakeIPFilter = [ 'fake-ip-filter': fakeIPFilter = [
@ -40,6 +41,7 @@ const DNS: React.FC = () => {
} = dns || {} } = dns || {}
const [changed, setChanged] = useState(false) const [changed, setChanged] = useState(false)
const [values, originSetValues] = useState({ const [values, originSetValues] = useState({
enable,
ipv6, ipv6,
useHosts, useHosts,
enhancedMode, enhancedMode,
@ -143,6 +145,7 @@ const DNS: React.FC = () => {
color="primary" color="primary"
onPress={() => { onPress={() => {
const dnsConfig = { const dnsConfig = {
enable: values.enable,
ipv6: values.ipv6, ipv6: values.ipv6,
'fake-ip-range': values.fakeIPRange, 'fake-ip-range': values.fakeIPRange,
'fake-ip-filter': values.fakeIPFilter, 'fake-ip-filter': values.fakeIPFilter,
@ -177,6 +180,15 @@ const DNS: React.FC = () => {
} }
> >
<SettingCard> <SettingCard>
<SettingItem title={t('dns.enable.title')} divider>
<Switch
size="sm"
isSelected={values.enable}
onValueChange={(v) => {
setValues({ ...values, enable: v })
}}
/>
</SettingItem>
<SettingItem title={t('dns.enhancedMode.title')} divider> <SettingItem title={t('dns.enhancedMode.title')} divider>
<Tabs <Tabs
size="sm" size="sm"

View File

@ -85,7 +85,7 @@ const Profiles: React.FC = () => {
<div> <div>
{sub.tag?.map((tag) => { {sub.tag?.map((tag) => {
return ( return (
<Chip key={tag} size="sm" className="ml-1" radius="xs"> <Chip key={tag} size="sm" className="ml-1" radius="sm">
{tag} {tag}
</Chip> </Chip>
) )
@ -108,7 +108,7 @@ const Profiles: React.FC = () => {
<div> <div>
{sub.tag?.map((tag) => { {sub.tag?.map((tag) => {
return ( return (
<Chip key={tag} size="sm" className="ml-1" radius="xs"> <Chip key={tag} size="sm" className="ml-1" radius="sm">
{tag} {tag}
</Chip> </Chip>
) )

View File

@ -324,7 +324,7 @@ const Proxies: React.FC = () => {
<Avatar <Avatar
className="bg-transparent mr-2" className="bg-transparent mr-2"
size="sm" size="sm"
radius="xs" radius="sm"
src={ src={
groups[index].icon.startsWith('<svg') groups[index].icon.startsWith('<svg')
? `data:image/svg+xml;utf8,${groups[index].icon}` ? `data:image/svg+xml;utf8,${groups[index].icon}`