Queue document writes durably and surface sync trouble in the UI
iCloud Drive writes now flow through a persistent WriteBacklog sidecar (drained with backoff, flushed on backgrounding, wiped with the cache on account change), so a save can never be lost to a transient coordinator error. A status banner on the workout list surfaces stuck syncing. Also: the split picker gains a Recent section with day labels, split rows fold SplitItem into SplitListView, and list rows dim the multiply sign in sets-by-reps. Claude-Session: https://claude.ai/code/session_01HJDQQDA9QdP8zByg43H5v3
This commit is contained in:
@@ -19,10 +19,15 @@ struct WorkoutLogListView: View {
|
||||
/// race against the cache, which lags local writes by a beat.
|
||||
@State private var doc: WorkoutDocument
|
||||
|
||||
/// The live cache entity, kept only to observe `updatedAt` for the absorb
|
||||
/// below — all rendering and editing goes through the `doc` snapshot.
|
||||
private let workout: Workout
|
||||
|
||||
@State private var showingExercisePicker = false
|
||||
@State private var selectedLogID: String?
|
||||
|
||||
init(workout: Workout) {
|
||||
self.workout = workout
|
||||
_doc = State(initialValue: WorkoutDocument(from: workout))
|
||||
}
|
||||
|
||||
@@ -94,6 +99,20 @@ struct WorkoutLogListView: View {
|
||||
}
|
||||
}
|
||||
.navigationTitle(doc.splitName ?? Split.unnamed)
|
||||
// Absorb phone edits while this screen is open (H1's watch-side gap):
|
||||
// without this, the snapshot stays frozen at init, and the next watch
|
||||
// tick — made against a state that's missing the phone's edit — would be
|
||||
// stamped fresh and clobber it wholesale on the phone. Strictly-newer
|
||||
// guard only: an equal timestamp is our own edit echoing back through
|
||||
// the phone's push, and a stale push in flight (the phone pushed before
|
||||
// ingesting our latest edit) must not regress what the user is looking
|
||||
// at. Clock skew across devices degrades this to a skipped absorb —
|
||||
// never to a clobber of local state.
|
||||
.onChange(of: workout.updatedAt) { _, incoming in
|
||||
if incoming > doc.updatedAt {
|
||||
doc = WorkoutDocument(from: workout)
|
||||
}
|
||||
}
|
||||
.navigationDestination(item: $selectedLogID) { logID in
|
||||
ExerciseProgressView(
|
||||
doc: $doc,
|
||||
|
||||
Reference in New Issue
Block a user