Fix timeline fetching when content filters hide all statuses#2389
Fix timeline fetching when content filters hide all statuses#2389
Conversation
|
@codex review |
There was a problem hiding this comment.
This PR is being reviewed by Cursor Bugbot
Details
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| guard await datasource.getFilteredItems().isEmpty else { return } | ||
| guard !(await datasource.getItems()).isEmpty else { return } | ||
|
|
||
| isAutoLoadingFilteredTimeline = true |
There was a problem hiding this comment.
Race condition in auto-fetch reentrancy guard
The reentrancy flag isAutoLoadingFilteredTimeline is checked at line 539 but not set to true until line 544, after two await suspension points at lines 541-542. In Swift's actor model, other code on @MainActor can run during these suspensions. Multiple calls to maybeLoadMoreForFilteredTimeline could pass the guard before any sets the flag, causing concurrent execution of the auto-load loop with duplicate network requests and potentially duplicate items appended to the datasource.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| guard await datasource.getFilteredItems().isEmpty else { return } | ||
| guard !(await datasource.getItems()).isEmpty else { return } |
There was a problem hiding this comment.
Treat gaps as empty when deciding auto-load
The guard here uses getFilteredItems().isEmpty, but getFilteredItems() always includes .gap entries. If a gap exists (e.g., after a prior pagination inserted one) and content filters hide all statuses, this check returns false and the auto-load is skipped even though there are zero visible statuses. That leaves the timeline effectively empty and defeats the intended “load until an unfiltered status appears” behavior. Consider checking getFiltered() or explicitly ignoring gaps when deciding to bail.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Summary
- Updated filtered timeline auto-load checks to ignore gaps and use filtered statuses when deciding to fetch more pages.
- Moved the auto-load reentrancy flag assignment ahead of async awaits to avoid concurrent auto-fetch loops.
Testing
⚠️ Not run (Xcode build tools not available in this environment).
Motivation
Description
filteredTimelineAutoFetchLimitandfilteredTimelineAutoFetchMaxPagesinTimelineViewModel.swiftto control auto-fetch thresholds.maybeLoadMoreForFilteredTimelinewhich usesstatusFetcher.fetchNextPageto append pages whendatasource.getFilteredItems()is empty butdatasource.getItems()is not empty.maybeLoadMoreForFilteredTimelineinto content-filter refresh and timeline update paths by calling it fromrefreshTimelineContentFilter,updateTimelineWithNewStatuses, andupdateDatasourceAndState.isAutoLoadingFilteredTimelineand stop loading when visible items appear, page limits are reached, or smaller-than-threshold pages are returned.Testing
Packages/Timeline/Sources/Timeline/View/TimelineViewModel.swiftbut compilation and unit tests should be run locally via Xcode orxcodebuildbefore merging.xcodebuild -scheme TimelineTests testand the app build for the target simulator to verify UI behaviour under various filter configurations.Codex Task
Note
Makes filtered timelines resilient when content filters hide all currently visible statuses.
Constants.filteredTimelineAutoFetchLimitandfilteredTimelineAutoFetchMaxPagesto bound auto-loadingmaybeLoadMoreForFilteredTimelineto iteratively callfetchNextPageuntil unfiltered items appear, limits are hit, or a short page is returned; guarded byisAutoLoadingFilteredTimelinerefreshTimelineContentFilter,updateTimelineWithNewStatuses, andupdateDatasourceAndStateso the UI populates after filtering updatesWritten by Cursor Bugbot for commit ebddf1b. This will update automatically on new commits. Configure here.