From 6fc7bb2c1e4ac91daa5d96ae5582e791fdd8c94b Mon Sep 17 00:00:00 2001 From: Jannik Date: Mon, 14 Dec 2020 23:46:55 +0100 Subject: [PATCH] add episodes list to player [Part 1] --- .../org/mosad/teapod/player/PlayerActivity.kt | 14 ++++- .../teapod/ui/components/EpisodesPlayer.kt | 37 +++++++++++++ .../util/adapter/PlayerEpisodeItemAdapter.kt | 52 +++++++++++++++++++ app/src/main/res/layout/fragment_about.xml | 1 - .../main/res/layout/item_episode_player.xml | 50 ++++++++++++++++++ app/src/main/res/layout/player_episodes.xml | 43 +++++++++++++++ 6 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/org/mosad/teapod/ui/components/EpisodesPlayer.kt create mode 100644 app/src/main/java/org/mosad/teapod/util/adapter/PlayerEpisodeItemAdapter.kt create mode 100644 app/src/main/res/layout/item_episode_player.xml create mode 100644 app/src/main/res/layout/player_episodes.xml diff --git a/app/src/main/java/org/mosad/teapod/player/PlayerActivity.kt b/app/src/main/java/org/mosad/teapod/player/PlayerActivity.kt index c825ddd..de0adda 100644 --- a/app/src/main/java/org/mosad/teapod/player/PlayerActivity.kt +++ b/app/src/main/java/org/mosad/teapod/player/PlayerActivity.kt @@ -29,6 +29,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.mosad.teapod.R import org.mosad.teapod.preferences.Preferences +import org.mosad.teapod.ui.components.EpisodesPlayer import org.mosad.teapod.util.DataTypes import org.mosad.teapod.util.Episode import java.util.* @@ -151,6 +152,7 @@ class PlayerActivity : AppCompatActivity() { } if (state == ExoPlayer.STATE_ENDED && model.nextEpisode != null && Preferences.autoplay) { + // if next episode btn was clicked, skipp playNextEpisode() on STATE_ENDED if (nextEpManually) { nextEpManually = false } else { @@ -187,6 +189,7 @@ class PlayerActivity : AppCompatActivity() { ffwd_10.setOnButtonClickListener { fastForward() } button_next_ep.setOnClickListener { playNextEpisode() } button_next_ep_c.setOnClickListener { playNextEpisode() } + button_episodes.setOnClickListener { showEpisodesList() } } private fun initTimeUpdates() { @@ -314,7 +317,11 @@ class PlayerActivity : AppCompatActivity() { private fun playCurrentMedia(seekToPosition: Boolean) { // update the gui exo_text_title.text = if (model.media.type == DataTypes.MediaType.TVSHOW) { - getString(R.string.component_episode_title, model.currentEpisode.number, model.currentEpisode.description) + getString( + R.string.component_episode_title, + model.currentEpisode.number, + model.currentEpisode.description + ) } else { model.currentEpisode.title } @@ -401,6 +408,11 @@ class PlayerActivity : AppCompatActivity() { } + private fun showEpisodesList() { + val rootView = window.decorView.rootView as ViewGroup + EpisodesPlayer(rootView, model) + } + inner class PlayerGestureListener : GestureDetector.SimpleOnGestureListener() { /** diff --git a/app/src/main/java/org/mosad/teapod/ui/components/EpisodesPlayer.kt b/app/src/main/java/org/mosad/teapod/ui/components/EpisodesPlayer.kt new file mode 100644 index 0000000..ba04599 --- /dev/null +++ b/app/src/main/java/org/mosad/teapod/ui/components/EpisodesPlayer.kt @@ -0,0 +1,37 @@ +package org.mosad.teapod.ui.components + +import android.view.LayoutInflater +import android.view.ViewGroup +import org.mosad.teapod.databinding.PlayerEpisodesBinding +import org.mosad.teapod.player.PlayerViewModel +import org.mosad.teapod.util.adapter.PlayerEpisodeItemAdapter + +/** + * TODO toggle play/pause on close/open + * TODO play selected episode + * TODO scroll to current episode + */ +class EpisodesPlayer(val parent: ViewGroup, private val model: PlayerViewModel) { + + private val binding = PlayerEpisodesBinding.inflate(LayoutInflater.from(parent.context), parent, true) + private var adapterRecEpisodes = PlayerEpisodeItemAdapter(model.media.episodes) + + init { + binding.recyclerEpisodesPlayer.adapter = adapterRecEpisodes + + initActions() + } + + private fun initActions() { + binding.buttonCloseEpisodesList.setOnClickListener { + parent.removeView(binding.root) + } + + adapterRecEpisodes.onImageClick = { _, position -> + println(model.media.episodes[position]) + //playEpisode(media.episodes[position]) + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/PlayerEpisodeItemAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/PlayerEpisodeItemAdapter.kt new file mode 100644 index 0000000..470a559 --- /dev/null +++ b/app/src/main/java/org/mosad/teapod/util/adapter/PlayerEpisodeItemAdapter.kt @@ -0,0 +1,52 @@ +package org.mosad.teapod.util.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +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 +import org.mosad.teapod.databinding.ItemEpisodePlayerBinding +import org.mosad.teapod.util.Episode + +class PlayerEpisodeItemAdapter(private val episodes: List) : RecyclerView.Adapter() { + + var onImageClick: ((String, Int) -> Unit)? = null + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EpisodeViewHolder { + return EpisodeViewHolder(ItemEpisodePlayerBinding.inflate(LayoutInflater.from(parent.context), parent, false)) + } + + override fun onBindViewHolder(holder: EpisodeViewHolder, position: Int) { + val context = holder.binding.root.context + val ep = episodes[position] + + val titleText = if (ep.priStreamUrl.isEmpty() && ep.secStreamOmU) { + context.getString(R.string.component_episode_title_sub, ep.number, ep.description) + } else { + context.getString(R.string.component_episode_title, ep.number, ep.description) + } + + holder.binding.textEpisodeTitle2.text = titleText + holder.binding.textEpisodeDesc2.text = ep.shortDesc + + if (episodes[position].posterUrl.isNotEmpty()) { + Glide.with(context).load(ep.posterUrl) + .apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(10, 0))) + .into(holder.binding.imageEpisode) + } + } + + override fun getItemCount(): Int { + return episodes.size + } + + inner class EpisodeViewHolder(val binding: ItemEpisodePlayerBinding) : RecyclerView.ViewHolder(binding.root) { + init { + binding.imageEpisode.setOnClickListener { + onImageClick?.invoke(episodes[adapterPosition].title, adapterPosition) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml index 12f0b67..7f35e23 100644 --- a/app/src/main/res/layout/fragment_about.xml +++ b/app/src/main/res/layout/fragment_about.xml @@ -1,6 +1,5 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/player_episodes.xml b/app/src/main/res/layout/player_episodes.xml new file mode 100644 index 0000000..00f5fb9 --- /dev/null +++ b/app/src/main/res/layout/player_episodes.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + \ No newline at end of file