From f6a65f38dbc5b8e55bc912e2955743c1cc41bc29 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:49:04 -0600 Subject: [PATCH] Add support for Next Episode in downloads (#1228) --- .../ui/download/DownloadButtonSetup.kt | 98 +++++++++++-------- .../ui/player/DownloadFileGenerator.kt | 20 +++- .../ui/player/ExtractorLinkGenerator.kt | 1 + .../cloudstream3/ui/player/GeneratorPlayer.kt | 2 +- .../cloudstream3/ui/player/IGenerator.kt | 1 + .../cloudstream3/ui/player/LinkGenerator.kt | 1 + .../ui/player/RepoLinkGenerator.kt | 1 + 7 files changed, 81 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadButtonSetup.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadButtonSetup.kt index bf2c1b49..494e82e5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadButtonSetup.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadButtonSetup.kt @@ -1,9 +1,11 @@ package com.lagradost.cloudstream3.ui.download import android.content.DialogInterface +import android.net.Uri import androidx.appcompat.app.AlertDialog import com.google.android.material.snackbar.Snackbar import com.lagradost.cloudstream3.AcraApplication.Companion.getKey +import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys import com.lagradost.cloudstream3.CommonActivity.activity import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.mvvm.logError @@ -12,6 +14,7 @@ import com.lagradost.cloudstream3.ui.player.ExtractorUri import com.lagradost.cloudstream3.ui.player.GeneratorPlayer import com.lagradost.cloudstream3.utils.AppContextUtils.getNameFull import com.lagradost.cloudstream3.utils.AppContextUtils.setDefaultFocus +import com.lagradost.cloudstream3.utils.DOWNLOAD_EPISODE_CACHE import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE import com.lagradost.cloudstream3.utils.SnackbarHelper.showSnackbar import com.lagradost.cloudstream3.utils.UIHelper.navigate @@ -109,56 +112,69 @@ object DownloadButtonSetup { DOWNLOAD_ACTION_PLAY_FILE -> { activity?.let { act -> - val info = - VideoDownloadManager.getDownloadFileInfoAndUpdateSettings( - act, - click.data.id - ) ?: return - val keyInfo = getKey( - VideoDownloadManager.KEY_DOWNLOAD_INFO, - click.data.id.toString() - ) ?: return val parent = getKey( DOWNLOAD_HEADER_CACHE, click.data.parentId.toString() ) ?: return - act.navigate( - R.id.global_to_navigation_player, GeneratorPlayer.newInstance( - DownloadFileGenerator( - listOf( - ExtractorUri( - uri = info.path, + val episodes = getKeys(DOWNLOAD_EPISODE_CACHE) + ?.mapNotNull { + getKey(it) + } + ?.filter { it.parentId == click.data.parentId } - id = click.data.id, - parentId = click.data.parentId, - name = act.getString(R.string.downloaded_file), // click.data.name ?: keyInfo.displayName - season = click.data.season, - episode = click.data.episode, - headerName = parent.name, - tvType = parent.type, + val currentSeason = click.data.season ?: 0 + val currentEpisode = click.data.episode - basePath = keyInfo.basePath, - displayName = keyInfo.displayName, - relativePath = keyInfo.relativePath, - ) - ) + val items = mutableListOf() + + // Make sure we only get this episode and episodes after it, + // and that we can go to the next season if we need to. + val allRelevantEpisodes = episodes + ?.sortedWith( + compareByDescending { it.id == click.data.id } + .thenBy { it.season ?: 0 } + .thenBy { it.episode } + ) + ?.filter { + if (it.season == null) return@filter true + val isCurrentOrLaterInSeason = it.season == currentSeason && (it.episode >= currentEpisode || it.id == click.data.id) + val isInFutureSeasons = it.season > currentSeason + + isCurrentOrLaterInSeason || isInFutureSeasons + } + + allRelevantEpisodes?.forEach { + val keyInfo = getKey( + VideoDownloadManager.KEY_DOWNLOAD_INFO, + it.id.toString() + ) ?: return@forEach + + items.add( + ExtractorUri( + // We just use a temporary placeholder for the URI, + // it will be updated in generateLinks(). + // We just do this for performance since getting + // all paths at once can be quite expensive. + uri = Uri.EMPTY, + id = it.id, + parentId = it.parentId, + name = act.getString(R.string.downloaded_file), + season = it.season, + episode = it.episode, + headerName = parent.name, + tvType = parent.type, + basePath = keyInfo.basePath, + displayName = keyInfo.displayName, + relativePath = keyInfo.relativePath, ) ) - // R.id.global_to_navigation_player, PlayerFragment.newInstance( - // UriData( - // info.path.toString(), - // keyInfo.basePath, - // keyInfo.relativePath, - // keyInfo.displayName, - // click.data.parentId, - // click.data.id, - // headerName ?: "null", - // if (click.data.episode <= 0) null else click.data.episode, - // click.data.season - // ), - // getViewPos(click.data.id)?.position ?: 0 - // ) + } + + act.navigate( + R.id.global_to_navigation_player, GeneratorPlayer.newInstance( + DownloadFileGenerator(items) + ) ) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/DownloadFileGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/DownloadFileGenerator.kt index a0668abc..c7db7d04 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/DownloadFileGenerator.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/DownloadFileGenerator.kt @@ -1,11 +1,14 @@ package com.lagradost.cloudstream3.ui.player +import android.net.Uri import com.lagradost.cloudstream3.AcraApplication.Companion.context +import com.lagradost.cloudstream3.CommonActivity.activity import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.SubtitleUtils.cleanDisplayName import com.lagradost.cloudstream3.utils.SubtitleUtils.isMatchingSubtitle +import com.lagradost.cloudstream3.utils.VideoDownloadManager.getDownloadFileInfoAndUpdateSettings import com.lagradost.cloudstream3.utils.VideoDownloadManager.getFolder import kotlin.math.max import kotlin.math.min @@ -15,6 +18,7 @@ class DownloadFileGenerator( private var currentIndex: Int = 0 ) : IGenerator { override val hasCache = false + override val canSkipLoading = false override fun hasNext(): Boolean { return currentIndex < episodes.size - 1 @@ -59,7 +63,21 @@ class DownloadFileGenerator( offset: Int ): Boolean { val meta = episodes[currentIndex + offset] - callback(null to meta) + + if (meta.uri == Uri.EMPTY) { + // We do this here so that we only load it when + // we actually need it as it can be more expensive. + val info = meta.id?.let { id -> + activity?.let { act -> + getDownloadFileInfoAndUpdateSettings(act, id) + } + } + + if (info != null) { + val newMeta = meta.copy(uri = info.path) + callback(null to newMeta) + } else callback(null to meta) + } else callback(null to meta) val ctx = context ?: return true val relative = meta.relativePath ?: return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/ExtractorLinkGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/ExtractorLinkGenerator.kt index 8255360c..ec485f1c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/ExtractorLinkGenerator.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/ExtractorLinkGenerator.kt @@ -7,6 +7,7 @@ class ExtractorLinkGenerator( private val subtitles: List, ) : IGenerator { override val hasCache = false + override val canSkipLoading = true override fun getCurrentId(): Int? { return null 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 8e8f6bf5..d4fd047c 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 @@ -1462,7 +1462,7 @@ class GeneratorPlayer : FullScreenPlayer() { observe(viewModel.currentLinks) { currentLinks = it - val turnVisible = it.isNotEmpty() + val turnVisible = it.isNotEmpty() && lastUsedGenerator?.canSkipLoading == true val wasGone = binding?.overlayLoadingSkipButton?.isGone == true binding?.overlayLoadingSkipButton?.isVisible = turnVisible diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/IGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/IGenerator.kt index 1e2cf4f5..6b8e6ea8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/IGenerator.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/IGenerator.kt @@ -45,6 +45,7 @@ fun LoadType.toSet() : Set { interface IGenerator { val hasCache: Boolean + val canSkipLoading: Boolean fun hasNext(): Boolean fun hasPrev(): Boolean diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt index 07ea56dd..20feae41 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/LinkGenerator.kt @@ -39,6 +39,7 @@ class LinkGenerator( private val isM3u8: Boolean? = null ) : IGenerator { override val hasCache = false + override val canSkipLoading = true override fun getCurrentId(): Int? { return null diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/RepoLinkGenerator.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/RepoLinkGenerator.kt index 6943c641..588afbb5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/RepoLinkGenerator.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/RepoLinkGenerator.kt @@ -29,6 +29,7 @@ class RepoLinkGenerator( } override val hasCache = true + override val canSkipLoading = true override fun hasNext(): Boolean { return currentIndex < episodes.size - 1