Add App Store screenshot harness + listing metadata
DEBUG-only screenshot support (seeded sample data via ScreenshotSeed, per-screen launch args, screenshot roots for both apps) so iPhone + Apple Watch App Store shots can be captured deterministically from the simulator — all excluded from release builds. Also seed ExerciseView's set-grid progress in init so it renders correctly on the first frame. Adds Scripts/metadata/ as the listing source of truth (copy, URLs, review notes, and the captured screenshots). Claude-Session: https://claude.ai/code/session_018gg69MaUetDNzWzBXisfMV
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
#if DEBUG
|
||||
import SwiftUI
|
||||
import SwiftData
|
||||
|
||||
/// DEBUG-only root for App Store screenshot capture on the watch. Renders one
|
||||
/// fully-formed screen (chosen by `--screen`) against the seeded cache so captures are
|
||||
/// deterministic. Never compiled into release.
|
||||
struct WatchScreenshotRoot: View {
|
||||
let services: WatchAppServices
|
||||
|
||||
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.bridge)
|
||||
.modelContainer(services.container)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var content: some View {
|
||||
if let workout = activeWorkout {
|
||||
switch ScreenshotSeed.screen(default: "list") {
|
||||
case "work":
|
||||
ProgressHost(workout: workout, exerciseName: "Lat Pulldown", page: nil)
|
||||
case "rest":
|
||||
ProgressHost(workout: workout, exerciseName: "Lat Pulldown", page: 1)
|
||||
default:
|
||||
NavigationStack { WorkoutLogListView(workout: workout) }
|
||||
}
|
||||
} else {
|
||||
Color.black
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Hosts the progress view with a working-copy binding (and an optional pinned page so
|
||||
/// we can capture a rest phase, which the normal resume logic never lands on).
|
||||
private struct ProgressHost: View {
|
||||
@State private var doc: WorkoutDocument
|
||||
private let logID: String
|
||||
private let page: Int?
|
||||
|
||||
init(workout: Workout, exerciseName: String, page: Int?) {
|
||||
let document = WorkoutDocument(from: workout)
|
||||
_doc = State(initialValue: document)
|
||||
logID = document.logs.first { $0.exerciseName == exerciseName }?.id ?? document.logs.first?.id ?? ""
|
||||
self.page = page
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ExerciseProgressView(doc: $doc, logID: logID, onChange: {}, debugInitialPage: page)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user