|
@@ -5,6 +5,7 @@ import { useFormContext, useWatch } from 'react-hook-form';
|
|
|
import { HeaderMapEditor } from '@/components/form';
|
|
import { HeaderMapEditor } from '@/components/form';
|
|
|
import { FormField } from '@/components/form/rhf';
|
|
import { FormField } from '@/components/form/rhf';
|
|
|
import { validateSessionIDLength, validateSessionIDTable } from '@/lib/xray/xhttp-session-id';
|
|
import { validateSessionIDLength, validateSessionIDTable } from '@/lib/xray/xhttp-session-id';
|
|
|
|
|
+import { xmuxSiblingOnEdit, type XmuxEditableField } from '@/lib/xray/stream-wire-normalize';
|
|
|
import { XHTTP_SESSION_ID_TABLES } from '@/schemas/protocols/stream/xhttp';
|
|
import { XHTTP_SESSION_ID_TABLES } from '@/schemas/protocols/stream/xhttp';
|
|
|
|
|
|
|
|
import { MODE_OPTIONS } from '../outbound-form-constants';
|
|
import { MODE_OPTIONS } from '../outbound-form-constants';
|
|
@@ -28,7 +29,7 @@ const XH = 'streamSettings.xhttpSettings';
|
|
|
|
|
|
|
|
export default function XhttpForm({ onXmuxToggle }: XhttpFormProps) {
|
|
export default function XhttpForm({ onXmuxToggle }: XhttpFormProps) {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
- const { control } = useFormContext();
|
|
|
|
|
|
|
+ const { control, setValue } = useFormContext();
|
|
|
const mode = useWatch({ control, name: `${XH}.mode` }) as string | undefined;
|
|
const mode = useWatch({ control, name: `${XH}.mode` }) as string | undefined;
|
|
|
const obfs = !!useWatch({ control, name: `${XH}.xPaddingObfsMode` });
|
|
const obfs = !!useWatch({ control, name: `${XH}.xPaddingObfsMode` });
|
|
|
const sessionPlacement = useWatch({ control, name: `${XH}.sessionIDPlacement` }) as string | undefined;
|
|
const sessionPlacement = useWatch({ control, name: `${XH}.sessionIDPlacement` }) as string | undefined;
|
|
@@ -37,6 +38,12 @@ export default function XhttpForm({ onXmuxToggle }: XhttpFormProps) {
|
|
|
const uplinkDataPlacement = useWatch({ control, name: `${XH}.uplinkDataPlacement` }) as string | undefined;
|
|
const uplinkDataPlacement = useWatch({ control, name: `${XH}.uplinkDataPlacement` }) as string | undefined;
|
|
|
const enableXmux = !!useWatch({ control, name: `${XH}.enableXmux` });
|
|
const enableXmux = !!useWatch({ control, name: `${XH}.enableXmux` });
|
|
|
|
|
|
|
|
|
|
+ function onXmuxFieldChange(edited: XmuxEditableField, value: unknown) {
|
|
|
|
|
+ const next = xmuxSiblingOnEdit(edited, value);
|
|
|
|
|
+ if (!next) return;
|
|
|
|
|
+ setValue(`${XH}.xmux.${next.field}`, next.value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return (
|
|
return (
|
|
|
<>
|
|
<>
|
|
|
<FormField label={t('host')} name={['streamSettings', 'xhttpSettings', 'host']}>
|
|
<FormField label={t('host')} name={['streamSettings', 'xhttpSettings', 'host']}>
|
|
@@ -283,12 +290,14 @@ export default function XhttpForm({ onXmuxToggle }: XhttpFormProps) {
|
|
|
<FormField
|
|
<FormField
|
|
|
label={t('pages.xray.outboundForm.maxConcurrency')}
|
|
label={t('pages.xray.outboundForm.maxConcurrency')}
|
|
|
name={['streamSettings', 'xhttpSettings', 'xmux', 'maxConcurrency']}
|
|
name={['streamSettings', 'xhttpSettings', 'xmux', 'maxConcurrency']}
|
|
|
|
|
+ onAfterChange={(v) => onXmuxFieldChange('maxConcurrency', v)}
|
|
|
>
|
|
>
|
|
|
<Input placeholder="16-32" />
|
|
<Input placeholder="16-32" />
|
|
|
</FormField>
|
|
</FormField>
|
|
|
<FormField
|
|
<FormField
|
|
|
label={t('pages.xray.outboundForm.maxConnections')}
|
|
label={t('pages.xray.outboundForm.maxConnections')}
|
|
|
name={['streamSettings', 'xhttpSettings', 'xmux', 'maxConnections']}
|
|
name={['streamSettings', 'xhttpSettings', 'xmux', 'maxConnections']}
|
|
|
|
|
+ onAfterChange={(v) => onXmuxFieldChange('maxConnections', v)}
|
|
|
>
|
|
>
|
|
|
<Input placeholder="0" />
|
|
<Input placeholder="0" />
|
|
|
</FormField>
|
|
</FormField>
|