Workout "mark all complete" + recurring-task done confirmation notification

- Workout window: the header ⋯ menu gains "Mark All Complete" and "Clear All
  Sets" (Manage Workouts preserved). New WorkoutViewModel.setAllSetsDone(_:)
  ticks every set across all sections/exercises and runs the normal completion/
  logging path.
- Recurring tasks: completing an occurrence now posts a quiet "✓ Done. Repeats
  <tomorrow / in 1 week / …>" confirmation via NotificationManager
  .notifyRecurringCompleted, phrased from the next active occurrence. Hooked
  into TaskViewModel.toggleOccurrence; un-completing does nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
kutesir
2026-06-16 23:20:13 +03:00
parent e7e8d07100
commit bcb66ef691
4 changed files with 80 additions and 2 deletions

View File

@@ -766,6 +766,24 @@ class WorkoutViewModel: ObservableObject {
if doneSets == totalSets && totalSets > 0 { logWorkoutCompleted() }
}
/// Mark every set of the active workout done/undone the "Select all & mark
/// complete" quick action. Logs completion when everything is checked.
func setAllSetsDone(_ done: Bool) {
for si in activeSections.indices {
for ei in activeSections[si].exercises.indices {
for idx in activeSections[si].exercises[ei].sets.indices {
activeSections[si].exercises[ei].sets[idx].isDone = done
}
}
}
if done {
if sessionStartDate == nil { sessionStartDate = Date() }
UserDefaults.kisani.set(iso.string(from: Date()), forKey: kLastActiveDay)
}
syncBack()
if done, doneSets == totalSets && totalSets > 0 { logWorkoutCompleted() }
}
func addSet(sectionId: UUID, to exerciseId: UUID) {
guard let si = activeSections.firstIndex(where: { $0.id == sectionId }),
let ei = activeSections[si].exercises.firstIndex(where: { $0.id == exerciseId })

View File

@@ -322,9 +322,15 @@ class TaskViewModel: ObservableObject {
guard let idx = tasks.firstIndex(where: { $0.id == t.id }) else { return }
let key = occurrenceKey(date)
var set = Set(tasks[idx].completedOccurrences ?? [])
if set.contains(key) { set.remove(key) } else { set.insert(key) }
let nowDone: Bool
if set.contains(key) { set.remove(key); nowDone = false } else { set.insert(key); nowDone = true }
tasks[idx].completedOccurrences = Array(set)
save()
// Completing a recurring occurrence " Done. Repeats " confirmation.
if nowDone {
let next = nextActiveOccurrence(tasks[idx], from: date)
NotificationManager.shared.notifyRecurringCompleted(title: tasks[idx].title, nextOccurrence: next)
}
}
/// A display copy of a recurring task pinned to one occurrence date, with that