diff --git a/Werkout_ios/APIModels/Workout.swift b/Werkout_ios/APIModels/Workout.swift index a1c59e2..b0e1c72 100644 --- a/Werkout_ios/APIModels/Workout.swift +++ b/Werkout_ios/APIModels/Workout.swift @@ -17,9 +17,11 @@ struct Workout: Codable, Identifiable, Equatable { let description: String? let exercises: [ExerciseElement] let registeredUser: RegisteredUser? + let muscles: [String]? + let equipment: [String]? enum CodingKeys: String, CodingKey { - case name, description, exercises, id + case name, description, exercises, id, muscles, equipment case registeredUser = "registered_user" } @@ -35,6 +37,8 @@ struct Workout: Codable, Identifiable, Equatable { self.description = try container.decodeIfPresent(String.self, forKey: .description) self.registeredUser = try container.decodeIfPresent(RegisteredUser.self, forKey: .registeredUser) self.id = try container.decode(Int.self, forKey: .id) + self.muscles = try container.decodeIfPresent([String].self, forKey: .muscles) + self.equipment = try container.decodeIfPresent([String].self, forKey: .equipment) } var exercisesSortedByCreated_at: [ExerciseElement] { diff --git a/Werkout_ios/JSON/WorkoutOne.json b/Werkout_ios/JSON/WorkoutOne.json index 90b34bf..1c93ecd 100644 --- a/Werkout_ios/JSON/WorkoutOne.json +++ b/Werkout_ios/JSON/WorkoutOne.json @@ -1,182 +1,162 @@ { - "id": 20, - "name": "Adsfadfafa", - "description": "description", + "id": 1, + "name": "test workout", + "description": null, "exercises": [ { - "workout": 20, + "workout": 1, "exercise": { - "id": 992, + "id": 1080, "muscles": [ { - "id": 7270, - "created_at": "2023-06-14T17:05:39.769351Z", - "updated_at": "2023-06-14T17:05:39.769758Z", - "exercise": 992, - "muscle": 6 + "id": 7267, + "created_at": "2023-06-28T04:04:39.263974Z", + "updated_at": "2023-06-28T04:04:39.263986Z", + "exercise": 1080, + "muscle": 4 }, { - "id": 7271, - "created_at": "2023-06-14T17:05:39.770480Z", - "updated_at": "2023-06-14T17:05:39.771111Z", - "exercise": 992, - "muscle": 4 + "id": 7266, + "created_at": "2023-06-28T04:04:39.268881Z", + "updated_at": "2023-06-28T04:04:39.268893Z", + "exercise": 1080, + "muscle": 5 } ], "equipment": [ { - "id": 944, - "created_at": "2023-06-13T02:28:04.294180Z", - "updated_at": "2023-06-13T02:28:04.294658Z", - "exercise": 992, + "id": 942, + "created_at": "2023-06-28T14:18:59.650301Z", + "updated_at": "2023-06-28T14:18:59.650313Z", + "exercise": 1080, "equipment": 1091 } ], - "audio_url": "/media/exercise_audio/2_Dumbbell_Single-Leg_Deadlift.m4a", - "video_url": "/media/exercise_videos/2_Dumbbell_Single-Leg_Deadlift.mp4", - "created_at": "2023-06-11T22:50:19.197099Z", - "updated_at": "2023-06-11T22:50:19.197105Z", - "name": "2 Dumbbell Single-Leg Deadlift", - "description": "Holding a dumbbell in each hand, with your right leg on the ground, hinge at your hips and let your body see-saw down until you are parallel with the ground. Snap back to a standing position.", - "side": "right_leg", + "audio_url": "/media/exercise_audio/2_Dumbbell_Lateral_Lunges.m4a", + "video_url": "/media/exercise_videos/2_Dumbbell_Lateral_Lunges.mp4", + "nsfw_video_url": "/media/nsfw_exercise_videos/2_Dumbbell_Lateral_Lunges.mp4", + "created_at": "2023-06-26T20:52:33.576028Z", + "updated_at": "2023-06-26T20:52:33.576040Z", + "name": "2 Dumbbell Lateral Lunges", + "description": "With dumbbells by your sides, step out to the side.. Reach your hips back like you're sitting in a chair.. Drive back up to the starting position, and repeat on the other side.", + "side": "", "is_two_dumbbells": true, "is_trackable_distance": false, - "is_alternating": false, + "is_alternating": true, "is_weight": true, "is_distance": false, "is_duration": true, "is_reps": true, - "joints_used": "ankle,lumbar spine,hip,knee,wrist", - "movement_patterns": "lower pull,lower pull - hip hinge", + "joints_used": "ankle,hip,knee,lumbar spine,wrist", + "movement_patterns": "lower push,lower push - lunge", "equipment_required": "Dumbbell", - "muscle_groups": "hamstrings,glutes", - "synonyms": "2 Dumbbell Single Leg Deadlift" + "muscle_groups": "quads,glutes", + "synonyms": "" }, - "weight": 10, - "reps": 12, + "weight": null, + "reps": null, "duration": null, "duration_audio": null, - "weight_audio": "/media/quantities_audio/for_10_pounds.m4a", - "created_at": "2023-06-20T20:53:51.251968Z" + "weight_audio": null, + "created_at": "2023-06-27T12:18:54.998026Z" }, { - "workout": 20, + "workout": 1, "exercise": { - "id": 992, - "muscles": [ - { - "id": 7270, - "created_at": "2023-06-14T17:05:39.769351Z", - "updated_at": "2023-06-14T17:05:39.769758Z", - "exercise": 992, - "muscle": 6 - }, - { - "id": 7271, - "created_at": "2023-06-14T17:05:39.770480Z", - "updated_at": "2023-06-14T17:05:39.771111Z", - "exercise": 992, - "muscle": 4 - } - ], - "equipment": [ - { - "id": 944, - "created_at": "2023-06-13T02:28:04.294180Z", - "updated_at": "2023-06-13T02:28:04.294658Z", - "exercise": 992, - "equipment": 1091 - } - ], - "audio_url": "/media/exercise_audio/2_Dumbbell_Single-Leg_Deadlift.m4a", - "video_url": "/media/exercise_videos/2_Dumbbell_Single-Leg_Deadlift.mp4", - "created_at": "2023-06-11T22:50:19.197099Z", - "updated_at": "2023-06-11T22:50:19.197105Z", - "name": "2 Dumbbell Single-Leg Deadlift", - "description": "Holding a dumbbell in each hand, with your right leg on the ground, hinge at your hips and let your body see-saw down until you are parallel with the ground. Snap back to a standing position.", - "side": "right_leg", - "is_two_dumbbells": true, + "id": 798, + "muscles": [], + "equipment": [], + "audio_url": "/media/exercise_audio/Recover.m4a", + "video_url": "/media/exercise_videos/Recover.mp4", + "nsfw_video_url": "/media/nsfw_exercise_videos/Recover_5.mp4", + "created_at": "2023-06-26T20:52:36.446337Z", + "updated_at": "2023-06-26T20:52:36.446348Z", + "name": "Recover", + "description": "Use this time to catch your breath. It will help you get more out of what's next", + "side": "", + "is_two_dumbbells": false, "is_trackable_distance": false, "is_alternating": false, - "is_weight": true, + "is_weight": false, "is_distance": false, "is_duration": true, - "is_reps": true, - "joints_used": "ankle,lumbar spine,hip,knee,wrist", - "movement_patterns": "lower pull,lower pull - hip hinge", - "equipment_required": "Dumbbell", - "muscle_groups": "hamstrings,glutes", - "synonyms": "2 Dumbbell Single Leg Deadlift" + "is_reps": false, + "joints_used": "", + "movement_patterns": "", + "equipment_required": "", + "muscle_groups": "", + "synonyms": "" }, - "weight": 10, - "reps": 12, + "weight": null, + "reps": null, "duration": null, "duration_audio": null, - "weight_audio": "/media/quantities_audio/for_10_pounds.m4a", - "created_at": "2023-06-20T20:53:51.254113Z" + "weight_audio": null, + "created_at": "2023-06-27T12:18:54.999424Z" }, { - "workout": 20, + "workout": 1, "exercise": { - "id": 992, + "id": 130, "muscles": [ { - "id": 7270, - "created_at": "2023-06-14T17:05:39.769351Z", - "updated_at": "2023-06-14T17:05:39.769758Z", - "exercise": 992, - "muscle": 6 + "id": 7282, + "created_at": "2023-06-28T04:04:39.194997Z", + "updated_at": "2023-06-28T04:04:39.195009Z", + "exercise": 130, + "muscle": 5 }, { - "id": 7271, - "created_at": "2023-06-14T17:05:39.770480Z", - "updated_at": "2023-06-14T17:05:39.771111Z", - "exercise": 992, - "muscle": 4 + "id": 7281, + "created_at": "2023-06-28T04:04:39.199685Z", + "updated_at": "2023-06-28T04:04:39.199697Z", + "exercise": 130, + "muscle": 1 } ], "equipment": [ { - "id": 944, - "created_at": "2023-06-13T02:28:04.294180Z", - "updated_at": "2023-06-13T02:28:04.294658Z", - "exercise": 992, - "equipment": 1091 + "id": 948, + "created_at": "2023-06-28T14:18:59.622982Z", + "updated_at": "2023-06-28T14:18:59.622994Z", + "exercise": 130, + "equipment": 1088 } ], - "audio_url": "/media/exercise_audio/2_Dumbbell_Single-Leg_Deadlift.m4a", - "video_url": "/media/exercise_videos/2_Dumbbell_Single-Leg_Deadlift.mp4", - "created_at": "2023-06-11T22:50:19.197099Z", - "updated_at": "2023-06-11T22:50:19.197105Z", - "name": "2 Dumbbell Single-Leg Deadlift", - "description": "Holding a dumbbell in each hand, with your right leg on the ground, hinge at your hips and let your body see-saw down until you are parallel with the ground. Snap back to a standing position.", - "side": "right_leg", - "is_two_dumbbells": true, + "audio_url": "/media/exercise_audio/2_Kettlebell_Push_Press.m4a", + "video_url": "/media/exercise_videos/2_Kettlebell_Push_Press.mp4", + "nsfw_video_url": "/media/nsfw_exercise_videos/2_Kettlebell_Push_Press.mp4", + "created_at": "2023-06-26T20:52:33.599643Z", + "updated_at": "2023-06-26T20:52:33.599655Z", + "name": "2 Kettlebell Push Press", + "description": "Stand with feet in a shoulder width stance and kettlebells in the front rack position. \nDip quickly at the knees into a quarter squat and then explode straight up as you press the kettlebells overhead.\nLower the kettlebells under control back to the starting position", + "side": "", + "is_two_dumbbells": false, "is_trackable_distance": false, "is_alternating": false, "is_weight": true, "is_distance": false, "is_duration": true, "is_reps": true, - "joints_used": "ankle,lumbar spine,hip,knee,wrist", - "movement_patterns": "lower pull,lower pull - hip hinge", - "equipment_required": "Dumbbell", - "muscle_groups": "hamstrings,glutes", - "synonyms": "2 Dumbbell Single Leg Deadlift" + "joints_used": "knee,hip,shoulder,wrist,elbow", + "movement_patterns": "upper push - vertical,upper push", + "equipment_required": "Kettlebell", + "muscle_groups": "deltoids,quads", + "synonyms": "" }, - "weight": 10, - "reps": 12, + "weight": null, + "reps": null, "duration": null, "duration_audio": null, - "weight_audio": "/media/quantities_audio/for_10_pounds.m4a", - "created_at": "2023-06-20T20:53:51.255969Z" + "weight_audio": null, + "created_at": "2023-06-27T12:18:54.999935Z" } ], "registered_user": { - "id": 2, - "first_name": "test2_first", - "last_name": "test2_last", + "id": 1, + "first_name": "User1", + "last_name": "user1", "image": "", - "nick_name": null + "nick_name": "test user1" } } diff --git a/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift b/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift index e815a2a..9dfb7ae 100644 --- a/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift +++ b/Werkout_ios/Views/AllWorkouts/AllWorkoutsView.swift @@ -67,7 +67,10 @@ struct AllWorkoutsView: View { switch selectedSegment { case .AllWorkout: - allWorkoutView(workouts: workouts) + AllWorkoutsListView(workouts: workouts, selectedWorkout: { workout in + selectedWorkout = workout + }) + Divider() case .MyWorkouts: plannedWorkout(workouts: UserStore.shared.plannedWorkouts) } @@ -101,24 +104,6 @@ struct AllWorkoutsView: View { } } - func allWorkoutView(workouts: [Workout]) -> some View { - List { - ForEach(workouts, id:\.name) { workout in - VStack { - Text(workout.name) - .font(.title2) - .frame(maxWidth: .infinity, alignment: .leading) - Text(workout.description ?? "") - .frame(maxWidth: .infinity, alignment: .leading) - } - .contentShape(Rectangle()) - .onTapGesture { - selectedWorkout = workout - } - } - } - } - func plannedWorkout(workouts: [PlannedWorkout]) -> some View { List { ForEach(workouts, id:\.workout.name) { plannedWorkout in @@ -185,6 +170,75 @@ struct AllWorkoutsView: View { } } +struct AllWorkoutsListView: View { + @State var searchString: String = "" + let workouts: [Workout] + + let selectedWorkout: ((Workout) -> Void) + + var filteredWorkouts: [Workout] { + if !searchString.isEmpty, searchString.count > 0 { + return workouts.filter({ + if $0.name.lowercased().contains(searchString.lowercased()) { + return true + } + if let equipment = $0.equipment?.joined(separator: "").lowercased(), + equipment.contains(searchString.lowercased()) { + return true + } + if let muscles = $0.muscles?.joined(separator: "").lowercased(), + muscles.contains(searchString.lowercased()) { + return true + } + + return false + }) + } else { + return workouts + } + } + + var body: some View { + VStack { + List { + ForEach(filteredWorkouts, id:\.name) { workout in + Section { + VStack { + Text(workout.name) + .font(.title2) + .frame(maxWidth: .infinity, alignment: .leading) + Text(workout.description ?? "") + .frame(maxWidth: .infinity, alignment: .leading) + + if let muscles = workout.muscles, + muscles.joined(separator: ", ").count > 0{ + Divider() + Text(muscles.joined(separator: ", ")) + .font(.footnote) + .frame(maxWidth: .infinity, alignment: .leading) + } + + if let equipment = workout.equipment, + equipment.joined(separator: ", ").count > 0 { + Divider() + Text(equipment.joined(separator: ", ")) + .font(.footnote) + .frame(maxWidth: .infinity, alignment: .leading) + } + } + .contentShape(Rectangle()) + .onTapGesture { + selectedWorkout(workout) + } + } + } + } + TextField("Filter", text: $searchString) + .padding(.leading) + } + } +} + struct AllWorkoutsView_Previews: PreviewProvider { static var previews: some View { AllWorkoutsView(workouts: PreviewData.allWorkouts()) diff --git a/Werkout_ios/Views/PlanWorkoutView.swift b/Werkout_ios/Views/PlanWorkoutView.swift index 6bdc440..5e55c43 100644 --- a/Werkout_ios/Views/PlanWorkoutView.swift +++ b/Werkout_ios/Views/PlanWorkoutView.swift @@ -24,10 +24,9 @@ struct PlanWorkoutView: View { .foregroundColor(Color.accentColor) .padding() .animation(.spring(), value: selectedDate) - .frame(width: 500) Divider().frame(height: 1) - + DatePicker("Select Date", selection: $selectedDate, displayedComponents: [.date]) .padding(.horizontal) .datePickerStyle(.graphical) diff --git a/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift index 43d71d1..a154a3e 100644 --- a/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift +++ b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift @@ -243,9 +243,25 @@ struct CurrentWorkoutElapsedTimeView: View { } struct ExerciseListView: View { + @AppStorage("showNSFWVideos") private var showNSFWVideos = false @ObservedObject var bridgeModule = BridgeModule.shared var workout: Workout - + @State var avPlayer = AVPlayer(url: URL(string: "https://dev.werkout.fitness/media/exercise_videos/2_Dumbbell_Lateral_Lunges.mp4")!) + @State var videoExercise: ExerciseExercise? { + didSet { + if showNSFWVideos { + if let viddd = self.videoExercise?.nsfwVideoURL, + let url = URL(string: BaseURLs.currentBaseURL + viddd) { + avPlayer = AVPlayer(url: url) + } + } else { + if let viddd = self.videoExercise?.videoURL, + let url = URL(string: BaseURLs.currentBaseURL + viddd) { + avPlayer = AVPlayer(url: url) + } + } + } + } var body: some View { List() { @@ -259,12 +275,17 @@ struct ExerciseListView: View { } Text(obj.exercise.name) - .onTapGesture { - bridgeModule.goToExerciseAt(index: i) - } - Spacer() } + .contentShape(Rectangle()) + .onTapGesture { + if bridgeModule.isInWorkout { + bridgeModule.goToExerciseAt(index: i) + } else { + videoExercise = obj.exercise + } + } + if i == bridgeModule.currentExerciseIdx { HStack { if obj.exercise.isReps { @@ -284,6 +305,9 @@ struct ExerciseListView: View { } } } + .sheet(item: $videoExercise) { exercise in + VideoPlayerView(avPlayer: $avPlayer) + } } }