Implemented the RecordingView view in the Recording package target.

This commit is contained in:
2026-07-03 18:52:21 +02:00
parent 1fb8ece751
commit 1487ecb3f4
@@ -0,0 +1,88 @@
import SwiftUI
/// A view that drives a recording session.
///
/// The view shows a main button that starts, pauses, and resumes a recording, with a label above it displaying the elapsed recording time.
/// While paused, a send button lets the user submit the recording for processing, showing a progress indicator until the processing finishes.
///
/// All state and control behavior lives in the view's ``Model``; the view itself only renders it and forwards button presses and state changes.
public struct RecordingView: View {
// MARK: Properties
/// The model that owns the recording state and drives the view's controls.
@State private var model: Model
// MARK: Initializers
/// Creates a recording view in the not-recording state.
public init() {
self.model = .init()
}
// MARK: Body
/// The content of the view: the timer label above the main and send buttons, with every change of the model's state forwarded back
/// to ``Model/updatedState(shouldRestartTimer:)``.
public var body: some View {
VStack(
spacing: Constant.Spacing.stack
) {
if model.shouldShowTimer {
Text(model.timerText)
}
HStack(
spacing: Constant.Spacing.stack
) {
Button {
model.pressedMain()
} label: {
Image(model.iconMain)
}
.disabled(model.shouldDisableMain)
if model.shouldShowSend {
Button {
model.pressedSend()
} label: {
if let icon = model.iconSend {
Image(icon)
} else {
ProgressView()
}
}
.disabled(model.isProcessing)
}
}
}
.onChange(
of: model.state,
initial: false
) { oldValue, _ in
model.updatedState(
shouldRestartTimer: oldValue == .notRecording
)
}
}
}
// MARK: - Constants
/// The constant values used across the view.
private enum Constant {
/// The spacing constants.
enum Spacing {
/// The spacing between the elements of a stack.
static let stack: CGFloat = 16
}
}
// MARK: - Previews
#Preview(
"Recording view"
) {
RecordingView()
}