mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-30 18:52:12 +08:00
feat(dns): remember override state per profile
Save the DNS override switch and session confirmation per profile so automatic protection only disables the affected profile. Preserve the legacy switch as the initial preference and show the profile scope beside the settings gear and in the DNS editor. Refs #7993
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { RestartAltRounded } from '@mui/icons-material'
|
||||
import {
|
||||
Alert,
|
||||
Box,
|
||||
Button,
|
||||
FormControl,
|
||||
@@ -33,6 +34,7 @@ import {
|
||||
Switch,
|
||||
} from '@/components/base'
|
||||
import { useClash } from '@/hooks/use-clash'
|
||||
import { useProfiles } from '@/hooks/use-profiles'
|
||||
import { useVerge } from '@/hooks/use-verge'
|
||||
import { showNotice } from '@/services/notice-service'
|
||||
import { useThemeMode } from '@/services/states'
|
||||
@@ -186,6 +188,12 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
const { t } = useTranslation()
|
||||
const { mutateClash } = useClash()
|
||||
const { verge } = useVerge()
|
||||
const { current: currentProfile } = useProfiles()
|
||||
const dnsEnabled = currentProfile
|
||||
? (verge?.profile_dns_settings?.[currentProfile.uid]?.enabled ??
|
||||
verge?.enable_dns_settings ??
|
||||
false)
|
||||
: false
|
||||
const themeMode = useThemeMode()
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
@@ -550,7 +558,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
return
|
||||
}
|
||||
|
||||
if (verge?.enable_dns_settings) {
|
||||
if (dnsEnabled) {
|
||||
await invoke('apply_dns_config', { apply: true })
|
||||
mutateClash()
|
||||
}
|
||||
@@ -638,6 +646,9 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
|
||||
onCancel={() => setOpen(false)}
|
||||
onOk={onSave}
|
||||
>
|
||||
<Alert severity="info" sx={{ mb: 2 }}>
|
||||
{t('settings.modals.dns.dialog.profileScope')}
|
||||
</Alert>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="warning.main"
|
||||
|
||||
@@ -9,6 +9,7 @@ import { BaseDialog, DialogRef, Switch, TooltipIcon } from '@/components/base'
|
||||
import { useClash } from '@/hooks/use-clash'
|
||||
import { useClashLog } from '@/hooks/use-clash-log'
|
||||
import { useDisplayedMixedPort } from '@/hooks/use-displayed-mixed-port'
|
||||
import { useProfiles } from '@/hooks/use-profiles'
|
||||
import { useVerge } from '@/hooks/use-verge'
|
||||
import { invoke_uwp_tool, setDnsOverride } from '@/services/cmds'
|
||||
import { showNotice } from '@/services/notice-service'
|
||||
@@ -36,6 +37,12 @@ const SettingClash = ({ onError }: Props) => {
|
||||
|
||||
const { clash, version, mutateClash, patchClash } = useClash()
|
||||
const { verge, mutateVerge } = useVerge()
|
||||
const { current: currentProfile } = useProfiles()
|
||||
const dnsEnabled = currentProfile
|
||||
? (verge?.profile_dns_settings?.[currentProfile.uid]?.enabled ??
|
||||
verge?.enable_dns_settings ??
|
||||
false)
|
||||
: false
|
||||
const displayedMixedPort = useDisplayedMixedPort()
|
||||
const [, setClashLog] = useClashLog()
|
||||
|
||||
@@ -46,7 +53,10 @@ const SettingClash = ({ onError }: Props) => {
|
||||
'unified-delay': unifiedDelay,
|
||||
} = clash ?? {}
|
||||
|
||||
const [dnsConfirmation, setDnsConfirmation] = useState<string | null>(null)
|
||||
const [dnsConfirmation, setDnsConfirmation] = useState<{
|
||||
profileUid: string
|
||||
source: string
|
||||
} | null>(null)
|
||||
const [dnsUpdating, setDnsUpdating] = useState(false)
|
||||
|
||||
const webRef = useRef<DialogRef>(null)
|
||||
@@ -72,12 +82,17 @@ const SettingClash = ({ onError }: Props) => {
|
||||
}
|
||||
|
||||
const handleDnsToggle = useLockFn(
|
||||
async (enable: boolean, confirmation?: string) => {
|
||||
async (
|
||||
enable: boolean,
|
||||
confirmation?: string,
|
||||
profileUid = currentProfile?.uid,
|
||||
) => {
|
||||
if (!profileUid) return
|
||||
setDnsUpdating(true)
|
||||
try {
|
||||
const outcome = await setDnsOverride(enable, confirmation)
|
||||
const outcome = await setDnsOverride(profileUid, enable, confirmation)
|
||||
if (outcome.status === 'confirmation_required') {
|
||||
setDnsConfirmation(outcome.source)
|
||||
setDnsConfirmation({ profileUid, source: outcome.source })
|
||||
} else {
|
||||
setDnsConfirmation(null)
|
||||
}
|
||||
@@ -114,7 +129,12 @@ const SettingClash = ({ onError }: Props) => {
|
||||
onCancel={closeDnsConfirmation}
|
||||
onClose={closeDnsConfirmation}
|
||||
onOk={() => {
|
||||
if (dnsConfirmation) void handleDnsToggle(true, dnsConfirmation)
|
||||
if (dnsConfirmation)
|
||||
void handleDnsToggle(
|
||||
true,
|
||||
dnsConfirmation.source,
|
||||
dnsConfirmation.profileUid,
|
||||
)
|
||||
}}
|
||||
>
|
||||
<Typography variant="body2">
|
||||
@@ -151,16 +171,22 @@ const SettingClash = ({ onError }: Props) => {
|
||||
<SettingItem
|
||||
label={t('settings.sections.clash.form.fields.dnsOverwrite')}
|
||||
extra={
|
||||
<TooltipIcon
|
||||
icon={SettingsRounded}
|
||||
onClick={() => dnsRef.current?.open()}
|
||||
/>
|
||||
<>
|
||||
<TooltipIcon
|
||||
icon={SettingsRounded}
|
||||
onClick={() => dnsRef.current?.open()}
|
||||
/>
|
||||
<TooltipIcon
|
||||
title={t('settings.modals.dns.dialog.profileScope')}
|
||||
sx={{ opacity: '0.7' }}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
edge="end"
|
||||
checked={verge?.enable_dns_settings ?? false}
|
||||
disabled={dnsUpdating || dnsConfirmation !== null}
|
||||
checked={dnsEnabled}
|
||||
disabled={!currentProfile || dnsUpdating || dnsConfirmation !== null}
|
||||
onChange={(_, checked) => handleDnsToggle(checked)}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS Overwrite",
|
||||
"profileScope": "تُحفظ حالة مفتاح تجاوز DNS بشكل مستقل لكل ملف تعريف، وتُطبَّق على ذلك الملف فقط.",
|
||||
"warning": "If you are not familiar with these settings, please do not modify them and keep DNS Overwrite disabled"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS-Überschreibung",
|
||||
"profileScope": "Der DNS-Überschreibungsschalter wird für jedes Profil separat gespeichert und gilt nur für dieses Profil.",
|
||||
"warning": "Wenn Sie sich nicht mit diesen Einstellungen auskennen, ändern Sie sie nicht und lassen Sie die DNS-Überschreibung deaktiviert."
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS Overwrite",
|
||||
"profileScope": "The DNS override switch is saved separately for each profile and applies only to that profile.",
|
||||
"warning": "If you are not familiar with these settings, please do not modify them and keep DNS Overwrite disabled"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "Sobrescritura de DNS",
|
||||
"profileScope": "El estado del interruptor de sobrescritura de DNS se guarda por separado para cada perfil y solo se aplica a ese perfil.",
|
||||
"warning": "Si no está seguro de cómo configurar esto, no realice cambios y mantenga deshabilitada la sobrescritura de DNS."
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "بازنویسی DNS",
|
||||
"profileScope": "وضعیت کلید بازنویسی DNS برای هر پروفایل جداگانه ذخیره میشود و فقط بر همان پروفایل اعمال میشود.",
|
||||
"warning": "اگر با این تنظیمات آشنا نیستید، لطفاً آنها را تغییر ندهید و DNS Overwrite را غیرفعال نگه دارید."
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS Overwrite",
|
||||
"profileScope": "Status sakelar penimpaan DNS disimpan secara terpisah untuk setiap profil dan hanya berlaku untuk profil tersebut.",
|
||||
"warning": "If you are not familiar with these settings, please do not modify them and keep DNS Overwrite disabled"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS上書き",
|
||||
"profileScope": "DNS 上書きスイッチの状態はプロファイルごとに保存され、そのプロファイルにのみ適用されます。",
|
||||
"warning": "ここの設定がわからない場合は、変更しないでください。DNS上書きを無効にしたままにしてください。"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS 덮어쓰기",
|
||||
"profileScope": "DNS 덮어쓰기 스위치 상태는 프로필별로 저장되며 해당 프로필에만 적용됩니다.",
|
||||
"warning": "이 설정에 익숙하지 않다면 수정하지 말고 DNS 덮어쓰기를 비활성화 상태로 유지하세요"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "Переопределение настроек DNS",
|
||||
"profileScope": "Состояние переключателя переопределения DNS сохраняется отдельно для каждого профиля и действует только для него.",
|
||||
"warning": "Если вы не знакомы с этими настройками, пожалуйста, не изменяйте их и оставьте переопределение DNS отключённым"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS Üzerine Yazma",
|
||||
"profileScope": "DNS geçersiz kılma anahtarının durumu her profil için ayrı kaydedilir ve yalnızca o profile uygulanır.",
|
||||
"warning": "Bu ayarlarla ilgili bilginiz yoksa, lütfen bunları değiştirmeyin ve DNS Üzerine Yazma'yı devre dışı tutun"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS Overwrite",
|
||||
"profileScope": "DNS көйләүләрен алыштыру күчергеченең хәле һәр профиль өчен аерым саклана һәм шул профильгә генә кагыла.",
|
||||
"warning": "If you are not familiar with these settings, please do not modify them and keep DNS Overwrite disabled"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS 覆写",
|
||||
"profileScope": "DNS 覆写开关按订阅独立保存,仅对对应订阅生效。",
|
||||
"warning": "如果你不清楚这里的设置请不要修改,并保持 DNS 覆写关闭"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
"dns": {
|
||||
"dialog": {
|
||||
"title": "DNS 覆寫",
|
||||
"profileScope": "DNS 覆寫開關依訂閱分別儲存,僅對對應訂閱生效。",
|
||||
"warning": "如果你不清楚這裡的設定請不要修改,並保持 DNS 覆寫關閉"
|
||||
},
|
||||
"protection": {
|
||||
|
||||
@@ -172,10 +172,14 @@ export async function patchVergeConfig(payload: IVergeConfig) {
|
||||
return invoke<void>('patch_verge_config', { payload })
|
||||
}
|
||||
|
||||
export async function setDnsOverride(enabled: boolean, confirmation?: string) {
|
||||
export async function setDnsOverride(
|
||||
profileUid: string,
|
||||
enabled: boolean,
|
||||
confirmation?: string,
|
||||
) {
|
||||
return invoke<
|
||||
{ status: 'applied' } | { status: 'confirmation_required'; source: string }
|
||||
>('set_dns_override', { enabled, confirmation })
|
||||
>('set_dns_override', { profileUid, enabled, confirmation })
|
||||
}
|
||||
|
||||
export async function takeDnsOverrideNotice() {
|
||||
|
||||
@@ -699,6 +699,7 @@ export const translationKeys = [
|
||||
'settings.modals.tun.messages.invalidRouteExcludeAddress',
|
||||
'settings.modals.tun.messages.routeExcludeAddressHint',
|
||||
'settings.modals.dns.dialog.title',
|
||||
'settings.modals.dns.dialog.profileScope',
|
||||
'settings.modals.dns.dialog.warning',
|
||||
'settings.modals.dns.protection.title',
|
||||
'settings.modals.dns.protection.message',
|
||||
|
||||
@@ -955,6 +955,7 @@ export interface TranslationResources {
|
||||
}
|
||||
dns: {
|
||||
dialog: {
|
||||
profileScope: string
|
||||
title: string
|
||||
warning: string
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -890,6 +890,7 @@ interface IVergeConfig {
|
||||
enable_system_proxy?: boolean
|
||||
enable_global_hotkey?: boolean
|
||||
enable_dns_settings?: boolean
|
||||
profile_dns_settings?: Record<string, { enabled: boolean }>
|
||||
proxy_auto_config?: boolean
|
||||
pac_file_content?: string
|
||||
proxy_host?: string
|
||||
|
||||
Reference in New Issue
Block a user