Add the discovery data layer behind Daily Picks, Trending and Recently Viewed - #114
Open
Conversation
…y Viewed Three new endpoints and the two view models that drive the Explore tab. No UI consumes them yet apart from view recording. `NetworkManager` gains `getDailyPicks`, `getTrendingPosts(category:page:limit:)` and `recordPostView`. The last one needed a `post(url:)` overload because it is the first request in the app that sends no body and decodes no response — the server upserts one view per viewer/post/UTC-day and ignores your own listings, so the client can fire it unconditionally and ignore failures. `ExploreViewModel` is a shared singleton with a 3-minute freshness window, since Explore is a tab root that re-appears constantly and should not refetch on every visit. Trending is keyed by category so switching categories bypasses the cache. `RecentlyViewedViewModel` keeps its own ordered id list plus a listing cache in `AppStorage`, so the section renders from disk on launch and only fetches the posts it is missing, eight at a time. `ProductDetailsViewModel.setPost` is what feeds it — opening a listing caches it locally and reports the view to the server. `Post` picks up the save-count fields. The count arrives under three different key spellings depending on endpoint, and `getPostInfo` returns `savers` as a user array rather than a number, so `displaySaveCount` takes the largest of whatever decoded. Trending payloads often omit savers entirely, hence `ensuringMinimumSaves` — if the viewer has the post saved locally, the true count is at least one. That is a lower bound, not a global total; worth confirming against the backend before we lean on it further. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017R8mua9xepzF3mnRETtd6W
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three new endpoints and the two view models that drive the Explore tab. No UI
consumes them yet apart from view recording.
NetworkManagergainsgetDailyPicks,getTrendingPosts(category:page:limit:)and
recordPostView. The last one needed apost(url:)overload because it isthe first request in the app that sends no body and decodes no response — the
server upserts one view per viewer/post/UTC-day and ignores your own listings,
so the client can fire it unconditionally and ignore failures.
ExploreViewModelis a shared singleton with a 3-minute freshness window, sinceExplore is a tab root that re-appears constantly and should not refetch on every
visit. Trending is keyed by category so switching categories bypasses the cache.
RecentlyViewedViewModelkeeps its own ordered id list plus a listing cache inAppStorage, so the section renders from disk on launch and only fetches theposts it is missing, eight at a time.
ProductDetailsViewModel.setPostis whatfeeds it — opening a listing caches it locally and reports the view to the
server.
Postpicks up the save-count fields. The count arrives under three differentkey spellings depending on endpoint, and
getPostInforeturnssaversas auser array rather than a number, so
displaySaveCounttakes the largest ofwhatever decoded. Trending payloads often omit savers entirely, hence
ensuringMinimumSaves— if the viewer has the post saved locally, the truecount is at least one. That is a lower bound, not a global total; worth
confirming against the backend before we lean on it further.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_017R8mua9xepzF3mnRETtd6W