Machine-based exercises now carry ordered name/value comfort settings (seat height, back-rest position, ...) on both ExerciseDocument and, as a plan-time snapshot, WorkoutLogDocument — the optional array doubles as the machine flag. Editable from the exercise editor's new Machine section and from the workout row's settings sheet, whose mid-workout edits write back to the originating split (workout saved first, so seed clone-on-edit repointing can't clobber the log edit). Schema tightening rides the same rev: splits bump to v2 (weight-reminder fields and the unused exercise category removed), workouts to v3 (the derived `completed` flag removed; status is the single source). Starter seeds regenerated at v2 with unchanged ULIDs; SwiftData cache schema bumped to rebuild. SCHEMA.md documents the shapes. Claude-Session: https://claude.ai/code/session_01LEoff8bXGBS83tK1c55Mf7
69 lines
2.4 KiB
Swift
69 lines
2.4 KiB
Swift
#if DEBUG
|
|
import SwiftUI
|
|
import SwiftData
|
|
|
|
/// DEBUG-only root used for App Store screenshot capture. Bypasses the iCloud gate and
|
|
/// renders one fully-formed screen (chosen by `--screen`) against the seeded cache, so
|
|
/// captures are deterministic with no UI automation. Never compiled into release.
|
|
struct ScreenshotRootView: View {
|
|
let services: AppServices
|
|
|
|
private var activeWorkout: Workout? {
|
|
let context = services.container.mainContext
|
|
var descriptor = FetchDescriptor<Workout>(sortBy: [SortDescriptor(\.start, order: .reverse)])
|
|
descriptor.fetchLimit = 25
|
|
let workouts = (try? context.fetch(descriptor)) ?? []
|
|
return workouts.first { $0.status == .inProgress } ?? workouts.first
|
|
}
|
|
|
|
var body: some View {
|
|
content
|
|
.environment(services)
|
|
.environment(services.syncEngine)
|
|
.environment(services.liveRunState)
|
|
.modelContainer(services.container)
|
|
}
|
|
|
|
@ViewBuilder
|
|
private var content: some View {
|
|
if let workout = activeWorkout {
|
|
switch ScreenshotSeed.screen(default: "workouts") {
|
|
case "exercise":
|
|
let logID = WorkoutDocument(from: workout).logs.first { $0.exerciseName == "Seated Row" }?.id
|
|
NavigationStack { ExerciseView(workout: workout, logID: logID ?? "") }
|
|
case "run":
|
|
ScreenshotRunView(workout: workout)
|
|
case "settings":
|
|
SettingsView()
|
|
default:
|
|
NavigationStack { WorkoutLogListView(workout: workout) }
|
|
}
|
|
} else {
|
|
Color(.systemBackground)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// The paged run flow for the in-progress exercise, showing the animated form guide
|
|
/// (with machine props) — the screenshot works off its own local document copy, so
|
|
/// nothing persists.
|
|
private struct ScreenshotRunView: View {
|
|
@State private var doc: WorkoutDocument
|
|
private let logID: String
|
|
|
|
init(workout: Workout) {
|
|
let document = WorkoutDocument(from: workout)
|
|
_doc = State(initialValue: document)
|
|
logID = document.logs.first { $0.exerciseName == "Seated Row" }?.id
|
|
?? document.logs.first?.id ?? ""
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
ExerciseProgressView(doc: $doc, logID: logID, onChange: {},
|
|
onLive: { _ in }, onLiveEnded: {}, incomingFrame: nil)
|
|
}
|
|
}
|
|
}
|
|
#endif
|