wip
This commit is contained in:
@ -28,7 +28,7 @@ struct WorkoutCardView: View {
|
||||
.font(.headline)
|
||||
.foregroundStyle(.white)
|
||||
|
||||
Text(workout.statusName)
|
||||
Text("\(workout.statusName)~")
|
||||
.font(.caption)
|
||||
.foregroundStyle(Color.accentColor)
|
||||
}
|
||||
|
@ -8,17 +8,24 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import SwiftData
|
||||
|
||||
struct WorkoutDetailView: View {
|
||||
let workout: Workout
|
||||
@Environment(\.modelContext) private var modelContext
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
@State private var showingCompletedDialog = false
|
||||
@State private var selectedLog: WorkoutLog? = nil
|
||||
@State private var navigateToExercise = false
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .center, spacing: 8) {
|
||||
if let logs = workout.logs?.sorted(by: { $0.order < $1.order }), !logs.isEmpty {
|
||||
List {
|
||||
ForEach(logs) { log in
|
||||
NavigationLink {
|
||||
ExerciseProgressControlView(log: log)
|
||||
Button {
|
||||
handleExerciseTap(log)
|
||||
} label: {
|
||||
WorkoutLogCardView(log: log)
|
||||
}
|
||||
@ -46,5 +53,88 @@ struct WorkoutDetailView: View {
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.navigationDestination(isPresented: $navigateToExercise) {
|
||||
if let selectedLog = selectedLog {
|
||||
ExerciseProgressControlView(log: selectedLog)
|
||||
}
|
||||
}
|
||||
.alert("Exercise Completed", isPresented: $showingCompletedDialog) {
|
||||
Button("Cancel", role: .cancel) {
|
||||
// Do nothing, just dismiss
|
||||
}
|
||||
Button("Restart") {
|
||||
if let log = selectedLog {
|
||||
restartExercise(log)
|
||||
}
|
||||
}
|
||||
Button("One More Set") {
|
||||
if let log = selectedLog {
|
||||
addOneMoreSet(log)
|
||||
}
|
||||
}
|
||||
} message: {
|
||||
Text("This exercise is already completed. What would you like to do?")
|
||||
}
|
||||
}
|
||||
|
||||
private func handleExerciseTap(_ log: WorkoutLog) {
|
||||
selectedLog = log
|
||||
|
||||
switch log.status {
|
||||
case .notStarted:
|
||||
// Start from beginning
|
||||
log.currentStateIndex = 0
|
||||
try? modelContext.save()
|
||||
navigateToExercise = true
|
||||
|
||||
case .inProgress:
|
||||
// If we're in a rest state, advance to the next set
|
||||
if let currentStateIndex = log.currentStateIndex, isRestState(currentStateIndex) {
|
||||
log.currentStateIndex = currentStateIndex + 1
|
||||
try? modelContext.save()
|
||||
}
|
||||
// Continue from current (possibly updated) position
|
||||
navigateToExercise = true
|
||||
|
||||
case .completed:
|
||||
// Show dialog for completed exercise
|
||||
showingCompletedDialog = true
|
||||
|
||||
default:
|
||||
// Default to not started behavior
|
||||
log.currentStateIndex = 0
|
||||
try? modelContext.save()
|
||||
navigateToExercise = true
|
||||
}
|
||||
}
|
||||
|
||||
private func restartExercise(_ log: WorkoutLog) {
|
||||
log.status = .notStarted
|
||||
log.currentStateIndex = 0
|
||||
log.elapsedSeconds = 0
|
||||
try? modelContext.save()
|
||||
navigateToExercise = true
|
||||
}
|
||||
|
||||
private func addOneMoreSet(_ log: WorkoutLog) {
|
||||
// Increment total sets
|
||||
log.sets += 1
|
||||
|
||||
// Calculate the state index for the additional set
|
||||
// States: intro(0) → set1(1) → rest1(2) → ... → setN(2N-1) → done(2N)
|
||||
// For the additional set, we want to go to setN+1 which is at index 2N+1
|
||||
let additionalSetStateIndex = (log.sets * 2) - 1
|
||||
|
||||
log.status = .inProgress
|
||||
log.currentStateIndex = additionalSetStateIndex
|
||||
log.elapsedSeconds = 0
|
||||
|
||||
try? modelContext.save()
|
||||
navigateToExercise = true
|
||||
}
|
||||
|
||||
private func isRestState(_ stateIndex: Int) -> Bool {
|
||||
// Rest states are at even indices > 0
|
||||
return stateIndex > 0 && stateIndex % 2 == 0
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ struct WorkoutLogCardView: View {
|
||||
.font(.headline)
|
||||
.lineLimit(1)
|
||||
|
||||
Text(log.status?.name ?? "Not Started")
|
||||
Text(getStatusText(for: log))
|
||||
.font(.caption)
|
||||
.foregroundStyle(Color.accentColor)
|
||||
|
||||
@ -31,4 +31,41 @@ struct WorkoutLogCardView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func getStatusText(for log: WorkoutLog) -> String {
|
||||
guard let status = log.status else {
|
||||
return "Not Started"
|
||||
}
|
||||
|
||||
if status == .inProgress, let currentStateIndex = log.currentStateIndex {
|
||||
let currentSet = getCurrentSetNumber(stateIndex: currentStateIndex, totalSets: log.sets)
|
||||
if currentSet > 0 {
|
||||
return "In Progress, Set #\(currentSet)"
|
||||
}
|
||||
}
|
||||
|
||||
return status.name
|
||||
}
|
||||
|
||||
private func getCurrentSetNumber(stateIndex: Int, totalSets: Int) -> Int {
|
||||
// Exercise states are structured as: intro(0) → set1(1) → rest1(2) → set2(3) → rest2(4) → ... → done
|
||||
// For each set number n, set state index = 2n-1, rest state index = 2n
|
||||
|
||||
if stateIndex <= 0 {
|
||||
return 0 // intro or invalid
|
||||
}
|
||||
|
||||
// Check if we're in a rest state (even indices > 0)
|
||||
let isRestState = stateIndex > 0 && stateIndex % 2 == 0
|
||||
|
||||
if isRestState {
|
||||
// During rest, show the next set number
|
||||
let nextSetNumber = (stateIndex / 2) + 1
|
||||
return min(nextSetNumber, totalSets)
|
||||
} else {
|
||||
// During set, show current set number
|
||||
let currentSetNumber = (stateIndex + 1) / 2
|
||||
return min(currentSetNumber, totalSets)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user