Browse Source

add playhead progress indicator to player episodes list

develop
Jannik 3 months ago
parent
commit
95c8a72c94
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
  1. 2
      app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerActivity.kt
  2. 22
      app/src/main/java/org/mosad/teapod/ui/activity/player/PlayerViewModel.kt
  3. 2
      app/src/main/java/org/mosad/teapod/ui/activity/player/fragment/EpisodeListDialogFragment.kt
  4. 12
      app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt
  5. 11
      app/src/main/res/layout/item_episode_player.xml
  6. 5
      app/src/main/res/values/styles.xml

2
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() {

22
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)
}
}
}

2
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)

12
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

11
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" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_playhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:max="100"
app:trackColor="#00FFFFFF"
app:trackThickness="2dp" />
</FrameLayout>
<TextView

5
app/src/main/res/values/styles.xml

@ -51,7 +51,7 @@
</style>
<!-- player theme -->
<style name="PlayerTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<style name="PlayerTheme" parent="AppTheme">
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
@ -86,7 +86,8 @@
<item name="android:popupBackground">?themeSecondary</item>
</style>
<style name="FullScreenDialogStyle" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- fullscreen dialog fragments -->
<style name="FullScreenDialogStyle" parent="AppTheme">
<item name="android:windowFullscreen">true</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowBackground">@android:color/transparent</item>

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close