From 93b8d674b49bd899c3bb8a0518ff25492fe5f6b1 Mon Sep 17 00:00:00 2001 From: Trey t Date: Thu, 13 Jul 2023 22:39:44 -0500 Subject: [PATCH] WIP --- Werkout_ios.xcodeproj/project.pbxproj | 6 ++ Werkout_ios/APIModels/Exercise.swift | 66 ++++++++++------ Werkout_ios/BridgeModule.swift | 2 +- .../Views/AccountView/AccountView.swift | 12 ++- .../CompletedWorkoutView.swift | 79 ++++++++++--------- .../CreateExerciseActionsView.swift | 60 +++++++------- .../CreateWorkout/CreateViewModels.swift | 26 +++++- .../CreateWorkout/CreateWorkoutMainView.swift | 1 + .../Views/ExternalWorkoutDetailView.swift | 4 +- Werkout_ios/Views/ThotStyle.swift | 28 +++++++ .../WorkoutDetail/ExerciseListView.swift | 4 +- .../WorkoutDetail/WorkoutDetailView.swift | 6 +- Werkout_ios/Views/WorkoutHistoryView.swift | 14 +++- 13 files changed, 205 insertions(+), 103 deletions(-) create mode 100644 Werkout_ios/Views/ThotStyle.swift diff --git a/Werkout_ios.xcodeproj/project.pbxproj b/Werkout_ios.xcodeproj/project.pbxproj index f74a93f..20af24d 100644 --- a/Werkout_ios.xcodeproj/project.pbxproj +++ b/Werkout_ios.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ 1C485C8A2A492BB400A6F896 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C485C892A492BB400A6F896 /* LoginView.swift */; }; 1C485C8C2A49D65600A6F896 /* WorkoutHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C485C8B2A49D65600A6F896 /* WorkoutHistoryView.swift */; }; 1C485C8D2A49D95700A6F896 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A822A42347D0042FFBD /* Extensions.swift */; }; + 1C4AFF152A60F25F0027710B /* ThotStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C4AFF142A60F25E0027710B /* ThotStyle.swift */; }; + 1C4AFF162A60F27E0027710B /* ThotStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C4AFF142A60F25E0027710B /* ThotStyle.swift */; }; 1C5190C22A57CA5F00885849 /* OvalTextFieldStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C5190C12A57CA5F00885849 /* OvalTextFieldStyle.swift */; }; 1C5190C42A589CAC00885849 /* InfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C5190C32A589CAC00885849 /* InfoView.swift */; }; 1C5190C62A589CC100885849 /* ActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C5190C52A589CC100885849 /* ActionsView.swift */; }; @@ -126,6 +128,7 @@ 1C485C862A4915C400A6F896 /* CreateWorkoutItemPickerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateWorkoutItemPickerView.swift; sourceTree = ""; }; 1C485C892A492BB400A6F896 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = ""; }; 1C485C8B2A49D65600A6F896 /* WorkoutHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutHistoryView.swift; sourceTree = ""; }; + 1C4AFF142A60F25E0027710B /* ThotStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThotStyle.swift; sourceTree = ""; }; 1C5190C12A57CA5F00885849 /* OvalTextFieldStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OvalTextFieldStyle.swift; sourceTree = ""; }; 1C5190C32A589CAC00885849 /* InfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoView.swift; sourceTree = ""; }; 1C5190C52A589CC100885849 /* ActionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionsView.swift; sourceTree = ""; }; @@ -323,6 +326,7 @@ 1C5190C12A57CA5F00885849 /* OvalTextFieldStyle.swift */, 1CAF4D942A52180600B00E50 /* PlanWorkoutView.swift */, 1C31C8862A55B2CC00350540 /* PlayerUIView.swift */, + 1C4AFF142A60F25E0027710B /* ThotStyle.swift */, 1C485C8B2A49D65600A6F896 /* WorkoutHistoryView.swift */, 1CF65A8B2A44B7590042FFBD /* AccountView */, 1CF65A8A2A44B74D0042FFBD /* AddExercise */, @@ -601,6 +605,7 @@ 1CAF4D952A52180600B00E50 /* PlanWorkoutView.swift in Sources */, 1C5190C62A589CC100885849 /* ActionsView.swift in Sources */, 1CF65A5B2A3BF4BE0042FFBD /* Equipment.swift in Sources */, + 1C4AFF152A60F25F0027710B /* ThotStyle.swift in Sources */, 1C5190C82A589CDA00885849 /* CurrentWorkoutElapsedTimeView.swift in Sources */, 1CF65A452A39FB550042FFBD /* Exercise.swift in Sources */, 1CF65A612A3BF6020042FFBD /* AddExerciseView.swift in Sources */, @@ -616,6 +621,7 @@ 1CF65A962A452D270042FFBD /* Werkout_watchApp.swift in Sources */, 1CF65AA92A452D9C0042FFBD /* Workout.swift in Sources */, 1CF65AA62A452D9C0042FFBD /* Equipment.swift in Sources */, + 1C4AFF162A60F27E0027710B /* ThotStyle.swift in Sources */, 1CF65AB12A452E1A0042FFBD /* BridgeModule.swift in Sources */, 1CF65AAA2A452D9C0042FFBD /* RegisteredUser.swift in Sources */, 1CF65AB62A4532940042FFBD /* WatchMainViewModel.swift in Sources */, diff --git a/Werkout_ios/APIModels/Exercise.swift b/Werkout_ios/APIModels/Exercise.swift index 8898bc1..7de4383 100644 --- a/Werkout_ios/APIModels/Exercise.swift +++ b/Werkout_ios/APIModels/Exercise.swift @@ -26,22 +26,33 @@ struct ExerciseElement: Codable, Equatable { } extension ExerciseElement { - func videoURL(nsfw: Bool) -> URL? { - var _url: URL? + func videoURL(thotStyle: ThotStyle) -> URL? { + var urlString: String? - if nsfw { - let viddd = exercise.nsfwVideoURL - if let url = URL(string: BaseURLs.currentBaseURL + viddd) { - _url = url + switch thotStyle { + case .always: + urlString = exercise.nsfwVideoURL + case .never: + urlString = exercise.videoURL + case .recovery: + if self.exercise.name.lowercased() == "recover" { + urlString = exercise.nsfwVideoURL + } else { + urlString = exercise.videoURL } - } else { - let viddd = exercise.videoURL - if let url = URL(string: BaseURLs.currentBaseURL + viddd) { - _url = url + case .random: + if Bool.random() { + urlString = exercise.nsfwVideoURL + } else { + urlString = exercise.videoURL } } - return _url + if let urlString = urlString, + let url = URL(string: BaseURLs.currentBaseURL + urlString) { + return url + } + return nil } } @@ -84,21 +95,32 @@ struct ExerciseExercise: Codable, Hashable, Identifiable { } extension ExerciseExercise { - func videoURL(nsfw: Bool) -> URL? { - var _url: URL? + func videoURL(thotStyle: ThotStyle) -> URL? { + var urlString: String? - if nsfw { - let viddd = nsfwVideoURL - if let url = URL(string: BaseURLs.currentBaseURL + viddd) { - _url = url + switch thotStyle { + case .always: + urlString = nsfwVideoURL + case .never: + urlString = videoURL + case .recovery: + if self.name.lowercased() == "recovery" { + urlString = nsfwVideoURL + } else { + urlString = videoURL } - } else { - let viddd = videoURL - if let url = URL(string: BaseURLs.currentBaseURL + viddd) { - _url = url + case .random: + if Bool.random() { + urlString = nsfwVideoURL + } else { + urlString = videoURL } } - return _url + if let urlString = urlString, + let url = URL(string: BaseURLs.currentBaseURL + urlString) { + return url + } + return nil } } diff --git a/Werkout_ios/BridgeModule.swift b/Werkout_ios/BridgeModule.swift index 26dd06e..a63f426 100644 --- a/Werkout_ios/BridgeModule.swift +++ b/Werkout_ios/BridgeModule.swift @@ -142,7 +142,7 @@ class BridgeModule: NSObject, ObservableObject { if currentExerciseTimeLeft == 0 { playFinished() } else { - if currentExerciseTimeLeft <= 4 { + if currentExerciseTimeLeft <= 3 { playBeep() } } diff --git a/Werkout_ios/Views/AccountView/AccountView.swift b/Werkout_ios/Views/AccountView/AccountView.swift index 207e242..c43ab20 100644 --- a/Werkout_ios/Views/AccountView/AccountView.swift +++ b/Werkout_ios/Views/AccountView/AccountView.swift @@ -12,7 +12,7 @@ struct AccountView: View { @State var completedWorkouts: [CompletedWorkout]? @ObservedObject var userStore = UserStore.shared @State var showCompletedWorkouts: Bool = false - @AppStorage("showNSFWVideos") private var showNSFWVideos = false + @AppStorage("thotStyle") private var thotStyle: ThotStyle = .never var body: some View { VStack(alignment: .leading) { @@ -62,7 +62,15 @@ struct AccountView: View { } } Divider() - Toggle("Show NSFW Videos", isOn: $showNSFWVideos) + + Picker("THOT Style:", selection: $thotStyle) { + ForEach(ThotStyle.allCases, id: \.self) { style in + Text(style.stringValue()) + .tag(thotStyle.rawValue) + } + } + .pickerStyle(.segmented) + Spacer() Button("Logout", action: { diff --git a/Werkout_ios/Views/CompletedWorkout/CompletedWorkoutView.swift b/Werkout_ios/Views/CompletedWorkout/CompletedWorkoutView.swift index 4256c3c..34df422 100644 --- a/Werkout_ios/Views/CompletedWorkout/CompletedWorkoutView.swift +++ b/Werkout_ios/Views/CompletedWorkout/CompletedWorkoutView.swift @@ -16,47 +16,54 @@ struct CompletedWorkoutView: View { @State var difficulty: Float = 0 @State var notes: String = "" let completedWorkoutDismissed: ((Bool) -> Void)? + @State var isUploading: Bool = false var body: some View { - VStack { - topViews() - - Divider() - - HStack { - calsBurned() - .frame(maxWidth: .infinity) - - heartRates() - .frame(maxWidth: .infinity) + ZStack { + if isUploading { + ProgressView("Uploading") } - - rateWorkout() - .frame(maxHeight: 88) - - Divider() - - TextField("Notes", text: $notes) - .frame(height: 55) - .textFieldStyle(PlainTextFieldStyle()) - .padding([.horizontal], 4) - .overlay(RoundedRectangle(cornerRadius: 16).stroke(Color(uiColor: .clear))).background(Color(uiColor: .init(red: 200/255, green: 200/255, blue: 200/255, alpha: 0.2))) + VStack { + topViews() + + Divider() + + HStack { + calsBurned() + .frame(maxWidth: .infinity) + + heartRates() + .frame(maxWidth: .infinity) + } + + rateWorkout() + .frame(maxHeight: 88) + + Divider() + + TextField("Notes", text: $notes) + .frame(height: 55) + .textFieldStyle(PlainTextFieldStyle()) + .padding([.horizontal], 4) + .overlay(RoundedRectangle(cornerRadius: 16).stroke(Color(uiColor: .clear))).background(Color(uiColor: .init(red: 200/255, green: 200/255, blue: 200/255, alpha: 0.2))) + .cornerRadius(8) + + Spacer() + + Button("Upload", action: { + isUploading = true + upload(postBody: postData) + }) + .frame(maxWidth: .infinity, alignment: .center) + .frame(height: 44) + .foregroundColor(.blue) + .background(.yellow) .cornerRadius(8) - - Spacer() - - Button("Upload", action: { - upload(postBody: postData) - }) - .frame(maxWidth: .infinity, alignment: .center) - .frame(height: 44) - .foregroundColor(.blue) - .background(.yellow) - .cornerRadius(8) - .padding() - .frame(maxWidth: .infinity) + .padding() + .frame(maxWidth: .infinity) + } + .padding([.leading, .trailing]) } - .padding([.leading, .trailing]) } func topViews() -> some View { diff --git a/Werkout_ios/Views/CreateWorkout/CreateExerciseActionsView.swift b/Werkout_ios/Views/CreateWorkout/CreateExerciseActionsView.swift index 3871e2c..19adf8e 100644 --- a/Werkout_ios/Views/CreateWorkout/CreateExerciseActionsView.swift +++ b/Werkout_ios/Views/CreateWorkout/CreateExerciseActionsView.swift @@ -14,39 +14,41 @@ struct CreateExerciseActionsView: View { var body: some View { VStack { - if workoutExercise.exercise.isReps { - HStack { + HStack { + VStack { VStack { - HStack { - Text("Reps: ") - Text("\(workoutExercise.reps)") - } - Stepper("", onIncrement: { - workoutExercise.increaseReps() - }, onDecrement: { - workoutExercise.decreaseReps() - }) - .labelsHidden() + Text("Reps: ") + Text("\(workoutExercise.reps)") } - .frame(maxWidth: .infinity) - Divider() - VStack{ - HStack { - Text("Weight: ") - Text("\(workoutExercise.weight)") - } - Stepper("", onIncrement: { - workoutExercise.increaseWeight() - }, onDecrement: { - workoutExercise.decreaseWeight() - }) - .labelsHidden() - } - .frame(maxWidth: .infinity) + Stepper("", onIncrement: { + workoutExercise.increaseReps() + }, onDecrement: { + workoutExercise.decreaseReps() + }) + .labelsHidden() } - } else if workoutExercise.exercise.isDuration { + .frame(maxWidth: .infinity) + + Divider() + VStack{ - HStack { + VStack { + Text("Weight: ") + Text("\(workoutExercise.weight)") + } + Stepper("", onIncrement: { + workoutExercise.increaseWeight() + }, onDecrement: { + workoutExercise.decreaseWeight() + }) + .labelsHidden() + } + .frame(maxWidth: .infinity) + + Divider() + + VStack{ + VStack { Text("Duration: ") Text("\(workoutExercise.duration)") } diff --git a/Werkout_ios/Views/CreateWorkout/CreateViewModels.swift b/Werkout_ios/Views/CreateWorkout/CreateViewModels.swift index f497ae1..4690092 100644 --- a/Werkout_ios/Views/CreateWorkout/CreateViewModels.swift +++ b/Werkout_ios/Views/CreateWorkout/CreateViewModels.swift @@ -34,6 +34,7 @@ class CreateWorkoutExercise: ObservableObject, Identifiable { func increaseDuration() { self.duration += 15 + self.reps = 0 } func decreaseDuration() { @@ -58,7 +59,7 @@ class CreateWorkoutExercise: ObservableObject, Identifiable { class CreateWorkoutSuperSet: ObservableObject, Identifiable { let id = UUID() @Published var exercises = [CreateWorkoutExercise]() - @Published var numberOfRounds = 1 + @Published var numberOfRounds = 0 func increaseNumberOfRounds() { self.numberOfRounds += 1 @@ -66,8 +67,8 @@ class CreateWorkoutSuperSet: ObservableObject, Identifiable { func decreaseNumberOfRounds() { self.numberOfRounds -= 1 - if self.numberOfRounds < 1 { - self.numberOfRounds = 1 + if self.numberOfRounds < 0 { + self.numberOfRounds = 0 } } @@ -97,11 +98,30 @@ class WorkoutViewModel: ObservableObject { } } + func showRoundsError() { + + } + + func showNoDurationOrReps() { + + } + func uploadWorkout() { var exercises = [[String: Any]]() superSets.forEach({ superset in + if superset.numberOfRounds == 0 { + showRoundsError() + return + } + for _ in 0 ..< superset.numberOfRounds { for exercise in superset.exercises { + + if exercise.reps == 0 && exercise.duration == 0 { + showNoDurationOrReps() + return + } + let item = ["id": exercise.exercise.id, "reps": exercise.reps, "weight": exercise.weight, diff --git a/Werkout_ios/Views/CreateWorkout/CreateWorkoutMainView.swift b/Werkout_ios/Views/CreateWorkout/CreateWorkoutMainView.swift index 286b2fa..96009d1 100644 --- a/Werkout_ios/Views/CreateWorkout/CreateWorkoutMainView.swift +++ b/Werkout_ios/Views/CreateWorkout/CreateWorkoutMainView.swift @@ -57,6 +57,7 @@ struct CreateWorkoutMainView: View { viewModel.objectWillChange.send() }) Text("\(superset.wrappedValue.numberOfRounds)") + .foregroundColor(superset.numberOfRounds.wrappedValue > 0 ? .black : .red) } CreateWorkoutSupersetActionsView(workoutSuperSet: superset.wrappedValue, diff --git a/Werkout_ios/Views/ExternalWorkoutDetailView.swift b/Werkout_ios/Views/ExternalWorkoutDetailView.swift index 11b3813..551fe5d 100644 --- a/Werkout_ios/Views/ExternalWorkoutDetailView.swift +++ b/Werkout_ios/Views/ExternalWorkoutDetailView.swift @@ -11,7 +11,7 @@ import AVKit struct ExternalWorkoutDetailView: View { @StateObject var bridgeModule = BridgeModule.shared @State var avPlayer = AVPlayer(url: URL(string: "https://dev.werkout.fitness/media/exercise_videos/2_Dumbbell_Lateral_Lunges.mp4")!) - @AppStorage("showNSFWVideos") private var showNSFWVideos = false + @AppStorage("thotStyle") private var thotStyle: ThotStyle = .never var body: some View { ZStack { @@ -54,7 +54,7 @@ struct ExternalWorkoutDetailView: View { } } .onChange(of: bridgeModule.currentExercise, perform: { newValue in - if let videoURL = newValue?.videoURL(nsfw: showNSFWVideos) { + if let videoURL = newValue?.videoURL(thotStyle: thotStyle) { avPlayer = AVPlayer(url: videoURL) avPlayer.play() } diff --git a/Werkout_ios/Views/ThotStyle.swift b/Werkout_ios/Views/ThotStyle.swift new file mode 100644 index 0000000..4abe3db --- /dev/null +++ b/Werkout_ios/Views/ThotStyle.swift @@ -0,0 +1,28 @@ +// +// ThotStyle.swift +// Werkout_ios +// +// Created by Trey Tartt on 7/13/23. +// + +import Foundation + +enum ThotStyle: Int, CaseIterable { + case always = 1 + case never = 2 + case recovery = 3 + case random = 4 + + func stringValue() -> String { + switch(self) { + case .always: + return "Always" + case .never: + return "Never" + case .recovery: + return "Recovery" + case .random: + return "Random" + } + } +} diff --git a/Werkout_ios/Views/WorkoutDetail/ExerciseListView.swift b/Werkout_ios/Views/WorkoutDetail/ExerciseListView.swift index 3bf7a3d..9fa2628 100644 --- a/Werkout_ios/Views/WorkoutDetail/ExerciseListView.swift +++ b/Werkout_ios/Views/WorkoutDetail/ExerciseListView.swift @@ -9,14 +9,14 @@ import SwiftUI import AVKit struct ExerciseListView: View { - @AppStorage("showNSFWVideos") private var showNSFWVideos = false + @AppStorage("thotStyle") private var thotStyle: ThotStyle = .never @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 let videoURL = self.videoExercise?.videoURL(nsfw: showNSFWVideos) { + if let videoURL = self.videoExercise?.videoURL(thotStyle: thotStyle) { avPlayer = AVPlayer(url: videoURL) avPlayer.play() } diff --git a/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift index e0d4c7f..c163bc4 100644 --- a/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift +++ b/Werkout_ios/Views/WorkoutDetail/WorkoutDetailView.swift @@ -14,7 +14,7 @@ struct WorkoutDetailView: View { @StateObject var bridgeModule = BridgeModule.shared @Environment(\.dismiss) var dismiss - @AppStorage("showNSFWVideos") private var showNSFWVideos = false + @AppStorage("thotStyle") private var thotStyle: ThotStyle = .never enum Sheet: Identifiable { case completedWorkout([String: Any]) @@ -80,13 +80,13 @@ struct WorkoutDetailView: View { } } .onChange(of: bridgeModule.currentExercise, perform: { newValue in - if let videoURL = newValue?.videoURL(nsfw: showNSFWVideos) { + if let videoURL = newValue?.videoURL(thotStyle: thotStyle) { avPlayer = AVPlayer(url: videoURL) avPlayer.play() } }) .onAppear{ - if let videoURL = bridgeModule.currentExercise?.videoURL(nsfw: showNSFWVideos) { + if let videoURL = bridgeModule.currentExercise?.videoURL(thotStyle: thotStyle) { avPlayer = AVPlayer(url: videoURL) avPlayer.play() } diff --git a/Werkout_ios/Views/WorkoutHistoryView.swift b/Werkout_ios/Views/WorkoutHistoryView.swift index d9a9616..f15cc92 100644 --- a/Werkout_ios/Views/WorkoutHistoryView.swift +++ b/Werkout_ios/Views/WorkoutHistoryView.swift @@ -34,6 +34,8 @@ struct WorkoutHistoryView: View { let completedWorkouts: [CompletedWorkout] + @State private var selectedPlannedWorkout: Workout? + var body: some View { List { ForEach(completedWorkouts, id:\.self.id) { completedWorkout in @@ -48,9 +50,6 @@ struct WorkoutHistoryView: View { } VStack(alignment: .leading) { - HStack { - - } Text(completedWorkout.workout.name) .font(.title3) @@ -71,9 +70,18 @@ struct WorkoutHistoryView: View { } } .padding(.leading) + .contentShape(Rectangle()) + .onTapGesture { + selectedPlannedWorkout = completedWorkout.workout + } + } } } + .sheet(item: $selectedPlannedWorkout) { item in + let viewModel = WorkoutDetailViewModel(workout: item) + WorkoutDetailView(viewModel: viewModel, showAddToCalendar: true) + } } }