Rework the Apple Watch progress flow

Watch root lists every in-progress workout; picking an exercise runs a paged Ready -> work/rest -> Finish flow (One More + auto-firing Done), with a phase-dot row and brand-tinted count-up/down timers. Includes the configurable rest and auto-finish settings synced over WatchConnectivity and the wrist-down timer fix.
This commit is contained in:
2026-06-20 14:15:31 -04:00
parent f2da47a70a
commit f06c4e996e
9 changed files with 373 additions and 111 deletions
@@ -32,7 +32,7 @@ final class WatchConnectivityBridge: NSObject {
// Apply whatever the phone last pushed, then ask for a fresh push.
applyState(WCPayload.decodeSplits(session.receivedApplicationContext),
workouts: WCPayload.decodeWorkouts(session.receivedApplicationContext))
applyRestSeconds(session.receivedApplicationContext)
applySettings(session.receivedApplicationContext)
requestSync()
}
@@ -63,10 +63,13 @@ final class WatchConnectivityBridge: NSObject {
}
}
private func applyRestSeconds(_ dict: [String: Any]) {
private func applySettings(_ dict: [String: Any]) {
if let rest = WCPayload.decodeRestSeconds(dict) {
UserDefaults.standard.set(rest, forKey: WCPayload.restSecondsKey)
}
if let done = WCPayload.decodeDoneCountdownSeconds(dict) {
UserDefaults.standard.set(done, forKey: WCPayload.doneCountdownSecondsKey)
}
}
private func applyState(_ splits: [SplitDocument], workouts: [WorkoutDocument]) {
@@ -101,9 +104,11 @@ extension WatchConnectivityBridge: WCSessionDelegate {
let splits = WCPayload.decodeSplits(applicationContext)
let workouts = WCPayload.decodeWorkouts(applicationContext)
let rest = WCPayload.decodeRestSeconds(applicationContext)
let done = WCPayload.decodeDoneCountdownSeconds(applicationContext)
Task { @MainActor in
self.applyState(splits, workouts: workouts)
if let rest { UserDefaults.standard.set(rest, forKey: WCPayload.restSecondsKey) }
if let done { UserDefaults.standard.set(done, forKey: WCPayload.doneCountdownSecondsKey) }
}
}
}