hysteria.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { useTranslation } from 'react-i18next';
  2. import { Form, Input, InputNumber, Select, Switch } from 'antd';
  3. import { useFormContext, useWatch } from 'react-hook-form';
  4. import { HeaderMapEditor } from '@/components/form';
  5. import { FormField } from '@/components/form/rhf';
  6. const MASQ = ['streamSettings', 'hysteriaSettings', 'masquerade'];
  7. const MASQ_DOT = 'streamSettings.hysteriaSettings.masquerade';
  8. export default function HysteriaForm() {
  9. const { t } = useTranslation();
  10. const { control, setValue } = useFormContext();
  11. const masquerade = useWatch({ control, name: MASQ_DOT }) as { type?: string } | undefined;
  12. return (
  13. <>
  14. <FormField
  15. label={t('pages.inbounds.form.version')}
  16. name={['streamSettings', 'hysteriaSettings', 'version']}
  17. >
  18. <InputNumber min={2} max={2} disabled style={{ width: '100%' }} />
  19. </FormField>
  20. <FormField
  21. label={t('pages.xray.outboundForm.authPassword')}
  22. name={['streamSettings', 'hysteriaSettings', 'auth']}
  23. >
  24. <Input />
  25. </FormField>
  26. <FormField
  27. label={t('pages.inbounds.form.udpIdleTimeout')}
  28. name={['streamSettings', 'hysteriaSettings', 'udpIdleTimeout']}
  29. >
  30. <InputNumber min={2} max={600} style={{ width: '100%' }} />
  31. </FormField>
  32. <Form.Item label={t('pages.inbounds.form.masquerade')}>
  33. <Switch
  34. checked={!!masquerade}
  35. onChange={(checked) =>
  36. setValue(
  37. MASQ_DOT,
  38. checked
  39. ? {
  40. type: '',
  41. dir: '',
  42. url: '',
  43. rewriteHost: false,
  44. insecure: false,
  45. content: '',
  46. headers: {},
  47. statusCode: 0,
  48. }
  49. : undefined,
  50. )
  51. }
  52. />
  53. </Form.Item>
  54. {masquerade && (
  55. <>
  56. <FormField label={t('pages.inbounds.form.type')} name={[...MASQ, 'type']}>
  57. <Select
  58. options={[
  59. { value: '', label: 'default (404 page)' },
  60. { value: 'proxy', label: 'proxy (reverse proxy)' },
  61. { value: 'file', label: 'file (serve directory)' },
  62. { value: 'string', label: 'string (fixed body)' },
  63. ]}
  64. />
  65. </FormField>
  66. {masquerade.type === 'proxy' && (
  67. <>
  68. <FormField label={t('pages.inbounds.form.upstreamUrl')} name={[...MASQ, 'url']}>
  69. <Input placeholder="https://www.example.com" />
  70. </FormField>
  71. <FormField
  72. label={t('pages.inbounds.form.rewriteHost')}
  73. name={[...MASQ, 'rewriteHost']}
  74. valueProp="checked"
  75. >
  76. <Switch />
  77. </FormField>
  78. <FormField
  79. label={t('pages.inbounds.form.xForwarded')}
  80. name={[...MASQ, 'xForwarded']}
  81. valueProp="checked"
  82. >
  83. <Switch />
  84. </FormField>
  85. <FormField
  86. label={t('pages.inbounds.form.skipTlsVerify')}
  87. name={[...MASQ, 'insecure']}
  88. valueProp="checked"
  89. >
  90. <Switch />
  91. </FormField>
  92. </>
  93. )}
  94. {masquerade.type === 'file' && (
  95. <FormField label={t('pages.inbounds.form.directory')} name={[...MASQ, 'dir']}>
  96. <Input placeholder="/var/www/html" />
  97. </FormField>
  98. )}
  99. {masquerade.type === 'string' && (
  100. <>
  101. <FormField label={t('pages.inbounds.form.statusCode')} name={[...MASQ, 'statusCode']}>
  102. <InputNumber min={0} max={599} style={{ width: '100%' }} />
  103. </FormField>
  104. <FormField label={t('pages.inbounds.form.body')} name={[...MASQ, 'content']}>
  105. <Input.TextArea autoSize={{ minRows: 3 }} />
  106. </FormField>
  107. <FormField label={t('pages.inbounds.form.headers')} name={[...MASQ, 'headers']}>
  108. <HeaderMapEditor mode="v1" />
  109. </FormField>
  110. </>
  111. )}
  112. </>
  113. )}
  114. </>
  115. );
  116. }