|
@@ -128,6 +128,26 @@ export default function DnsTab({ templateSettings, setTemplateSettings }: DnsTab
|
|
|
return list.map((server, idx) => ({ key: idx, server }));
|
|
return list.map((server, idx) => ({ key: idx, server }));
|
|
|
}, [dns?.servers]);
|
|
}, [dns?.servers]);
|
|
|
|
|
|
|
|
|
|
+ // Stable callbacks: the column definitions in useDnsServerColumns are
|
|
|
|
|
+ // memoized, so they must be able to depend on these (see issue #5155)
|
|
|
|
|
+ const openEditServer = useCallback(
|
|
|
|
|
+ (idx: number) => {
|
|
|
|
|
+ setEditingServer((dns?.servers || [])[idx] || null);
|
|
|
|
|
+ setEditingIndex(idx);
|
|
|
|
|
+ setServerModalOpen(true);
|
|
|
|
|
+ },
|
|
|
|
|
+ [dns?.servers],
|
|
|
|
|
+ );
|
|
|
|
|
+ const deleteServer = useCallback(
|
|
|
|
|
+ (idx: number) => {
|
|
|
|
|
+ mutate((tt) => {
|
|
|
|
|
+ const cfg = tt.dns as DnsConfig | undefined;
|
|
|
|
|
+ if (cfg?.servers) cfg.servers.splice(idx, 1);
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ [mutate],
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
const dnsColumns = useDnsServerColumns({ openEditServer, deleteServer });
|
|
const dnsColumns = useDnsServerColumns({ openEditServer, deleteServer });
|
|
|
|
|
|
|
|
function openAddServer() {
|
|
function openAddServer() {
|
|
@@ -135,11 +155,6 @@ export default function DnsTab({ templateSettings, setTemplateSettings }: DnsTab
|
|
|
setEditingIndex(null);
|
|
setEditingIndex(null);
|
|
|
setServerModalOpen(true);
|
|
setServerModalOpen(true);
|
|
|
}
|
|
}
|
|
|
- function openEditServer(idx: number) {
|
|
|
|
|
- setEditingServer((dns?.servers || [])[idx] || null);
|
|
|
|
|
- setEditingIndex(idx);
|
|
|
|
|
- setServerModalOpen(true);
|
|
|
|
|
- }
|
|
|
|
|
function onServerConfirm(value: DnsServerValue) {
|
|
function onServerConfirm(value: DnsServerValue) {
|
|
|
mutate((tt) => {
|
|
mutate((tt) => {
|
|
|
if (!tt.dns) return;
|
|
if (!tt.dns) return;
|
|
@@ -150,12 +165,6 @@ export default function DnsTab({ templateSettings, setTemplateSettings }: DnsTab
|
|
|
});
|
|
});
|
|
|
setServerModalOpen(false);
|
|
setServerModalOpen(false);
|
|
|
}
|
|
}
|
|
|
- function deleteServer(idx: number) {
|
|
|
|
|
- mutate((tt) => {
|
|
|
|
|
- const cfg = tt.dns as DnsConfig | undefined;
|
|
|
|
|
- if (cfg?.servers) cfg.servers.splice(idx, 1);
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
function clearAllServers() {
|
|
function clearAllServers() {
|
|
|
modal.confirm({
|
|
modal.confirm({
|
|
|
title: t('pages.xray.dns.clearAllTitle'),
|
|
title: t('pages.xray.dns.clearAllTitle'),
|
|
@@ -182,6 +191,28 @@ export default function DnsTab({ templateSettings, setTemplateSettings }: DnsTab
|
|
|
return list.map((entry, idx) => ({ key: idx, ...entry }));
|
|
return list.map((entry, idx) => ({ key: idx, ...entry }));
|
|
|
}, [templateSettings?.fakedns]);
|
|
}, [templateSettings?.fakedns]);
|
|
|
|
|
|
|
|
|
|
+ const deleteFakedns = useCallback(
|
|
|
|
|
+ (idx: number) => {
|
|
|
|
|
+ mutate((tt) => {
|
|
|
|
|
+ const list = tt.fakedns as FakednsRow[] | undefined;
|
|
|
|
|
+ if (!list) return;
|
|
|
|
|
+ list.splice(idx, 1);
|
|
|
|
|
+ if (list.length === 0) tt.fakedns = null;
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ [mutate],
|
|
|
|
|
+ );
|
|
|
|
|
+ const updateFakednsField = useCallback(
|
|
|
|
|
+ (idx: number, field: 'ipPool' | 'poolSize', value: string | number) => {
|
|
|
|
|
+ mutate((tt) => {
|
|
|
|
|
+ const list = tt.fakedns as FakednsRow[] | undefined;
|
|
|
|
|
+ if (!list?.[idx]) return;
|
|
|
|
|
+ (list[idx] as unknown as Record<string, unknown>)[field] = value;
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ [mutate],
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
const fakednsColumns = useFakednsColumns({ deleteFakedns, updateFakednsField });
|
|
const fakednsColumns = useFakednsColumns({ deleteFakedns, updateFakednsField });
|
|
|
|
|
|
|
|
function addFakedns() {
|
|
function addFakedns() {
|
|
@@ -190,21 +221,6 @@ export default function DnsTab({ templateSettings, setTemplateSettings }: DnsTab
|
|
|
(tt.fakedns as FakednsRow[]).push(DEFAULT_FAKEDNS());
|
|
(tt.fakedns as FakednsRow[]).push(DEFAULT_FAKEDNS());
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
- function deleteFakedns(idx: number) {
|
|
|
|
|
- mutate((tt) => {
|
|
|
|
|
- const list = tt.fakedns as FakednsRow[] | undefined;
|
|
|
|
|
- if (!list) return;
|
|
|
|
|
- list.splice(idx, 1);
|
|
|
|
|
- if (list.length === 0) tt.fakedns = null;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- function updateFakednsField(idx: number, field: 'ipPool' | 'poolSize', value: string | number) {
|
|
|
|
|
- mutate((tt) => {
|
|
|
|
|
- const list = tt.fakedns as FakednsRow[] | undefined;
|
|
|
|
|
- if (!list?.[idx]) return;
|
|
|
|
|
- (list[idx] as unknown as Record<string, unknown>)[field] = value;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
const items = useMemo(() => {
|
|
const items = useMemo(() => {
|
|
|
const out = [
|
|
const out = [
|