diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadAdapter.kt index 99342bd1..a3579172 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadAdapter.kt @@ -61,80 +61,33 @@ class DownloadAdapter( var cardList: List, private val clickCallback: (DownloadHeaderClickEvent) -> Unit, private val movieClickCallback: (DownloadClickEvent) -> Unit, -) : RecyclerView.Adapter() { +) : RecyclerView.Adapter() { companion object { private const val VIEW_TYPE_HEADER = 0 private const val VIEW_TYPE_CHILD = 1 } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - 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( + inner class DownloadViewHolder( private val binding: ViewBinding, private val clickCallback: (DownloadHeaderClickEvent) -> Unit, private val movieClickCallback: (DownloadClickEvent) -> Unit, - ) : RecyclerView.ViewHolder(binding.root) { + ) : RecyclerView.ViewHolder(binding.root) { - /*private val poster: ImageView? = itemView.download_header_poster + /* private val poster: ImageView? = itemView.download_header_poster private val title: TextView = itemView.download_header_title private val extraInfo: TextView = itemView.download_header_info private val holder: CardView = itemView.episode_holder private val downloadBar: ContentLoadingProgressBar = itemView.download_header_progress_downloaded private val downloadImage: ImageView = itemView.download_header_episode_download - private val normalImage: ImageView = itemView.download_header_goto_child*/ + private val normalImage: ImageView = itemView.download_header_goto_child */ @SuppressLint("SetTextI18n") - fun bind(card: VisualDownloadCachedAbstract) { + fun bind(card: VisualDownloadCachedAbstract?) { when (binding) { is DownloadHeaderEpisodeBinding -> binding.apply { - if (card !is VisualDownloadHeaderCached) return + if (card == null || card !is VisualDownloadHeaderCached) return@apply val d = card.data downloadHeaderPoster.apply { @@ -147,10 +100,9 @@ class DownloadAdapter( downloadHeaderTitle.text = d.name val mbString = formatShortFileSize(itemView.context, card.totalBytes) - //val isMovie = d.type.isMovieType() + // val isMovie = d.type.isMovieType() if (card.child != null) { - //downloadHeaderProgressDownloaded.visibility = View.VISIBLE - + // downloadHeaderProgressDownloaded.visibility = View.VISIBLE // downloadHeaderEpisodeDownload.visibility = View.VISIBLE downloadHeaderGotoChild.visibility = View.GONE @@ -197,19 +149,19 @@ class DownloadAdapter( mbString ) } catch (t: Throwable) { - // you probably formatted incorrectly + // You probably formatted incorrectly downloadHeaderInfo.text = "Error" logError(t) } - episodeHolder.setOnClickListener { clickCallback.invoke(DownloadHeaderClickEvent(0, d)) } } } + is DownloadChildEpisodeBinding -> binding.apply { - if (card !is VisualDownloadChildCached) return + if (card == null || card !is VisualDownloadChildCached) return@apply val d = card.data val posDur = DataStoreHelper.getViewPos(d.id) @@ -219,16 +171,14 @@ class DownloadAdapter( max = (visualPos.duration / 1000).toInt() progress = (visualPos.position / 1000).toInt() visibility = View.VISIBLE - } else { - visibility = View.GONE - } + } else visibility = View.GONE } downloadButton.setDefaultClickListener(card.data, downloadChildEpisodeTextExtra, movieClickCallback) downloadChildEpisodeText.apply { text = context.getNameFull(d.name, d.episode, d.season) - isSelected = true // is needed for text repeating + isSelected = true // Needed for text repeating } 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() + } } \ No newline at end of file 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 10ce67a7..880d5f6c 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,6 +1,5 @@ package com.lagradost.cloudstream3.ui.download -import android.app.Activity import android.content.DialogInterface import android.widget.Toast import androidx.appcompat.app.AlertDialog @@ -22,7 +21,6 @@ import com.lagradost.cloudstream3.utils.VideoDownloadManager object DownloadButtonSetup { fun handleDownloadClick(click: DownloadClickEvent) { val id = click.data.id - if (click.data !is VideoDownloadHelper.DownloadEpisodeCached) return when (click.action) { DOWNLOAD_ACTION_DELETE_FILE -> { activity?.let { ctx -> diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt index 5e4cb56b..53e0bccb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadChildFragment.kt @@ -62,7 +62,11 @@ class DownloadChildFragment : Fragment() { }.mapNotNull { val info = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(ctx, it.id) ?: 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 } if (eps.isEmpty()) { @@ -100,7 +104,7 @@ class DownloadChildFragment : Fragment() { setAppBarNoScrollFlagsOnTV() } - val adapter: RecyclerView.Adapter = + val adapter: RecyclerView.Adapter = DownloadAdapter( ArrayList(), {} diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt index 53be74d8..cd9a42fb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadFragment.kt @@ -138,7 +138,7 @@ class DownloadFragment : Fragment() { } } - val adapter: RecyclerView.Adapter = + val adapter: RecyclerView.Adapter = DownloadAdapter( ArrayList(), { click -> diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt index 3c329410..ec2999b0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/download/DownloadViewModel.kt @@ -39,6 +39,8 @@ class DownloadViewModel : ViewModel() { val availableBytes: LiveData = _availableBytes val downloadBytes: LiveData = _downloadBytes + private var previousVisual: List? = null + fun updateList(context: Context) = viewModelScope.launchSafe { val children = withContext(Dispatchers.IO) { val headers = context.getKeys(DOWNLOAD_EPISODE_CACHE) @@ -53,7 +55,6 @@ class DownloadViewModel : ViewModel() { // parentId : downloadsCount val totalDownloads = HashMap() - // Gets all children downloads withContext(Dispatchers.IO) { 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 { context.getKey( DOWNLOAD_HEADER_CACHE, @@ -91,32 +92,36 @@ class DownloadViewModel : ViewModel() { getFolderName(it.id.toString(), it.id.toString()) ) VisualDownloadHeaderCached( - currentBytes, - bytes, - it, - movieEpisode, - 0, - downloads + currentBytes = currentBytes, + totalBytes = bytes, + data = it, + child = movieEpisode, + currentOngoingDownloads = 0, + totalDownloads = downloads, ) }.sortedBy { (it.child?.episode ?: 0) + (it.child?.season?.times(10000) ?: 0) } // episode sorting by episode, lowest to highest } - try { - val stat = StatFs(Environment.getExternalStorageDirectory().path) - val localBytesAvailable = stat.availableBytes//stat.blockSizeLong * stat.blockCountLong - val localTotalBytes = stat.blockSizeLong * stat.blockCountLong - val localDownloadedBytes = visual.sumOf { it.totalBytes } + // Only update list if different from the previous one to prevent duplicate initialization + if (visual != previousVisual) { + previousVisual = visual - _usedBytes.postValue(localTotalBytes - localBytesAvailable - localDownloadedBytes) - _availableBytes.postValue(localBytesAvailable) - _downloadBytes.postValue(localDownloadedBytes) - } catch (t : Throwable) { - _downloadBytes.postValue(0) - logError(t) + try { + val stat = StatFs(Environment.getExternalStorageDirectory().path) + val localBytesAvailable = stat.availableBytes + val localTotalBytes = stat.blockSizeLong * stat.blockCountLong + val localDownloadedBytes = visual.sumOf { it.totalBytes } + + _usedBytes.postValue(localTotalBytes - localBytesAvailable - localDownloadedBytes) + _availableBytes.postValue(localBytesAvailable) + _downloadBytes.postValue(localDownloadedBytes) + } catch (t: Throwable) { + _downloadBytes.postValue(0) + logError(t) + } + + _headerCards.postValue(visual) } - - _headerCards.postValue(visual) - } -} + } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt index e4fd0559..62b1fdd1 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt @@ -192,15 +192,15 @@ class EpisodeAdapter( downloadButton.isVisible = hasDownloadSupport downloadButton.setDefaultClickListener( VideoDownloadHelper.DownloadEpisodeCached( - card.name, - card.poster, - card.episode, - card.season, - card.id, - card.parentId, - card.rating, - card.description, - System.currentTimeMillis(), + name = card.name, + poster = card.poster, + episode = card.episode, + season = card.season, + id = card.id, + parentId = card.parentId, + rating = card.rating, + description = card.description, + cacheTime = System.currentTimeMillis(), ), null ) { when (it.action) { @@ -343,15 +343,15 @@ class EpisodeAdapter( downloadButton.isVisible = hasDownloadSupport downloadButton.setDefaultClickListener( VideoDownloadHelper.DownloadEpisodeCached( - card.name, - card.poster, - card.episode, - card.season, - card.id, - card.parentId, - card.rating, - card.description, - System.currentTimeMillis(), + name = card.name, + poster = card.poster, + episode = card.episode, + season = card.season, + id = card.id, + parentId = card.parentId, + rating = card.rating, + description = card.description, + cacheTime = System.currentTimeMillis(), ), null ) { when (it.action) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt index fb5160a7..1bb56f50 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragmentPhone.kt @@ -630,15 +630,15 @@ open class ResultFragmentPhone : FullScreenPlayer() { } downloadButton.setDefaultClickListener( VideoDownloadHelper.DownloadEpisodeCached( - ep.name, - ep.poster, - 0, - null, - ep.id, - ep.id, - null, - null, - System.currentTimeMillis(), + name = ep.name, + poster = ep.poster, + episode = 0, + season = null, + id = ep.id, + parentId = ep.id, + rating = null, + description = null, + cacheTime = System.currentTimeMillis(), ), null ) { click -> diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt index 4285feb1..ac6527de 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel2.kt @@ -705,13 +705,13 @@ class ResultViewModel2 : ViewModel() { DOWNLOAD_HEADER_CACHE, parentId.toString(), VideoDownloadHelper.DownloadHeaderCached( - apiName, - url, - currentType, - currentHeaderName, - currentPoster, - parentId, - System.currentTimeMillis(), + apiName = apiName, + url = url, + type = currentType, + name = currentHeaderName, + poster = currentPoster, + id = parentId, + cacheTime = System.currentTimeMillis(), ) ) @@ -722,15 +722,15 @@ class ResultViewModel2 : ViewModel() { ), // 3 deep folder for faster acess episode.id.toString(), VideoDownloadHelper.DownloadEpisodeCached( - episode.name, - episode.poster, - episode.episode, - episode.season, - episode.id, - parentId, - episode.rating, - episode.description, - System.currentTimeMillis(), + name = episode.name, + poster = episode.poster, + episode = episode.episode, + season = episode.season, + id = episode.id, + parentId = parentId, + rating = episode.rating, + description = episode.description, + cacheTime = System.currentTimeMillis(), ) ) @@ -2776,13 +2776,13 @@ class ResultViewModel2 : ViewModel() { DOWNLOAD_HEADER_CACHE, mainId.toString(), VideoDownloadHelper.DownloadHeaderCached( - apiName, - validUrl, - loadResponse.type, - loadResponse.name, - loadResponse.posterUrl, - mainId, - System.currentTimeMillis(), + apiName = apiName, + url = validUrl, + type = loadResponse.type, + name = loadResponse.name, + poster = loadResponse.posterUrl, + id = mainId, + cacheTime = System.currentTimeMillis(), ) ) if (loadTrailers) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt index 5b943105..66423982 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchHelper.kt @@ -25,7 +25,7 @@ object SearchHelper { SEARCH_ACTION_PLAY_FILE -> { if (card is DataStoreHelper.ResumeWatchingResult) { val id = card.id - if(id == null) { + if (id == null) { showToast(R.string.error_invalid_id, Toast.LENGTH_SHORT) } else { if (card.isFromDownload) { @@ -33,15 +33,15 @@ object SearchHelper { DownloadClickEvent( DOWNLOAD_ACTION_PLAY_FILE, VideoDownloadHelper.DownloadEpisodeCached( - card.name, - card.posterUrl, - card.episode ?: 0, - card.season, - id, - card.parentId ?: return, - null, - null, - System.currentTimeMillis() + name = card.name, + poster = card.posterUrl, + episode = card.episode ?: 0, + season = card.season, + id = id, + parentId = card.parentId ?: return, + rating = null, + description = null, + cacheTime = System.currentTimeMillis(), ) ) ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadHelper.kt index 34b109e0..a2a2bbd5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadHelper.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/VideoDownloadHelper.kt @@ -12,11 +12,11 @@ object VideoDownloadHelper { @JsonProperty("poster") val poster: String?, @JsonProperty("episode") val episode: Int, @JsonProperty("season") val season: Int?, - override val id: Int, @JsonProperty("parentId") val parentId: Int, @JsonProperty("rating") val rating: Int?, @JsonProperty("description") val description: String?, @JsonProperty("cacheTime") val cacheTime: Long, + override val id: Int, ): DownloadCachedAbstract(id) data class DownloadHeaderCached( @@ -25,8 +25,8 @@ object VideoDownloadHelper { @JsonProperty("type") val type: TvType, @JsonProperty("name") val name: String, @JsonProperty("poster") val poster: String?, - override val id: Int, @JsonProperty("cacheTime") val cacheTime: Long, + override val id: Int, ): DownloadCachedAbstract(id) data class ResumeWatching(