feat(core,app,android,ios): keep a show in Continue watching after an episode ends

Continue watching listed only part-watched episodes, so finishing one -
the most ordinary moment to want the next - dropped the show from the
shelf. Title::continue_with now reads the episode touched last: a
part-watched one is resumed, a finished one offers the episode after it
("Next: S01E04"), and one reset to the start (what leaving the shelf
does) keeps the title off. A few seconds of an episode are passed over.

The phones computed their own shelf from episode records. The bridge now
exports the engine's choice as TitleRecord.continue_index, and Play on a
title lands there on every client.

Undo on the phones re-saved a watch state with a fresh time, which both
reordered the shelf and could not express "never played". A new
restore_watch_state puts the state back as it was read.
This commit is contained in:
nvrl committed 2026-10-12 22:05:05 +02:00
1 parent c6b0457c4d
commit a306d02cf1
15 files changed
+225 -68

No files matched your search

+3 -3
View File
@@ -36,7 +36,7 @@ struct TitleView: View {
self.onOpenTitle = onOpenTitle
// One season on screen at a time, opened on the one Play would land in.
let playlist = title.playlist
let nextUp = nextUpIndex(playlist)
let nextUp = nextUpIndex(playlist, continueIndex: title.continueIndex)
let upNext = playlist.indices.contains(nextUp) ? playlist[nextUp] : nil
_seasonIndex = State(initialValue: max(title.seasons.firstIndex { $0.episodes.contains { $0.linkId == upNext?.linkId } } ?? 0, 0))
}
@@ -44,7 +44,7 @@ struct TitleView: View {
var body: some View {
// Display order across seasons: what previous/next and autoplay walk.
let playlist = title.playlist
let nextUp = nextUpIndex(playlist)
let nextUp = nextUpIndex(playlist, continueIndex: title.continueIndex)
let upNext = playlist.indices.contains(nextUp) ? playlist[nextUp] : nil
let season = title.seasons.indices.contains(seasonIndex) ? title.seasons[seasonIndex] : nil
let downloads = DownloadCoordinator.shared.records
@@ -105,7 +105,7 @@ struct TitleView: View {
.onChange(of: title.key) {
overviewOpen = false
let playlist = title.playlist
let upNext = playlist.indices.contains(nextUpIndex(playlist)) ? playlist[nextUpIndex(playlist)] : nil
let upNext = playlist.indices.contains(nextUpIndex(playlist, continueIndex: title.continueIndex)) ? playlist[nextUpIndex(playlist, continueIndex: title.continueIndex)] : nil
seasonIndex = title.seasons.firstIndex { $0.episodes.contains { $0.linkId == upNext?.linkId } } ?? 0
}
}