Reorganized the Sample app target into folders and also, extracted the ContentViewModel view model from the ContentView view.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import Recording
|
||||
import SwiftUI
|
||||
|
||||
/// The root view of the Attendi sample app.
|
||||
///
|
||||
/// The view hosts the `RecordingView` feature from the `Recording` target of the `Features` package, which drives the whole recording flow,
|
||||
/// inside a navigation stack, and presents the transcribed text of every processed recording in a modal sheet of its own navigation stack.
|
||||
///
|
||||
/// The services attached to the feature and the transcription shown in the sheet live in the view's ``Model``; the view itself only renders it and
|
||||
/// forwards the feature's output and the sheet's dismissal. The navigation titles of the stacks are localized through the app's string catalog.
|
||||
struct ContentView: View {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The model that owns the attached services and the transcription presented in the modal sheet.
|
||||
@State private var model = Model()
|
||||
|
||||
// MARK: Body
|
||||
|
||||
/// The content of the view: a navigation stack with the recording feature's view, attached to the model's services, and a modal sheet
|
||||
/// presenting the transcribed text of every processed recording, closable through its toolbar button or a swipe.
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
RecordingView(
|
||||
recorder: model.recorder,
|
||||
transcriber: model.transcriber
|
||||
) { text in
|
||||
model.received(text)
|
||||
}
|
||||
.navigationTitle("view.recording.navigation.title")
|
||||
#if !os(macOS)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#endif
|
||||
}
|
||||
.sheet(item: $model.transcription) { transcription in
|
||||
NavigationStack {
|
||||
ScrollView {
|
||||
Text(transcription.text)
|
||||
.font(.body)
|
||||
.fontWeight(.regular)
|
||||
.foregroundStyle(.primary)
|
||||
.frame(
|
||||
maxWidth: .infinity,
|
||||
alignment: .leading
|
||||
)
|
||||
.padding()
|
||||
}
|
||||
.navigationTitle("view.transcription.navigation.title")
|
||||
#if !os(macOS)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#endif
|
||||
.toolbar {
|
||||
Button(role: .close) {
|
||||
model.dismissed()
|
||||
}
|
||||
}
|
||||
}
|
||||
.presentationDetents([.medium, .large])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
#Preview(
|
||||
"Content view"
|
||||
) {
|
||||
ContentView()
|
||||
}
|
||||
Reference in New Issue
Block a user