mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-04 03:19:34 +00:00
feat(outbounds): pick dialerProxy from other outbound tags for proxy chaining
Turn the outbound sockopt dialerProxy free-text input into a searchable Select populated with the other outbound tags, so users can build a proxy chain (route one outbound through another) without typing tags by hand. The list excludes the current outbound, so self-reference cycles cannot be selected. A tooltip and placeholder explain the chaining concept. Adds dialerProxyPlaceholder and dialerProxyHint to all 13 locales. Closes #4446
This commit is contained in:
@@ -575,7 +575,9 @@ export default function OutboundFormModal({
|
||||
|
||||
{security === 'reality' && realityAllowed && <RealityForm />}
|
||||
|
||||
{((streamAllowed && network) || !streamAllowed) && <SockoptForm form={form} />}
|
||||
{((streamAllowed && network) || !streamAllowed) && (
|
||||
<SockoptForm form={form} outboundTags={existingTags} />
|
||||
)}
|
||||
|
||||
<FinalMaskForm
|
||||
name={['streamSettings', 'finalmask']}
|
||||
|
||||
@@ -7,7 +7,13 @@ import type { OutboundFormValues } from '@/schemas/forms/outbound-form';
|
||||
|
||||
import { ADDRESS_PORT_STRATEGY_OPTIONS } from '../outbound-form-constants';
|
||||
|
||||
export default function SockoptForm({ form }: { form: FormInstance<OutboundFormValues> }) {
|
||||
export default function SockoptForm({
|
||||
form,
|
||||
outboundTags = [],
|
||||
}: {
|
||||
form: FormInstance<OutboundFormValues>;
|
||||
outboundTags?: string[];
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Form.Item shouldUpdate noStyle>
|
||||
@@ -16,6 +22,14 @@ export default function SockoptForm({ form }: { form: FormInstance<OutboundFormV
|
||||
'streamSettings',
|
||||
'sockopt',
|
||||
]);
|
||||
const dialerProxy = (form.getFieldValue([
|
||||
'streamSettings',
|
||||
'sockopt',
|
||||
'dialerProxy',
|
||||
]) ?? '') as string;
|
||||
const dialerProxyOptions = Array.from(
|
||||
new Set([...outboundTags, dialerProxy].filter(Boolean)),
|
||||
).map((tg) => ({ value: tg, label: tg }));
|
||||
return (
|
||||
<>
|
||||
<Form.Item label={t('pages.xray.outboundForm.sockopts')}>
|
||||
@@ -34,8 +48,14 @@ export default function SockoptForm({ form }: { form: FormInstance<OutboundFormV
|
||||
<Form.Item
|
||||
label={t('pages.inbounds.form.dialerProxy')}
|
||||
name={['streamSettings', 'sockopt', 'dialerProxy']}
|
||||
tooltip={t('pages.xray.outboundForm.dialerProxyHint')}
|
||||
>
|
||||
<Input />
|
||||
<Select
|
||||
allowClear
|
||||
showSearch
|
||||
placeholder={t('pages.xray.outboundForm.dialerProxyPlaceholder')}
|
||||
options={dialerProxyOptions}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t('pages.xray.wireguard.domainStrategy')}
|
||||
|
||||
Reference in New Issue
Block a user