SniffingFields.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { useTranslation } from 'react-i18next';
  2. import { Form, Select, Switch } from 'antd';
  3. import type { FormInstance } from 'antd/es/form';
  4. import { SNIFFING_OPTION } from '@/schemas/primitives';
  5. const DEST_OPTIONS = Object.entries(SNIFFING_OPTION).map(([label, value]) => ({ value, label }));
  6. export interface SniffingFieldsProps {
  7. // Base path to the sniffing object in the form, e.g. ['sniffing'] (inbound),
  8. // ['settings', 'reverseSniffing'] (VLESS reverse), ['settings', 'sniffing']
  9. // (loopback). All sub-fields hang off this path.
  10. name: (string | number)[];
  11. form: FormInstance;
  12. // Label for the enable toggle — Enable / Reverse Sniffing / Sniffing differ
  13. // per host.
  14. enableLabel: string;
  15. }
  16. // Shared sniffing form fragment used everywhere the panel edits an xray
  17. // SniffingConfig: the inbound Sniffing tab, VLESS reverse sniffing, and the
  18. // loopback outbound. Renders the enable toggle plus the destOverride /
  19. // metadataOnly / routeOnly / excluded fields when enabled.
  20. export default function SniffingFields({ name, form, enableLabel }: SniffingFieldsProps) {
  21. const { t } = useTranslation();
  22. const enabled = Form.useWatch([...name, 'enabled'], form) ?? false;
  23. return (
  24. <>
  25. <Form.Item label={enableLabel} name={[...name, 'enabled']} valuePropName="checked">
  26. <Switch />
  27. </Form.Item>
  28. {enabled && (
  29. <>
  30. <Form.Item name={[...name, 'destOverride']} wrapperCol={{ md: { span: 14, offset: 8 } }}>
  31. <Select mode="multiple" className="sniffing-options" options={DEST_OPTIONS} />
  32. </Form.Item>
  33. <Form.Item
  34. label={t('pages.inbounds.sniffingMetadataOnly')}
  35. name={[...name, 'metadataOnly']}
  36. valuePropName="checked"
  37. >
  38. <Switch />
  39. </Form.Item>
  40. <Form.Item
  41. label={t('pages.inbounds.sniffingRouteOnly')}
  42. name={[...name, 'routeOnly']}
  43. valuePropName="checked"
  44. >
  45. <Switch />
  46. </Form.Item>
  47. <Form.Item label={t('pages.inbounds.sniffingIpsExcluded')} name={[...name, 'ipsExcluded']}>
  48. <Select mode="tags" tokenSeparators={[',']} placeholder="IP/CIDR/geoip:*/ext:*" style={{ width: '100%' }} />
  49. </Form.Item>
  50. <Form.Item label={t('pages.inbounds.sniffingDomainsExcluded')} name={[...name, 'domainsExcluded']}>
  51. <Select mode="tags" tokenSeparators={[',']} placeholder="domain:*/ext:*" style={{ width: '100%' }} />
  52. </Form.Item>
  53. </>
  54. )}
  55. </>
  56. );
  57. }