Surfaced recording flow errors to the user through an alert in the Recording package target.
This commit is contained in:
@@ -19,7 +19,10 @@ extension RecordingView {
|
||||
|
||||
/// The number of seconds spent recording, excluding any time spent paused.
|
||||
private(set) var elapsedSeconds: Int = 0
|
||||
|
||||
|
||||
/// The error to surface to the user, or `nil` when none occurred. Cleared when it is dismissed or a new recording starts.
|
||||
private(set) var error: RecordingError?
|
||||
|
||||
/// The transcription of the last processed recording, or `nil` when none has been processed yet.
|
||||
private(set) var transcription: Transcription?
|
||||
|
||||
@@ -149,6 +152,11 @@ extension RecordingView {
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles the dismissal of the surfaced ``error``, clearing it.
|
||||
func dismissedError() {
|
||||
error = nil
|
||||
}
|
||||
|
||||
/// Handles a press of the send button.
|
||||
///
|
||||
/// Moves a paused recording into processing, stopping the timer and kicking off ``processInput()``. Does nothing in any other state.
|
||||
@@ -188,7 +196,8 @@ private extension RecordingView.Model {
|
||||
// MARK: Methods
|
||||
|
||||
/// Processes the recorded input: it stops the audio capture, transcribes the captured audio, and publishes the result in ``transcription``;
|
||||
/// when finished — or when either service fails — it resets ``elapsedSeconds`` and returns the model to the not-recording state.
|
||||
/// when finished — or when either service fails, in which case the failure is published in ``error`` — it resets ``elapsedSeconds``
|
||||
/// and returns the model to the not-recording state.
|
||||
func processInput() async {
|
||||
guard state == .processing else {
|
||||
return
|
||||
@@ -197,12 +206,18 @@ private extension RecordingView.Model {
|
||||
do {
|
||||
let audio = try await capturer.stop()
|
||||
|
||||
transcription = try await transcribe(
|
||||
audio,
|
||||
locale: locale.wrappedValue
|
||||
)
|
||||
do {
|
||||
transcription = try await transcribe(
|
||||
audio,
|
||||
locale: locale.wrappedValue
|
||||
)
|
||||
} catch {
|
||||
transcription = nil
|
||||
self.error = .transcriptionFailed
|
||||
}
|
||||
} catch {
|
||||
transcription = nil
|
||||
self.error = .captureFailed
|
||||
}
|
||||
|
||||
accumulated = .zero
|
||||
@@ -257,7 +272,8 @@ private extension RecordingView.Model {
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts the audio capture through the attached ``Capturing``, falling back to the not-recording state when the service fails.
|
||||
/// Starts the audio capture through the attached ``Capturing``, falling back to the not-recording state and publishing the failure
|
||||
/// in ``error`` when the service fails.
|
||||
///
|
||||
/// - Parameter isNewRecording: Whether a new recording should be started, as opposed to a paused one being resumed.
|
||||
func startCapturer(
|
||||
@@ -272,6 +288,9 @@ private extension RecordingView.Model {
|
||||
self.stopTimer()
|
||||
|
||||
self.state = .notRecording
|
||||
self.error = error as? AudioCapturingError == .permissionNotGranted
|
||||
? .permissionDenied
|
||||
: .captureFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,14 +298,15 @@ private extension RecordingView.Model {
|
||||
/// Starts the timer task, which updates ``elapsedSeconds`` from the time measured by the clock on every whole second until it is
|
||||
/// cancelled, so scheduling latency never accumulates as drift. Any previously running timer task is cancelled first.
|
||||
///
|
||||
/// - Parameter shouldRestartTimer: Whether the measured recording time, ``elapsedSeconds``, and ``transcription`` should be
|
||||
/// cleared before the timer starts, which is the case for a new recording as opposed to one resuming from a pause.
|
||||
/// - Parameter shouldRestartTimer: Whether the measured recording time, ``elapsedSeconds``, ``error``, and ``transcription``
|
||||
/// should be cleared before the timer starts, which is the case for a new recording as opposed to one resuming from a pause.
|
||||
func startTimer(
|
||||
_ shouldRestartTimer: Bool
|
||||
) {
|
||||
if shouldRestartTimer {
|
||||
accumulated = .zero
|
||||
elapsedSeconds = 0
|
||||
error = nil
|
||||
transcription = nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user