wip
This commit is contained in:
@ -85,7 +85,7 @@ struct WorkoutDetailView: View {
|
||||
List {
|
||||
ForEach(logs) { log in
|
||||
NavigationLink {
|
||||
WorkoutLogDetailView(log: log)
|
||||
ExerciseProgressControlView(log: log)
|
||||
} label: {
|
||||
WorkoutLogCardView(log: log)
|
||||
}
|
||||
|
@ -11,12 +11,15 @@ import SwiftUI
|
||||
import SwiftData
|
||||
|
||||
enum ExerciseState: Identifiable {
|
||||
case detail
|
||||
case set(number: Int)
|
||||
case rest(afterSet: Int)
|
||||
case done
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
case .detail:
|
||||
return "detail"
|
||||
case .set(let number):
|
||||
return "set_\(number)"
|
||||
case .rest(let afterSet):
|
||||
@ -46,6 +49,13 @@ enum ExerciseState: Identifiable {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var isDetail: Bool {
|
||||
if case .detail = self {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
struct ExerciseProgressControlView: View {
|
||||
@ -62,6 +72,10 @@ struct ExerciseProgressControlView: View {
|
||||
var body: some View {
|
||||
TabView(selection: $currentStateIndex) {
|
||||
ForEach(Array(exerciseStates.enumerated()), id: \.element.id) { index, state in
|
||||
if state.isDetail {
|
||||
ExerciseDetailView(log: log, onStart: { moveToNextState() })
|
||||
.tag(index)
|
||||
} else {
|
||||
ExerciseStateView(
|
||||
state: state,
|
||||
elapsedSeconds: elapsedSeconds,
|
||||
@ -72,6 +86,7 @@ struct ExerciseProgressControlView: View {
|
||||
.tag(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
.tabViewStyle(.page(indexDisplayMode: .never))
|
||||
.onChange(of: currentStateIndex) { oldValue, newValue in
|
||||
if oldValue != newValue {
|
||||
@ -91,17 +106,20 @@ struct ExerciseProgressControlView: View {
|
||||
private func setupExerciseStates() {
|
||||
var states: [ExerciseState] = []
|
||||
|
||||
// Create states for each set and rest period
|
||||
for setNumber in 1...log.sets {
|
||||
states.append(.set(number: setNumber))
|
||||
// Add the detail view as the first state
|
||||
states.append(.detail)
|
||||
|
||||
// Add rest period after each set except the last one
|
||||
if setNumber < log.sets {
|
||||
states.append(.rest(afterSet: setNumber))
|
||||
// Create alternating set and rest states based on the log's set count
|
||||
for i in 1...log.sets {
|
||||
states.append(.set(number: i))
|
||||
|
||||
// Add rest after each set except the last one
|
||||
if i < log.sets {
|
||||
states.append(.rest(afterSet: i))
|
||||
}
|
||||
}
|
||||
|
||||
// Add done state at the end
|
||||
// Add the final DONE state
|
||||
states.append(.done)
|
||||
|
||||
exerciseStates = states
|
||||
@ -219,30 +237,32 @@ struct ExerciseStateView: View {
|
||||
return "Resting"
|
||||
case .done:
|
||||
return "Exercise Complete"
|
||||
case .detail:
|
||||
return "Swipe to Start"
|
||||
}
|
||||
}
|
||||
|
||||
private var buttonTitle: String {
|
||||
switch state {
|
||||
case .set:
|
||||
return "Complete Set"
|
||||
case .rest:
|
||||
return "Start Next Set"
|
||||
case .done:
|
||||
return "DONE"
|
||||
}
|
||||
}
|
||||
// private var buttonTitle: String {
|
||||
// switch state {
|
||||
// case .set:
|
||||
// return "Complete Set"
|
||||
// case .rest:
|
||||
// return "Start Next Set"
|
||||
// case .done:
|
||||
// return "DONE"
|
||||
// }
|
||||
// }
|
||||
|
||||
private var buttonColor: Color {
|
||||
switch state {
|
||||
case .set:
|
||||
return .accentColor
|
||||
case .rest:
|
||||
return .orange
|
||||
case .done:
|
||||
return .green
|
||||
}
|
||||
}
|
||||
// private var buttonColor: Color {
|
||||
// switch state {
|
||||
// case .set:
|
||||
// return .accentColor
|
||||
// case .rest:
|
||||
// return .orange
|
||||
// case .done:
|
||||
// return .green
|
||||
// }
|
||||
// }
|
||||
|
||||
private var timeFormatted: String {
|
||||
let minutes = elapsedSeconds / 60
|
||||
@ -251,7 +271,53 @@ struct ExerciseStateView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Extension to safely access array elements
|
||||
// Detail view shown as the first item in the exercise progress carousel
|
||||
struct ExerciseDetailView: View {
|
||||
let log: WorkoutLog
|
||||
let onStart: () -> Void
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .center, spacing: 16) {
|
||||
Text(log.exerciseName)
|
||||
.font(.title)
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.layoutPriority(1)
|
||||
|
||||
HStack(alignment: .bottom) {
|
||||
Text("\(log.weight)")
|
||||
Text("lbs")
|
||||
.fontWeight(.light)
|
||||
.padding([.trailing], 10)
|
||||
|
||||
Text("\(log.sets)")
|
||||
Text("×")
|
||||
.fontWeight(.light)
|
||||
Text("\(log.reps)")
|
||||
}
|
||||
.font(.title3)
|
||||
.lineLimit(1)
|
||||
.minimumScaleFactor(0.5)
|
||||
.layoutPriority(1)
|
||||
|
||||
Text(log.status?.name ?? "Not Started")
|
||||
.foregroundStyle(Color.accentColor)
|
||||
|
||||
// Spacer()
|
||||
//
|
||||
// Button(action: onStart) {
|
||||
// Text("Start Exercise")
|
||||
// .font(.headline)
|
||||
// .frame(maxWidth: .infinity)
|
||||
// }
|
||||
// .buttonStyle(.borderedProminent)
|
||||
// .tint(.accentColor)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
// Helper extension to safely access array elements
|
||||
extension Array {
|
||||
subscript(safe index: Index) -> Element? {
|
||||
return indices.contains(index) ? self[index] : nil
|
||||
|
Reference in New Issue
Block a user