Repository navigation
feat(info): read show pages from the feed - #1184
Merged
Merged
Conversation
# Conflicts: # app/README.md # core/catalog/src/main/java/cx/aswin/boxlore/core/catalog/FeedReports.kt # core/catalog/src/test/resources/fixtures/v2/README.md # core/rss/src/main/java/cx/aswin/boxlore/core/rss/LocalEpisodeCatalogRefresh.kt
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 17 minutes. View limit details
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 |
# Conflicts: # core/catalog/README.md
…w-page # Conflicts: # app/README.md # app/src/main/java/cx/aswin/boxlore/AppContainer.kt # core/catalog/README.md # core/catalog/src/main/java/cx/aswin/boxlore/core/catalog/FeedReports.kt # core/catalog/src/main/java/cx/aswin/boxlore/core/catalog/SubscriptionForegroundSync.kt # core/catalog/src/test/java/cx/aswin/boxlore/core/catalog/FeedReportsTest.kt # core/catalog/src/test/resources/fixtures/v2/README.md # core/rss/src/main/java/cx/aswin/boxlore/core/rss/LocalEpisodeCatalogRefresh.kt
ashwkun
enabled auto-merge (squash)
October 27, 2026 18:58
|
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.



Title
feat(info): read show pages from the feedBuilt on top of #1182, which merges first. This PR uses that change's
FeedAddressUpdater, feed report and registry address unchanged.Summary
feed_first(off by default, fixed per process), the show page of a show you don't follow reads that show's own RSS feed into a copy stored on the phone. The copy shows straight away on the next visit, and the page reads the rest of the archive when search, oldest-first sorting or scrolling needs it./v2/episodes) and says so on a status line.feed_firstoff, shows you don't follow list/v2/episodesunder the IDs stored on this phone. In-show search filters that list on the phone. v1episodes/searchis no longer called, so served IDs never mix with recipe IDs. v1/episodesremains only as the last fallback.Motivation
What changed
:core:catalogPodcastRepository.showPageSource:RSS,FOLLOWED_CATALOG,FEEDorSERVER_LIST.getShowPageEpisodesserves the show page only. Smart Queue, Android Auto, Home, downloads and the episode page keepgetEpisodesPaginated, which reads a followed show's catalog or/v2/episodesand never the page's stored copy.FeedFirstShowPagesruns the failure ladder: read, one retry (not on 404/410),/v2/feed-report(reading a different direct address, or a proxy address through/v2/feed/<id>), then/v2/episodeswith a notice.404 not_proxiedanswer to its HTTPSfetchUrl.FeedReportLimiterbuilt inAppContaineris shared with feat(catalog): update feed addresses in one place and check them daily #1182's daily check. The show page leaves 5 of the 20 daily reports for followed shows and never reports a followed show.getEpisodeWindow,getEpisodes) for shows whose catalog isn't ready use the same IDs as the page: the copy around an episode it holds, else/v2/episodes, with v1 last (LEGACY(own-ids)).:core:rssShowPageFeedCatalogreads the newest 100 items with a streaming prefix reader (FeedPrefixReader,RssFeedClient.fetchNewest) or the whole archive.readyand unsubscribe TTL. A newest read that skips past stored items marks the archive incomplete again.:core:databaseLocalEpisodeCatalogDaoqueries for the v39 feed-first columns:setArchiveComplete,setLastOpenedAt,setTtlAndFollowed,seedFollowed,searchLimited,listUnfollowedCopies,deleteCatalogIfUnfollowed. No schema change; Room stays at v39.:core:domain:ShowPageFeedPort.:feature:infoPodcastInfoFeedFirstruns reads, the status line and reloads that keep rows, scroll and selection.ShowFeedLogicholds the decisions.ShowFeedStatusLineis a solidsurfaceContainerHighcard with a polite live region.Behavior & compatibility
feed_firstoff (default): show pages for shows you don't follow list boxlore's episode list under the IDs already stored on this phone. Followed shows andrss:shows are unchanged.feed_firston, new page states:podcastsrow are unchanged, exceptepNs, which a read may fill once. This path never calls/v2/episodes/registeror/v2/shows/feedsand never touches notification registrations. It reads and writes onlylocal_episodesandlocal_episode_feeds.rss:/negative IDs, cache keys, worker names, notification topics or the Room schema.Impact (required)
User impact — pick exactly one
user-impact-criticaluser-impact-highuser-impact-mediumuser-impact-lowno-user-impactListener impact
What changes in the user’s life:
Backend
backend-changeRelease copy (verbatim — highest priority)
CHANGELOG.md (required developer copy)
Added
feed_first: shows you don't follow read their own feed into a stored copy (FeedFirstShowPages,ShowPageFeedCatalog,PodcastInfoFeedFirst), with a failure ladder to/v2/episodes, a status line, and a daily cleanup of unfollowed copies after 30 days.Changed
/v2/episodesunder locally stored IDs whenfeed_firstis off; in-show search filters that list on the phone instead of calling v1episodes/search. Broken-feed reports share one limiter between the show page and the daily address check.README What's New / Upcoming
Improvements
Adaptive UI (phone / tablet / foldable)
PodcastInfoUiState, so it survives recreation.PodcastInfoAdaptiveTransitionTest(extended) drives 599↔600, 479↔480, 839↔840 landscape, portrait↔landscape and flat↔tabletop fold both ways, plusStateRestorationTesterrecreation. It covers the status line in every state, a list that grows (older episodes below, newer above, the archive read) and switches source (stored copy → server list → back) in the same frame as each window change. The scrolled-to row, the selection and the episodes it plays are kept.ShowFeedLogicTestandPodcastInfoFeedFirstTestcover the reload anchor and the status states.Test plan
./gradlew :feature:info:testDebugUnitTest :core:catalog:testDebugUnitTest :core:rss:testDebugUnitTest :core:downloads:testDebugUnitTest :core:database:testDebugUnitTest :app:testDebugUnitTest :app:compileDebugKotlin detektPodcastRepositoryShowPagesTest: recorded/v2/episodes,/v2/podcastdirect and proxy, and/v2/feednot_proxiedfixtures through the real repository; only the show page reads the copy; rollback; playback windows under the page's IDs.FeedFirstShowPagesTest: ladder, report to proxy target, followed shows not reported, cleanup not blocking open.FeedReportsTest: shared limiter, reserve.ShowPageFeedCatalogTest: TTL kept, gap marks the archive incomplete,followedseeded, cleanup keeps history, downloads, queue and aliases.ShowPageFeedRulesTest,FeedPrefixReaderTest,ShowFeedLogicTest,PodcastInfoFeedFirstTest,AutoDownloadCoordinatorTest.installDebug)feed_firston for the device, restart the app, and open a show you don't follow.feed_firstoff. The same show lists its episodes from boxlore's list, and search still finds them.Notes
/v2/feed-reportanswer. Recording one would queue a real re-check and use up report quota. Tests use the documented response shape instead.