Skip to content

Add SpeechTextInput for dictation support in any text input - #1066

Merged
kevinaboos merged 7 commits into
mainfrom
speech_text_input
Sep 12, 2026
Merged

Add SpeechTextInput for dictation support in any text input#1066
kevinaboos merged 7 commits into
mainfrom
speech_text_input

Conversation

@kevinaboos

Copy link
Copy Markdown
Member

SpeechTextInput is a text input wrapper with a mic button that handles all the
dictation logic, which is necessary now that we support speech recognition in
multiple text inputs across Robrix.

  • MentionableTextInput uses it, so dictation is visible and supported in the
    regular room input bar and the editing pane.
  • RoomFilterInputBar uses it too, for the rooms list and Space lobby filter bars.
    Punctuation that recognizers often add is dropped, e.g. "Robrix." becomes "Robrix"
    so it still matches any room containing "Robrix". Clearing the filter text also
    stops dictation.
  • Navigating away from a text input now cancels dictation, instead of recording into
    a now-hidden input. Losing focus doesn't, so you can dictate into one room while
    typing into another, side by side.
  • robius-speech enforces the "one session at a time" rule, which makes this much
    easier to deal with at the app level.
  • Pressing escape to stop dictation only stops dictation — it isn't doubly handled as
    a regular escape press by modals and other widgets.
  • Speech input stops when a logout occurs, e.g. if your token gets revoked.
  • Updated robius-speech to upstream now that its PR merged, including the dictation
    char-boundary fix (speech: don't assume byte ranges are always at a char boundary robius#26).

This can happen if your token gets revoked, etc.
It handles all the dictation stuff now, which is necessary because
we're supporting speech recognition in multiple text inputs across Robrix.
The `MentionableTextInput` widget now uses it, which means it's visible
and supported in the regular room input bar and the editing pane.

Refactoring it into one widget makes it easier to fix key problems:
* If you navigated away from a room, dictation kept recording and
  inserting text into a now-hidden text input, which is dumb.
  Now any kind of navigation away from the text input will cancel dictation.
  But not lost focus, so you can still dictate into one room while
  typing into a different room, side-by-side.
* We modified `robius-speech` to enforce the "one session at a time" rule,
  which makes everything easier to deal with at the app-level.
* Pressing escape to stop dictation only stops dictation, it's not treated
  as a regular escape press by other widgets like modals.
The `RoomFilterInputBar` widget now uses `SpeechTextInput`.
We drop punctuation and other irrelevant characters that are often added
by speech recognizers, e.g., "Robrix." will become "Robrix" so it matches
any room containing "Robrix".

Clearing the filter input bar's inputted text also stops dictation.
Pressing escape stops dictation but is also handled by other widgets
like modals, so we don't want it to be doubly handled.

UI-wise, fix up the microphone button's spacing and padding and ensure
that it's vertically centered and nicely sized in the text input
@kevinaboos
kevinaboos merged commit 8ec27c1 into main Sep 12, 2026
11 checks passed
@kevinaboos
kevinaboos deleted the speech_text_input branch September 12, 2026 01:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant