fix(mobile-chat): parity with desktop ChatTab — multi-send, thinking indicator, banner-clear (core#2697) #2762
Reference in New Issue
Block a user
Delete Branch "fix/mobile-chat-parity"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 0 of the mobile user-flow alignment
MobileChat reuses the fixed hooks (
useChatSend/useChatSocket), so the 524-as-still-processing + dedup fixes already reached mobile. But three ChatTab behaviors lived in the desktop render and never made it to mobile:sending, so mobile users couldn't fire a follow-up while the agent worked (the hook supports it; #2726). Removed the|| sendingblock.thinking(#2745).●●● Nswith an elapsed timer keyed onsending || currentTask(#2720) so a long turn doesn't look stalled.Tests / CI
+2 MobileChat tests (indicator shows on currentTask, hidden when idle); full mobile suite green (249). Runs in the blocking canvas vitest gate.
First step of the mobile-flow optimization plan; bigger phases (Tasks/Approvals inbox, agent tree) await CTO steer on scope.
🤖 Generated with Claude Code
REQUEST_CHANGES on head
04eac0f.Blocking correctness issue: the PR removes the
sendingguard from thesend()handler, but the primary mobile send button is still disabled whilesending:That means tap-based mobile users still cannot multi-send during an in-flight turn, which is one of the three explicit desktop-parity behaviors this PR is meant to ship. Only the Enter-key path can reach
send()whilesending; the main mobile UI path remains blocked. The cursor/background logic around the button also still keys on!sending, so it visually advertises the old behavior.Please remove the stale
sendinggating from the send button disabled/style state to match the handler, and add/adjust a MobileChat test that proves a second tap-send is possible whilesendingis true. The thinking-indicator tests are useful, but they do not cover the multi-send parity behavior.REQUEST_CHANGES on head
04eac0f01f5f878340e4cb90a05e28788122d290.Findings:
Mobile multi-send is still blocked on the primary tap path.
MobileChat.send()correctly removes thesendingguard atcanvas/src/components/mobile/MobileChat.tsx:357-369, but the Send button remains disabled whilesendingis true atMobileChat.tsx:834-838, and its cursor/background/color state also keys on!sendingat:845-853. On mobile, the send button is the primary follow-up-send affordance; after the first message starts, the button disables and a second distinct message cannot be sent by tapping until the prior turn completes. That is not desktop ChatTab parity, where the Send button is not disabled bysending(ChatTab.tsx:895-898), and it does not satisfy the PR's multi-send claim. The attach button also still gates onsendingatMobileChat.tsx:767-785, which is another mobile/desktop parity mismatch for composing a follow-up while the agent is working.The new tests do not cover the core multi-send behavior or the #2759 overlap. The added tests at
canvas/src/components/mobile/__tests__/MobileChat.test.tsx:649-661only assert thinking indicator visibility fromcurrentTask; there is no mobile test that sends one message, leavesuseChatSend.sendingtrue, edits a second draft, and proves the mobile Send button remains enabled and dispatches a second POST. There is also no test proving the stale-banner clear behavior added inMobileChat.tsx:243-262. Given #2759 is currently RC'd for shareduseChatSendconcurrent-send token lifecycle, #2762 should at minimum avoid adding untested mobile multi-send assumptions and should compose with the pending hook fix.I do not see #2762 directly reintroducing the #2759 token leak because it does not modify
useChatSend, but enabling mobile multi-send while the mobile UI still blocks onsendingand while no mobile race coverage exists is a correctness gap. Please remove thesendinggate from the mobile send affordance(s) where desktop parity requires it, add a mobile multi-send regression test for the tap workflow, and add/confirm coverage for the banner-clear path. I did not approve; Canvas CI was still pending when I inspected, but these are blocking issues independent of CI.The send() handler dropped the `sending` guard but the tap button — mobile's PRIMARY send affordance — still had `disabled={... || sending ...}` + cursor/ bg/color keyed on `!sending`, so a follow-up couldn't be tapped mid-turn. Remove `sending` from the button's disabled + styling to match the handler. Test: button stays enabled during an in-flight (hanging) send. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>APPROVED on head
323a8f39.Re-review after CR2 #11456: the blocking tap-path issue is fixed. The mobile Send button no longer disables or styles itself as unavailable while
sending; it now gates on empty input, reachability, and uploading, matching the updatedsend()handler and the desktop multi-send behavior. The added regression drives a hanging send and verifies the primary mobile tap affordance stays enabled for a follow-up message.5-axis:
Verified current head is open/mergeable and
CI/all-requiredis green. /sop-ackPost-merge audit on merged head
323a8f39(review endpoint is closed because the PR merged while I was re-reviewing).My prior RC is only partially resolved. The mobile Send tap path is fixed:
send()and the Send button no longer gate onsending, and the new tap-path test covers that part.Residual issues I would still want followed up:
canvas/src/components/mobile/MobileChat.tsx:770still disables Attach whilesendingis true, with matching disabled cursor/opacity at lines 778 and 785. That leaves the attach affordance blocked during an in-flight turn, so the parity gap I flagged is still present for follow-up attachment sends.I do not see a mobile regression test for the banner-clear path. The implementation clears stale send errors from
onAgentMessage,onSendComplete, andthinking, butcanvas/src/components/mobile/__tests__/MobileChat.test.tsxonly adds thinking indicator coverage and the Send-button tap multi-send test. Please add a test that proves a stale send-error banner clears on the mobile callback path changed here.This is a post-merge follow-up note, not a formal blocking review, because the PR is already merged.