This commit is contained in:
Trey t
2025-03-13 22:12:50 -05:00
parent fb22f47a82
commit ca25d61019
15 changed files with 218 additions and 90 deletions

View File

@@ -28,6 +28,7 @@ struct ContentView: View {
} else { } else {
PlayerView(player: $avPlayer) PlayerView(player: $avPlayer)
.onAppear{ .onAppear{
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
.onReceive(videoEnded){ _ in .onReceive(videoEnded){ _ in
@@ -49,6 +50,7 @@ struct ContentView: View {
func playVideo(url: String) { func playVideo(url: String) {
let url = URL(string: BaseURLs.currentBaseURL + url) let url = URL(string: BaseURLs.currentBaseURL + url)
avPlayer = AVPlayer(url: url!) avPlayer = AVPlayer(url: url!)
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }

View File

@@ -63,31 +63,51 @@ struct Workout: Codable, Identifiable, Equatable {
} }
extension Array where Element == Workout { extension Array where Element == Workout {
func filterWorkouts(searchString: String, filteredRegisterdUser: RegisteredUser?) -> [Workout] { func filterWorkouts(nameSearchString: String,
musclesSearchString: Set<String>,
equipmentSearchString: Set<String>,
filteredRegisterdUser: RegisteredUser?) -> [Workout] {
var matchingWorkouts = [Workout]() var matchingWorkouts = [Workout]()
if (!searchString.isEmpty && searchString.count > 0) { if matchingWorkouts.isEmpty {
matchingWorkouts.append(contentsOf: self)
}
if (!nameSearchString.isEmpty && nameSearchString.count > 0) {
matchingWorkouts = self.filter({ matchingWorkouts = self.filter({
if $0.name.lowercased().contains(searchString.lowercased()) { if $0.name.lowercased().contains(nameSearchString.lowercased()) {
return true 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 return false
}) })
} }
if matchingWorkouts.isEmpty { if (!equipmentSearchString.isEmpty && equipmentSearchString.count > 0) {
matchingWorkouts.append(contentsOf: self) matchingWorkouts = matchingWorkouts.filter({
if let equipment = $0.equipment?.joined(separator: "").lowercased() {
for word in equipmentSearchString {
if equipment.contains(word.lowercased()) {
return true
}
}
return false
}
return false
})
}
if (!musclesSearchString.isEmpty && musclesSearchString.count > 0) {
matchingWorkouts = matchingWorkouts.filter({
if let muscles = $0.muscles?.joined(separator: "").lowercased() {
for word in musclesSearchString {
if muscles.contains(word.lowercased()) {
return true
}
}
return false
}
return false
})
} }
if let filteredRegisterdUser = filteredRegisterdUser { if let filteredRegisterdUser = filteredRegisterdUser {

View File

@@ -12,6 +12,6 @@ enum BaseURLs: String {
case dev = "https://dev.werkout.fitness" case dev = "https://dev.werkout.fitness"
static var currentBaseURL: String { static var currentBaseURL: String {
return BaseURLs.local.rawValue return BaseURLs.dev.rawValue
} }
} }

View File

@@ -9,11 +9,13 @@ import SwiftUI
enum SortType: String, CaseIterable { enum SortType: String, CaseIterable {
case name = "Name" case name = "Name"
case date = "Date" case createdDate = "Created Date"
} }
struct AllWorkoutsListView: View { struct AllWorkoutsListView: View {
@State var searchString: String = "" @State var searchNameString: String = ""
@State var selectedMuscles: Set<String> = []
@State var selectedEquipment: Set<String> = []
@Binding var uniqueWorkoutUsers: [RegisteredUser]? @Binding var uniqueWorkoutUsers: [RegisteredUser]?
@State private var filteredRegisterdUser: RegisteredUser? @State private var filteredRegisterdUser: RegisteredUser?
@@ -30,7 +32,9 @@ struct AllWorkoutsListView: View {
Text((filteredRegisterdUser.firstName ?? "NA") + "'s Workouts") Text((filteredRegisterdUser.firstName ?? "NA") + "'s Workouts")
} }
FilterAllView(searchString: $searchString, FilterAllView(selectedMuscles: $selectedMuscles,
selectedEquipment: $selectedEquipment,
searchNameString: $searchNameString,
uniqueWorkoutUsers: $uniqueWorkoutUsers, uniqueWorkoutUsers: $uniqueWorkoutUsers,
filteredRegisterdUser: $filteredRegisterdUser, filteredRegisterdUser: $filteredRegisterdUser,
filteredWorkouts: $filteredWorkouts, filteredWorkouts: $filteredWorkouts,
@@ -55,13 +59,28 @@ struct AllWorkoutsListView: View {
refresh() refresh()
} }
} }
.onChange(of: searchString) { newValue in .onChange(of: searchNameString) { newValue in
filteredWorkouts = workouts.filterWorkouts(searchString: searchString, filteredRegisterdUser: filteredRegisterdUser) filterWorkouts()
}
.onChange(of: selectedMuscles) { newValue in
filterWorkouts()
}
.onChange(of: selectedEquipment) { newValue in
filterWorkouts()
} }
.onAppear{ .onAppear{
filteredWorkouts = workouts.filterWorkouts(searchString: searchString, filteredRegisterdUser: filteredRegisterdUser) filterWorkouts()
} }
} }
func filterWorkouts() {
filteredWorkouts = workouts.filterWorkouts(
nameSearchString: searchNameString,
musclesSearchString: selectedMuscles,
equipmentSearchString: selectedEquipment,
filteredRegisterdUser: filteredRegisterdUser
)
}
} }
struct AllWorkoutsListView_Previews: PreviewProvider { struct AllWorkoutsListView_Previews: PreviewProvider {

View File

@@ -155,7 +155,7 @@ struct AllWorkoutsView: View {
healthStore.requestAuthorization(toShare: nil, read: healthKitTypes) { (succ, error) in healthStore.requestAuthorization(toShare: nil, read: healthKitTypes) { (succ, error) in
if !succ { if !succ {
fatalError("Error requesting authorization from health store: \(String(describing: error)))") // fatalError("Error requesting authorization from health store: \(String(describing: error)))")
} }
} }
} }

View File

@@ -76,19 +76,19 @@ struct CompletedWorkoutView: View {
.onAppear{ .onAppear{
bridgeModule.sendWorkoutCompleteToWatch() bridgeModule.sendWorkoutCompleteToWatch()
} }
.onChange(of: bridgeModule.healthKitUUID, perform: { healthKitUUID in // .onChange(of: bridgeModule.healthKitUUID, perform: { healthKitUUID in
if let healthKitUUID = healthKitUUID { // if let healthKitUUID = healthKitUUID {
gettingHealthKitData = true // gettingHealthKitData = true
healthKitHelper.getDetails(forHealthKitUUID: healthKitUUID, // healthKitHelper.getDetails(forHealthKitUUID: healthKitUUID,
completion: { healthKitWorkoutData in // completion: { healthKitWorkoutData in
guard let healthStore = healthKitWorkoutData else { // guard let healthStore = healthKitWorkoutData else {
return // return
} // }
self.healthKitWorkoutData = healthKitWorkoutData // self.healthKitWorkoutData = healthKitWorkoutData
gettingHealthKitData = false // gettingHealthKitData = false
}) // })
} // }
}) // })
} }
func upload(postBody: [String: Any]) { func upload(postBody: [String: Any]) {

View File

@@ -89,8 +89,6 @@ struct CreateExerciseActionsView: View {
Spacer() Spacer()
} }
Divider()
} }
} }
} }

View File

@@ -26,6 +26,7 @@ struct ExternalWorkoutDetailView: View {
PlayerView(player: $avPlayer) PlayerView(player: $avPlayer)
.frame(width: metrics.size.width * 0.5, height: metrics.size.height * 0.8) .frame(width: metrics.size.width * 0.5, height: metrics.size.height * 0.8)
.onAppear{ .onAppear{
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
} }
@@ -48,6 +49,7 @@ struct ExternalWorkoutDetailView: View {
.frame(width: metrics.size.width * 0.2, .frame(width: metrics.size.width * 0.2,
height: metrics.size.height * 0.2) height: metrics.size.height * 0.2)
.onAppear{ .onAppear{
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
} }

View File

@@ -25,6 +25,7 @@ struct ExerciseListView: View {
exerciseName: self.videoExercise?.name, exerciseName: self.videoExercise?.name,
workout: bridgeModule.currentWorkoutInfo.workout) { workout: bridgeModule.currentWorkoutInfo.workout) {
avPlayer = AVPlayer(url: videoURL) avPlayer = AVPlayer(url: videoURL)
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
} }
@@ -137,6 +138,7 @@ struct ExerciseListView: View {
.sheet(item: $videoExercise) { exercise in .sheet(item: $videoExercise) { exercise in
PlayerView(player: $avPlayer) PlayerView(player: $avPlayer)
.onAppear{ .onAppear{
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
} }

View File

@@ -46,6 +46,7 @@ struct WorkoutDetailView: View {
PlayerView(player: $avPlayer) PlayerView(player: $avPlayer)
.frame(width: metrics.size.width * 1, height: metrics.size.height * 1) .frame(width: metrics.size.width * 1, height: metrics.size.height * 1)
.onAppear{ .onAppear{
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
@@ -59,6 +60,7 @@ struct WorkoutDetailView: View {
exerciseName: currentExtercise.exercise.name, exerciseName: currentExtercise.exercise.name,
workout: bridgeModule.currentWorkoutInfo.workout) { workout: bridgeModule.currentWorkoutInfo.workout) {
avPlayer = AVPlayer(url: otherVideoURL) avPlayer = AVPlayer(url: otherVideoURL)
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
}, label: { }, label: {
@@ -169,6 +171,7 @@ struct WorkoutDetailView: View {
exerciseName: currentExtercise.exercise.name, exerciseName: currentExtercise.exercise.name,
workout: bridgeModule.currentWorkoutInfo.workout) { workout: bridgeModule.currentWorkoutInfo.workout) {
avPlayer = AVPlayer(url: videoURL) avPlayer = AVPlayer(url: videoURL)
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
} }
@@ -181,6 +184,7 @@ struct WorkoutDetailView: View {
} }
.onReceive(NotificationCenter.default.publisher( .onReceive(NotificationCenter.default.publisher(
for: UIScene.willEnterForegroundNotification)) { _ in for: UIScene.willEnterForegroundNotification)) { _ in
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
} }
@@ -194,6 +198,7 @@ struct WorkoutDetailView: View {
exerciseName: currentExtercise.exercise.name, exerciseName: currentExtercise.exercise.name,
workout: bridgeModule.currentWorkoutInfo.workout) { workout: bridgeModule.currentWorkoutInfo.workout) {
avPlayer = AVPlayer(url: videoURL) avPlayer = AVPlayer(url: videoURL)
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
} }

View File

@@ -12,9 +12,8 @@ struct AddSupersetView: View {
@Binding var selectedCreateWorkoutSuperSet: CreateWorkoutSuperSet? @Binding var selectedCreateWorkoutSuperSet: CreateWorkoutSuperSet?
var body: some View { var body: some View {
VStack { TabView {
ForEach(createWorkoutSuperSet.exercises, id: \.id) { createWorkoutExercise in ForEach(createWorkoutSuperSet.exercises, id: \.id) { createWorkoutExercise in
HStack {
VStack { VStack {
Text(createWorkoutExercise.exercise.name) Text(createWorkoutExercise.exercise.name)
.font(.title2) .font(.title2)
@@ -27,10 +26,20 @@ struct AddSupersetView: View {
CreateExerciseActionsView(workoutExercise: createWorkoutExercise, CreateExerciseActionsView(workoutExercise: createWorkoutExercise,
superset: createWorkoutSuperSet, superset: createWorkoutSuperSet,
viewModel: viewModel) viewModel: viewModel)
}
.frame(width: 300.0)
.padding(.bottom, 40)
}
}
.frame(height: 300)
.tabViewStyle(.page)
.onAppear {
setupAppearance()
}
}
} func setupAppearance() {
} UIPageControl.appearance().currentPageIndicatorTintColor = .black
} UIPageControl.appearance().pageIndicatorTintColor = UIColor.black.withAlphaComponent(0.2)
}
} }
} }

View File

@@ -82,6 +82,7 @@ struct AllExerciseView: View {
.sheet(item: $videoExercise) { exercise in .sheet(item: $videoExercise) { exercise in
PlayerView(player: $avPlayer) PlayerView(player: $avPlayer)
.onAppear{ .onAppear{
avPlayer.isMuted = true
avPlayer.play() avPlayer.play()
} }
} }

View File

@@ -8,7 +8,9 @@
import SwiftUI import SwiftUI
struct FilterAllView: View { struct FilterAllView: View {
@Binding var searchString: String @Binding var selectedMuscles: Set<String>
@Binding var selectedEquipment: Set<String>
@Binding var searchNameString: String
@Binding var uniqueWorkoutUsers: [RegisteredUser]? @Binding var uniqueWorkoutUsers: [RegisteredUser]?
@Binding var filteredRegisterdUser: RegisteredUser? @Binding var filteredRegisterdUser: RegisteredUser?
@Binding var filteredWorkouts: [Workout] @Binding var filteredWorkouts: [Workout]
@@ -16,18 +18,23 @@ struct FilterAllView: View {
@Binding var currentSort: SortType? @Binding var currentSort: SortType?
var body: some View { var body: some View {
HStack { VStack {
TextField("Filter" ,text: $searchString) TextField("Search by name" ,text: $searchNameString)
.padding(.horizontal) .padding(.horizontal)
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
HStack {
if let uniqueWorkoutUsers = uniqueWorkoutUsers { if let uniqueWorkoutUsers = uniqueWorkoutUsers {
Menu(content: { Menu(content: {
ForEach(uniqueWorkoutUsers, id: \.self) { index in ForEach(uniqueWorkoutUsers, id: \.self) { index in
Button(action: { Button(action: {
filteredRegisterdUser = index filteredRegisterdUser = index
filteredWorkouts = workouts.filterWorkouts(searchString: searchString, filteredWorkouts = workouts.filterWorkouts(
filteredRegisterdUser: filteredRegisterdUser) nameSearchString: searchNameString,
musclesSearchString: selectedMuscles,
equipmentSearchString: selectedEquipment,
filteredRegisterdUser: filteredRegisterdUser
)
}, label: { }, label: {
Text((index.firstName ?? "") + " -" + (index.lastName ?? "")) Text((index.firstName ?? "") + " -" + (index.lastName ?? ""))
}) })
@@ -35,7 +42,12 @@ struct FilterAllView: View {
Button(action: { Button(action: {
filteredRegisterdUser = nil filteredRegisterdUser = nil
filteredWorkouts = workouts.filterWorkouts(searchString: searchString,filteredRegisterdUser: filteredRegisterdUser) filteredWorkouts = workouts.filterWorkouts(
nameSearchString: searchNameString,
musclesSearchString: selectedMuscles,
equipmentSearchString: selectedEquipment,
filteredRegisterdUser: filteredRegisterdUser
)
}, label: { }, label: {
Text("All") Text("All")
}) })
@@ -58,6 +70,61 @@ struct FilterAllView: View {
Image(systemName: "list.number") Image(systemName: "list.number")
.padding(.trailing) .padding(.trailing)
}) })
if let equipments = DataStore.shared.allEquipment {
Menu(content: {
ForEach(equipments, id: \.id) { equipment in
Button(action: {
if selectedEquipment.contains(equipment.name) {
selectedEquipment.remove(equipment.name)
} else {
selectedEquipment.insert(equipment.name)
}
}, label: {
if selectedEquipment.contains(equipment.name) {
Image(systemName: "checkmark")
}
Text(equipment.name)
})
}
}, label: {
Image(systemName: "scalemass")
.padding(.trailing)
})
}
if let muscles = DataStore.shared.allMuscles {
Menu(content: {
ForEach(muscles, id: \.id) { muscle in
Button(action: {
if selectedMuscles.contains(muscle.name) {
selectedMuscles.remove(muscle.name)
} else {
selectedMuscles.insert(muscle.name)
}
}, label: {
if selectedMuscles.contains(muscle.name) {
Image(systemName: "checkmark")
}
Text(muscle.name)
})
}
}, label: {
Image(systemName: "brain.head.profile")
.padding(.trailing)
})
}
Button(action: {
selectedMuscles.removeAll()
selectedEquipment.removeAll()
searchNameString = ""
filteredRegisterdUser = nil
}, label: {
Image(systemName: "xmark.circle")
.padding(.trailing)
})
}
} }
} }
@@ -71,7 +138,7 @@ struct FilterAllView: View {
filteredWorkouts = filteredWorkouts.sorted(by: { filteredWorkouts = filteredWorkouts.sorted(by: {
$0.name < $1.name $0.name < $1.name
}) })
case .date: case .createdDate:
filteredWorkouts = filteredWorkouts.sorted(by: { filteredWorkouts = filteredWorkouts.sorted(by: {
$0.createdAt ?? Date() < $1.createdAt ?? Date() $0.createdAt ?? Date() < $1.createdAt ?? Date()
}) })
@@ -81,7 +148,9 @@ struct FilterAllView: View {
} }
#Preview { #Preview {
FilterAllView(searchString: .constant(""), FilterAllView(selectedMuscles: .constant([]),
selectedEquipment: .constant([]),
searchNameString: .constant(""),
uniqueWorkoutUsers: .constant(nil), uniqueWorkoutUsers: .constant(nil),
filteredRegisterdUser: .constant(nil), filteredRegisterdUser: .constant(nil),
filteredWorkouts: .constant(PreviewData.allWorkouts()), filteredWorkouts: .constant(PreviewData.allWorkouts()),

View File

@@ -13,7 +13,7 @@ struct PlannedWorkoutView: View {
var body: some View { var body: some View {
List { List {
ForEach(workouts, id:\.workout.name) { plannedWorkout in ForEach(workouts.sorted(by: { $0.onDate < $1.onDate }), id:\.workout.name) { plannedWorkout in
HStack { HStack {
VStack(alignment: .leading) { VStack(alignment: .leading) {
Text(plannedWorkout.onDate.plannedDate?.weekDay ?? "-") Text(plannedWorkout.onDate.plannedDate?.weekDay ?? "-")

View File

@@ -62,6 +62,7 @@ class PlayerUIView: UIView {
if let playerItem = notification.object as? AVPlayerItem { if let playerItem = notification.object as? AVPlayerItem {
playerItem.seek(to: .zero, completionHandler: nil) playerItem.seek(to: .zero, completionHandler: nil)
self.playerLayer.player?.play() self.playerLayer.player?.play()
self.playerLayer.player?.isMuted = true
} }
} }
} }