Commit Graph
2 Commits
Author SHA1 Message Date
Muhammad ZaimandBohdan Triapitsyn 2bdd9af90a feat(ui): add composer enter-to-send toggle (#3178)
* feat(ui): add composer enter-to-send toggle and native hardware-keyboard detection

Replaces the settings-page "Enter sends with a keyboard attached" checkbox with
an EnterKeyToggle in the composer footer: plain Enter submits / Shift+Enter
inserts a newline when enabled, Shift+Enter submits / Enter inserts a newline
when disabled. Ctrl/Cmd+Enter always submits as the soft-keyboard fallback.
Persisted as enterToSend.

Adds the Android HardwareKeyboardPlugin: scans input devices for an alphabetic
physical keyboard (ignoring phantom key/sensor devices), re-answers on config
changes/foreground, and confirms attachment from real hardware key events.
MainActivity surfaces key events to it before the WebView consumes them. The
composer and draft layout start keyboard-aware instead of inferring one focus
late; ComposerEditor preserves Enter modifiers through CodeMirror's deferred
re-dispatch so the toggle can tell Shift/Ctrl+Enter from plain Enter.

Removes the settings search entry and i18n keys for the old checkbox.

* refactor(ui): keep enter-to-send branch focused

* fix(ui): preserve enter-toggle taps on touch

* fix(ui): preserve enter key defaults and move setting

* fix(ui): keep enter setting lint-clean

* fix(i18n): preserve current Turkish message parity

* fix(settings): persist enter-to-send preference

* fix(ui): clarify enter-to-send setting

* fix(ui): apply enter preference on desktop

* fix(ui): match enter setting focus mode default

* test(ui): cover enter key policy matrix

* fix(ui): harden deferred enter handling

* fix(chat): preserve untouched Enter policy and validate settings

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-09-05 19:07:28 +03:00
Muhammad Zaim 6a2f0b8135 fix(relay): never forward a tunneled body that lost frames (#2822)
When the relay drops mid-request, the prompt_async body frames can be
lost. The tunnel host forwarded the request to loopback as an
empty/truncated chunked body, which the server rejects with a bare 400
(empty response body) — the mobile app's 'Failed to send message (400)'.

Host now buffers request bodies (<512KB) and forwards the complete body
only once StreamEnd arrives; larger bodies still stream live. A new
hasBody flag on the request head lets the host detect a body that
delivered zero frames and abort it as an ambiguous transport failure
(which the client already retries) instead of forwarding an empty body.
A 15s body-delivery deadline converts stalled tunnels into clean aborts.
2026-08-12 16:54:23 +03:00