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:
13
.changeset/chatview-mobile-send-quick-tap.md
Normal file
13
.changeset/chatview-mobile-send-quick-tap.md
Normal 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).
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user