The UX redesign's first landing (spec in UX-REDESIGN.md): ContentView becomes a Today / Progress / Settings TabView, "Routine" replaces "Split" in every user-facing string and view name (code-level types keep their names), and workout starting moves to shared WorkoutStarter / StartedWorkoutNavigator plumbing. - New Progress tab: weekly goal streaks, workout trends, per-exercise weight progression, achievements, and the full history list (WorkoutLogsView -> WorkoutHistoryView). - Goals: stable categories workouts roll up to, managed from Settings. - New Meditation exercise + starter routine; timed sits record to Apple Health as Mind & Body sessions. Claude-Session: https://claude.ai/code/session_012qw2itfzKyEJ1HpsFt8Ex4
46 lines
1.7 KiB
Swift
46 lines
1.7 KiB
Swift
//
|
|
// WorkoutStarter.swift
|
|
// Workouts
|
|
//
|
|
// Copyright 2026 Rouslan Zenetl. All Rights Reserved.
|
|
//
|
|
|
|
import IndieSync
|
|
import Foundation
|
|
|
|
/// The one place a workout is created from a routine. Both start paths — the routine
|
|
/// picker sheet and the Today board — call this so the plan-time log snapshot and
|
|
/// the returned id stay identical per site.
|
|
@MainActor
|
|
enum WorkoutStarter {
|
|
/// Builds and saves a fresh workout from a routine (plan-time log snapshot per
|
|
/// exercise) and returns the new workout's id so the caller can navigate once the
|
|
/// cache catches up. Deliberately does NOT touch the watch: the wrist session
|
|
/// launches only when the first exercise actually starts (see
|
|
/// `SyncEngine.onWorkoutBecameActive`), so a peek-then-back never spins one up.
|
|
static func start(routine: Routine, sync: SyncEngine) async -> String {
|
|
let startDate = Date()
|
|
let logs = routine.exercisesArray.enumerated().map { index, exercise in
|
|
WorkoutLogDocument(planFrom: ExerciseDocument(from: exercise), order: index, date: startDate)
|
|
}
|
|
|
|
// A freshly started workout has no `end` — only completion stamps it.
|
|
let doc = WorkoutDocument(
|
|
schemaVersion: WorkoutDocument.currentSchemaVersion,
|
|
id: ULID.make(),
|
|
routineID: routine.id,
|
|
routineName: routine.name,
|
|
start: startDate,
|
|
end: nil,
|
|
status: WorkoutStatus.notStarted.rawValue,
|
|
createdAt: startDate,
|
|
updatedAt: startDate,
|
|
logs: logs,
|
|
restSeconds: routine.restSeconds, autoAdvance: routine.autoAdvance
|
|
)
|
|
|
|
await sync.save(workout: doc)
|
|
return doc.id
|
|
}
|
|
}
|