import type { ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import { Button, Form, Input, InputNumber, Select, Space, Switch } from 'antd'; import { DeleteOutlined, PlusOutlined, ReloadOutlined } from '@ant-design/icons'; import { ALPN_OPTION, UTLS_FINGERPRINT } from '@/schemas/primitives'; import './external-proxy.css'; const newEntry = () => ({ forceTls: 'same', dest: '', port: 443, remark: '', sni: '', fingerprint: '', alpn: [], pinnedPeerCertSha256: [], echConfigList: '', }); function Field({ label, children }: { label: ReactNode; children: ReactNode }) { return (
{label} {children}
); } export default function ExternalProxyForm({ toggleExternalProxy, }: { toggleExternalProxy: (on: boolean) => void; }) { const { t } = useTranslation(); const form = Form.useFormInstance(); const generateRandomPin = (name: number) => { const bytes = new Uint8Array(32); crypto.getRandomValues(bytes); const hash = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join(''); const path = ['streamSettings', 'externalProxy', name, 'pinnedPeerCertSha256']; const current = (form.getFieldValue(path) as string[] | undefined) ?? []; form.setFieldValue(path, [...current, hash]); }; return ( { const a = (prev.streamSettings as { externalProxy?: unknown[] } | undefined)?.externalProxy; const b = (curr.streamSettings as { externalProxy?: unknown[] } | undefined)?.externalProxy; return (Array.isArray(a) ? a.length : 0) !== (Array.isArray(b) ? b.length : 0); }} > {({ getFieldValue }) => { const arr = getFieldValue(['streamSettings', 'externalProxy']); const on = Array.isArray(arr) && arr.length > 0; return ( <> {on && ( {(fields, { add, remove }) => ( <>
{fields.map((field, idx) => (
#{idx + 1}
prev.streamSettings?.externalProxy?.[field.name]?.forceTls !== curr.streamSettings?.externalProxy?.[field.name]?.forceTls } > {({ getFieldValue }) => { const ft = getFieldValue([ 'streamSettings', 'externalProxy', field.name, 'forceTls', ]); if (ft !== 'tls') return null; return (
({ value: a, label: a, }))} />