implement preferred season/languag choosing in MediaFragment
This commit is contained in:
parent
4fd6f9ca7e
commit
ecbbc5db7b
@ -8,9 +8,9 @@ import com.github.kittinunf.fuel.json.FuelJson
|
||||
import com.github.kittinunf.fuel.json.responseJson
|
||||
import com.github.kittinunf.result.Result
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.mosad.teapod.preferences.Preferences
|
||||
import java.util.*
|
||||
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
@ -27,10 +27,10 @@ object Crunchyroll {
|
||||
private var keyPairID = ""
|
||||
|
||||
// TODO temp helper vary
|
||||
var locale = "${Locale.GERMANY.language}-${Locale.GERMANY.country}"
|
||||
var country = Locale.GERMANY.country
|
||||
private var locale: String = Preferences.preferredLocal.toLanguageTag()
|
||||
private var country: String = Preferences.preferredLocal.country
|
||||
|
||||
val browsingCache = arrayListOf<Item>()
|
||||
private val browsingCache = arrayListOf<Item>()
|
||||
|
||||
fun login(username: String, password: String): Boolean = runBlocking {
|
||||
val tokenEndpoint = "/auth/v1/token"
|
||||
|
@ -2,6 +2,7 @@ package org.mosad.teapod.parser.crunchyroll
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* data classes for browse
|
||||
@ -36,6 +37,7 @@ val NoneSearchResult = SearchResult(0, emptyList())
|
||||
data class BrowseResult(val total: Int, val items: List<Item>)
|
||||
|
||||
// the data class Item is used in browse and search
|
||||
// TODO rename to MediaPanel
|
||||
@Serializable
|
||||
data class Item(
|
||||
val id: String,
|
||||
@ -74,14 +76,38 @@ val NoneSeries = Series("", "", "", Images(listOf(), listOf()))
|
||||
* Seasons data type
|
||||
*/
|
||||
@Serializable
|
||||
data class Seasons(val total: Int, val items: List<Season>)
|
||||
data class Seasons(
|
||||
val total: Int,
|
||||
val items: List<Season>
|
||||
) {
|
||||
fun getPreferredSeasonId(local: Locale): String {
|
||||
// try to get the the first seasons which matches the preferred local
|
||||
items.forEach { season ->
|
||||
if (season.title.startsWith("(${local.language})", true)) {
|
||||
return season.id
|
||||
}
|
||||
}
|
||||
|
||||
// if there is no season with the preferred local, try to find a subbed season
|
||||
items.forEach { season ->
|
||||
if (season.isSubbed) {
|
||||
return season.id
|
||||
}
|
||||
}
|
||||
|
||||
// if there is no preferred language season and no sub, use the first season
|
||||
return items.first().id
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Season(
|
||||
val id: String,
|
||||
val title: String,
|
||||
val series_id: String,
|
||||
val season_number: Int
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("title") val title: String,
|
||||
@SerialName("series_id") val seriesId: String,
|
||||
@SerialName("season_number") val seasonNumber: Int,
|
||||
@SerialName("is_subbed") val isSubbed: Boolean,
|
||||
@SerialName("is_dubbed") val isDubbed: Boolean,
|
||||
)
|
||||
|
||||
val NoneSeasons = Seasons(0, listOf())
|
||||
@ -101,7 +127,7 @@ data class Episode(
|
||||
@SerialName("season_id") val seasonId: String,
|
||||
@SerialName("season_number") val seasonNumber: Int,
|
||||
@SerialName("episode") val episode: String,
|
||||
@SerialName("episode_number") val episodeNumber: Int,
|
||||
@SerialName("episode_number") val episodeNumber: Int? = null,
|
||||
@SerialName("description") val description: String,
|
||||
@SerialName("next_episode_id") val nextEpisodeId: String? = null, // default/nullable value since optional
|
||||
@SerialName("next_episode_title") val nextEpisodeTitle: String? = null, // default/nullable value since optional
|
||||
|
@ -4,11 +4,14 @@ import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import org.mosad.teapod.R
|
||||
import org.mosad.teapod.util.DataTypes
|
||||
import java.util.*
|
||||
|
||||
object Preferences {
|
||||
|
||||
var preferSecondary = false
|
||||
internal set
|
||||
var preferredLocal = Locale.GERMANY
|
||||
internal set
|
||||
var autoplay = true
|
||||
internal set
|
||||
var devSettings = false
|
||||
|
@ -15,6 +15,7 @@ import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import jp.wasabeef.glide.transformations.BlurTransformation
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mosad.teapod.R
|
||||
@ -56,14 +57,14 @@ class MediaFragment(private val mediaIdStr: String, mediaCr: Item = NoneItem) :
|
||||
// fix material components issue #1878, if more tabs are added increase
|
||||
binding.pagerEpisodesSimilar.offscreenPageLimit = 2
|
||||
binding.pagerEpisodesSimilar.adapter = pagerAdapter
|
||||
// TODO implement for cr media items
|
||||
// TabLayoutMediator(binding.tabEpisodesSimilar, binding.pagerEpisodesSimilar) { tab, position ->
|
||||
// tab.text = if (model.media.type == MediaType.TVSHOW && position == 0) {
|
||||
// getString(R.string.episodes)
|
||||
// } else {
|
||||
// getString(R.string.similar_titles)
|
||||
// }
|
||||
// }.attach()
|
||||
// TODO is position 0 always episodes? (and 1 always similar titles)
|
||||
TabLayoutMediator(binding.tabEpisodesSimilar, binding.pagerEpisodesSimilar) { tab, position ->
|
||||
tab.text = when(position) {
|
||||
0 -> getString(R.string.episodes)
|
||||
1 -> getString(R.string.similar_titles)
|
||||
else -> ""
|
||||
}
|
||||
}.attach()
|
||||
|
||||
lifecycleScope.launch {
|
||||
model.loadCrunchy(mediaIdStr)
|
||||
@ -77,9 +78,10 @@ class MediaFragment(private val mediaIdStr: String, mediaCr: Item = NoneItem) :
|
||||
super.onResume()
|
||||
|
||||
// update the next ep text if there is one, since it may have changed
|
||||
if (model.media.getEpisodeById(model.nextEpisodeId).title.isNotEmpty()) {
|
||||
binding.textTitle.text = model.media.getEpisodeById(model.nextEpisodeId).title
|
||||
}
|
||||
// TODO reimplement
|
||||
// if (model.media.getEpisodeById(model.nextEpisodeId).title.isNotEmpty()) {
|
||||
// binding.textTitle.text = model.media.getEpisodeById(model.nextEpisodeId).title
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,9 +90,9 @@ class MediaFragment(private val mediaIdStr: String, mediaCr: Item = NoneItem) :
|
||||
private fun updateGUI() = with(model) {
|
||||
// generic gui
|
||||
val backdropUrl = tmdbResult?.backdropPath?.let { TMDBApiController.imageUrl + it }
|
||||
?: mediaCrunchy.images.poster_wide[0][2].source
|
||||
?: seriesCrunchy.images.poster_wide[0][2].source
|
||||
val posterUrl = tmdbResult?.posterPath?.let { TMDBApiController.imageUrl + it }
|
||||
?: mediaCrunchy.images.poster_tall[0][2].source
|
||||
?: seriesCrunchy.images.poster_tall[0][2].source
|
||||
|
||||
// load poster and backdrop
|
||||
Glide.with(requireContext()).load(posterUrl)
|
||||
@ -100,65 +102,74 @@ class MediaFragment(private val mediaIdStr: String, mediaCr: Item = NoneItem) :
|
||||
.apply(RequestOptions.bitmapTransform(BlurTransformation(20, 3)))
|
||||
.into(binding.imageBackdrop)
|
||||
|
||||
binding.textTitle.text = mediaCrunchy.title
|
||||
//binding.textYear.text = media.year.toString() // TODO
|
||||
//binding.textAge.text = media.age.toString() // TODO
|
||||
binding.textOverview.text = mediaCrunchy.description
|
||||
binding.textTitle.text = seriesCrunchy.title
|
||||
//binding.textYear.text = media.year.toString() // TODO get from tmdb
|
||||
//binding.textAge.text = media.age.toString() // TODO get from tmdb
|
||||
binding.textOverview.text = seriesCrunchy.description
|
||||
|
||||
// TODO set "my list" indicator
|
||||
if (StorageController.myList.contains(media.aodId)) {
|
||||
Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(binding.imageMyListAction)
|
||||
} else {
|
||||
Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(binding.imageMyListAction)
|
||||
}
|
||||
// if (StorageController.myList.contains(media.aodId)) {
|
||||
// Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(binding.imageMyListAction)
|
||||
// } else {
|
||||
// Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(binding.imageMyListAction)
|
||||
// }
|
||||
|
||||
// clear fragments, since it lives in onCreate scope (don't do this in onPause/onStop -> FragmentManager transaction)
|
||||
val fragmentsSize = if (fragments.lastIndex < 0) 0 else fragments.lastIndex
|
||||
fragments.clear()
|
||||
pagerAdapter.notifyItemRangeRemoved(0, fragmentsSize)
|
||||
|
||||
// specific gui
|
||||
if (mediaCrunchy.type == MediaType.TVSHOW.str) {
|
||||
// TODO get next episode
|
||||
// nextEpisodeId = media.playlist.firstOrNull{ !it.watched }?.mediaId
|
||||
// ?: media.playlist.first().mediaId
|
||||
|
||||
// TODO title is the next episodes title
|
||||
// binding.textTitle.text = media.getEpisodeById(nextEpisodeId).title
|
||||
|
||||
// episodes count
|
||||
binding.textEpisodesOrRuntime.text = resources.getQuantityString(
|
||||
R.plurals.text_episodes_count,
|
||||
episodesCrunchy.total,
|
||||
episodesCrunchy.total
|
||||
)
|
||||
|
||||
// episodes
|
||||
MediaFragmentEpisodes().also {
|
||||
fragments.add(it)
|
||||
pagerAdapter.notifyItemInserted(fragments.indexOf(it))
|
||||
}
|
||||
} else if (media.type == MediaType.MOVIE) {
|
||||
val tmdbMovie = (tmdbResult as TMDBMovie?)
|
||||
|
||||
if (tmdbMovie?.runtime != null) {
|
||||
binding.textEpisodesOrRuntime.text = resources.getQuantityString(
|
||||
R.plurals.text_runtime,
|
||||
tmdbMovie.runtime,
|
||||
tmdbMovie.runtime
|
||||
)
|
||||
} else {
|
||||
binding.textEpisodesOrRuntime.visibility = View.GONE
|
||||
}
|
||||
// add the episodes fragment (as tab)
|
||||
MediaFragmentEpisodes().also {
|
||||
fragments.add(it)
|
||||
pagerAdapter.notifyItemInserted(fragments.indexOf(it))
|
||||
}
|
||||
|
||||
// TODO reimplement via tmdb/metaDB
|
||||
// specific gui
|
||||
// if (mediaCrunchy.type == MediaType.TVSHOW.str) {
|
||||
// // TODO get next episode
|
||||
//// nextEpisodeId = media.playlist.firstOrNull{ !it.watched }?.mediaId
|
||||
//// ?: media.playlist.first().mediaId
|
||||
//
|
||||
// // TODO title is the next episodes title
|
||||
//// binding.textTitle.text = media.getEpisodeById(nextEpisodeId).title
|
||||
//
|
||||
// // episodes count
|
||||
// binding.textEpisodesOrRuntime.text = resources.getQuantityString(
|
||||
// R.plurals.text_episodes_count,
|
||||
// episodesCrunchy.total,
|
||||
// episodesCrunchy.total
|
||||
// )
|
||||
//
|
||||
// // episodes
|
||||
// MediaFragmentEpisodes().also {
|
||||
// fragments.add(it)
|
||||
// pagerAdapter.notifyItemInserted(fragments.indexOf(it))
|
||||
// }
|
||||
// } else if (media.type == MediaType.MOVIE) {
|
||||
// val tmdbMovie = (tmdbResult as TMDBMovie?)
|
||||
//
|
||||
// if (tmdbMovie?.runtime != null) {
|
||||
// binding.textEpisodesOrRuntime.text = resources.getQuantityString(
|
||||
// R.plurals.text_runtime,
|
||||
// tmdbMovie.runtime,
|
||||
// tmdbMovie.runtime
|
||||
// )
|
||||
// } else {
|
||||
// binding.textEpisodesOrRuntime.visibility = View.GONE
|
||||
// }
|
||||
// }
|
||||
|
||||
// if has similar titles
|
||||
if (media.similar.isNotEmpty()) {
|
||||
MediaFragmentSimilar().also {
|
||||
fragments.add(it)
|
||||
pagerAdapter.notifyItemInserted(fragments.indexOf(it))
|
||||
}
|
||||
}
|
||||
// TODO reimplement
|
||||
// if (media.similar.isNotEmpty()) {
|
||||
// MediaFragmentSimilar().also {
|
||||
// fragments.add(it)
|
||||
// pagerAdapter.notifyItemInserted(fragments.indexOf(it))
|
||||
// }
|
||||
// }
|
||||
|
||||
// disable scrolling on appbar, if no tabs where added
|
||||
if(fragments.isEmpty()) {
|
||||
@ -171,28 +182,30 @@ class MediaFragment(private val mediaIdStr: String, mediaCr: Item = NoneItem) :
|
||||
|
||||
private fun initActions() = with(model) {
|
||||
binding.buttonPlay.setOnClickListener {
|
||||
when (media.type) {
|
||||
//MediaType.MOVIE -> playEpisode(media.playlist.first().mediaId) // TODO
|
||||
//MediaType.TVSHOW -> playEpisode(nextEpisodeId) // TODO
|
||||
else -> Log.e(javaClass.name, "Wrong Type: ${media.type}")
|
||||
}
|
||||
// TODO reimplement
|
||||
// when (media.type) {
|
||||
// MediaType.MOVIE -> playEpisode(media.playlist.first().mediaId)
|
||||
// MediaType.TVSHOW -> playEpisode(nextEpisodeId)
|
||||
// else -> Log.e(javaClass.name, "Wrong Type: ${media.type}")
|
||||
// }
|
||||
}
|
||||
|
||||
// add or remove media from myList
|
||||
binding.linearMyListAction.setOnClickListener {
|
||||
if (StorageController.myList.contains(media.aodId)) {
|
||||
StorageController.myList.remove(media.aodId)
|
||||
Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(binding.imageMyListAction)
|
||||
} else {
|
||||
StorageController.myList.add(media.aodId)
|
||||
Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(binding.imageMyListAction)
|
||||
}
|
||||
StorageController.saveMyList(requireContext())
|
||||
|
||||
// notify home fragment on change
|
||||
parentFragmentManager.findFragmentByTag("HomeFragment")?.let {
|
||||
(it as HomeFragment).updateMyListMedia()
|
||||
}
|
||||
// TODO reimplement
|
||||
// if (StorageController.myList.contains(media.aodId)) {
|
||||
// StorageController.myList.remove(media.aodId)
|
||||
// Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(binding.imageMyListAction)
|
||||
// } else {
|
||||
// StorageController.myList.add(media.aodId)
|
||||
// Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(binding.imageMyListAction)
|
||||
// }
|
||||
// StorageController.saveMyList(requireContext())
|
||||
//
|
||||
// // notify home fragment on change
|
||||
// parentFragmentManager.findFragmentByTag("HomeFragment")?.let {
|
||||
// (it as HomeFragment).updateMyListMedia()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,10 +44,11 @@ class MediaFragmentEpisodes : Fragment() {
|
||||
|
||||
// if adapterRecEpisodes is initialized, update the watched state for the episodes
|
||||
if (this::adapterRecEpisodes.isInitialized) {
|
||||
model.media.playlist.forEachIndexed { index, episodeInfo ->
|
||||
adapterRecEpisodes.updateWatchedState(episodeInfo.watched, index)
|
||||
}
|
||||
adapterRecEpisodes.notifyDataSetChanged()
|
||||
// TODO reimplement, if needed
|
||||
// model.media.playlist.forEachIndexed { index, episodeInfo ->
|
||||
// adapterRecEpisodes.updateWatchedState(episodeInfo.watched, index)
|
||||
// }
|
||||
// adapterRecEpisodes.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ class MediaFragmentSimilar : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
adapterSimilar = MediaItemAdapter(model.media.similar)
|
||||
adapterSimilar = MediaItemAdapter(emptyList()) //(model.media.similar)
|
||||
binding.recyclerMediaSimilar.adapter = adapterSimilar
|
||||
binding.recyclerMediaSimilar.addItemDecoration(MediaItemDecoration(9))
|
||||
|
||||
|
@ -3,9 +3,16 @@ package org.mosad.teapod.ui.activity.main.viewmodel
|
||||
import android.app.Application
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import org.mosad.teapod.parser.crunchyroll.*
|
||||
import org.mosad.teapod.util.*
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mosad.teapod.parser.crunchyroll.Crunchyroll
|
||||
import org.mosad.teapod.parser.crunchyroll.NoneEpisodes
|
||||
import org.mosad.teapod.parser.crunchyroll.NoneSeasons
|
||||
import org.mosad.teapod.parser.crunchyroll.NoneSeries
|
||||
import org.mosad.teapod.preferences.Preferences
|
||||
import org.mosad.teapod.util.DataTypes.MediaType
|
||||
import org.mosad.teapod.util.Meta
|
||||
import org.mosad.teapod.util.tmdb.TMDBApiController
|
||||
import org.mosad.teapod.util.tmdb.TMDBResult
|
||||
import org.mosad.teapod.util.tmdb.TMDBTVSeason
|
||||
@ -16,12 +23,9 @@ import org.mosad.teapod.util.tmdb.TMDBTVSeason
|
||||
*/
|
||||
class MediaFragmentViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
var media = AoDMediaNone
|
||||
internal set
|
||||
var nextEpisodeId = -1
|
||||
internal set
|
||||
|
||||
var mediaCrunchy = NoneItem
|
||||
// var mediaCrunchy = NoneItem
|
||||
// internal set
|
||||
var seriesCrunchy = NoneSeries // TODO it seems movies also series?
|
||||
internal set
|
||||
var seasonsCrunchy = NoneSeasons
|
||||
internal set
|
||||
@ -35,34 +39,31 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
||||
var mediaMeta: Meta? = null
|
||||
internal set
|
||||
|
||||
/**
|
||||
* @param crunchyId the crunchyroll series id
|
||||
*/
|
||||
suspend fun loadCrunchy(crunchyId: String) {
|
||||
val tmdbApiController = TMDBApiController()
|
||||
|
||||
println("loading crunchyroll media $crunchyId")
|
||||
// load series and seasons info in parallel
|
||||
listOf(
|
||||
viewModelScope.launch { seriesCrunchy = Crunchyroll.series(crunchyId) },
|
||||
viewModelScope.launch { seasonsCrunchy = Crunchyroll.seasons(crunchyId) }
|
||||
).joinAll()
|
||||
|
||||
// TODO info also in browse result item
|
||||
// TODO doesn't support search
|
||||
mediaCrunchy = Crunchyroll.browsingCache.find { it ->
|
||||
it.id == crunchyId
|
||||
} ?: NoneItem
|
||||
println("media: $mediaCrunchy")
|
||||
|
||||
// load seasons
|
||||
seasonsCrunchy = Crunchyroll.seasons(crunchyId)
|
||||
println("series: $seriesCrunchy")
|
||||
println("seasons: $seasonsCrunchy")
|
||||
|
||||
// load first season
|
||||
// TODO make sure to load the preferred season (language), language is set per season, not per stream
|
||||
episodesCrunchy = Crunchyroll.episodes(seasonsCrunchy.items.first().id)
|
||||
// load the preferred season (preferred language, language per season, not per stream)
|
||||
val preferredSeasonId = seasonsCrunchy.getPreferredSeasonId(Preferences.preferredLocal)
|
||||
episodesCrunchy = Crunchyroll.episodes(preferredSeasonId)
|
||||
println("episodes: $episodesCrunchy")
|
||||
|
||||
|
||||
|
||||
// TODO check if metaDB knows the title
|
||||
|
||||
// use tmdb search to get media info TODO media type is hardcoded, use type info from browse result once implemented
|
||||
// use tmdb search to get media info TODO media type is hardcoded, use episodeNumber? (if null it should be a movie)
|
||||
mediaMeta = null // set mediaMeta to null, if metaDB doesn't know the media
|
||||
val tmdbId = tmdbApiController.search(mediaCrunchy.title, MediaType.TVSHOW)
|
||||
val tmdbId = tmdbApiController.search(seriesCrunchy.title, MediaType.TVSHOW)
|
||||
|
||||
tmdbResult = when (MediaType.TVSHOW) {
|
||||
MediaType.MOVIE -> tmdbApiController.getMovieDetails(tmdbId)
|
||||
@ -122,10 +123,11 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
||||
* if no matching is found, use first episode
|
||||
*/
|
||||
fun updateNextEpisode(episodeId: Int) {
|
||||
if (media.type == MediaType.MOVIE) return // return if movie
|
||||
|
||||
nextEpisodeId = media.playlist.firstOrNull { it.index > media.getEpisodeById(episodeId).index }?.mediaId
|
||||
?: media.playlist.first().mediaId
|
||||
// TODO reimplement if needed
|
||||
// if (media.type == MediaType.MOVIE) return // return if movie
|
||||
//
|
||||
// nextEpisodeId = media.playlist.firstOrNull { it.index > media.getEpisodeById(episodeId).index }?.mediaId
|
||||
// ?: media.playlist.first().mediaId
|
||||
}
|
||||
|
||||
// remove unneeded info from the media title before searching
|
||||
|
@ -168,7 +168,9 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
||||
currentEpisodeChangedListener.forEach { it() }
|
||||
|
||||
// get preferred stream url TODO implement
|
||||
val url = currentPlayback.streams.adaptive_hls["en-US"]?.url ?: ""
|
||||
val localeKey = Preferences.preferredLocal.toLanguageTag()
|
||||
val url = currentPlayback.streams.adaptive_hls[localeKey]?.url
|
||||
?: currentPlayback.streams.adaptive_hls[""]?.url ?: ""
|
||||
println("stream url: $url")
|
||||
|
||||
// create the media source object
|
||||
|
@ -34,7 +34,7 @@ class EpisodesListPlayer @JvmOverloads constructor(
|
||||
model.setCurrentEpisode(episodeId, startPlayback = true)
|
||||
}
|
||||
// episodeNumber starts at 1, we need the episode index -> - 1
|
||||
adapterRecEpisodes.currentSelected = (model.currentEpisode.episodeNumber - 1)
|
||||
adapterRecEpisodes.currentSelected = model.currentEpisode.episodeNumber?.minus(1) ?: 0
|
||||
|
||||
binding.recyclerEpisodesPlayer.adapter = adapterRecEpisodes
|
||||
binding.recyclerEpisodesPlayer.scrollToPosition(adapterRecEpisodes.currentSelected)
|
||||
|
Loading…
Reference in New Issue
Block a user