Add support for Next Episode in downloads (#1228)

This commit is contained in:
Luna712 2024-08-05 12:49:04 -06:00 committed by GitHub
parent 4d9a080341
commit f6a65f38db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 81 additions and 43 deletions

View file

@ -1,9 +1,11 @@
package com.lagradost.cloudstream3.ui.download package com.lagradost.cloudstream3.ui.download
import android.content.DialogInterface import android.content.DialogInterface
import android.net.Uri
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.getKeys
import com.lagradost.cloudstream3.CommonActivity.activity import com.lagradost.cloudstream3.CommonActivity.activity
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.mvvm.logError 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.ui.player.GeneratorPlayer
import com.lagradost.cloudstream3.utils.AppContextUtils.getNameFull import com.lagradost.cloudstream3.utils.AppContextUtils.getNameFull
import com.lagradost.cloudstream3.utils.AppContextUtils.setDefaultFocus 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.DOWNLOAD_HEADER_CACHE
import com.lagradost.cloudstream3.utils.SnackbarHelper.showSnackbar import com.lagradost.cloudstream3.utils.SnackbarHelper.showSnackbar
import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.navigate
@ -109,57 +112,70 @@ object DownloadButtonSetup {
DOWNLOAD_ACTION_PLAY_FILE -> { DOWNLOAD_ACTION_PLAY_FILE -> {
activity?.let { act -> activity?.let { act ->
val info =
VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
act,
click.data.id
) ?: return
val keyInfo = getKey<VideoDownloadManager.DownloadedFileInfo>(
VideoDownloadManager.KEY_DOWNLOAD_INFO,
click.data.id.toString()
) ?: return
val parent = getKey<VideoDownloadHelper.DownloadHeaderCached>( val parent = getKey<VideoDownloadHelper.DownloadHeaderCached>(
DOWNLOAD_HEADER_CACHE, DOWNLOAD_HEADER_CACHE,
click.data.parentId.toString() click.data.parentId.toString()
) ?: return ) ?: return
act.navigate( val episodes = getKeys(DOWNLOAD_EPISODE_CACHE)
R.id.global_to_navigation_player, GeneratorPlayer.newInstance( ?.mapNotNull {
DownloadFileGenerator( getKey<VideoDownloadHelper.DownloadEpisodeCached>(it)
listOf( }
ExtractorUri( ?.filter { it.parentId == click.data.parentId }
uri = info.path,
id = click.data.id, val currentSeason = click.data.season ?: 0
parentId = click.data.parentId, val currentEpisode = click.data.episode
name = act.getString(R.string.downloaded_file), // click.data.name ?: keyInfo.displayName
season = click.data.season, val items = mutableListOf<ExtractorUri>()
episode = click.data.episode,
// 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<VideoDownloadHelper.DownloadEpisodeCached> { 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.DownloadedFileInfo>(
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, headerName = parent.name,
tvType = parent.type, tvType = parent.type,
basePath = keyInfo.basePath, basePath = keyInfo.basePath,
displayName = keyInfo.displayName, displayName = keyInfo.displayName,
relativePath = keyInfo.relativePath, relativePath = keyInfo.relativePath,
) )
) )
}
act.navigate(
R.id.global_to_navigation_player, GeneratorPlayer.newInstance(
DownloadFileGenerator(items)
) )
) )
// 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
// )
)
} }
} }
} }

View file

@ -1,11 +1,14 @@
package com.lagradost.cloudstream3.ui.player package com.lagradost.cloudstream3.ui.player
import android.net.Uri
import com.lagradost.cloudstream3.AcraApplication.Companion.context import com.lagradost.cloudstream3.AcraApplication.Companion.context
import com.lagradost.cloudstream3.CommonActivity.activity
import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.SubtitleUtils.cleanDisplayName import com.lagradost.cloudstream3.utils.SubtitleUtils.cleanDisplayName
import com.lagradost.cloudstream3.utils.SubtitleUtils.isMatchingSubtitle import com.lagradost.cloudstream3.utils.SubtitleUtils.isMatchingSubtitle
import com.lagradost.cloudstream3.utils.VideoDownloadManager.getDownloadFileInfoAndUpdateSettings
import com.lagradost.cloudstream3.utils.VideoDownloadManager.getFolder import com.lagradost.cloudstream3.utils.VideoDownloadManager.getFolder
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -15,6 +18,7 @@ class DownloadFileGenerator(
private var currentIndex: Int = 0 private var currentIndex: Int = 0
) : IGenerator { ) : IGenerator {
override val hasCache = false override val hasCache = false
override val canSkipLoading = false
override fun hasNext(): Boolean { override fun hasNext(): Boolean {
return currentIndex < episodes.size - 1 return currentIndex < episodes.size - 1
@ -59,7 +63,21 @@ class DownloadFileGenerator(
offset: Int offset: Int
): Boolean { ): Boolean {
val meta = episodes[currentIndex + offset] 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 ctx = context ?: return true
val relative = meta.relativePath ?: return true val relative = meta.relativePath ?: return true

View file

@ -7,6 +7,7 @@ class ExtractorLinkGenerator(
private val subtitles: List<SubtitleData>, private val subtitles: List<SubtitleData>,
) : IGenerator { ) : IGenerator {
override val hasCache = false override val hasCache = false
override val canSkipLoading = true
override fun getCurrentId(): Int? { override fun getCurrentId(): Int? {
return null return null

View file

@ -1462,7 +1462,7 @@ class GeneratorPlayer : FullScreenPlayer() {
observe(viewModel.currentLinks) { observe(viewModel.currentLinks) {
currentLinks = it currentLinks = it
val turnVisible = it.isNotEmpty() val turnVisible = it.isNotEmpty() && lastUsedGenerator?.canSkipLoading == true
val wasGone = binding?.overlayLoadingSkipButton?.isGone == true val wasGone = binding?.overlayLoadingSkipButton?.isGone == true
binding?.overlayLoadingSkipButton?.isVisible = turnVisible binding?.overlayLoadingSkipButton?.isVisible = turnVisible

View file

@ -45,6 +45,7 @@ fun LoadType.toSet() : Set<ExtractorLinkType> {
interface IGenerator { interface IGenerator {
val hasCache: Boolean val hasCache: Boolean
val canSkipLoading: Boolean
fun hasNext(): Boolean fun hasNext(): Boolean
fun hasPrev(): Boolean fun hasPrev(): Boolean

View file

@ -39,6 +39,7 @@ class LinkGenerator(
private val isM3u8: Boolean? = null private val isM3u8: Boolean? = null
) : IGenerator { ) : IGenerator {
override val hasCache = false override val hasCache = false
override val canSkipLoading = true
override fun getCurrentId(): Int? { override fun getCurrentId(): Int? {
return null return null

View file

@ -29,6 +29,7 @@ class RepoLinkGenerator(
} }
override val hasCache = true override val hasCache = true
override val canSkipLoading = true
override fun hasNext(): Boolean { override fun hasNext(): Boolean {
return currentIndex < episodes.size - 1 return currentIndex < episodes.size - 1