Skip to content

fix(player): finalize playback before next-episode navigation - #583

Merged
ProdigyV21 merged 3 commits into
ProdigyV21:mainfrom
Aerya:fix/issue-582-next-episode-watched
Aug 19, 2026
Merged

fix(player): finalize playback before next-episode navigation#583
ProdigyV21 merged 3 commits into
ProdigyV21:mainfrom
Aerya:fix/issue-582-next-episode-watched

Conversation

@Aerya

@Aerya Aerya commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Fixes #582

Summary

Finalize the current episode's playback state before navigating to the next episode.

The existing Next Episode flow can replace the current Player destination before its asynchronous saveProgress() work finishes, which may cancel the watched/scrobble update with the old PlayerViewModel.

Changes

  • add saveProgressAndWait() to wait for the final playback save;
  • route Next Episode transitions through a single helper;
  • wait for persistence before calling onPlayNext();
  • cover the Up Next prompt, MediaNext, and the explicit Next Episode button;
  • preserve the existing watched threshold behavior.

@github-actions github-actions Bot added the area: android Changes to the Android app or Gradle build label Aug 17, 2026

Copy link
Copy Markdown
Owner

Thank you for working on this. It addresses a real issue, and routing all Next Episode actions through one finalization path is the right direction.

I cannot merge it yet because a few lifecycle races remain:

  • saveProgressAndWait() first cancels the active save. If that save already set hasMarkedWatched = true but is cancelled before the Trakt/history work finishes, the replacement save skips the watched block and the episode can still remain unwatched.
  • The completion callback from an older cancelled job always clears progressSaveJob. It can therefore clear the reference to the newer save before saveProgressAndWait() joins it, allowing navigation to happen early.
  • After the explicit save completes, Player disposal calls saveProgress() again. Because ExoPlayer may still report isPlaying=true, this can send a new scrobble-start for the old episode after it was already paused or stopped.

Please make saveProgress() return the exact new Job and join that Job directly, only clear progressSaveJob when it still references the completing Job, and prevent the disposal save from restarting/saving the old session during a successful Next Episode transition. A focused test covering an in-flight threshold save followed by Next Episode would also be valuable.

The PR otherwise merges cleanly into current main. GitHub CI passes, both Play and Sideload compile locally, all Sideload unit tests pass, and git diff --check passes. This is a useful fix once these final race conditions are handled.

@ProdigyV21
ProdigyV21 merged commit c846ae8 into ProdigyV21:main Aug 19, 2026
1 check 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.

[BUG]: Episodes played using "Next Episode" may remain marked as unwatched

2 participants