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

@@ -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>