fix(dashboard): stop mobile send-button double-fire that aborted chats

The ChatView and QuickChat send/stop buttons each had both an
onPointerDown and an onTouchStart handler invoking the action. On a
quick mobile tap both fire, so handleSend / handleSendMessage /
stopStreaming ran twice in rapid succession. The second invocation
closed the first's SSE stream (streamRef.current.close()), the server
treated that as a cancel via beginGeneration, and the chat ended with
no output — exactly matching the reported "tap silently fails, long
press works" symptom (long press happened to suppress one of the two
events).

Both handlers now early-return when the existing handledMobile*Ref
flag is already set, so only the first event for a given tap fires the
action. The send button additionally gets touch-action: manipulation
(removes the click delay that lets the textarea blur win the race) and
an expanded invisible hit area via ::before so slightly-off taps don't
land on the surrounding textarea and dismiss the keyboard without
sending.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-06 19:55:37 -07:00
parent a296b4d3bd
commit 35ea499e08
4 changed files with 57 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
---
"@runfusion/fusion": patch
---
Fix mobile chat send button silently failing on quick taps. Both the
ChatView and QuickChat send/stop buttons had `onPointerDown` and
`onTouchStart` handlers that each invoked the send/stop action — on a
quick mobile tap both handlers fire, so the action ran twice in rapid
succession. The second invocation closed the first one's SSE stream,
which the server treated as a cancel, leaving the chat with no output.
A long press happened to suppress one of the events, so holding the
button "worked" while quick tapping silently failed.
The handlers now share the existing `handledMobile*Ref` flag so only
the first event for a given tap actually fires the action. The send
button also gets `touch-action: manipulation` and an expanded invisible
hit area so slightly-off taps don't fall through to the surrounding
textarea (which would dismiss the keyboard without sending).