diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt index e4616c93bcf..122f492ad25 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/GeneratorPlayer.kt @@ -1677,6 +1677,9 @@ class GeneratorPlayer : FullScreenPlayer() { } override fun nextEpisode() { + if (isAtVideoEnd()) { + saveCurrentAsCompleted() + } if (viewModel.hasNextEpisode() == true) { isNextEpisode = true releasePlayer() @@ -1692,6 +1695,37 @@ class GeneratorPlayer : FullScreenPlayer() { } } + override fun onVideoEnded() { + context?.let { ctx -> + val autoplayNext = PreferenceManager.getDefaultSharedPreferences(ctx) + ?.getBoolean(ctx.getString(R.string.autoplay_next_key), true) == true + if (autoplayNext) return@let + saveCurrentAsCompleted() + } + } + + private fun isAtVideoEnd(): Boolean { + val duration = player.getDuration() ?: return false + if (duration <= 0L) return false + val position = player.getPosition() ?: return false + return position >= duration - 1000 + } + + private fun saveCurrentAsCompleted() { + if ((currentMeta as? ResultEpisode)?.tvType?.isLiveStream() == true) return + if ((currentMeta as? ResultEpisode)?.tvType == TvType.NSFW) return + val duration = player.getDuration() ?: return + if (duration <= 0L) return + DataStoreHelper.setViewPosAndResume( + viewModel.state.generatorState?.id, + duration, + duration, + currentMeta, + nextMeta, + completed = true, + ) + } + private fun getNextLink(): DisplayLink? { val links = viewModel.state.sortLinks(currentQualityProfile) val currentIndex = links.indexOfFirst { it.link == currentSelectedLink } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerView.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerView.kt index 0e6f1a3677d..28d861c4b3d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerView.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerView.kt @@ -115,6 +115,7 @@ class PlayerView @JvmOverloads constructor( fun nextEpisode() {} fun prevEpisode() {} fun playerPositionChanged(position: Long, duration: Long) {} + fun onVideoEnded() {} fun playerStatusChanged() {} fun playerDimensionsLoaded(width: Int, height: Int) {} fun subtitlesChanged() {} @@ -772,6 +773,7 @@ class PlayerView @JvmOverloads constructor( duration = event.durationMs ) is VideoEndedEvent -> { + callbacks?.onVideoEnded() // Only play next episode if autoplay is on (default). val ctx = context if (PreferenceManager.getDefaultSharedPreferences(ctx) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt index eabac20d322..4348a98f84d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/DataStoreHelper.kt @@ -26,7 +26,6 @@ import com.lagradost.cloudstream3.syncproviders.SyncAPI import com.lagradost.cloudstream3.ui.WatchType import com.lagradost.cloudstream3.ui.library.ListSorting import com.lagradost.cloudstream3.ui.player.ExtractorUri -import com.lagradost.cloudstream3.ui.player.NEXT_WATCH_EPISODE_PERCENTAGE import com.lagradost.cloudstream3.ui.result.EpisodeSortType import com.lagradost.cloudstream3.ui.result.ResultEpisode import com.lagradost.cloudstream3.ui.result.VideoWatchState @@ -705,7 +704,14 @@ object DataStoreHelper { * Sets the position, duration, and resume data of an episode/movie, * If nextEpisode is not specified it will not be able to set the next episode as resumable if progress > NEXT_WATCH_EPISODE_PERCENTAGE */ - fun setViewPosAndResume(id: Int?, position: Long, duration: Long, currentEpisode: Any?, nextEpisode: Any?) { + fun setViewPosAndResume( + id: Int?, + position: Long, + duration: Long, + currentEpisode: Any?, + nextEpisode: Any?, + completed: Boolean = false, + ) { setViewPos(id, position, duration) if (id != null) { when (val meta = currentEpisode) { @@ -717,10 +723,8 @@ object DataStoreHelper { } } - val percentage = position * 100L / duration - val nextEp = percentage >= NEXT_WATCH_EPISODE_PERCENTAGE - val resumeMeta = if (nextEp) nextEpisode else currentEpisode - if (resumeMeta == null && nextEp) { + val resumeMeta = if (completed) nextEpisode else currentEpisode + if (resumeMeta == null && completed) { // remove last watched as it is the last episode and you have watched too much when (val newMeta = currentEpisode) { is ResultEpisode -> {