diff --git a/src/modules/extensions/builtin/user-center/components/VlessQrCard.tsx b/src/modules/extensions/builtin/user-center/components/VlessQrCard.tsx index c572d5b..7b526eb 100644 --- a/src/modules/extensions/builtin/user-center/components/VlessQrCard.tsx +++ b/src/modules/extensions/builtin/user-center/components/VlessQrCard.tsx @@ -33,15 +33,40 @@ export type VlessQrCopy = { interface VlessQrCardProps { uuid: string | null | undefined copy: VlessQrCopy + defaultTransport?: VlessTransport + visibleTransports?: VlessTransport[] +} + +const DEFAULT_TRANSPORT: VlessTransport = 'xhttp' +const DEFAULT_VISIBLE_TRANSPORTS: VlessTransport[] = ['xhttp'] + +function normalizeVisibleTransports(transports?: VlessTransport[]): VlessTransport[] { + const visible = (transports ?? DEFAULT_VISIBLE_TRANSPORTS).filter( + (transport, index, values) => values.indexOf(transport) === index, + ) + + return visible.length > 0 ? visible : DEFAULT_VISIBLE_TRANSPORTS +} + +function resolveInitialTransport(defaultTransport: VlessTransport | undefined, visibleTransports: VlessTransport[]): VlessTransport { + if (defaultTransport && visibleTransports.includes(defaultTransport)) { + return defaultTransport + } + + return visibleTransports[0] ?? DEFAULT_TRANSPORT } export default function VlessQrCard({ uuid, copy, + defaultTransport, + visibleTransports, }: VlessQrCardProps) { const { data: allNodes, error: nodesError } = useSWR('user-center-agent-nodes', fetchAgentNodes) + const transportOptions = useMemo(() => normalizeVisibleTransports(visibleTransports), [visibleTransports]) + const nodes = useMemo(() => { return (allNodes ?? []).filter((node) => { const name = (node.name || '').toLowerCase() @@ -53,7 +78,9 @@ export default function VlessQrCard({ }) }, [allNodes]) const [selectedNode, setSelectedNode] = useState(null) - const [preferredTransport, setPreferredTransport] = useState('tcp') + const [preferredTransport, setPreferredTransport] = useState(() => + resolveInitialTransport(defaultTransport, transportOptions), + ) const [isSelectorOpen, setIsSelectorOpen] = useState(false) const [qrDataUrl, setQrDataUrl] = useState(null) @@ -61,6 +88,16 @@ export default function VlessQrCard({ const [generationError, setGenerationError] = useState(null) const [copied, setCopied] = useState(false) + useEffect(() => { + setPreferredTransport((currentTransport) => { + if (transportOptions.includes(currentTransport)) { + return currentTransport + } + + return resolveInitialTransport(defaultTransport, transportOptions) + }) + }, [defaultTransport, transportOptions]) + const rawNode = useMemo(() => { if (selectedNode) return selectedNode @@ -238,7 +275,7 @@ export default function VlessQrCard({
- {(['tcp', 'xhttp'] as const).map((transport) => ( + {transportOptions.map((transport) => (