Defer update prompts until dictation completes - #746
Conversation
Greptile SummaryThis PR defers automatic update prompts until dictation lifecycle work has completed.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b05c4908ef
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| var hasActiveDictation: Bool { | ||
| self._asr.map { $0.isRunningOrStarting || $0.isFinalizing } ?? false | ||
| } |
There was a problem hiding this comment.
Keep update deferral active through output delivery
When dictation uses AI post-processing, ContentView.stopAndProcessTranscription continues refining, saving, and typing after ASRService.stop() returns; this helper flips false as soon as ASR finalization ends. A deferred update alert can therefore wake during that post-stop processing and take focus before the dictated output is delivered, so update prompts can still interrupt the active dictation workflow. Track the higher-level stop/output processing state, or keep the deferral active until callers finish delivering the transcription.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8e23a8b000
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
|
||
| private func stopAndProcessTranscription(route: DictationOutputRoute = .normal) async { | ||
| self.appServices.setDictationOutputDeliveryActive(true) | ||
| defer { self.appServices.setDictationOutputDeliveryActive(false) } |
There was a problem hiding this comment.
Keep deferral active until typing finishes
In the external typing route, this defer clears hasActiveDictation as soon as stopAndProcessTranscription returns, but the actual insertion has only been dispatched: ASRService.typeOutputPlanToActiveField calls TypingService.typeOutputPlanInstantly, which queues a background worker and can wait before inserting/pasting. Fresh evidence in this revision is that the new higher-level flag still drops before that worker completes, so a deferred automatic update alert can wake during that window, take focus, and cause the dictated output to miss or target the wrong UI; keep the flag active until the typing/paste operation has actually completed.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 957d43c242
ℹ️ 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".
| var hasActiveDictation: Bool { | ||
| self.isDeliveringDictationOutput || | ||
| (self._asr.map { $0.isRunningOrStarting || $0.isFinalizing } ?? false) |
There was a problem hiding this comment.
Mark dictation active before scheduling ASR startup
When a user triggers dictation as the automatic update check completes, startRecording() schedules asr.start() in a new Task, so there is a main-actor scheduling window before isStarting becomes true. During that window this expression reports no active dictation, allowing showUpdateNotification to enter its modal alert even though recording startup has already been requested; track the pending start synchronously or set the activity flag before creating the startup task.
Useful? React with 👍 / 👎.
| "complete totalMs=\(Self.elapsedMs(from: requestedAt, to: completedAt)) textReadyToCompleteMs=\(textReadyAt.map { String(Self.elapsedMs(from: $0, to: completedAt)) } ?? "nil")" | ||
| ) | ||
| self.log("[TypingService] Typing operation completed, isCurrentlyTyping set to false") | ||
| completion?() |
There was a problem hiding this comment.
Wait for paste confirmation before firing completion
When reliable-paste mode or the clipboard fallback is used, insertTextInstantly reaches withTemporaryPasteboardString, which queues insertion verification on pasteboardRestoreQueue (for up to five seconds) and returns immediately; this completion therefore clears the update deferral while the paste is still only dispatched, so a modal alert can take focus before a global Cmd+V is consumed. Fresh evidence in this revision is that awaiting the worker still does not await that existing asynchronous verification; invoke completion after verification/restoration finishes instead.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d5232e10c3
ℹ️ 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".
| } | ||
| } else { | ||
| Task { await self.asr.start() } | ||
| self.appServices.beginDictationStartup() |
There was a problem hiding this comment.
Track voice-command processing through completion
When recording from CommandModeView, this registers only the startup phase; after asr.stop() finishes, hasActiveDictation becomes false while processUserCommand is still awaiting the generated response. A deferred automatic update alert can therefore appear during a voice-originated command and, if the user installs it, restart the app before the response is produced. Keep output-delivery activity set around the stop-and-command-processing task, as the main ContentView dictation route does.
Useful? React with 👍 / 👎.
| func setDictationOutputDeliveryActive(_ active: Bool) { | ||
| self.isDeliveringDictationOutput = active |
There was a problem hiding this comment.
Count overlapping output-delivery operations
When two stop triggers queue stopAndProcessTranscription before the first has finished—for example, a recording-control action and the global shortcut—the second call can quickly return empty because the first already cleared isRunning, then set this shared Boolean to false. Once the first asr.stop() returns, isFinalizing is also false even though its AI processing and typing are still active, so the deferred update alert can wake prematurely. Use a balanced counter/token rather than a Boolean so one invocation cannot clear another invocation's deferral.
Useful? React with 👍 / 👎.
Description
Prevents automatic update prompts from interrupting active dictation and discarding the final transcript. FluidVoice now tracks transcript finalization and defers the modal update prompt until recording startup, capture, and final transcription have all completed.
Manual “Check for Updates…” behavior is unchanged.
Type of Change
Related Issue or Discussion
Closes #745
Related: #564
Testing
swiftlint --strict --config .swiftlint.yml Sourcesswiftformat --config .swiftformat Sourcesswiftc -parsegit diff HEAD^ --checkFull SwiftLint and Xcode tests could not run locally because full Xcode is unavailable in the selected developer environment. GitHub Actions will run the repository’s required lint, build, and test checks.
Screenshots / Video
Notes
The existing update alert is unchanged. Only its automatic presentation timing is deferred while dictation owns recording or transcript-finalization work.