android: keep the paged feed stable across no-op refreshes #7
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/feed-scroll-state-restore"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Scroll deep into the feed, leave the app for a moment, and come back: the grid has jumped towards the top and takes a long time to load the items again.
Root cause
Three stacked issues:
SyncWorker.syncConfigured(pullOnly = true)) and after every periodic feed sync,refreshCoreData()bumped the feed revision unconditionally — even when the sync merged nothing. The revision bump makesFeedScreenre-runFeedRepository.reset(...).reset()truncated the loaded list. A same-query refresh replaced the loaded rows with only the first page (48 rows), so a deeply scrolled grid clamped towards the top.loadUntil(anchor), which paged 48 rows at a time through the single serialized core lane — one round-trip per page — and each page fetch ran inside the anchorLaunchedEffect, which restarts whenloadingtoggles and could cancel the in-flight fetch.Fix
SyncWorker.syncConfigurednow skipsrefreshCoreData()when the sync'sSyncMergeStatsare all zero: a routine foreground pull or no-op push can no longer disturb the feed.FeedRepository.reset()keeps the already-loaded rows when the fresh first page is identical to their prefix (feed content unchanged); any real change still falls through to the fresh page.FeedRepository.loadUntil()fetches a single batch sized to cover the anchor (one core round-trip instead of one per page), andFeedScreenlaunches the restore on a composition scope so it survives the effect'sloading-triggered restarts.Testing
FeedRepositoryRoutingTest: updatedloadUntilPagesDownToTheTargetIndexfor batched fetching and addedloadUntilCoversADeepAnchorWithOneBatchedRequest,sameQueryResetKeepsPagedRowsWhenTheFeedDidNotChange, andsameQueryResetReplacesRowsWhenTheFeedChanged. All pass.UniffiLib/libinvio_core.sonot loadable in the unit-test JVM) are pre-existing onmainand unrelated.