Cleanup and performance improvements

This commit is contained in:
Luna712 2024-06-20 13:07:55 -06:00 committed by GitHub
parent 452bdf68ed
commit a386521309
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 151 additions and 154 deletions

View file

@ -61,61 +61,14 @@ class DownloadAdapter(
var cardList: List<VisualDownloadCachedAbstract>, var cardList: List<VisualDownloadCachedAbstract>,
private val clickCallback: (DownloadHeaderClickEvent) -> Unit, private val clickCallback: (DownloadHeaderClickEvent) -> Unit,
private val movieClickCallback: (DownloadClickEvent) -> Unit, private val movieClickCallback: (DownloadClickEvent) -> Unit,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<DownloadAdapter.DownloadViewHolder>() {
companion object { companion object {
private const val VIEW_TYPE_HEADER = 0 private const val VIEW_TYPE_HEADER = 0
private const val VIEW_TYPE_CHILD = 1 private const val VIEW_TYPE_CHILD = 1
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { inner class DownloadViewHolder(
return DownloadViewHolder(
binding = when (viewType) {
VIEW_TYPE_HEADER -> {
DownloadHeaderEpisodeBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}
VIEW_TYPE_CHILD -> {
DownloadChildEpisodeBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}
else -> throw IllegalArgumentException("Invalid view type")
},
clickCallback,
movieClickCallback
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is DownloadViewHolder -> {
holder.bind(cardList[position])
}
}
}
var viewType = 0
override fun getItemViewType(position: Int): Int {
if (viewType != 0) {
return viewType
}
val isEpisodeBased = cardList[position] !is VisualDownloadHeaderCached
return if (isEpisodeBased) VIEW_TYPE_CHILD else VIEW_TYPE_HEADER
}
override fun getItemCount(): Int {
return cardList.count()
}
class DownloadViewHolder(
private val binding: ViewBinding, private val binding: ViewBinding,
private val clickCallback: (DownloadHeaderClickEvent) -> Unit, private val clickCallback: (DownloadHeaderClickEvent) -> Unit,
private val movieClickCallback: (DownloadClickEvent) -> Unit, private val movieClickCallback: (DownloadClickEvent) -> Unit,
@ -131,10 +84,10 @@ class DownloadAdapter(
private val normalImage: ImageView = itemView.download_header_goto_child */ private val normalImage: ImageView = itemView.download_header_goto_child */
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun bind(card: VisualDownloadCachedAbstract) { fun bind(card: VisualDownloadCachedAbstract?) {
when (binding) { when (binding) {
is DownloadHeaderEpisodeBinding -> binding.apply { is DownloadHeaderEpisodeBinding -> binding.apply {
if (card !is VisualDownloadHeaderCached) return if (card == null || card !is VisualDownloadHeaderCached) return@apply
val d = card.data val d = card.data
downloadHeaderPoster.apply { downloadHeaderPoster.apply {
@ -150,7 +103,6 @@ class DownloadAdapter(
// val isMovie = d.type.isMovieType() // val isMovie = d.type.isMovieType()
if (card.child != null) { if (card.child != null) {
// downloadHeaderProgressDownloaded.visibility = View.VISIBLE // downloadHeaderProgressDownloaded.visibility = View.VISIBLE
// downloadHeaderEpisodeDownload.visibility = View.VISIBLE // downloadHeaderEpisodeDownload.visibility = View.VISIBLE
downloadHeaderGotoChild.visibility = View.GONE downloadHeaderGotoChild.visibility = View.GONE
@ -197,19 +149,19 @@ class DownloadAdapter(
mbString mbString
) )
} catch (t: Throwable) { } catch (t: Throwable) {
// you probably formatted incorrectly // You probably formatted incorrectly
downloadHeaderInfo.text = "Error" downloadHeaderInfo.text = "Error"
logError(t) logError(t)
} }
episodeHolder.setOnClickListener { episodeHolder.setOnClickListener {
clickCallback.invoke(DownloadHeaderClickEvent(0, d)) clickCallback.invoke(DownloadHeaderClickEvent(0, d))
} }
} }
} }
is DownloadChildEpisodeBinding -> binding.apply { is DownloadChildEpisodeBinding -> binding.apply {
if (card !is VisualDownloadChildCached) return if (card == null || card !is VisualDownloadChildCached) return@apply
val d = card.data val d = card.data
val posDur = DataStoreHelper.getViewPos(d.id) val posDur = DataStoreHelper.getViewPos(d.id)
@ -219,16 +171,14 @@ class DownloadAdapter(
max = (visualPos.duration / 1000).toInt() max = (visualPos.duration / 1000).toInt()
progress = (visualPos.position / 1000).toInt() progress = (visualPos.position / 1000).toInt()
visibility = View.VISIBLE visibility = View.VISIBLE
} else { } else visibility = View.GONE
visibility = View.GONE
}
} }
downloadButton.setDefaultClickListener(card.data, downloadChildEpisodeTextExtra, movieClickCallback) downloadButton.setDefaultClickListener(card.data, downloadChildEpisodeTextExtra, movieClickCallback)
downloadChildEpisodeText.apply { downloadChildEpisodeText.apply {
text = context.getNameFull(d.name, d.episode, d.season) text = context.getNameFull(d.name, d.episode, d.season)
isSelected = true // is needed for text repeating isSelected = true // Needed for text repeating
} }
downloadChildEpisodeHolder.setOnClickListener { downloadChildEpisodeHolder.setOnClickListener {
@ -238,4 +188,44 @@ class DownloadAdapter(
} }
} }
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DownloadViewHolder =
DownloadViewHolder(
binding = when (viewType) {
VIEW_TYPE_HEADER -> {
DownloadHeaderEpisodeBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}
VIEW_TYPE_CHILD -> {
DownloadChildEpisodeBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
}
else -> throw IllegalArgumentException("Invalid view type")
},
clickCallback,
movieClickCallback
)
override fun onBindViewHolder(holder: DownloadViewHolder, position: Int) {
holder.bind(cardList.getOrNull(position))
}
var viewType = 0
override fun getItemViewType(position: Int): Int {
if (viewType != 0) return viewType
val isChildView = cardList[position] !is VisualDownloadHeaderCached
return if (isChildView) VIEW_TYPE_CHILD else VIEW_TYPE_HEADER
}
override fun getItemCount(): Int {
return cardList.count()
}
} }

View file

@ -1,6 +1,5 @@
package com.lagradost.cloudstream3.ui.download package com.lagradost.cloudstream3.ui.download
import android.app.Activity
import android.content.DialogInterface import android.content.DialogInterface
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
@ -22,7 +21,6 @@ import com.lagradost.cloudstream3.utils.VideoDownloadManager
object DownloadButtonSetup { object DownloadButtonSetup {
fun handleDownloadClick(click: DownloadClickEvent) { fun handleDownloadClick(click: DownloadClickEvent) {
val id = click.data.id val id = click.data.id
if (click.data !is VideoDownloadHelper.DownloadEpisodeCached) return
when (click.action) { when (click.action) {
DOWNLOAD_ACTION_DELETE_FILE -> { DOWNLOAD_ACTION_DELETE_FILE -> {
activity?.let { ctx -> activity?.let { ctx ->

View file

@ -62,7 +62,11 @@ class DownloadChildFragment : Fragment() {
}.mapNotNull { }.mapNotNull {
val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(ctx, it.id) val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(ctx, it.id)
?: return@mapNotNull null ?: return@mapNotNull null
VisualDownloadChildCached(info.fileLength, info.totalBytes, it) VisualDownloadChildCached(
currentBytes = info.fileLength,
totalBytes = info.totalBytes,
data = it,
)
} }
}.sortedBy { it.data.episode + (it.data.season ?: 0) * 100000 } }.sortedBy { it.data.episode + (it.data.season ?: 0) * 100000 }
if (eps.isEmpty()) { if (eps.isEmpty()) {
@ -100,7 +104,7 @@ class DownloadChildFragment : Fragment() {
setAppBarNoScrollFlagsOnTV() setAppBarNoScrollFlagsOnTV()
} }
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder> = val adapter: RecyclerView.Adapter<DownloadAdapter.DownloadViewHolder> =
DownloadAdapter( DownloadAdapter(
ArrayList(), ArrayList(),
{} {}

View file

@ -138,7 +138,7 @@ class DownloadFragment : Fragment() {
} }
} }
val adapter: RecyclerView.Adapter<RecyclerView.ViewHolder> = val adapter: RecyclerView.Adapter<DownloadAdapter.DownloadViewHolder> =
DownloadAdapter( DownloadAdapter(
ArrayList(), ArrayList(),
{ click -> { click ->

View file

@ -39,6 +39,8 @@ class DownloadViewModel : ViewModel() {
val availableBytes: LiveData<Long> = _availableBytes val availableBytes: LiveData<Long> = _availableBytes
val downloadBytes: LiveData<Long> = _downloadBytes val downloadBytes: LiveData<Long> = _downloadBytes
private var previousVisual: List<VisualDownloadHeaderCached>? = null
fun updateList(context: Context) = viewModelScope.launchSafe { fun updateList(context: Context) = viewModelScope.launchSafe {
val children = withContext(Dispatchers.IO) { val children = withContext(Dispatchers.IO) {
val headers = context.getKeys(DOWNLOAD_EPISODE_CACHE) val headers = context.getKeys(DOWNLOAD_EPISODE_CACHE)
@ -53,7 +55,6 @@ class DownloadViewModel : ViewModel() {
// parentId : downloadsCount // parentId : downloadsCount
val totalDownloads = HashMap<Int, Int>() val totalDownloads = HashMap<Int, Int>()
// Gets all children downloads // Gets all children downloads
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
for (c in children) { for (c in children) {
@ -69,7 +70,7 @@ class DownloadViewModel : ViewModel() {
} }
} }
val cached = withContext(Dispatchers.IO) { // wont fetch useless keys val cached = withContext(Dispatchers.IO) { // Won't fetch useless keys
totalDownloads.entries.filter { it.value > 0 }.mapNotNull { totalDownloads.entries.filter { it.value > 0 }.mapNotNull {
context.getKey<VideoDownloadHelper.DownloadHeaderCached>( context.getKey<VideoDownloadHelper.DownloadHeaderCached>(
DOWNLOAD_HEADER_CACHE, DOWNLOAD_HEADER_CACHE,
@ -91,21 +92,25 @@ class DownloadViewModel : ViewModel() {
getFolderName(it.id.toString(), it.id.toString()) getFolderName(it.id.toString(), it.id.toString())
) )
VisualDownloadHeaderCached( VisualDownloadHeaderCached(
currentBytes, currentBytes = currentBytes,
bytes, totalBytes = bytes,
it, data = it,
movieEpisode, child = movieEpisode,
0, currentOngoingDownloads = 0,
downloads totalDownloads = downloads,
) )
}.sortedBy { }.sortedBy {
(it.child?.episode ?: 0) + (it.child?.season?.times(10000) ?: 0) (it.child?.episode ?: 0) + (it.child?.season?.times(10000) ?: 0)
} // episode sorting by episode, lowest to highest } // episode sorting by episode, lowest to highest
} }
// Only update list if different from the previous one to prevent duplicate initialization
if (visual != previousVisual) {
previousVisual = visual
try { try {
val stat = StatFs(Environment.getExternalStorageDirectory().path) val stat = StatFs(Environment.getExternalStorageDirectory().path)
val localBytesAvailable = stat.availableBytes
val localBytesAvailable = stat.availableBytes//stat.blockSizeLong * stat.blockCountLong
val localTotalBytes = stat.blockSizeLong * stat.blockCountLong val localTotalBytes = stat.blockSizeLong * stat.blockCountLong
val localDownloadedBytes = visual.sumOf { it.totalBytes } val localDownloadedBytes = visual.sumOf { it.totalBytes }

View file

@ -192,15 +192,15 @@ class EpisodeAdapter(
downloadButton.isVisible = hasDownloadSupport downloadButton.isVisible = hasDownloadSupport
downloadButton.setDefaultClickListener( downloadButton.setDefaultClickListener(
VideoDownloadHelper.DownloadEpisodeCached( VideoDownloadHelper.DownloadEpisodeCached(
card.name, name = card.name,
card.poster, poster = card.poster,
card.episode, episode = card.episode,
card.season, season = card.season,
card.id, id = card.id,
card.parentId, parentId = card.parentId,
card.rating, rating = card.rating,
card.description, description = card.description,
System.currentTimeMillis(), cacheTime = System.currentTimeMillis(),
), null ), null
) { ) {
when (it.action) { when (it.action) {
@ -343,15 +343,15 @@ class EpisodeAdapter(
downloadButton.isVisible = hasDownloadSupport downloadButton.isVisible = hasDownloadSupport
downloadButton.setDefaultClickListener( downloadButton.setDefaultClickListener(
VideoDownloadHelper.DownloadEpisodeCached( VideoDownloadHelper.DownloadEpisodeCached(
card.name, name = card.name,
card.poster, poster = card.poster,
card.episode, episode = card.episode,
card.season, season = card.season,
card.id, id = card.id,
card.parentId, parentId = card.parentId,
card.rating, rating = card.rating,
card.description, description = card.description,
System.currentTimeMillis(), cacheTime = System.currentTimeMillis(),
), null ), null
) { ) {
when (it.action) { when (it.action) {

View file

@ -630,15 +630,15 @@ open class ResultFragmentPhone : FullScreenPlayer() {
} }
downloadButton.setDefaultClickListener( downloadButton.setDefaultClickListener(
VideoDownloadHelper.DownloadEpisodeCached( VideoDownloadHelper.DownloadEpisodeCached(
ep.name, name = ep.name,
ep.poster, poster = ep.poster,
0, episode = 0,
null, season = null,
ep.id, id = ep.id,
ep.id, parentId = ep.id,
null, rating = null,
null, description = null,
System.currentTimeMillis(), cacheTime = System.currentTimeMillis(),
), ),
null null
) { click -> ) { click ->

View file

@ -705,13 +705,13 @@ class ResultViewModel2 : ViewModel() {
DOWNLOAD_HEADER_CACHE, DOWNLOAD_HEADER_CACHE,
parentId.toString(), parentId.toString(),
VideoDownloadHelper.DownloadHeaderCached( VideoDownloadHelper.DownloadHeaderCached(
apiName, apiName = apiName,
url, url = url,
currentType, type = currentType,
currentHeaderName, name = currentHeaderName,
currentPoster, poster = currentPoster,
parentId, id = parentId,
System.currentTimeMillis(), cacheTime = System.currentTimeMillis(),
) )
) )
@ -722,15 +722,15 @@ class ResultViewModel2 : ViewModel() {
), // 3 deep folder for faster acess ), // 3 deep folder for faster acess
episode.id.toString(), episode.id.toString(),
VideoDownloadHelper.DownloadEpisodeCached( VideoDownloadHelper.DownloadEpisodeCached(
episode.name, name = episode.name,
episode.poster, poster = episode.poster,
episode.episode, episode = episode.episode,
episode.season, season = episode.season,
episode.id, id = episode.id,
parentId, parentId = parentId,
episode.rating, rating = episode.rating,
episode.description, description = episode.description,
System.currentTimeMillis(), cacheTime = System.currentTimeMillis(),
) )
) )
@ -2776,13 +2776,13 @@ class ResultViewModel2 : ViewModel() {
DOWNLOAD_HEADER_CACHE, DOWNLOAD_HEADER_CACHE,
mainId.toString(), mainId.toString(),
VideoDownloadHelper.DownloadHeaderCached( VideoDownloadHelper.DownloadHeaderCached(
apiName, apiName = apiName,
validUrl, url = validUrl,
loadResponse.type, type = loadResponse.type,
loadResponse.name, name = loadResponse.name,
loadResponse.posterUrl, poster = loadResponse.posterUrl,
mainId, id = mainId,
System.currentTimeMillis(), cacheTime = System.currentTimeMillis(),
) )
) )
if (loadTrailers) if (loadTrailers)

View file

@ -33,15 +33,15 @@ object SearchHelper {
DownloadClickEvent( DownloadClickEvent(
DOWNLOAD_ACTION_PLAY_FILE, DOWNLOAD_ACTION_PLAY_FILE,
VideoDownloadHelper.DownloadEpisodeCached( VideoDownloadHelper.DownloadEpisodeCached(
card.name, name = card.name,
card.posterUrl, poster = card.posterUrl,
card.episode ?: 0, episode = card.episode ?: 0,
card.season, season = card.season,
id, id = id,
card.parentId ?: return, parentId = card.parentId ?: return,
null, rating = null,
null, description = null,
System.currentTimeMillis() cacheTime = System.currentTimeMillis(),
) )
) )
) )

View file

@ -12,11 +12,11 @@ object VideoDownloadHelper {
@JsonProperty("poster") val poster: String?, @JsonProperty("poster") val poster: String?,
@JsonProperty("episode") val episode: Int, @JsonProperty("episode") val episode: Int,
@JsonProperty("season") val season: Int?, @JsonProperty("season") val season: Int?,
override val id: Int,
@JsonProperty("parentId") val parentId: Int, @JsonProperty("parentId") val parentId: Int,
@JsonProperty("rating") val rating: Int?, @JsonProperty("rating") val rating: Int?,
@JsonProperty("description") val description: String?, @JsonProperty("description") val description: String?,
@JsonProperty("cacheTime") val cacheTime: Long, @JsonProperty("cacheTime") val cacheTime: Long,
override val id: Int,
): DownloadCachedAbstract(id) ): DownloadCachedAbstract(id)
data class DownloadHeaderCached( data class DownloadHeaderCached(
@ -25,8 +25,8 @@ object VideoDownloadHelper {
@JsonProperty("type") val type: TvType, @JsonProperty("type") val type: TvType,
@JsonProperty("name") val name: String, @JsonProperty("name") val name: String,
@JsonProperty("poster") val poster: String?, @JsonProperty("poster") val poster: String?,
override val id: Int,
@JsonProperty("cacheTime") val cacheTime: Long, @JsonProperty("cacheTime") val cacheTime: Long,
override val id: Int,
): DownloadCachedAbstract(id) ): DownloadCachedAbstract(id)
data class ResumeWatching( data class ResumeWatching(