From 95c8a72c9451ac60bfb46b774291f3cb09876d07 Mon Sep 17 00:00:00 2001 From: Jannik Date: Fri, 15 Apr 2022 17:47:17 +0200 Subject: [PATCH] add playhead progress indicator to player episodes list --- .../ui/activity/player/PlayerActivity.kt | 2 ++ .../ui/activity/player/PlayerViewModel.kt | 22 ++++++++++++++----- .../fragment/EpisodeListDialogFragment.kt | 2 +- .../teapod/util/adapter/EpisodeItemAdapter.kt | 12 ++++++++-- .../main/res/layout/item_episode_player.xml | 11 +++++++++- app/src/main/res/values/styles.xml | 5 +++-- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerActivity.kt b/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerActivity.kt index d539b2e..34bbd85 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerActivity.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerActivity.kt @@ -200,6 +200,8 @@ class PlayerActivity : AppCompatActivity() { // Hide the full-screen UI (controls, etc.) while in picture-in-picture mode. playerBinding.videoView.useController = !isInPictureInPictureMode + + // TODO also hide language settings/episodes list } private fun initPlayer() { diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt b/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt index cde7d97..bf85840 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt @@ -37,10 +37,7 @@ import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.mosad.teapod.R -import org.mosad.teapod.parser.crunchyroll.Crunchyroll -import org.mosad.teapod.parser.crunchyroll.NoneEpisode -import org.mosad.teapod.parser.crunchyroll.NoneEpisodes -import org.mosad.teapod.parser.crunchyroll.NonePlayback +import org.mosad.teapod.parser.crunchyroll.* import org.mosad.teapod.preferences.Preferences import org.mosad.teapod.util.metadb.EpisodeMeta import org.mosad.teapod.util.metadb.Meta @@ -67,6 +64,8 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) internal set var currentEpisodeMeta: EpisodeMeta? = null internal set + var currentPlayheads: PlayheadsMap = mutableMapOf() + internal set // var tmdbTVSeason: TMDBTVSeason? =null // internal set @@ -121,7 +120,15 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) fun loadMediaAsync(seasonId: String, episodeId: String) = viewModelScope.launch { episodes = Crunchyroll.episodes(seasonId) - mediaMeta = loadMediaMeta(episodes.items.first().seriesId) + + listOf( + viewModelScope.launch { mediaMeta = loadMediaMeta(episodes.items.first().seriesId) }, + viewModelScope.launch { + val episodeIDs = episodes.items.map { it.id } + currentPlayheads = Crunchyroll.playheads(episodeIDs) + } + ).joinAll() + Log.d(classTag, "meta: $mediaMeta") @@ -271,6 +278,11 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application) viewModelScope.launch { Crunchyroll.postPlayheads(currentEpisode.id, playhead.toInt()) } Log.i(javaClass.name, "Set playhead for episode ${currentEpisode.id} to $playhead sec.") } + + viewModelScope.launch { + val episodeIDs = episodes.items.map { it.id } + currentPlayheads = Crunchyroll.playheads(episodeIDs) + } } } diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/player/fragment/EpisodeListDialogFragment.kt b/app/src/main/java/org/mosad/teapod/ui/activity/player/fragment/EpisodeListDialogFragment.kt index b80d404..b0ca37d 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/player/fragment/EpisodeListDialogFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/player/fragment/EpisodeListDialogFragment.kt @@ -43,7 +43,7 @@ class EpisodeListDialogFragment : DialogFragment() { val adapterRecEpisodes = EpisodeItemAdapter( model.episodes.items, null, - mapOf(), + model.currentPlayheads.toMap(), EpisodeItemAdapter.OnClickListener { episode -> dismiss() model.setCurrentEpisode(episode.id, startPlayback = true) diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt index 5eba924..3cdbf30 100644 --- a/app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt @@ -51,7 +51,7 @@ class EpisodeItemAdapter( (holder as EpisodeViewHolder).bind(episode, playhead, tmdbEpisode) } ViewType.PLAYER.ordinal -> { - (holder as PlayerEpisodeViewHolder).bind(episode, currentSelected) + (holder as PlayerEpisodeViewHolder).bind(episode, playhead, currentSelected) } } } @@ -122,7 +122,7 @@ class EpisodeItemAdapter( RecyclerView.ViewHolder(binding.root) { // -1, since position should never be < 0 - fun bind(episode: Episode, currentSelected: Int) { + fun bind(episode: Episode, playhead: PlayheadObject?, currentSelected: Int) { val context = binding.root.context val titleText = if (episode.episodeNumber != null) { @@ -145,6 +145,14 @@ class EpisodeItemAdapter( .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 diff --git a/app/src/main/res/layout/item_episode_player.xml b/app/src/main/res/layout/item_episode_player.xml index 6cf0ad9..9f18325 100644 --- a/app/src/main/res/layout/item_episode_player.xml +++ b/app/src/main/res/layout/item_episode_player.xml @@ -26,7 +26,16 @@ android:background="@drawable/bg_circle__black_transparent_24dp" android:contentDescription="@string/button_play" app:srcCompat="@drawable/ic_baseline_play_arrow_24" - app:tint="#FFFFFF" /> + app:tint="@color/player_white" /> + + - -