AquaStream/app/src/main/java/com/lagradost/cloudstream3/ui/result/EpisodeAdapter.kt

306 lines
12 KiB
Kotlin
Raw Normal View History

2021-05-18 13:43:32 +00:00
package com.lagradost.cloudstream3.ui.result
2021-06-26 19:32:50 +00:00
import android.annotation.SuppressLint
2021-05-18 13:43:32 +00:00
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
2022-06-18 00:30:39 +00:00
import androidx.core.view.isGone
2022-01-07 19:27:25 +00:00
import androidx.core.view.isVisible
2021-06-26 19:32:50 +00:00
import androidx.core.widget.ContentLoadingProgressBar
2022-08-02 00:43:42 +00:00
import androidx.recyclerview.widget.DiffUtil
2021-05-18 13:43:32 +00:00
import androidx.recyclerview.widget.RecyclerView
2022-01-07 19:27:25 +00:00
import com.google.android.material.button.MaterialButton
2021-07-23 23:44:54 +00:00
import com.lagradost.cloudstream3.R
2021-07-24 20:50:57 +00:00
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_ACTION_DOWNLOAD
2021-07-28 19:14:45 +00:00
import com.lagradost.cloudstream3.ui.download.DownloadButtonViewHolder
2021-07-24 20:50:57 +00:00
import com.lagradost.cloudstream3.ui.download.DownloadClickEvent
2021-07-28 19:14:45 +00:00
import com.lagradost.cloudstream3.ui.download.EasyDownloadButton
2022-02-18 19:29:48 +00:00
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
2022-06-29 01:20:23 +00:00
import com.lagradost.cloudstream3.utils.AppUtils.html
2021-08-19 20:05:18 +00:00
import com.lagradost.cloudstream3.utils.UIHelper.setImage
2021-07-24 20:50:57 +00:00
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
2021-07-24 23:16:30 +00:00
import com.lagradost.cloudstream3.utils.VideoDownloadManager
2022-01-07 19:27:25 +00:00
import kotlinx.android.synthetic.main.result_episode.view.*
2021-06-26 19:32:50 +00:00
import kotlinx.android.synthetic.main.result_episode.view.episode_text
import kotlinx.android.synthetic.main.result_episode_large.view.*
2022-01-07 19:27:25 +00:00
import kotlinx.android.synthetic.main.result_episode_large.view.episode_filler
import kotlinx.android.synthetic.main.result_episode_large.view.episode_progress
import kotlinx.android.synthetic.main.result_episode_large.view.result_episode_download
import kotlinx.android.synthetic.main.result_episode_large.view.result_episode_progress_downloaded
2021-07-28 19:14:45 +00:00
import java.util.*
2021-05-18 13:43:32 +00:00
2021-06-29 23:14:48 +00:00
const val ACTION_PLAY_EPISODE_IN_PLAYER = 1
2021-07-17 21:36:50 +00:00
const val ACTION_PLAY_EPISODE_IN_VLC_PLAYER = 2
2021-07-17 14:14:25 +00:00
const val ACTION_PLAY_EPISODE_IN_BROWSER = 3
const val ACTION_CHROME_CAST_EPISODE = 4
const val ACTION_CHROME_CAST_MIRROR = 5
const val ACTION_DOWNLOAD_EPISODE = 6
const val ACTION_DOWNLOAD_MIRROR = 7
const val ACTION_RELOAD_EPISODE = 8
const val ACTION_COPY_LINK = 9
const val ACTION_SHOW_OPTIONS = 10
2021-05-20 20:56:21 +00:00
2021-07-23 23:44:54 +00:00
const val ACTION_CLICK_DEFAULT = 11
const val ACTION_SHOW_TOAST = 12
2022-06-18 00:30:39 +00:00
const val ACTION_SHOW_DESCRIPTION = 15
2021-07-23 23:44:54 +00:00
const val ACTION_DOWNLOAD_EPISODE_SUBTITLE = 13
const val ACTION_DOWNLOAD_EPISODE_SUBTITLE_MIRROR = 14
2021-05-20 20:56:21 +00:00
data class EpisodeClickEvent(val action: Int, val data: ResultEpisode)
2021-05-18 13:43:32 +00:00
class EpisodeAdapter(
2021-07-24 20:50:57 +00:00
private val hasDownloadSupport: Boolean,
2021-06-10 15:15:14 +00:00
private val clickCallback: (EpisodeClickEvent) -> Unit,
2021-07-24 20:50:57 +00:00
private val downloadClickCallback: (DownloadClickEvent) -> Unit,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var cardList: MutableList<ResultEpisode> = mutableListOf()
2021-07-28 19:14:45 +00:00
private val mBoundViewHolders: HashSet<DownloadButtonViewHolder> = HashSet()
private fun getAllBoundViewHolders(): Set<DownloadButtonViewHolder?>? {
return Collections.unmodifiableSet(mBoundViewHolders)
}
fun killAdapter() {
getAllBoundViewHolders()?.forEach { view ->
view?.downloadButton?.dispose()
}
}
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
if (holder.itemView.hasFocus()) {
2022-08-06 18:36:45 +00:00
holder.itemView.clearFocus()
}
//(holder.itemView as? FrameLayout?)?.descendantFocusability =
// ViewGroup.FOCUS_BLOCK_DESCENDANTS
2021-07-28 19:14:45 +00:00
if (holder is DownloadButtonViewHolder) {
holder.downloadButton.dispose()
}
}
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
if (holder is DownloadButtonViewHolder) {
holder.downloadButton.dispose()
2021-08-19 20:05:18 +00:00
mBoundViewHolders.remove(holder)
//(holder.itemView as? FrameLayout?)?.descendantFocusability =
// ViewGroup.FOCUS_BLOCK_DESCENDANTS
2021-07-28 19:14:45 +00:00
}
}
override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
if (holder is DownloadButtonViewHolder) {
//println("onViewAttachedToWindow = ${holder.absoluteAdapterPosition}")
//holder.itemView.post {
// if (holder.itemView.isAttachedToWindow)
// (holder.itemView as? FrameLayout?)?.descendantFocusability =
// ViewGroup.FOCUS_AFTER_DESCENDANTS
//}
2021-07-28 19:14:45 +00:00
holder.reattachDownloadButton()
}
}
2022-08-02 00:43:42 +00:00
fun updateList(newList: List<ResultEpisode>) {
val diffResult = DiffUtil.calculateDiff(
ResultDiffCallback(this.cardList, newList)
)
cardList.clear()
cardList.addAll(newList)
diffResult.dispatchUpdatesTo(this)
}
2022-08-05 23:41:35 +00:00
var layout = R.layout.result_episode_both
2021-05-18 13:43:32 +00:00
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
2021-06-26 19:32:50 +00:00
/*val layout = if (cardList.filter { it.poster != null }.size >= cardList.size / 2)
R.layout.result_episode_large
else R.layout.result_episode*/
2021-07-28 19:14:45 +00:00
return EpisodeCardViewHolder(
2022-06-29 01:20:23 +00:00
LayoutInflater.from(parent.context)
2022-08-05 23:41:35 +00:00
.inflate(layout, parent, false),
2021-07-23 23:44:54 +00:00
hasDownloadSupport,
2021-07-24 20:50:57 +00:00
clickCallback,
downloadClickCallback
2021-05-18 13:43:32 +00:00
)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
2021-07-28 19:14:45 +00:00
is EpisodeCardViewHolder -> {
2021-05-18 13:43:32 +00:00
holder.bind(cardList[position])
2021-07-28 19:14:45 +00:00
mBoundViewHolders.add(holder)
2021-05-18 13:43:32 +00:00
}
}
}
override fun getItemCount(): Int {
return cardList.size
}
2021-07-28 19:14:45 +00:00
class EpisodeCardViewHolder
2021-05-20 20:56:21 +00:00
constructor(
itemView: View,
2021-07-30 23:41:54 +00:00
private val hasDownloadSupport: Boolean,
2021-06-06 18:06:01 +00:00
private val clickCallback: (EpisodeClickEvent) -> Unit,
2021-07-24 20:50:57 +00:00
private val downloadClickCallback: (DownloadClickEvent) -> Unit,
2021-07-28 19:14:45 +00:00
) : RecyclerView.ViewHolder(itemView), DownloadButtonViewHolder {
override var downloadButton = EasyDownloadButton()
2022-06-18 00:30:39 +00:00
var episodeDownloadBar: ContentLoadingProgressBar? = null
var episodeDownloadImage: ImageView? = null
2021-07-28 19:14:45 +00:00
var localCard: ResultEpisode? = null
2021-06-26 19:32:50 +00:00
@SuppressLint("SetTextI18n")
2021-05-18 13:43:32 +00:00
fun bind(card: ResultEpisode) {
2021-07-28 19:14:45 +00:00
localCard = card
2021-09-12 14:10:22 +00:00
2022-08-28 23:52:15 +00:00
val isTrueTv = isTrueTvSettings()
2022-08-05 23:41:35 +00:00
2022-06-29 01:20:23 +00:00
val (parentView, otherView) = if (card.poster == null) {
2022-06-18 00:30:39 +00:00
itemView.episode_holder to itemView.episode_holder_large
} else {
itemView.episode_holder_large to itemView.episode_holder
}
parentView.isVisible = true
otherView.isVisible = false
val episodeText: TextView = parentView.episode_text
val episodeFiller: MaterialButton? = parentView.episode_filler
val episodeRating: TextView? = parentView.episode_rating
val episodeDescript: TextView? = parentView.episode_descript
val episodeProgress: ContentLoadingProgressBar? = parentView.episode_progress
val episodePoster: ImageView? = parentView.episode_poster
episodeDownloadBar =
parentView.result_episode_progress_downloaded
episodeDownloadImage = parentView.result_episode_download
val name =
if (card.name == null) "${episodeText.context.getString(R.string.episode)} ${card.episode}" else "${card.episode}. ${card.name}"
2022-01-07 19:27:25 +00:00
episodeFiller?.isVisible = card.isFiller == true
2022-06-18 00:30:39 +00:00
episodeText.text =
name//if(card.isFiller == true) episodeText.context.getString(R.string.filler).format(name) else name
2021-09-12 14:10:22 +00:00
episodeText.isSelected = true // is needed for text repeating
2021-05-18 13:43:32 +00:00
2021-07-29 15:16:08 +00:00
val displayPos = card.getDisplayPosition()
episodeProgress?.max = (card.duration / 1000).toInt()
episodeProgress?.progress = (displayPos / 1000).toInt()
episodeProgress?.isVisible = displayPos > 0L
2021-06-26 19:32:50 +00:00
episodePoster?.isVisible = episodePoster?.setImage(card.poster) == true
2021-06-26 19:32:50 +00:00
if (card.rating != null) {
2022-06-18 00:30:39 +00:00
episodeRating?.text = episodeRating?.context?.getString(R.string.rated_format)
?.format(card.rating.toFloat() / 10f)
2021-06-26 19:32:50 +00:00
} else {
episodeRating?.text = ""
}
2022-06-18 00:30:39 +00:00
episodeRating?.isGone = episodeRating?.text.isNullOrBlank()
episodeDescript?.apply {
2022-06-29 01:20:23 +00:00
text = card.description.html()
2022-06-18 00:30:39 +00:00
isGone = text.isNullOrBlank()
setOnClickListener {
clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_DESCRIPTION, card))
}
2021-06-26 19:32:50 +00:00
}
2021-05-18 13:43:32 +00:00
2022-08-05 23:41:35 +00:00
if (!isTrueTv) {
episodePoster?.setOnClickListener {
clickCallback.invoke(EpisodeClickEvent(ACTION_CLICK_DEFAULT, card))
}
2021-08-04 01:50:24 +00:00
2022-08-05 23:41:35 +00:00
episodePoster?.setOnLongClickListener {
clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_TOAST, card))
return@setOnLongClickListener true
}
2021-08-04 01:50:24 +00:00
}
itemView.setOnClickListener {
2021-07-23 23:44:54 +00:00
clickCallback.invoke(EpisodeClickEvent(ACTION_CLICK_DEFAULT, card))
2021-07-17 14:14:25 +00:00
}
2022-08-05 23:41:35 +00:00
if (isTrueTv) {
itemView.isFocusable = true
itemView.isFocusableInTouchMode = true
//itemView.touchscreenBlocksFocus = false
2021-11-25 17:26:14 +00:00
}
itemView.setOnLongClickListener {
2021-07-17 14:14:25 +00:00
clickCallback.invoke(EpisodeClickEvent(ACTION_SHOW_OPTIONS, card))
return@setOnLongClickListener true
2021-07-15 16:45:25 +00:00
}
2022-06-18 00:30:39 +00:00
episodeDownloadImage?.isVisible = hasDownloadSupport
episodeDownloadBar?.isVisible = hasDownloadSupport
reattachDownloadButton()
2021-07-28 19:14:45 +00:00
}
2021-07-24 23:16:30 +00:00
2021-07-28 19:14:45 +00:00
override fun reattachDownloadButton() {
downloadButton.dispose()
val card = localCard
if (hasDownloadSupport && card != null) {
if (episodeDownloadBar == null ||
episodeDownloadImage == null
) return
2022-06-18 00:30:39 +00:00
val downloadInfo = VideoDownloadManager.getDownloadFileInfoAndUpdateSettings(
itemView.context,
card.id
)
2021-07-24 23:16:30 +00:00
2021-07-28 19:14:45 +00:00
downloadButton.setUpButton(
2022-06-18 00:30:39 +00:00
downloadInfo?.fileLength,
downloadInfo?.totalBytes,
episodeDownloadBar ?: return,
episodeDownloadImage ?: return,
null,
2021-07-24 20:50:57 +00:00
VideoDownloadHelper.DownloadEpisodeCached(
2021-08-04 01:50:24 +00:00
card.name,
card.poster,
card.episode,
card.season,
card.id,
card.parentId,
2021-08-04 01:50:24 +00:00
card.rating,
card.description,
2021-08-04 01:50:24 +00:00
System.currentTimeMillis(),
2021-07-24 20:50:57 +00:00
)
) {
2021-07-24 23:16:30 +00:00
if (it.action == DOWNLOAD_ACTION_DOWNLOAD) {
2021-07-24 20:50:57 +00:00
clickCallback.invoke(EpisodeClickEvent(ACTION_DOWNLOAD_EPISODE, card))
} else {
downloadClickCallback.invoke(it)
}
}
2021-05-18 13:43:32 +00:00
}
}
}
}
2022-08-02 00:43:42 +00:00
class ResultDiffCallback(
private val oldList: List<ResultEpisode>,
private val newList: List<ResultEpisode>
) :
DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
oldList[oldItemPosition].id == newList[newItemPosition].id
override fun getOldListSize() = oldList.size
override fun getNewListSize() = newList.size
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
oldList[oldItemPosition] == newList[newItemPosition]
}