fix(web): show subscription outbounds in dialer proxy dropdown (#5540)

The outbound edit form's Dialer Proxy dropdown only listed local outbounds because subscriptionOutboundTags never reached OutboundsTab. Thread it through XrayPage and feed a dedicated dialerProxyTags list (local non-blackhole outbounds plus subscription tags, excluding the outbound being edited) to SockoptForm. Tag-uniqueness validation still uses the full local tag set, so the blackhole outbound is hidden only from the dropdown, matching HostSockoptForm.
This commit is contained in:
MHSanaei
2026-06-24 22:35:39 +02:00
parent fe025e8af3
commit e2d25d0ac7
3 changed files with 20 additions and 1 deletions
+1
View File
@@ -221,6 +221,7 @@ export default function XrayPage() {
testingAll={testingAll} testingAll={testingAll}
inboundTags={inboundTags} inboundTags={inboundTags}
subscriptionOutbounds={subscriptionOutbounds} subscriptionOutbounds={subscriptionOutbounds}
subscriptionOutboundTags={subscriptionOutboundTags}
isMobile={isMobile} isMobile={isMobile}
onResetTraffic={resetOutboundsTraffic} onResetTraffic={resetOutboundsTraffic}
onTest={onTestOutbound} onTest={onTestOutbound}
@@ -83,6 +83,7 @@ interface OutboundFormModalProps {
open: boolean; open: boolean;
outbound: Record<string, unknown> | null; outbound: Record<string, unknown> | null;
existingTags: string[]; existingTags: string[];
dialerProxyTags?: string[];
onClose: () => void; onClose: () => void;
onConfirm: (outbound: Record<string, unknown>) => void; onConfirm: (outbound: Record<string, unknown>) => void;
} }
@@ -92,6 +93,7 @@ export default function OutboundFormModal({
open, open,
outbound: outboundProp, outbound: outboundProp,
existingTags, existingTags,
dialerProxyTags,
onClose, onClose,
onConfirm, onConfirm,
}: OutboundFormModalProps) { }: OutboundFormModalProps) {
@@ -514,7 +516,7 @@ export default function OutboundFormModal({
{security === 'reality' && realityAllowed && <RealityForm />} {security === 'reality' && realityAllowed && <RealityForm />}
{((streamAllowed && network) || !streamAllowed || protocol === 'wireguard') && ( {((streamAllowed && network) || !streamAllowed || protocol === 'wireguard') && (
<SockoptForm form={form} outboundTags={existingTags} /> <SockoptForm form={form} outboundTags={dialerProxyTags ?? existingTags} />
)} )}
<FinalMaskForm <FinalMaskForm
@@ -75,6 +75,7 @@ interface OutboundsTabProps {
testingAll: boolean; testingAll: boolean;
inboundTags: string[]; inboundTags: string[];
subscriptionOutbounds?: unknown[]; subscriptionOutbounds?: unknown[];
subscriptionOutboundTags?: string[];
isMobile: boolean; isMobile: boolean;
onResetTraffic: (tag: string) => void; onResetTraffic: (tag: string) => void;
onTest: (index: number, mode: string) => void; onTest: (index: number, mode: string) => void;
@@ -94,6 +95,7 @@ export default function OutboundsTab({
testingAll, testingAll,
inboundTags: _inboundTags, inboundTags: _inboundTags,
subscriptionOutbounds, subscriptionOutbounds,
subscriptionOutboundTags,
isMobile, isMobile,
onResetTraffic, onResetTraffic,
onTest, onTest,
@@ -140,6 +142,19 @@ export default function OutboundsTab({
const rows = useMemo(() => outbounds.map((o, i) => ({ ...o, key: i })), [outbounds]); const rows = useMemo(() => outbounds.map((o, i) => ({ ...o, key: i })), [outbounds]);
const dialerProxyTags = useMemo(() => {
const tags = new Set<string>();
(templateSettings?.outbounds || []).forEach((o, i) => {
if (i === editingIndex) return;
if (o?.protocol === 'blackhole') return;
if (o?.tag) tags.add(o.tag);
});
for (const tag of subscriptionOutboundTags || []) {
if (tag) tags.add(tag);
}
return [...tags];
}, [templateSettings?.outbounds, editingIndex, subscriptionOutboundTags]);
const mutate = useCallback( const mutate = useCallback(
(mutator: (next: XraySettingsValue) => void) => { (mutator: (next: XraySettingsValue) => void) => {
setTemplateSettings((prev) => { setTemplateSettings((prev) => {
@@ -521,6 +536,7 @@ export default function OutboundsTab({
open={modalOpen} open={modalOpen}
outbound={editingOutbound} outbound={editingOutbound}
existingTags={existingTags} existingTags={existingTags}
dialerProxyTags={dialerProxyTags}
onClose={() => setModalOpen(false)} onClose={() => setModalOpen(false)}
onConfirm={onConfirm} onConfirm={onConfirm}
/> />