SubJsonFinalMaskForm.tsx 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { useEffect, useRef, useState } from 'react';
  2. import { Form } from 'antd';
  3. import { FinalMaskForm } from '@/lib/xray/forms/transport';
  4. import type { FinalMaskStreamSettings } from '@/schemas/protocols/stream/finalmask';
  5. interface SubJsonFinalMaskFormProps {
  6. value: string;
  7. onChange: (next: string) => void;
  8. }
  9. function hasValue(v: unknown): boolean {
  10. if (v == null) return false;
  11. if (Array.isArray(v)) return v.some(hasValue);
  12. if (typeof v === 'object') return Object.values(v as Record<string, unknown>).some(hasValue);
  13. if (typeof v === 'string') return v.length > 0;
  14. return true;
  15. }
  16. function parseFinalMask(raw: string): FinalMaskStreamSettings {
  17. try {
  18. if (raw) return JSON.parse(raw) as FinalMaskStreamSettings;
  19. } catch {
  20. return { tcp: [], udp: [] };
  21. }
  22. return { tcp: [], udp: [] };
  23. }
  24. export default function SubJsonFinalMaskForm({ value, onChange }: SubJsonFinalMaskFormProps) {
  25. const [form] = Form.useForm();
  26. const [initial] = useState(() => parseFinalMask(value));
  27. const onChangeRef = useRef(onChange);
  28. useEffect(() => {
  29. onChangeRef.current = onChange;
  30. });
  31. const finalmask = Form.useWatch('finalmask', form) as FinalMaskStreamSettings | undefined;
  32. useEffect(() => {
  33. if (finalmask === undefined) return;
  34. const next = hasValue(finalmask) ? JSON.stringify(finalmask) : '';
  35. if (next !== value) onChangeRef.current(next);
  36. }, [finalmask, value]);
  37. return (
  38. <Form
  39. form={form}
  40. layout="horizontal"
  41. labelCol={{ flex: '160px' }}
  42. wrapperCol={{ flex: 'auto' }}
  43. colon={false}
  44. initialValues={{ finalmask: initial }}
  45. >
  46. <FinalMaskForm name="finalmask" network="" protocol="" form={form} showAll />
  47. </Form>
  48. );
  49. }