Let people choose their push-to-talk key - #188
Open
HamptonMakes wants to merge 2 commits into
Open
Conversation
Push-to-talk was Shift, for everyone, forever. Shift is a key people are already pressing all day, which is why the gesture needed a 350ms hold delay and a selection check to tell talking from typing a capital — and why it still couldn't work at all for anyone whose browser or OS already spends the key. It's now a setting: Ctrl+Space (the new default), Shift, Option/Alt, or off. Presets rather than a free capture, because each one behaves differently on purpose. A chord is nobody's accident, so it records from the press — no delay to sit out and nothing to guess. A bare modifier keeps all the old hedging, because the ambiguity is real. Everyone who was already here is written down as a Shift user by a backfill, so no hands have to relearn anything on deploy; "no preference recorded" now means "arrived after the setting existed". The mic names its own key on hover and to a screen reader — with the shortcut configurable, the button is the only thing on the page that can say which one yours is. The server renders it; the controller rewrites it knowing whether that key says Option or Alt on this machine. Also folds the theme switcher's CSS into a shared .segmented control rather than growing a second copy of it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f0af9251cc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Two things from review. The PATCH was fire-and-forget: a refused or dropped save left the page lit up on a key the server never took, discovered only on the next visit when push-to-talk silently wasn't what the settings said. The click stays the feedback — no spinner narrating a round trip that takes milliseconds — but a failure now puts the previous choice back and says so. And the picker didn't fit a phone. Its no-shrink rule kept the strip at full width, which crushed the explanation into one word per line and ran the last option off the screen. Below 640px the row stacks and the strip takes the width; segments size to content rather than splitting it evenly, because "Ctrl+Space" has nowhere to break and an equal quarter clips it; below about 350px the strip wraps to a second line rather than hiding "Off" off the edge. Fixes the Theme row at those widths too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Push-to-talk was Shift, for everyone, forever. That's a key people are already pressing all day, which is why the gesture needed a 350ms hold delay and a selection check to tell talking from typing a capital — and why it couldn't work at all for anyone whose browser or OS already spends the key.
It's now a setting.
What changed
Settings → Hold to talk — a segmented control:
Ctrl+Space(new default),Shift,Option / Alt,Off. Saves on click, no save button, same shape as the Theme row. Choosing Ctrl+Space reveals a note that macOS uses it to switch input sources: if the OS eats the key the browser never sees it, and a shortcut that silently does nothing is worse than one you were warned about.Two kinds of gesture, on purpose. A chord is nobody's accident, so it records from the press — no hold delay to sit out, no selection check, nothing to guess. A bare modifier keeps every one of the old guards, because the ambiguity that motivated them is real.
offis a supported answer, not a broken state: the mic button stays and the keyboard belongs to the page again.Existing users keep Shift. A data migration writes it into their metadata, so nobody's hands relearn anything on deploy. From here, "no preference recorded" means "arrived after the setting existed" and reads as Ctrl+Space.
The mic names its own key — a hover tooltip and the aria-label. With the shortcut configurable, the button is the only thing on the page that can tell you which one yours is. The server renders a platform-neutral version; the controller rewrites it knowing whether the key in front of this person says ⌥ Option or Alt. It's suppressed mid-take, when the button is a stop button and the status text is already talking.
Also folds the theme switcher's CSS into a shared
.segmentedcontrol rather than growing a second copy of it — hence the one-line touch innav_stimulus_spec.rb.Notes for review
db/schema.rbhas only its version line bumped, by hand. The migration is data-only, and a real dump off this dev database picked up columns from other unmerged branches (wake_url,behavior) that don't belong here.db/migrate/20260820195225_..._.co_plan.rb, per the usualco_plan:install:migrationsflow. It's idempotent — only users with novoice_hotkeyrecorded are touched.Testing
Full suite green: 1577 examples, 0 failures. Also driven in a browser — the settings row, the live save, and the tooltip were checked by hand.
🤖 Generated with Claude Code