teapod/app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt

179 lines
7.1 KiB
Kotlin
Raw Normal View History

package org.mosad.teapod.util.adapter
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import jp.wasabeef.glide.transformations.RoundedCornersTransformation
import org.mosad.teapod.R
2020-11-25 22:35:55 +01:00
import org.mosad.teapod.databinding.ItemEpisodeBinding
import org.mosad.teapod.databinding.ItemEpisodePlayerBinding
import org.mosad.teapod.parser.crunchyroll.Episode
import org.mosad.teapod.parser.crunchyroll.PlayheadObject
import org.mosad.teapod.parser.crunchyroll.PlayheadsMap
2021-07-25 19:15:31 +02:00
import org.mosad.teapod.util.tmdb.TMDBTVEpisode
class EpisodeItemAdapter(
private val episodes: List<Episode>,
private val tmdbEpisodes: List<TMDBTVEpisode>?,
private val playheads: PlayheadsMap,
private val onClickListener: OnClickListener,
private val viewType: ViewType
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var currentSelected: Int = -1 // -1, since position should never be < 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ViewType.PLAYER.ordinal -> {
PlayerEpisodeViewHolder((ItemEpisodePlayerBinding.inflate(LayoutInflater.from(parent.context), parent, false)))
}
else -> {
// media fragment episode list is default
EpisodeViewHolder(ItemEpisodeBinding.inflate(LayoutInflater.from(parent.context), parent, false))
2021-12-29 20:51:53 +01:00
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val episode = episodes[position]
val playhead = playheads[episode.id]
val tmdbEpisode = tmdbEpisodes?.getOrNull(position)
when (holder.itemViewType) {
ViewType.MEDIA_FRAGMENT.ordinal -> {
(holder as EpisodeViewHolder).bind(episode, playhead, tmdbEpisode)
}
ViewType.PLAYER.ordinal -> {
(holder as PlayerEpisodeViewHolder).bind(episode, playhead, currentSelected)
}
}
}
override fun getItemViewType(position: Int): Int {
return when (viewType) {
ViewType.MEDIA_FRAGMENT -> ViewType.MEDIA_FRAGMENT.ordinal
ViewType.PLAYER -> ViewType.PLAYER.ordinal
}
}
override fun getItemCount(): Int {
return episodes.size
}
2021-12-20 22:14:58 +01:00
inner class EpisodeViewHolder(val binding: ItemEpisodeBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(episode: Episode, playhead: PlayheadObject?, tmdbEpisode: TMDBTVEpisode?) {
val context = binding.root.context
val titleText = if (episode.episodeNumber != null) {
// for tv shows add ep prefix and episode number
if (episode.isDubbed) {
context.getString(R.string.component_episode_title, episode.episode, episode.title)
} else {
context.getString(R.string.component_episode_title_sub, episode.episode, episode.title)
}
} else {
episode.title
}
binding.textEpisodeTitle.text = titleText
binding.textEpisodeDesc.text = episode.description.ifEmpty {
tmdbEpisode?.overview ?: ""
}
if (episode.images.thumbnail[0][0].source.isNotEmpty()) {
Glide.with(context).load(episode.images.thumbnail[0][0].source)
.apply(RequestOptions.placeholderOf(ColorDrawable(Color.DKGRAY)))
.apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(10, 0)))
.into(binding.imageEpisode)
}
// add watched progress
val playheadProgress = playhead?.playhead?.let {
((it.toFloat() / (episode.durationMs / 1000)) * 100).toInt()
} ?: 0
binding.progressPlayhead.setProgressCompat(playheadProgress, false)
binding.progressPlayhead.visibility = if (playheadProgress <= 0)
View.GONE else View.VISIBLE
// add watched icon to episode, if the episode id is present in playheads and fullyWatched
val watchedImage: Drawable? = if (playhead?.fullyWatched == true) {
ContextCompat.getDrawable(context, R.drawable.ic_baseline_check_circle_24)
} else {
null
}
binding.imageWatched.setImageDrawable(watchedImage)
2020-11-25 22:35:55 +01:00
binding.imageEpisode.setOnClickListener {
onClickListener.onClick(episode)
2020-10-16 10:05:11 +02:00
}
}
}
inner class PlayerEpisodeViewHolder(val binding: ItemEpisodePlayerBinding) :
RecyclerView.ViewHolder(binding.root) {
// -1, since position should never be < 0
fun bind(episode: Episode, playhead: PlayheadObject?, currentSelected: Int) {
val context = binding.root.context
val titleText = if (episode.episodeNumber != null) {
// for tv shows add ep prefix and episode number
if (episode.isDubbed) {
context.getString(R.string.component_episode_title, episode.episode, episode.title)
} else {
context.getString(R.string.component_episode_title_sub, episode.episode, episode.title)
}
} else {
episode.title
}
binding.textEpisodeTitle2.text = titleText
binding.textEpisodeDesc2.text = episode.description.ifEmpty { "" }
if (episode.images.thumbnail[0][0].source.isNotEmpty()) {
Glide.with(context).load(episode.images.thumbnail[0][0].source)
.apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(10, 0)))
.into(binding.imageEpisode)
}
// add watched progress
val playheadProgress = playhead?.playhead?.let {
((it.toFloat() / (episode.durationMs / 1000)) * 100).toInt()
} ?: 0
binding.progressPlayhead.setProgressCompat(playheadProgress, false)
binding.progressPlayhead.visibility = if (playheadProgress <= 0)
View.GONE else View.VISIBLE
// hide the play icon, if it's the current episode
binding.imageEpisodePlay.visibility = if (currentSelected == bindingAdapterPosition) {
View.GONE
} else {
View.VISIBLE
}
if (currentSelected != bindingAdapterPosition) {
binding.imageEpisode.setOnClickListener {
onClickListener.onClick(episode)
}
}
}
}
class OnClickListener(val clickListener: (episode: Episode) -> Unit) {
fun onClick(episode: Episode) = clickListener(episode)
}
enum class ViewType {
MEDIA_FRAGMENT,
PLAYER
}
}