diff --git a/android/app/src/main/java/io/narl/protonstream/playback/PlayerScreen.kt b/android/app/src/main/java/io/narl/protonstream/playback/PlayerScreen.kt index 960f159..2510a2b 100644 --- a/android/app/src/main/java/io/narl/protonstream/playback/PlayerScreen.kt +++ b/android/app/src/main/java/io/narl/protonstream/playback/PlayerScreen.kt @@ -333,7 +333,12 @@ fun PlayerScreen( val problem by nativeHost.problem.collectAsState() LaunchedEffect(problem) { problem?.let { playbackError = it } } - val offer = remember(chapters, key, (state.position * 4).roundToInt()) { + // Whether mpv's readings are this episode's. Not while the next one opens: + // the last one's credits play on until it is loaded, and read against the + // new index they offered the episode after the next as up next. + val playingThis = state.media == key + val offer = remember(chapters, key, playingThis, (state.position * 4).roundToInt()) { + if (!playingThis) return@remember null runCatching { skipOffer(chapters, state.position) }.getOrNull() } // Auto-skip is offered once per chapter: seeking back into an opening on @@ -475,7 +480,7 @@ fun PlayerScreen( UpNextCard( next = next, - visible = autoplay && !state.paused && + visible = autoplay && !state.paused && playingThis && chapters.creditsStart?.let { state.position >= it } == true, onPlayNow = { advance() }, modifier = Modifier diff --git a/ios/ProtonStream/Player/PlayerHost.swift b/ios/ProtonStream/Player/PlayerHost.swift index 2990b9e..9934d77 100644 --- a/ios/ProtonStream/Player/PlayerHost.swift +++ b/ios/ProtonStream/Player/PlayerHost.swift @@ -111,6 +111,11 @@ final class PlayerHost { var episode: EpisodeRecord? { episodes.indices.contains(index) ? episodes[index] : nil } var key: String? { episode.map(mediaKey) } var next: EpisodeRecord? { episodes.indices.contains(index + 1) ? episodes[index + 1] : nil } + /// Whether mpv's readings — position, chapters — are the open episode's. + /// Not while the next one opens: the last one's credits go on playing + /// until it is loaded, and read against the new index they offered the + /// episode *after* the next as up next. + var playingOpenEpisode: Bool { player?.media != nil && player?.media == key } var isOpen: Bool { title != nil } // MARK: - Opening @@ -329,7 +334,7 @@ final class PlayerHost { } private func tick() { - guard let player else { return } + guard let player, playingOpenEpisode else { return } replanChapters(player) // Auto-skip, once per chapter. if autoSkip, !player.paused, let offer = skipOffer(plan: chapters, position: player.position), @@ -352,7 +357,7 @@ final class PlayerHost { /// The skip button's offer at the current position, if any. var offer: SkipOffer? { - guard let player else { return nil } + guard let player, playingOpenEpisode else { return nil } return skipOffer(plan: chapters, position: player.position) } diff --git a/ios/ProtonStream/Player/PlayerView.swift b/ios/ProtonStream/Player/PlayerView.swift index 101083e..b24727d 100644 --- a/ios/ProtonStream/Player/PlayerView.swift +++ b/ios/ProtonStream/Player/PlayerView.swift @@ -63,7 +63,8 @@ struct PlayerView: View { } UpNextCard( next: host.next, - visible: host.autoplay && !player.paused && host.chapters.creditsStart.map { player.position >= $0 } == true, + visible: host.autoplay && !player.paused && host.playingOpenEpisode + && host.chapters.creditsStart.map { player.position >= $0 } == true, onPlayNow: host.advance ) }