Files
WerkoutIOS/Werkout_ios/Views/AddExercise/AddExerciseView.swift
Trey t 1a06a1dc95 WIP
2023-06-27 23:47:55 -05:00

254 lines
9.6 KiB
Swift

//
// CreateWorkout.swift
// Werkout_ios
//
// Created by Trey Tartt on 6/15/23.
//
import Foundation
import SwiftUI
import Combine
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?
var body: some View {
VStack {
exerciseView()
.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
if let url = URL(string: BaseURLs.dev.rawValue + exercise.videoURL) {
VideoPlayerView(url: url)
}
}
.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()
})
}
.background(Color(uiColor: .tertiarySystemBackground))
}
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 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 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 exerciseView() -> 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.count > 0 {
Text(exercise.side)
.font(.footnote)
.frame(maxWidth: .infinity, alignment: .leading)
}
Text(exercise.equipmentRequired)
.font(.footnote)
.frame(maxWidth: .infinity, alignment: .leading)
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: 44, height: 44)
Image(systemName: "video.fill")
.frame(width: 44, height: 44)
.foregroundColor(.white)
}
}
.frame(width: 44, height: 44)
.background(.clear)
.cornerRadius(10)
}
}
}
}
}
}
struct AddExerciseView_Previews: PreviewProvider {
static var previews: some View {
AddExerciseView(selectedExercise: { _ in })
}
}