Skip to content

feat(sources): pin the recently played source to the top of the source list - #790

Merged
ProdigyV21 merged 3 commits into
ProdigyV21:mainfrom
silentbil:feature/recent-played-source
Oct 8, 2026
Merged

ProdigyV21 merged 3 commits into
ProdigyV21:mainfrom
silentbil:feature/recent-played-source

Conversation

@silentbil

@silentbil silentbil commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

What

When you reopen a movie or episode, the source you last actually watched it from is pinned to the top of the source list with a "Recently played" chip, ahead of the normal sort. Focus lands on it, so resuming is one click.

Rules

  • One source per title. Each profile keeps one record per title (the last 200 titles). Playing another source or episode replaces it.
  • Only sources that really played. A source is saved after 10 s of real playback on it. Pausing, buffering and seeking don't count, and resuming deep into a title counts from zero. A new selection, manual or failover, starts the count over, so a source dropped for being slow or broken never becomes "recent".
  • Matched against fresh addon results by URL, then torrent hash + file index, then filename, then source text, always within the same addon. The addon's own entry is saved rather than the copy resolved for playback, since Stalker and HubCloud links get exchanged for one-off URLs.

Where it shows

  • The Details source picker, on TV and mobile.
  • The player's source menu.
  • Series match the exact episode only. Live streams are never saved.

Autoplay

Users with "autoplay single source" never see the list, so autoplay now picks the recent source over its own ranking.

  • Autoplay normally fires within ~2 s, as soon as any cached source appears. When a recent source exists but its addon hasn't answered yet, those quick picks hold for up to 6 s.
  • The hold ends as soon as the recent source arrives, when the search finishes, or when it arrives but the autoplay quality settings filter it out. After that, autoplay picks as before.
  • Titles without a recent source autoplay exactly as before.
  • Failover is unchanged: it walks the source list and never re-picks the recent source through autoplay.

Changes

  • RecentPlayedSource (model + matcher), RecentPlayedSourceRepository (per-profile DataStore), RecentSourcePlayTracker (the 10 s rule).
  • PlayerViewModel feeds the tracker from saveProgress and prefers the record in autoplaySelectBest, holding the quick autoplay picks while it's missing. DetailsViewModel loads the record when sources open. StreamSelector pins the match and draws the chip.
  • New string stream_recently_played in English and Hebrew.

Testing

  • New unit tests: RecentPlayedSourceTest (8) and RecentSourcePlayTrackerTest (7).
  • DetailsStreamCompletionTest, DetailsWatchlistToggleTest and ForcedSubtitleSelectionTest updated for the new constructor parameter; all pass.
  • Player, details and recent-source unit suites: 337 tests, all passing.
  • Manually checked on an Android TV emulator (API 30), sideload debug build: the source-list pin and autoplay picking the recent source.

🤖 Generated with Claude Code

…e list

When a title is reopened, the source it was last really watched from leads
the source picker with a "Recently played" chip, ahead of the normal sort.

- One record per title per profile (last 200 titles kept); playing another
  source or episode replaces it.
- A source is recorded only after 10 s of real playback on it. Pausing,
  buffering and seeks do not count, and a new selection (manual or failover)
  starts over, so a source abandoned for being slow or broken is never kept.
- Later source lists are matched by URL, then torrent hash + file index,
  then filename, then source text, always within the same addon. The addon's
  own entry is recorded, not the copy resolved for playback.
- Shown in the Details source picker (TV and mobile) and the player's source
  menu. Series match the exact episode only. Live streams are skipped.
@github-actions github-actions Bot added the area: android Changes to the Android app or Gradle build label Oct 7, 2026
@silentbil
silentbil requested a review from ProdigyV21 October 7, 2026 08:58
Autoplay users never see the source list, so the pin alone did nothing for
them. When the title has a recently played source, autoplay now picks it
over its own ranking.

- Its addon may answer after autoplay's quick picks (a cached source, the
  1.75 s window) would fire, so those hold for up to 6 s while it is missing.
  The hold ends as soon as it arrives, when the search finishes, or when it
  arrives but the autoplay quality settings filter it out.
- Titles without a recent source autoplay exactly as before.
- Failover is unchanged: it walks the source list and never re-picks the
  recent source through autoplay.
@ProdigyV21

Copy link
Copy Markdown
Owner

Thanks for adding this, remembering the source that actually worked is a useful improvement. Two timing cases need fixing before merging:

  1. During a slow source switch, selectedStream changes before streamSelectionNonce/the playback URL changes. The old video can keep feeding progress into the tracker, which can save the newly selected source as recently played even though it never played. Please count playback against the active prepared source and suspend recording while a replacement is resolving.

  2. Home Server/IPTV background results can call autoplaySelectBest before the recent-source hold is initialized by the progressive results. That lets another source start before the remembered source gets its chance. Please initialize the gate before starting background lookups and make every autoplay entry point respect it.

Please add regression tests for both cases. The build checks pass and the PR merges cleanly; these are playback-timing gaps, not video-quality concerns.

1. A slow source switch could save the replacement as recently played.
   selectStream() names the replacement in selectedStream right away, while
   the old video keeps playing until the new URL is resolved and applied.
   Playback is now credited to the source the player has actually loaded
   (preparedStream, set wherever a URL is applied), and nothing counts while
   a replacement is resolving. A failed switch keeps crediting the source
   that is still playing.

2. Home Server / IPTV background results could autoplay before the
   recent-source hold existed, since it was only set up by the first addon
   result. The hold is now a RecentSourceAutoplayGate armed at the start of
   loading, before any lookup starts, with its own 6 s timer. Every autoplay
   entry point goes through autoplaySelectBest, which respects it.

Regression tests: RecentSourcePlaybackTimingTest (slow switch, failed
switch, early background result held, hold expiry, no recent source) and
RecentSourceAutoplayGateTest.
@silentbil

Copy link
Copy Markdown
Collaborator Author

Thanks @ProdigyV21 - all issues fixed

@ProdigyV21
ProdigyV21 merged commit 00d4703 into ProdigyV21:main Oct 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: android Changes to the Android app or Gradle build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants