// // CreateWorkout.swift // Werkout_ios // // Created by Trey Tartt on 6/15/23. // import Foundation import SwiftUI import Combine import AVKit struct AddExerciseView: View { enum CreateWorkoutItemPickerViewType { case muscles case equipment } @State var selectedMuscles = [Muscle]() @State var selectedEquipment = [Equipment]() @State var filteredExercises = [ExerciseExercise]() @StateObject var bridgeModule = BridgeModule.shared @Environment(\.dismiss) var dismiss var selectedExercise: ((ExerciseExercise) -> Void) @State var createWorkoutItemPickerViewModel: CreateWorkoutItemPickerViewModel? @State var createWorkoutItemPickerViewType: CreateWorkoutItemPickerViewType? @State var searchString: String = "" @State var videoExercise: ExerciseExercise? { didSet { if let viddd = self.videoExercise?.videoURL, let url = URL(string: BaseURLs.currentBaseURL + viddd) { self.avPlayer = AVPlayer(url: url) } } } @State var avPlayer = AVPlayer(url: URL(string: "https://dev.werkout.fitness/media/exercise_videos/2_Dumbbell_Lateral_Lunges.mp4")!) var body: some View { VStack { AllExerciseList() .padding(.top) TextField("Filter", text: $searchString) .padding() HStack { muscleView() .frame(maxWidth: .infinity) Divider() equipmentView() .frame(maxWidth: .infinity) } .padding(.top) .frame(height: 44) } .onAppear{ if #function.hasPrefix("__preview") { DataStore.shared.setupFakeData() } guard let exercises = DataStore.shared.allExercise, let muscles = DataStore.shared.allMuscles, let equipment = DataStore.shared.allEquipment else { return } selectedMuscles = muscles selectedEquipment = equipment filteredExercises = exercises } .sheet(item: $videoExercise) { exercise in PlayerView(player: $avPlayer) .onAppear{ avPlayer.play() } } .sheet(item: $createWorkoutItemPickerViewModel) { item in CreateWorkoutItemPickerView(viewModel: item, completed: { selectedids in if let viewType = createWorkoutItemPickerViewType { switch viewType { case .muscles: if let muscles = DataStore.shared.allMuscles { selectedMuscles.removeAll() for id in selectedids { if let muscle = muscles.first(where: { $0.id == id }) { selectedMuscles.append(muscle) } } } case .equipment: if let equipment = DataStore.shared.allEquipment { selectedEquipment.removeAll() for id in selectedids { if let equipment = equipment.first(where: { $0.id == id }) { selectedEquipment.append(equipment) } } } } } filterExercises() }) } } func filterExercises() { if selectedMuscles.count == 0 { filteredExercises = [ExerciseExercise]() return } if selectedEquipment.count == 0 { filteredExercises = [ExerciseExercise]() return } guard let exercises = DataStore.shared.allExercise, let muscles = DataStore.shared.allMuscles, let equipment = DataStore.shared.allEquipment else { filteredExercises = [ExerciseExercise]() return } filteredExercises = exercises.filter({ exercise in var hasCorrectMuscles = false if selectedMuscles.count == muscles.count { hasCorrectMuscles = true } else { let exerciseMuscleIds = exercise.muscles.map({ $0.muscle }) let selctedMuscleIds = selectedMuscles.map({ $0.id }) // if one items match if exerciseMuscleIds.contains(where: selctedMuscleIds.contains) { // if all items match // if exerciseMuscleIds.contains(selctedMuscleIds) { hasCorrectMuscles = true } } var hasCorrectEquipment = false if selectedEquipment.count == equipment.count { hasCorrectEquipment = true } else { let exerciseEquipmentIds = exercise.equipment.map({ $0.equipment }) let selctedEquipmentIds = selectedEquipment.map({ $0.id }) // if one items match if exerciseEquipmentIds.contains(where: selctedEquipmentIds.contains) { // if all items match // if exerciseEquipmentIds.contains(selctedEquipmentIds) { hasCorrectEquipment = true } } return hasCorrectMuscles && hasCorrectEquipment }) } func muscleView() -> some View { VStack { if let _ = DataStore.shared.allMuscles { Text("Select Muscles") .foregroundColor(.cyan) Text("\(selectedMuscles.count) Selected") } } .onTapGesture { if let muscles = DataStore.shared.allMuscles { var createWorkoutItemPickerModels = [CreateWorkoutItemPickerModel]() muscles.forEach({ let model = CreateWorkoutItemPickerModel(id: $0.id, name: $0.name.lowercased()) createWorkoutItemPickerModels.append(model) }) createWorkoutItemPickerModels = createWorkoutItemPickerModels.sorted(by: { $0.name < $1.name }) let selectedIds = selectedMuscles.map { $0.id } createWorkoutItemPickerViewModel = CreateWorkoutItemPickerViewModel(allValues: createWorkoutItemPickerModels, selectedIds: selectedIds) createWorkoutItemPickerViewType = .muscles } } } func equipmentView() -> some View { VStack { if let _ = DataStore.shared.allEquipment { Text("Select Equipment") .foregroundColor(.cyan) Text("\(selectedEquipment.count) Selected") } } .onTapGesture { if let equipment = DataStore.shared.allEquipment { var createWorkoutItemPickerModels = [CreateWorkoutItemPickerModel]() equipment.forEach({ let model = CreateWorkoutItemPickerModel(id: $0.id, name: $0.name?.lowercased() ?? "-") createWorkoutItemPickerModels.append(model) }) createWorkoutItemPickerModels = createWorkoutItemPickerModels.sorted(by: { $0.name < $1.name }) let selectedIds = selectedEquipment.map { $0.id } createWorkoutItemPickerViewModel = CreateWorkoutItemPickerViewModel(allValues: createWorkoutItemPickerModels, selectedIds: selectedIds) createWorkoutItemPickerViewType = .equipment } } } func AllExerciseList() -> some View { List() { ForEach(filteredExercises.indices, id: \.self) { i in let exercise = filteredExercises[i] if searchString.isEmpty || exercise.name.lowercased().contains(searchString.lowercased()) { HStack { VStack { Text(exercise.name) .frame(maxWidth: .infinity, alignment: .leading) if !exercise.side.isEmpty { Text(exercise.side) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) } if !exercise.equipmentRequired.isEmpty { Text(exercise.equipmentRequired) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) } if !exercise.muscleGroups.isEmpty { Text(exercise.muscleGroups) .font(.footnote) .frame(maxWidth: .infinity, alignment: .leading) } } .contentShape(Rectangle()) .onTapGesture { selectedExercise(exercise) dismiss() } Button(action: { videoExercise = exercise }) { ZStack { Circle() .fill(.blue) .frame(width: 33, height: 33) Image(systemName: "video.fill") .frame(width: 33, height: 33) .foregroundColor(.white ) } } .frame(width: 33, height: 33) } } } } } } struct AddExerciseView_Previews: PreviewProvider { static var previews: some View { AddExerciseView(selectedExercise: { _ in }) } }