package ani.dantotsu.media.novel import android.util.Log import android.util.TypedValue import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import ani.dantotsu.R import ani.dantotsu.databinding.ItemNovelResponseBinding import ani.dantotsu.parsers.ShowResponse import ani.dantotsu.setAnimation import ani.dantotsu.snackString import com.bumptech.glide.Glide import com.bumptech.glide.load.model.GlideUrl class NovelResponseAdapter( val fragment: NovelReadFragment, val downloadTriggerCallback: DownloadTriggerCallback, val downloadedCheckCallback: DownloadedCheckCallback ) : RecyclerView.Adapter() { val list: MutableList = mutableListOf() inner class ViewHolder(val binding: ItemNovelResponseBinding) : RecyclerView.ViewHolder(binding.root) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val bind = ItemNovelResponseBinding.inflate(LayoutInflater.from(parent.context), parent, false) return ViewHolder(bind) } override fun getItemCount(): Int = list.size override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding val novel = list[position] setAnimation(fragment.requireContext(), holder.binding.root) val cover = GlideUrl(novel.coverUrl.url) { novel.coverUrl.headers } Glide.with(binding.itemEpisodeImage).load(cover).override(400, 0) .into(binding.itemEpisodeImage) val typedValue = TypedValue() fragment.requireContext().theme?.resolveAttribute( com.google.android.material.R.attr.colorOnBackground, typedValue, true ) val color = typedValue.data binding.itemEpisodeTitle.text = novel.name binding.itemEpisodeFiller.text = if (downloadedCheckCallback.downloadedCheck(novel)) { "Downloaded" } else { novel.extra?.get("0") ?: "" } if (binding.itemEpisodeFiller.text.contains("Downloading")) { binding.itemEpisodeFiller.setTextColor( fragment.requireContext().getColor(android.R.color.holo_blue_light) ) } else if (binding.itemEpisodeFiller.text.contains("Downloaded")) { binding.itemEpisodeFiller.setTextColor( fragment.requireContext().getColor(android.R.color.holo_green_light) ) } else { binding.itemEpisodeFiller.setTextColor(color) } binding.itemEpisodeDesc2.text = novel.extra?.get("1") ?: "" val desc = novel.extra?.get("2") binding.itemEpisodeDesc.visibility = if (desc != null && desc.trim(' ') != "") View.VISIBLE else View.GONE binding.itemEpisodeDesc.text = desc ?: "" binding.root.setOnClickListener { //make sure the file is not downloading if (activeDownloads.contains(novel.link)) { return@setOnClickListener } if (downloadedCheckCallback.downloadedCheckWithStart(novel)) { return@setOnClickListener } val bookDialog = BookDialog.newInstance(fragment.novelName, novel, fragment.source) bookDialog.setCallback(object : BookDialog.Callback { override fun onDownloadTriggered(link: String) { downloadTriggerCallback.downloadTrigger( NovelDownloadPackage( link, novel.coverUrl.url, novel.name, novel.link ) ) bookDialog.dismiss() } }) bookDialog.show(fragment.parentFragmentManager, "dialog") } binding.root.setOnLongClickListener { val builder = androidx.appcompat.app.AlertDialog.Builder( fragment.requireContext(), R.style.MyPopup ) builder.setTitle("Delete ${novel.name}?") builder.setMessage("Are you sure you want to delete ${novel.name}?") builder.setPositiveButton("Yes") { _, _ -> downloadedCheckCallback.deleteDownload(novel) deleteDownload(novel.link) snackString("Deleted ${novel.name}") if (binding.itemEpisodeFiller.text.toString() .contains("Download", ignoreCase = true) ) { binding.itemEpisodeFiller.text = "" } } builder.setNegativeButton("No") { _, _ -> // Do nothing } val dialog = builder.show() dialog.window?.setDimAmount(0.8f) true } } private val activeDownloads = mutableSetOf() private val downloadedChapters = mutableSetOf() fun startDownload(link: String) { activeDownloads.add(link) val position = list.indexOfFirst { it.link == link } if (position != -1) { list[position].extra?.remove("0") list[position].extra?.set("0", "Downloading: 0%") notifyItemChanged(position) } } fun stopDownload(link: String) { activeDownloads.remove(link) downloadedChapters.add(link) val position = list.indexOfFirst { it.link == link } if (position != -1) { list[position].extra?.remove("0") list[position].extra?.set("0", "Downloaded") notifyItemChanged(position) } } fun deleteDownload(link: String) { //TODO: downloadedChapters.remove(link) val position = list.indexOfFirst { it.link == link } if (position != -1) { list[position].extra?.remove("0") list[position].extra?.set("0", "") notifyItemChanged(position) } } fun purgeDownload(link: String) { activeDownloads.remove(link) downloadedChapters.remove(link) val position = list.indexOfFirst { it.link == link } if (position != -1) { list[position].extra?.remove("0") list[position].extra?.set("0", "Failed") notifyItemChanged(position) } } fun updateDownloadProgress(link: String, progress: Int) { if (!activeDownloads.contains(link)) { activeDownloads.add(link) } val position = list.indexOfFirst { it.link == link } if (position != -1) { list[position].extra?.remove("0") list[position].extra?.set("0", "Downloading: $progress%") Log.d("NovelResponseAdapter", "updateDownloadProgress: $progress, position: $position") notifyItemChanged(position) } } fun submitList(it: List) { val old = list.size list.addAll(it) notifyItemRangeInserted(old, it.size) } fun clear() { val size = list.size list.clear() notifyItemRangeRemoved(0, size) } } data class NovelDownloadPackage( val link: String, val coverUrl: String, val novelName: String, val originalLink: String )