add WorkoutStateManager for ViewModel functionality

This commit is contained in:
Felix Förtsch
2024-11-23 16:12:39 +01:00
parent 1668b29803
commit 1c177c5336
18 changed files with 355 additions and 338 deletions
@@ -8,71 +8,76 @@
import SwiftUI
struct ActiveWorkoutSessionControls: View {
@Binding var session: WorkoutSession
@Environment(WorkoutStateManager.self) private var workoutStateManager
private var activeWorkoutSession: WorkoutSession? { workoutStateManager.activeWorkoutSession }
var body: some View {
VStack {
SimpleStopWatch(
startDate: session.startDate,
duration: $session.workoutDuration)
.font(.system(.largeTitle, design: .monospaced))
.fontWeight(.bold)
HStack {
Text(session.getCurrentExerciseName())
.font(.system(size: 24, weight: .bold, design: .rounded))
}
ProgressView("",
value: session.getCurrentExerciseIndex(),
total: session.getTotalExerciseCount() - 1
)
HStack {
Button(action: {
session.prevExercise()
}) {
HStack {
Image(systemName: "backward.end.fill")
Text("Prev")
}
}
.buttonStyle(.borderedProminent)
if let session = activeWorkoutSession, workoutStateManager.isWorkoutInProgress {
VStack {
Text(session.name)
SimpleStopWatch(
startDate: session.startDate,
duration: Binding(
get: { session.workoutDuration },
set: { session.workoutDuration = $0 }))
.font(.system(.largeTitle, design: .monospaced))
.fontWeight(.bold)
.tint(.accentColor)
Button(action: {
// TODO: Implement proper Pausing
session.isPaused = true
}) {
HStack {
Image(systemName: "pause.fill")
Text("Pause")
}
HStack {
Text(session.getCurrentExerciseName())
.font(.system(size: 24, weight: .bold, design: .rounded))
}
.buttonStyle(.borderedProminent)
.fontWeight(.bold)
.tint(.gray)
.disabled(true)
Button(action: {
session.nextExercise()
}) {
HStack {
Text("Next")
Image(systemName: "forward.end.fill")
ProgressView("",
value: session.getCurrentExerciseIndex(),
total: session.getTotalExerciseCount() - 1
)
HStack {
Button(action: {
workoutStateManager.prevExercise()
}) {
HStack {
Image(systemName: "backward.end.fill")
Text("Prev")
}
}
.buttonStyle(.borderedProminent)
.fontWeight(.bold)
.tint(.accentColor)
Button(action: {
// TODO: Implement proper Pausing
session.workoutSessionStatus = .paused
}) {
HStack {
Image(systemName: "pause.fill")
Text("Pause")
}
}
.buttonStyle(.borderedProminent)
.fontWeight(.bold)
.tint(.gray)
.disabled(true)
Button(action: {
workoutStateManager.nextExercise()
}) {
HStack {
Text("Next")
Image(systemName: "forward.end.fill")
}
}
.buttonStyle(.borderedProminent)
.fontWeight(.bold)
.tint(.accentColor)
}
.buttonStyle(.borderedProminent)
.fontWeight(.bold)
.tint(.accentColor)
}
}
}
}
#Preview("isWorkingOut = true") {
@Previewable @State var activeWorkoutSession = WorkoutSession(start: Workout.sampleData.first!)
@Previewable @State var stateManager = WorkoutStateManager(modelContext: SampleData.shared.modelContainer.mainContext)
// For some reason the return keyword is required here to avoid the error "Type of expression is ambiguous without a type annotation"
return ActiveWorkoutSessionControls(session: $activeWorkoutSession)
.onAppear() {
Defaults.shared.isWorkingOut = true
}
ActiveWorkoutSessionControls()
.modelContainer(SampleData.shared.modelContainer)
.environment(stateManager)
}