Make the live run two-way: drive from either device
The propped-up iPhone now runs the real ExerciseProgressView for a live watch workout instead of a read-only mirror, and the live-run channel is symmetric — either device can drive the flow and the other follows. Each page transition is classified human / auto / remote: only human transitions (swipe, Start, One More, swipe-back reset) are broadcast and recorded by the actor; auto-advances (rest / timed-work countdown) record locally but aren't sent, since both devices reach them independently off the shared wall-clock anchors; an applied remote frame jumps the page without re-recording or re-broadcasting. That rule is also what stops an echo loop. - PhoneConnectivityBridge gains sendLiveProgress/sendLiveEnded (the missing phone->watch direction); WatchConnectivityBridge receives frames into an observable liveIncoming via a new didReceiveMessage route. Both share one increasing per-run version sequence so the stale-frame guard works across the two devices' counters. - Both ExerciseProgressViews gain an incomingFrame input + applyIncoming (syncing setCount for a remote One More); the iPhone one gains the liveSnapshot/broadcast machinery the watch already had. - New LiveRunCoverView wraps the real driver for the cover (resolves the workout, persists via SyncEngine, wires the live channel + close); ContentView presents it; LiveProgressMirrorView is removed. Claude-Session: https://claude.ai/code/session_01SCv7zvGFcKy47KSTnTLxRe
This commit is contained in:
@@ -12,13 +12,14 @@ struct ContentView: View {
|
||||
|
||||
var body: some View {
|
||||
WorkoutLogsView()
|
||||
// Prop the phone up and it mirrors a live workout running on the Apple Watch.
|
||||
// Prop the phone up and it runs the live Apple Watch workout — two-way: drive from
|
||||
// either device and the other follows.
|
||||
.fullScreenCover(isPresented: Binding(
|
||||
get: { liveRun.presentable != nil },
|
||||
set: { presenting in if !presenting { liveRun.mute() } }
|
||||
)) {
|
||||
if let frame = liveRun.presentable {
|
||||
LiveProgressMirrorView(progress: frame) { liveRun.mute() }
|
||||
LiveRunCoverView(frame: frame) { liveRun.mute() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user