Switch dictation to tap-to-toggle by default#48
Conversation
Review Summary by QodoSwitch dictation to tap-to-toggle by default with send-on-stop support
WalkthroughsDescription• Switch dictation to tap-to-toggle interaction by default • Add explicit dictation stop modes for insert vs send • Update send button to transcribe-and-send while recording • Add loading spinner for microphone button during transcription • Add manual verification steps to tests documentation Diagramflowchart LR
A["User taps microphone"] --> B["Recording starts hands-free"]
B --> C{"User action"}
C -->|"Tap microphone"| D["Stop and insert transcript"]
C -->|"Tap send button"| E["Transcribe and send immediately"]
D --> F["Transcribing spinner shown"]
E --> F
F --> G["Message ready or sent"]
File Changes1. src/composables/useDictation.ts
|
Code Review by Qodo
|
| const dictationClickToToggle = ref(loadBoolPref(DICTATION_CLICK_TO_TOGGLE_KEY, true)) | ||
| const dictationAutoSend = ref(loadBoolPref(DICTATION_AUTO_SEND_KEY, false)) |
There was a problem hiding this comment.
1. Second tap ignored startup 🐞 Bug ≡ Correctness
With click-to-toggle now default, a second mic tap during startRecording() (while isStartingRecording is true and state is still idle) is ignored, so recording may still begin even though the user tried to stop it. This breaks the expected tap-to-toggle behavior and can leave users recording unintentionally until they notice and stop later.
Agent Prompt
### Issue description
With tap-to-toggle dictation enabled by default, users can tap the mic twice quickly. During the `getUserMedia()` startup window, `useDictation.toggleRecording()` ignores the second tap (because `startRecording()` bails out when `isStartingRecording` is true), so recording still starts even though the user intended to stop.
### Issue Context
`useDictation.stopRecording()` already supports a “stop requested before start” flow (`isStartingRecording && state === 'idle'`), but `toggleRecording()` never calls `stopRecording()` in that state.
### Fix Focus Areas
- src/composables/useDictation.ts[147-176]
- src/composables/useDictation.ts[185-202]
- src/composables/useDictation.ts[293-301]
### Suggested change
Update `toggleRecording()` to treat `isStartingRecording` as a stoppable state, e.g.:
- If `isStartingRecording` is true (and/or `state === 'idle'`), call `stopRecording()` to set `stopRequestedBeforeStart` and exit.
- Optionally consider introducing an explicit `'starting'` state to simplify UI/logic, but a minimal fix is to route the second tap into `stopRecording()`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
This PR updates voice dictation to use the interaction pattern most users already expect from Codex and modern chat apps.
Instead of holding the microphone button while speaking, dictation now works as a tap-to-toggle flow:
This makes dictation much more comfortable to use because recording becomes hands-free.
What changed
Transcribe and sendwhile recording.tests.md.Behavior
New default dictation flow:
Alternative fast path:
Why
This matches the standard interaction pattern users are already familiar with from Codex and common chat applications, and removes the need to keep the microphone button pressed during the whole recording.
Testing
pnpm run build375x812) and tablet (768x1024)tap -> stop -> insertrecording -> send/codex-api/transcribeis pending