view download status

This commit is contained in:
rebelonion 2024-01-16 22:05:29 -06:00
parent 84fc5e6e2c
commit 6a42832855
6 changed files with 96 additions and 32 deletions

View file

@ -166,16 +166,12 @@ class AnimeWatchFragment : Fragment() {
if (!loaded) {
model.watchSources = if (media.isAdult) HAnimeSources else AnimeSources
val offlineMode = model.watchSources!!.list[media.selected!!.sourceIndex].name == "Downloaded"
val offlineMode = model.watchSources!!.isDownloadedSource(media.selected!!.sourceIndex)
headerAdapter = AnimeWatchAdapter(it, this, model.watchSources!!)
episodeAdapter =
EpisodeAdapter(style ?: uiSettings.animeDefaultView, media, this, offlineMode = offlineMode)
for (download in downloadManager.animeDownloadedTypes) {
episodeAdapter.stopDownload(download.chapter)
}
binding.animeSourceRecycler.adapter =
ConcatAdapter(headerAdapter, episodeAdapter)
@ -514,7 +510,7 @@ class AnimeWatchFragment : Fragment() {
model.saveSelected(media.id, selected, requireActivity())
headerAdapter.handleEpisodes()
val isDownloaded = model.watchSources?.list?.get(selected.sourceIndex)?.name == "Downloaded"
val isDownloaded = model.watchSources!!.isDownloadedSource(media.selected!!.sourceIndex)
episodeAdapter.offlineMode = isDownloaded
episodeAdapter.notifyItemRangeRemoved(0, episodeAdapter.arr.size)
var arr: ArrayList<Episode> = arrayListOf()
@ -530,6 +526,9 @@ class AnimeWatchFragment : Fragment() {
episodeAdapter.arr = arr
episodeAdapter.updateType(style ?: uiSettings.animeDefaultView)
episodeAdapter.notifyItemRangeInserted(0, arr.size)
for (download in downloadManager.animeDownloadedTypes) {
episodeAdapter.stopDownload(download.chapter)
}
}
override fun onDestroy() {

View file

@ -1,12 +1,16 @@
package ani.dantotsu.media.anime
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import android.widget.LinearLayout
import androidx.annotation.OptIn
import androidx.core.content.ContextCompat
import androidx.lifecycle.coroutineScope
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.offline.Download
import androidx.recyclerview.widget.RecyclerView
import ani.dantotsu.*
@ -14,11 +18,15 @@ import ani.dantotsu.connections.updateProgress
import ani.dantotsu.databinding.ItemEpisodeCompactBinding
import ani.dantotsu.databinding.ItemEpisodeGridBinding
import ani.dantotsu.databinding.ItemEpisodeListBinding
import ani.dantotsu.download.anime.AnimeDownloaderService
import ani.dantotsu.download.video.Helper
import ani.dantotsu.media.Media
import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.math.ln
import kotlin.math.pow
fun handleProgress(cont: LinearLayout, bar: View, empty: View, mediaId: Int, ep: String) {
val curr = loadData<Long>("${mediaId}_${ep}")
@ -98,7 +106,7 @@ class EpisodeAdapter(
Glide.with(binding.itemEpisodeImage).load(thumb ?: media.cover).override(400, 0)
.into(binding.itemEpisodeImage)
binding.itemEpisodeNumber.text = ep.number
binding.itemEpisodeTitle.text = title
binding.itemEpisodeTitle.text = if (ep.number == title) "Episode $title" else title
if (ep.filler) {
binding.itemEpisodeFiller.visibility = View.VISIBLE
@ -223,13 +231,26 @@ class EpisodeAdapter(
}
}
@OptIn(UnstableApi::class)
fun stopDownload(episodeNumber: String) {
activeDownloads.remove(episodeNumber)
downloadedEpisodes.add(episodeNumber)
// Find the position of the chapter and notify only that item
val position = arr.indexOfFirst { it.number == episodeNumber }
if (position != -1) {
arr[position].downloadProgress = "Downloaded"
val taskName = AnimeDownloaderService.AnimeDownloadTask.getTaskName(media.mainName(), episodeNumber)
val id = fragment.requireContext().getSharedPreferences(
ContextCompat.getString(fragment.requireContext(), R.string.anime_downloads),
Context.MODE_PRIVATE
).getString(
taskName,
""
) ?: ""
val index = Helper.downloadManager(fragment.requireContext()).downloadIndex
val download = index.getDownload(id)
val size = bytesToHuman(download?.bytesDownloaded?:0)
arr[position].downloadProgress = "Downloaded" + if (size != null) ": ($size)" else ""
notifyItemChanged(position)
}
}
@ -319,7 +340,7 @@ class EpisodeAdapter(
fun bind(episodeNumber: String, progress: String?) {
if (progress != null) {
binding.itemDownloadStatus.visibility = View.VISIBLE
binding.itemDownloadStatus.text = "$progress"
binding.itemDownloadStatus.text = progress
} else {
binding.itemDownloadStatus.visibility = View.GONE
binding.itemDownloadStatus.text = ""
@ -329,6 +350,7 @@ class EpisodeAdapter(
binding.itemDownload.setImageResource(R.drawable.ic_sync)
startOrContinueRotation(episodeNumber)
} else if (downloadedEpisodes.contains(episodeNumber)) {
binding.itemDownloadStatus.visibility = View.VISIBLE
// Show checkmark
binding.itemDownload.setImageResource(R.drawable.ic_circle_check)
//binding.itemDownload.setColorFilter(typedValue2.data) //TODO: colors go to wrong places
@ -338,6 +360,7 @@ class EpisodeAdapter(
//binding.itemDownload.setColorFilter(typedValue2.data)
}, 1000)
} else {
binding.itemDownloadStatus.visibility = View.GONE
// Show download icon
binding.itemDownload.setImageResource(R.drawable.ic_circle_add)
}
@ -371,5 +394,14 @@ class EpisodeAdapter(
fun updateType(t: Int) {
type = t
}
private fun bytesToHuman(bytes: Long): String? {
if (bytes < 0) return null
val unit = 1000
if (bytes < unit) return "$bytes B"
val exp = (Math.log(bytes.toDouble()) / ln(unit.toDouble())).toInt()
val pre = ("KMGTPE")[exp - 1]
return String.format("%.1f %sB", bytes / unit.toDouble().pow(exp.toDouble()), pre)
}
}

View file

@ -6,6 +6,7 @@ import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
import android.view.HapticFeedbackConstants
import android.view.LayoutInflater
@ -31,6 +32,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.DecimalFormat
import java.util.concurrent.CountDownLatch
class SelectorDialogFragment : BottomSheetDialogFragment() {
private var _binding: BottomSheetSelectorBinding? = null
@ -43,7 +46,7 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
private var makeDefault = false
private var selected: String? = null
private var launch: Boolean? = null
private var isDownload: Boolean? = null
private var isDownloadMenu: Boolean? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -51,7 +54,7 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
selected = it.getString("server")
launch = it.getBoolean("launch", true)
prevEpisode = it.getString("prev")
isDownload = it.getBoolean("isDownload")
isDownloadMenu = it.getBoolean("isDownload")
}
}
@ -79,10 +82,11 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
val ep = media?.anime?.episodes?.get(media?.anime?.selectedEpisode)
episode = ep
if (ep != null) {
if (isDownload == true) {
if (isDownloadMenu == true) {
binding.selectorMakeDefault.visibility = View.GONE
}
if (selected != null && isDownload == false) {
if (selected != null && isDownloadMenu == false) {
binding.selectorListContainer.visibility = View.GONE
binding.selectorAutoListContainer.visibility = View.VISIBLE
binding.selectorAutoText.text = selected
@ -100,7 +104,12 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
fun load() {
val size =
ep.extractors?.find { it.server.name == selected }?.videos?.size
if (model.watchSources!!.isDownloadedSource(media!!.selected!!.sourceIndex)) {
ep.extractors?.firstOrNull()?.videos?.size
} else {
ep.extractors?.find { it.server.name == selected }?.videos?.size
}
if (size != null && size >= media!!.selected!!.video) {
media!!.anime!!.episodes?.get(media!!.anime!!.selectedEpisode!!)?.selectedExtractor =
selected
@ -150,6 +159,9 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
ep.extractorCallback = {
scope.launch {
adapter.add(it)
if (model.watchSources!!.isDownloadedSource(media?.selected!!.sourceIndex)) {
adapter.perfromClick(0)
}
}
}
model.getEpisode().observe(this) {
@ -169,6 +181,9 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
} else {
media!!.anime?.episodes?.set(media!!.anime?.selectedEpisode!!, ep)
adapter.addAll(ep.extractors)
if (model.watchSources!!.isDownloadedSource(media?.selected!!.sourceIndex)) {
adapter.perfromClick(0)
}
binding.selectorProgressBar.visibility = View.GONE
}
}
@ -184,7 +199,7 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
prevEpisode = null
dismiss()
if (launch!!) {
if (launch!! || model.watchSources!!.isDownloadedSource(media.selected!!.sourceIndex)) {
stopAddingToList()
val intent = Intent(activity, ExoplayerView::class.java)
ExoplayerView.media = media
@ -241,6 +256,14 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
notifyItemRangeInserted(0, extractors.size)
}
fun perfromClick(position: Int) {
val extractor = links[position]
media!!.anime!!.episodes!![media!!.anime!!.selectedEpisode!!]?.selectedExtractor =
extractor.server.name
media!!.anime!!.episodes!![media!!.anime!!.selectedEpisode!!]?.selectedVideo = 0
startExoplayer(media!!)
}
private inner class StreamViewHolder(val binding: ItemStreamBinding) :
RecyclerView.ViewHolder(binding.root)
}
@ -262,7 +285,7 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
override fun onBindViewHolder(holder: UrlViewHolder, position: Int) {
val binding = holder.binding
val video = extractor.videos[position]
if (isDownload == true) {
if (isDownloadMenu == true) {
binding.urlDownload.visibility = View.VISIBLE
} else {
binding.urlDownload.visibility = View.GONE
@ -318,7 +341,7 @@ class SelectorDialogFragment : BottomSheetDialogFragment() {
RecyclerView.ViewHolder(binding.root) {
init {
itemView.setSafeOnClickListener {
if (isDownload == true) {
if (isDownloadMenu == true) {
binding.urlDownload.performClick()
return@setSafeOnClickListener
}