Workout check-in: missed state + rest-day compensation (KC-16)
- Notification actions on workout reminders/check-ins: "Yes, I completed it", "No, I didn't" (marks the day missed, then asks to compensate on a rest day), "Remind me in 1 hour" (snooze). - VM: missedDates + compensations (persisted/synced), per-date markWorkoutDone/Missed, workoutStatus, upcomingRestDays, scheduleCompensation, promptCompensation, checkPendingMissed. program(for:) returns a compensation program on its rest day. - CompensationSheet: pick a rest day or keep as missed; compensation days get a one-off "Missed workout recovery" reminder. - Long-press menus: workout row (Done / Not Done / Compensate) in Today + Calendar; exercise cards (Mark as Done / Not Done). All actions are per-date — one occurrence never affects another. - Workout row shows Pending / Done / Missed + "Compensation" label. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,7 @@ struct ContentView: View {
|
||||
.onAppear {
|
||||
if !hasOnboarded { showOnboarding = true }
|
||||
workoutVM.resetSetsForNewDayIfNeeded()
|
||||
workoutVM.checkPendingMissed()
|
||||
CloudSyncManager.shared.restoreSettings()
|
||||
CloudSyncManager.shared.backupSettings()
|
||||
HealthKitManager.shared.bootstrap()
|
||||
@@ -111,6 +112,7 @@ struct ContentView: View {
|
||||
consumeWidgetAddTask()
|
||||
workoutVM.resetSetsForNewDayIfNeeded()
|
||||
workoutVM.checkPendingHealthConfirm()
|
||||
workoutVM.checkPendingMissed()
|
||||
CloudSyncManager.shared.backupSettings()
|
||||
NotificationManager.shared.reschedule(workoutVM: workoutVM, taskVM: taskVM)
|
||||
Task {
|
||||
@@ -123,6 +125,12 @@ struct ContentView: View {
|
||||
NotificationManager.shared.reschedule(workoutVM: workoutVM, taskVM: taskVM)
|
||||
WidgetCenter.shared.reloadAllTimelines()
|
||||
}
|
||||
.sheet(item: $workoutVM.askCompensate) { missed in
|
||||
CompensationSheet(missed: missed)
|
||||
.environmentObject(workoutVM)
|
||||
.presentationDetents([.medium, .large])
|
||||
.presentationDragIndicator(.visible)
|
||||
}
|
||||
.onChange(of: workoutVM.doneSets) { _ in
|
||||
NotificationManager.shared.reschedule(workoutVM: workoutVM, taskVM: taskVM)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user