fix(recording): defer media pause and volume mute until hold threshold#240
fix(recording): defer media pause and volume mute until hold threshold#240mml555 wants to merge 2 commits into
Conversation
Pause/mute now waits until the hotkey hold crosses the minimum threshold, with debounced resume and duplicate-start guards to stop flicker on brief or accidental presses. Fixes kitlangton#239 Co-authored-by: Cursor <cursoragent@cursor.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughRecordingClient defers pause/mute until an activation delay, debounces resume actions, and centralizes media-control helpers. startRecording cancels pending resume tasks and schedules media control; stopRecording debounces resumption. TranscriptionFeature prevents starting when already recording/transcribing. ChangesMedia Control Debouncing and Recording Safety
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bacefdd9fa
ℹ️ 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".
| if isCaptureActive { | ||
| recordingLogger.notice("Ignoring duplicate startRecording while capture is active") | ||
| return |
There was a problem hiding this comment.
Preserve new session IDs during overlapping stop/start
When a user starts another dictation immediately after releasing the hotkey, stopRecording() can still be in its capture-engine grace sleep with captureController.isRecording == true. This guard returns before assigning a fresh recordingSessionID, so the in-flight stop does not trip shouldIgnoreStopRequest and proceeds to finish the old capture, while the UI has already entered a new recording with no underlying capture; the next release then yields an ignored/stale recording. This affects rapid successive recordings/double-tap workflows where start arrives during the 20–80 ms stop grace window.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Hex/Clients/RecordingClient.swift (1)
1287-1321:⚠️ Potential issue | 🔴 Critical | ⚡ Quick win
cleanup()still references a removed helper and will not compile.After this refactor,
resumeMediaIfNeeded()is no longer defined, but it is still called at Line 1504.🛠️ Suggested fix
+ private func resumeMediaIfNeeded() async { + guard hasActiveMediaControlState else { return } + resumeMediaTask?.cancel() + resumeMediaTask = nil + await resumeMediaImmediately() + } + private func resumeMediaImmediately() async {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Hex/Clients/RecordingClient.swift` around lines 1287 - 1321, The cleanup() function still calls the removed resumeMediaIfNeeded; update cleanup() to call the new resumeMediaImmediately() instead and ensure it's awaited from the correct concurrency context (e.g., await resumeMediaImmediately() or Task { await resumeMediaImmediately() } / await MainActor.run if cleanup() is not async or runs on MainActor). Locate the call to resumeMediaIfNeeded in cleanup() and replace it with an awaited call to resumeMediaImmediately(), making any necessary signature/context adjustments so the code compiles.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@Hex/Clients/RecordingClient.swift`:
- Around line 1287-1321: The cleanup() function still calls the removed
resumeMediaIfNeeded; update cleanup() to call the new resumeMediaImmediately()
instead and ensure it's awaited from the correct concurrency context (e.g.,
await resumeMediaImmediately() or Task { await resumeMediaImmediately() } /
await MainActor.run if cleanup() is not async or runs on MainActor). Locate the
call to resumeMediaIfNeeded in cleanup() and replace it with an awaited call to
resumeMediaImmediately(), making any necessary signature/context adjustments so
the code compiles.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bba96e7d-6398-4bf6-a420-1a7d51248751
📒 Files selected for processing (3)
.changeset/03f45a3f.mdHex/Clients/RecordingClient.swiftHex/Features/Transcription/TranscriptionFeature.swift
Assign session IDs before stop-grace overlap waits and fix cleanup to call resumeMediaImmediately after the media defer refactor. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
startRecordingwhile capture is already activeFixes #239
Context
These fixes were developed while testing live dictation preview (#237 / #238) and are split out so they can ship independently.
Test plan
Made with Cursor
Summary by CodeRabbit