// // MainView.swift // Werkout_ios // // Created by Trey Tartt on 6/14/23. // import SwiftUI struct WorkoutDetailView: View { @StateObject var viewModel: WorkoutDetailViewModel var bridgeModule = BridgeModule.shared @Environment(\.dismiss) var dismiss var body: some View { ZStack { switch viewModel.status { case .loading: Text("Loading") case .showWorkout(let workout): VStack { InfoView(workout: workout) Divider() CurrentWorkoutElapsedTimeView() .padding(.top) CountdownView() ExerciseListView(workout: workout) ActionsView(workout: workout) .frame(height: 44) } .interactiveDismissDisabled() } } } } struct InfoView: View { @ObservedObject var bridgeModule = BridgeModule.shared var workout: Workout var body: some View { VStack { if bridgeModule.isInWorkout == false { Text(workout.name) .frame(maxWidth: .infinity, alignment: .leading) .font(.title3) .padding() if let desc = workout.description { Text(desc) .frame(maxWidth: .infinity, alignment: .leading) .font(.body) .padding([.leading, .trailing]) } } } } } struct ActionsView: View { @ObservedObject var bridgeModule = BridgeModule.shared var workout: Workout @Environment(\.dismiss) var dismiss var body: some View { HStack { if bridgeModule.isInWorkout == false { Button(action: { bridgeModule.resetCurrentWorkout() dismiss() }, label: { Image(systemName: "xmark.octagon.fill") .font(.title) .frame(maxWidth: .infinity, maxHeight: .infinity) }) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.red) .foregroundColor(.white) Button(action: { startWorkout() }, label: { Image(systemName: "arrowtriangle.forward.fill") .font(.title) .frame(maxWidth: .infinity, maxHeight: .infinity) }) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.green) .foregroundColor(.white) } else { Button(action: { nextExercise() }, label: { Image(systemName: "arrow.forward") .font(.title) .frame(maxWidth: .infinity, maxHeight: .infinity) }) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.yellow) .foregroundColor(.white) Button(action: { completeWorkout() }, label: { Image(systemName: "checkmark") .font(.title) .frame(maxWidth: .infinity, maxHeight: .infinity) }) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(.blue) .foregroundColor(.white) } } } func completeWorkout() { guard let workoutid = bridgeModule.currentWorkout?.id, let startTime = bridgeModule.workoutStartDate?.timeFormatForUpload else { return } let postBody = [ "difficulty": 1, "workout_start_time": startTime, "workout": workoutid, "total_time": bridgeModule.currentWorkoutRunTimeInSeconds ] as [String : Any] CompleteWorkoutFetchable(postData: postBody).fetch(completion: { result in switch result { case .success(_): DispatchQueue.main.async { bridgeModule.resetCurrentWorkout() dismiss() } case .failure(let failure): print(failure) } }) } func nextExercise() { bridgeModule.nextExercise() } func startWorkout() { bridgeModule.start(workout: workout) } } struct CurrentWorkoutElapsedTimeView: View { @ObservedObject var bridgeModule = BridgeModule.shared var body: some View { if bridgeModule.currentWorkoutRunTimeInSeconds > -1 { Text("\(bridgeModule.currentWorkoutRunTimeInSeconds)") .font(.title2) } } } struct ExerciseListView: View { @ObservedObject var bridgeModule = BridgeModule.shared var workout: Workout var body: some View { List() { ForEach(workout.exercisesSortedByCreated_at.indices, id: \.self) { i in let obj = workout.exercisesSortedByCreated_at[i] VStack { HStack { if i == bridgeModule.currentExerciseIdx { Image(systemName: "checkmark") .foregroundColor(.green) } Text(obj.exercise.name) .onTapGesture { bridgeModule.start(workout: workout, atExerciseIndex: i) } Spacer() } if i == bridgeModule.currentExerciseIdx { HStack { if obj.exercise.isReps { Text("is reps") .frame(maxWidth: .infinity, maxHeight: .infinity) } if obj.exercise.isWeight { Text("is weight") .frame(maxWidth: .infinity, maxHeight: .infinity) } if obj.exercise.isDuration { Text("is duration") .frame(maxWidth: .infinity, maxHeight: .infinity) } } } } } } } } struct CountdownView: View { @StateObject var bridgeModule = BridgeModule.shared var body: some View { VStack { if let duration = bridgeModule.currentExercise?.duration { HStack { ProgressView(value: Float(bridgeModule.timeLeft), total: Float(duration)) Text("\(bridgeModule.timeLeft)") }.padding(16) } } } } struct WorkoutDetailView_Previews: PreviewProvider { static var previews: some View { WorkoutDetailView(viewModel: WorkoutDetailViewModel(workout: PreviewWorkout.workout())) } }