Commit graph

4 commits

Author SHA1 Message Date
MHSanaei
d2f5f530e0
fix(frontend): Outbound submit crash on non-mux protocols + tab a11y (B21)
Two issues surfaced on Outbound save:

1. Crash: `Cannot read properties of undefined (reading 'enabled')` at
   formValuesToWirePayload. The modal hides the Mux switch entirely
   for non-stream protocols (dns/freedom/blackhole/loopback) and for
   stream protocols when isMuxAllowed gates it out (xhttp, vless+flow).
   With the field never registered, validateFields() returns no `mux`
   key — `values.mux.enabled` then dereferences undefined.
   Fix: optional chain `values.mux?.enabled` so missing mux skips the
   mux clause silently. Documented why mux can be absent.

2. Chrome a11y warning: "Blocked aria-hidden on an element because its
   descendant retained focus" — when the user has an input focused
   inside one Tab panel and switches to another tab, AntD marks the
   outgoing panel aria-hidden while focus is still inside. The browser
   warns, but the focused control is now invisible to AT users.
   Fix: blur the active element before setActiveKey in onTabChange.
2026-05-26 20:24:15 +02:00
MHSanaei
e01acae843
feat(frontend): XHTTP advanced fields on outbound modal
Replace the 'edit via JSON' deferred-features hint with the full XHTTP
sub-form matching the legacy modal's XhttpFields helper.

schemas/protocols/stream/xhttp.ts:
- New XHttpXmuxSchema: 6 connection-multiplexing knobs
  (maxConcurrency, maxConnections, cMaxReuseTimes, hMaxRequestTimes,
  hMaxReusableSecs, hKeepAlivePeriod).
- XHttpStreamSettingsSchema gains 5 outbound-only fields and one
  UI-only toggle: scMinPostsIntervalMs, uplinkChunkSize, noGRPCHeader,
  xmux, enableXmux.

outbound-form-adapter.ts:
- New stripUiOnlyStreamFields() drops xhttpSettings.enableXmux on the
  way to wire so the panel never embeds the UI toggle into the saved
  config. xray-core ignores unknown fields anyway, but the panel reads
  back its own emitted JSON, so a clean wire shape matters.

OutboundFormModal.tsx:
- Headers editor (HeaderMapEditor v1) for xhttpSettings.headers.
- Padding obfs Switch + 4 conditional fields (key/header/placement/
  method) when on.
- Uplink HTTP method Select with GET disabled outside packet-up.
- Session placement + session key (key shown when placement != path).
- Sequence placement + sequence key (same pattern).
- packet-up mode: scMinPostsIntervalMs, scMaxEachPostBytes, uplink
  data placement + key + chunk size (key/chunk-size shown when
  placement != body).
- stream-up / stream-one mode: noGRPCHeader Switch.
- XMUX Switch + 6 nested fields when on.
2026-05-26 13:19:08 +02:00
MHSanaei
e64d1a9bef
feat(frontend): OutboundFormModal.new.tsx skeleton (Pattern A)
Sibling .new.tsx file with the Modal shell, Tabs (Basic/JSON), Form.useForm
hydration via rawOutboundToFormValues, and the submit pipeline that calls
formValuesToWirePayload before onConfirm. Tag uniqueness check is wired in.

Protocol-specific sub-forms, stream, security, sockopt, and mux sections
are deferred to subsequent commits — accessible via the JSON tab in the
meantime. The InboundsPage continues to render the legacy modal until the
atomic swap at the end.

Also: rawOutboundToFormValues now returns streamSettings as undefined
when the wire payload omits it, so Form.useForm doesn't receive a value
that does not match the NetworkSettings discriminated union.
2026-05-26 12:01:32 +02:00
MHSanaei
b554bb6b75
feat(frontend): outbound form schema + wire adapter foundation
Lay the groundwork for OutboundFormModal's Pattern A rewrite:

- schemas/forms/outbound-form.ts: discriminated-union form values across
  all 12 outbound protocols, with flat per-protocol settings shapes that
  match the legacy class fields (vmess vnext / trojan-ss-socks-http
  servers / wireguard csv address-reserved all flattened).

- lib/xray/outbound-form-adapter.ts: rawOutboundToFormValues converts
  wire-shape outbound JSON to typed form values; formValuesToWirePayload
  re-nests on submit. Replaces the Outbound.fromJson/toJson dependency
  the modal currently has on the legacy class hierarchy.

- test/outbound-form-adapter.test.ts: 15 round-trip cases covering each
  protocol's wire quirks (vmess vnext flatten, vless reverse-wrap,
  wireguard csv↔array, blackhole response wrap, DNS rule normalization,
  mux gating).
2026-05-26 11:58:36 +02:00