182 lines
6.1 KiB
Swift
182 lines
6.1 KiB
Swift
//
|
|
// AllWorkoutsView.swift
|
|
// Werkout_ios
|
|
//
|
|
// Created by Trey Tartt on 6/15/23.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftUI
|
|
import HealthKit
|
|
import SharedCore
|
|
|
|
enum MainViewTypes: Int, CaseIterable {
|
|
case AllWorkout = 0
|
|
case MyWorkouts
|
|
|
|
var title: String {
|
|
switch self {
|
|
|
|
case .AllWorkout:
|
|
return "All Workouts"
|
|
case .MyWorkouts:
|
|
return "Planned Workouts"
|
|
}
|
|
}
|
|
}
|
|
|
|
struct AllWorkoutsView: View {
|
|
@State var isUpdating = false
|
|
@State var workouts: [Workout]?
|
|
@State var uniqueWorkoutUsers: [RegisteredUser]?
|
|
let healthStore = HKHealthStore()
|
|
var bridgeModule = BridgeModule.shared
|
|
@State public var needsUpdating: Bool = true
|
|
|
|
@ObservedObject var dataStore = DataStore.shared
|
|
@ObservedObject var userStore = UserStore.shared
|
|
|
|
@State private var showWorkoutDetail = false
|
|
@State private var selectedWorkout: Workout? {
|
|
didSet {
|
|
bridgeModule.currentWorkoutInfo.workout = selectedWorkout
|
|
}
|
|
}
|
|
|
|
@State private var selectedPlannedWorkout: Workout? {
|
|
didSet {
|
|
bridgeModule.currentWorkoutInfo.workout = selectedPlannedWorkout
|
|
}
|
|
}
|
|
|
|
@State private var showLoginView = false
|
|
@State private var selectedSegment: MainViewTypes = .AllWorkout
|
|
@State var selectedDate: Date = Date()
|
|
private let runtimeReporter = RuntimeReporter.shared
|
|
|
|
let pub = NotificationCenter.default.publisher(for: AppNotifications.createdNewWorkout)
|
|
|
|
var body: some View {
|
|
ZStack {
|
|
if let workouts = workouts {
|
|
VStack {
|
|
AllWorkoutPickerView(mainViews: MainViewTypes.allCases,
|
|
selectedSegment: $selectedSegment,
|
|
showCurrentWorkout: {
|
|
selectedWorkout = bridgeModule.currentWorkoutInfo.workout
|
|
})
|
|
|
|
switch selectedSegment {
|
|
case .AllWorkout:
|
|
if isUpdating {
|
|
ProgressView()
|
|
.progressViewStyle(.circular)
|
|
}
|
|
|
|
AllWorkoutsListView(uniqueWorkoutUsers: $uniqueWorkoutUsers,
|
|
workouts: workouts,
|
|
selectedWorkout: { workout in
|
|
selectedWorkout = workout
|
|
}, refresh: {
|
|
self.needsUpdating = true
|
|
maybeRefreshData()
|
|
})
|
|
|
|
Divider()
|
|
case .MyWorkouts:
|
|
PlannedWorkoutView(workouts: userStore.plannedWorkouts,
|
|
selectedPlannedWorkout: $selectedPlannedWorkout)
|
|
}
|
|
}
|
|
} else {
|
|
ProgressView("Updating")
|
|
}
|
|
}
|
|
.background(Color(uiColor: .systemGray5))
|
|
.onAppear{
|
|
// UserStore.shared.logout()
|
|
authorizeHealthKit()
|
|
maybeRefreshData()
|
|
}
|
|
.sheet(item: $selectedWorkout) { item in
|
|
let isPreview = item.id == bridgeModule.currentWorkoutInfo.workout?.id
|
|
let viewModel = WorkoutDetailViewModel(workout: item, isPreview: isPreview)
|
|
WorkoutDetailView(viewModel: viewModel)
|
|
}
|
|
.sheet(item: $selectedPlannedWorkout) { item in
|
|
let viewModel = WorkoutDetailViewModel(workout: item, isPreview: true)
|
|
WorkoutDetailView(viewModel: viewModel)
|
|
}
|
|
.sheet(isPresented: $showLoginView) {
|
|
LoginView(completion: {
|
|
self.needsUpdating = true
|
|
maybeRefreshData()
|
|
})
|
|
.interactiveDismissDisabled()
|
|
}
|
|
.onReceive(pub) { (output) in
|
|
self.needsUpdating = true
|
|
maybeRefreshData()
|
|
}
|
|
}
|
|
|
|
func maybeRefreshData() {
|
|
if userStore.token != nil{
|
|
if userStore.plannedWorkouts.isEmpty {
|
|
userStore.fetchPlannedWorkouts()
|
|
}
|
|
|
|
if needsUpdating {
|
|
self.isUpdating = true
|
|
dataStore.fetchAllData(completion: {
|
|
DispatchQueue.main.async {
|
|
guard let allWorkouts = dataStore.allWorkouts else {
|
|
self.isUpdating = false
|
|
return
|
|
}
|
|
self.workouts = allWorkouts.sorted(by: {
|
|
$0.createdAt ?? Date() < $1.createdAt ?? Date()
|
|
})
|
|
self.isUpdating = false
|
|
self.uniqueWorkoutUsers = dataStore.workoutsUniqueUsers
|
|
self.needsUpdating = false
|
|
}
|
|
})
|
|
}
|
|
} else {
|
|
isUpdating = false
|
|
showLoginView = true
|
|
}
|
|
}
|
|
|
|
func authorizeHealthKit() {
|
|
let quantityTypes = [
|
|
HKObjectType.quantityType(forIdentifier: .heartRate),
|
|
HKObjectType.quantityType(forIdentifier: .activeEnergyBurned),
|
|
HKObjectType.quantityType(forIdentifier: .oxygenSaturation)
|
|
].compactMap { $0 }
|
|
|
|
let healthKitTypes: Set<HKObjectType> = Set(
|
|
quantityTypes + [
|
|
HKObjectType.activitySummaryType(),
|
|
HKQuantityType.workoutType()
|
|
]
|
|
)
|
|
|
|
healthStore.requestAuthorization(toShare: nil, read: healthKitTypes) { (success, error) in
|
|
if success == false {
|
|
runtimeReporter.recordWarning(
|
|
"HealthKit authorization request did not succeed",
|
|
metadata: ["error": error?.localizedDescription ?? "unknown"]
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct AllWorkoutsView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
AllWorkoutsView(workouts: PreviewData.allWorkouts())
|
|
}
|
|
}
|