import { useTranslation } from 'react-i18next'; import { Button, Dropdown, Tag, Tooltip } from 'antd'; import { RetweetOutlined, MoreOutlined, EditOutlined, DeleteOutlined, VerticalAlignTopOutlined, ThunderboltOutlined, CheckCircleFilled, CloseCircleFilled, LoadingOutlined, } from '@ant-design/icons'; import { SizeFormatter } from '@/utils'; import { OutboundProtocols as Protocols } from '@/schemas/primitives'; import type { OutboundTestState, OutboundTrafficRow } from '@/hooks/useXraySetting'; import type { OutboundRow } from './outbounds-tab-types'; import { isTesting, isUntestable, outboundAddresses, showSecurity, testResult, trafficFor, } from './outbounds-tab-helpers'; interface OutboundCardListProps { rows: OutboundRow[]; testMode: 'tcp' | 'http'; outboundsTraffic: OutboundTrafficRow[]; outboundTestStates: Record; setFirst: (idx: number) => void; openEdit: (idx: number) => void; onResetTraffic: (tag: string) => void; confirmDelete: (idx: number) => void; onTest: (index: number, mode: string) => void; } export default function OutboundCardList({ rows, testMode, outboundsTraffic, outboundTestStates, setFirst, openEdit, onResetTraffic, confirmDelete, onTest, }: OutboundCardListProps) { const { t } = useTranslation(); if (rows.length === 0) { return
; } return ( <> {rows.map((record, index) => (
{index + 1} {record.tag} {record.protocol} {[Protocols.VMess, Protocols.VLESS, Protocols.Trojan, Protocols.Shadowsocks].includes(record.protocol as never) && ( <> {record.streamSettings?.network} {showSecurity(record.streamSettings?.security) && {record.streamSettings?.security}} )}
0 ? [{ key: 'top', label: , onClick: () => setFirst(index) }] : []), { key: 'edit', label: <> {t('edit')}, onClick: () => openEdit(index) }, { key: 'reset', label: <> {t('pages.inbounds.resetTraffic')}, onClick: () => onResetTraffic(record.tag || '') }, { key: 'del', danger: true, label: <> {t('delete')}, onClick: () => confirmDelete(index) }, ], }} >
{outboundAddresses(record).length > 0 && (
{outboundAddresses(record).map((addr) => ( {addr} ))}
)}
↑ {SizeFormatter.sizeFormat(trafficFor(outboundsTraffic, record).up)} ↓ {SizeFormatter.sizeFormat(trafficFor(outboundsTraffic, record).down)} {testResult(outboundTestStates, index) ? ( {testResult(outboundTestStates, index)!.success ? : } {testResult(outboundTestStates, index)!.success ? {testResult(outboundTestStates, index)!.delay} ms : failed} ) : isTesting(outboundTestStates, index) ? ( ) : null}
))} ); }