fix(dashboard): make ChatView mobile send fire on quick tap

The mobile send button used pointerdown + touchstart with preventDefault
and a focus-preservation dance to keep the keyboard up while sending.
That path silently failed on quick taps on iOS — only a long press
registered. Switching to plain onClick (with touch-action: manipulation
to skip the click delay) fires reliably on tap. The soft keyboard may
dismiss on send now, which is a minor regression vs. the previous
intent but vastly preferable to silent failure.

QuickChat is unchanged because it already works on mobile.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-06 20:15:30 -07:00
parent 073c5047ea
commit 74378dcfc7
2 changed files with 21 additions and 32 deletions

View File

@@ -0,0 +1,13 @@
---
"@runfusion/fusion": patch
---
Workaround long-standing bug where ChatView's mobile send button only
fired on a long press — quick taps silently did nothing. The previous
implementation used `pointerdown` + `touchstart` with `preventDefault`
and a focus-preservation dance so the keyboard would stay up while
sending; on iOS that path made quick taps fall through entirely. The
button now uses plain `onClick` with `touch-action: manipulation`. The
soft keyboard may dismiss on send, which is a minor UX regression
compared to silent failure. QuickChat is unchanged (it already works
on mobile).

View File

@@ -1994,43 +1994,19 @@ export function ChatView({ projectId, addToast }: ChatViewProps) {
<button
type="button"
className="chat-input-send"
onPointerDown={(event) => {
if (typeof window === "undefined" || window.innerWidth > 768) return;
event.preventDefault();
if (event.pointerType && event.pointerType !== "mouse") {
handledMobileSendRef.current = true;
markPreserveComposerFocus();
focusComposerInput();
void handleSend();
window.setTimeout(() => {
preserveComposerFocusRef.current = false;
}, 1500);
}
}}
onTouchStart={(event) => {
if (typeof window === "undefined" || window.innerWidth > 768) return;
event.preventDefault();
handledMobileSendRef.current = true;
markPreserveComposerFocus();
focusComposerInput();
void handleSend();
window.setTimeout(() => {
preserveComposerFocusRef.current = false;
}, 1500);
}}
onMouseDown={(event) => {
if (typeof window === "undefined" || window.innerWidth > 768) return;
event.preventDefault();
}}
// Workaround: previous mobile flow used pointerdown +
// touchstart with preventDefault and a focus-preservation
// dance to keep the keyboard up while sending. On iOS that
// path made quick taps fail entirely (only long press
// registered). Falling back to plain onClick reliably fires
// the send on tap; the soft keyboard may dismiss but the
// message goes through, which beats silent failure.
onClick={() => {
if (handledMobileSendRef.current) {
handledMobileSendRef.current = false;
return;
}
void handleSend();
}}
disabled={!messageInput.trim() && pendingAttachments.length === 0}
data-testid="chat-send-btn"
style={{ touchAction: "manipulation" }}
>
<Send size={16} />
</button>