fix(app): stop the composer showing a mic while it holds text - #1673
Open
chphch wants to merge 1 commit into
Open
fix(app): stop the composer showing a mic while it holds text#1673chphch wants to merge 1 commit into
chphch wants to merge 1 commit into
Conversation
The send button and the mic are one control, and which one it draws comes from `hasText` — state the keystroke handler updates inside `React.startTransition`. React is free to defer that, so the composer can hold a typed message while the button still shows a mic, for as long as higher-priority work keeps arriving. A session streaming a reply is exactly that, which is why this shows up mid-conversation and is hard to pin to any one action. The button's behaviour is already right — both press handlers read the live text and send. That is what makes the stale icon worth fixing rather than tolerating: it is not a brief cosmetic lag, it is the button advertising dictation while it would in fact send. `hasText` only changes at the empty/non-empty boundary, so compare against a ref and call setState only when it actually flips. Ordinary keystrokes now hand React nothing at all — strictly less work than the transition they used to schedule — and the one update that matters is urgent. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
chphch
force-pushed
the
fix/send-icon-lags-typing
branch
from
August 22, 2026 00:21
3874602 to
daf980c
Compare
Contributor
Author
|
@bra1nDump — after the August 22 batch, here are six more of the same shape, in one comment rather than six pings. Each one repairs a regression I traced to a specific commit, each is still reproducible on
Two things I'd rather say up front than have you find:
No rush on any of these; I know the queue is long. Happy to split, shrink, or close any of them if a different shape suits you better. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The mobile composer folds send, stop and the mic into one button, and which one it draws comes from
hasText— state the keystroke handler sets insideReact.startTransition. React may defer that update for as long as higher-priority work keeps arriving, so the composer can hold a typed message while the button still shows a mic. A session streaming a reply is exactly that kind of work, which is why it surfaces mid-conversation and is hard to attribute to any one action; I only found it because a user reported "the send button shows up as the voice button" and could not say when.What makes it worth fixing rather than tolerating is that the button's behaviour is already correct —
handleMobilePrimaryPressandhandleSendPressboth read the live text and send. The comment above the first one says as much. So the stale icon is not a brief cosmetic lag; it is the button advertising dictation while it would in fact send. The user confirmed that: tapping the mic-looking button sent the message.hasTextonly ever changes at the empty/non-empty boundary, so the handler now compares against a ref and calls setState only on the flip. Ordinary keystrokes hand React nothing at all — strictly less work than the transition they used to schedule, which was the reason the transition was there — and the one update that matters is urgent.Every path that changes the text funnels through
onChangeText, including the imperativesetTextAndSelectionon both the native and webMultiTextInput(autocomplete insert, Escape, and SessionView's post-send clear), so the ref cannot drift out of step with the field.