Browse Source

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.
MHSanaei 13 giờ trước cách đây
mục cha
commit
e2d25d0ac7

+ 1 - 0
frontend/src/pages/xray/XrayPage.tsx

@@ -221,6 +221,7 @@ export default function XrayPage() {
             testingAll={testingAll}
             inboundTags={inboundTags}
             subscriptionOutbounds={subscriptionOutbounds}
+            subscriptionOutboundTags={subscriptionOutboundTags}
             isMobile={isMobile}
             onResetTraffic={resetOutboundsTraffic}
             onTest={onTestOutbound}

+ 3 - 1
frontend/src/pages/xray/outbounds/OutboundFormModal.tsx

@@ -83,6 +83,7 @@ interface OutboundFormModalProps {
   open: boolean;
   outbound: Record<string, unknown> | null;
   existingTags: string[];
+  dialerProxyTags?: string[];
   onClose: () => void;
   onConfirm: (outbound: Record<string, unknown>) => void;
 }
@@ -92,6 +93,7 @@ export default function OutboundFormModal({
   open,
   outbound: outboundProp,
   existingTags,
+  dialerProxyTags,
   onClose,
   onConfirm,
 }: OutboundFormModalProps) {
@@ -514,7 +516,7 @@ export default function OutboundFormModal({
                     {security === 'reality' && realityAllowed && <RealityForm />}
 
                     {((streamAllowed && network) || !streamAllowed || protocol === 'wireguard') && (
-                      <SockoptForm form={form} outboundTags={existingTags} />
+                      <SockoptForm form={form} outboundTags={dialerProxyTags ?? existingTags} />
                     )}
 
                     <FinalMaskForm

+ 16 - 0
frontend/src/pages/xray/outbounds/OutboundsTab.tsx

@@ -75,6 +75,7 @@ interface OutboundsTabProps {
   testingAll: boolean;
   inboundTags: string[];
   subscriptionOutbounds?: unknown[];
+  subscriptionOutboundTags?: string[];
   isMobile: boolean;
   onResetTraffic: (tag: string) => void;
   onTest: (index: number, mode: string) => void;
@@ -94,6 +95,7 @@ export default function OutboundsTab({
   testingAll,
   inboundTags: _inboundTags,
   subscriptionOutbounds,
+  subscriptionOutboundTags,
   isMobile,
   onResetTraffic,
   onTest,
@@ -140,6 +142,19 @@ export default function OutboundsTab({
 
   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(
     (mutator: (next: XraySettingsValue) => void) => {
       setTemplateSettings((prev) => {
@@ -521,6 +536,7 @@ export default function OutboundsTab({
           open={modalOpen}
           outbound={editingOutbound}
           existingTags={existingTags}
+          dialerProxyTags={dialerProxyTags}
           onClose={() => setModalOpen(false)}
           onConfirm={onConfirm}
         />