mirror of
https://github.com/block/buzz.git
synced 2026-11-02 15:31:27 +00:00
Returning to an already-open channel after a few minutes in the background could replace its messages with the loading skeleton. The relay session drops its socket five seconds into the background, so nearly every return to the app reconnects. When that reconnect took more than two seconds, the channel page covered the loaded timeline with the connection skeleton until the relay came back. The messages provider already keeps the cached timeline through a reconnect, so the overlay was the only thing hiding it. Now a loaded timeline stays visible while the relay reconnects. The skeleton still shows when nothing has loaded yet, and forums keep their existing behavior (skeleton only before any posts load). To keep a reconnect indicator, the iOS title capsule now shows a thin bar in the chat color (the Appearance accent) along its bottom edge while a page with loaded content is not current. For a channel timeline that covers both the reconnect and the catch-up after it (resubscribing and fetching the newest window). The wait has no known length, so the bar sweeps in, pulses until the channel is current, then fades. Reduce Motion shows a static bar. Forums show it only while reconnecting, because their posts provider doesn't refetch after a reconnect. The native navigation view owns the bar, so it survives title rebuilds. Android has no title capsule and is unchanged. ### Demo iPhone 18 Pro simulator on a local relay: background the app for more than 5s with the relay down, return, then let the relay come back. About 8s of relay startup is cut from the middle. https://github.com/user-attachments/assets/e88d0191-766b-4054-bc00-99ed306cd0cc ### Before merge - [x] Kenny Lopez reviews the visible changes ([approved in Buzz #buzz-mobile](buzz://message?channel=9f18f3c6-b5e5-453d-b36d-65487913be0b&id=c8b01eaa3760e44c3b6583f2e02bec576d78679adfb364e5fe718cc0926bdc2d)). ### Validation - Updated tests: the reconnect cases in `channel_detail_page_test.dart` and `loading_review_tests.dart` now assert that loaded messages and cached media stay visible and in place during a reconnect. - Added test: the iOS navigation payload sets `titleRefreshing` while a loaded timeline reconnects and clears it on connect. - Added test: `isCatchingUp` holds from reconnect until the newest window merges, and is already false when that state publishes. - Added test: a failed catch-up after reconnect still notifies listeners once, with `isCatchingUp` false, so the bar clears. - `flutter analyze` clean, iOS simulator build succeeds, and the full mobile suite passes on the final head. - Checked visually on an iOS 27 simulator (demo above): loaded messages stay visible on resume, and the bar pulses from foreground until the reconnect's catch-up finishes, then fades. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Tom Brow <tomb@squareup.com> Co-authored-by: Tom Brow <tomb@squareup.com> Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>