feat(anime): episode navigation and autoplay in the stream player #92
No reviewers
Labels
No labels
bug
documentation
duplicate
good first issue
help wanted
improvement
invalid
maintenance
phone
question
tablet
tv
ui
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
asteria/ProxerAndroid!92
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/anime-episode-navigation"
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?
Adds next/previous episode controls to the anime player and continues automatically into the next episode when one finishes.
What it does
areBookmarksAutomatic, exactly as the episode list already does. Going backwards does not bookmark.How it works
StreamActivityis launched with an already-resolved video URL, so it previously had no way to reach a neighbouring episode. A new standaloneStreamEpisodeViewModellists the hosters for the target episode, prefers the one already playing, and walks candidates until one resolves to a playableVideo— resolvers can also returnLink/App/Message, which the internal player can't use. The activity then swaps the media source in place rather than restarting itself.Two things fall out of that worth calling out for review:
episodeAmountandhosterNameride along as intent extras;AnimeScreenalready has both before any stream can play, andStreamActivityisn't exported. WhenepisodeAmountis absent the controls hide and autoplay is off.makeIntentnow copies its template intent.StreamActivityassigns the returned intent to itself andStreamPlayerManagerwrites playback bookkeeping onto it, which would otherwise mutate the shared instance across episodes.Bugs caught in review and fixed here
retry()prepares the local player withsetMediaSource(source, resetPosition = false), which deliberately keepsgetCurrentPosition().reset()only seeked whenstartPosition > 0, but the ordinary autoplay case is<= 0— a never-watched episode has no stored position. Episode 2 therefore started at episode 1's runtime, ended instantly, and chain-loaded the rest of the series. Now seeks unconditionally, coerced to 0 (which also stops-1reachingCastPlayer.seekTo).Refererinterceptor and ad tag were baked in at construction, so an episode resolved from a different hoster was fetched with the wrong referer (403 on hosts that check it). Both are now rebuilt on reset, and the IMA loader is created lazily so an episode that gains an ad tag still gets one.Verification
assembleDebug,compileDebugAndroidTestKotlin: pass.testDebugUnitTest: 381 tests, 0 failures (16 new, covering the candidate walk, hoster preference and fallback,Link/App/Messageand resolver-error skipping, bookmark gating, and the new preference).detekt: no new findings. It is red onChatActivity.kt,IndustryActivity.ktandErrorUtils.kt, but those files are byte-identical tomasterhere — pre-existing.androidTestfiles covering the swap have never been executed (no device attached; they need API 31+ per CLAUDE.md). The swap behaviour is covered by unit tests and reasoning, not by a real player run.The TV frontend (
tv/stream/) opts out viaepisodeAmount = -1and deserves its own pass.Design:
docs/superpowers/specs/2026-07-18-anime-episode-navigation-design.mdPlan:
docs/superpowers/plans/2026-07-18-anime-episode-navigation.md🤖 Generated with Claude Code