migrate playheads() to crunchyroll v2 api
This commit is contained in:
parent
2e7db26d1d
commit
d40ab9519c
|
@ -567,18 +567,20 @@ object Crunchyroll {
|
|||
* @param episodeIDs A **[List]** of episodes IDs as strings.
|
||||
* @return A **[Map]**<String, **[PlayheadObject]**> containing playback info.
|
||||
*/
|
||||
suspend fun playheads(episodeIDs: List<String>): PlayheadsMap {
|
||||
val playheadsEndpoint = "/content/v1/playheads/$accountID/${episodeIDs.joinToString(",")}"
|
||||
val parameters = listOf("locale" to Preferences.preferredSubtitleLocale.toLanguageTag())
|
||||
suspend fun playheads(episodeIDs: List<String>): Playheads {
|
||||
val playheadsEndpoint = "/content/v2/$accountID/playheads"
|
||||
val parameters = listOf(
|
||||
"content_ids" to episodeIDs.joinToString(","),
|
||||
"preferred_audio_language" to Preferences.preferredAudioLocale.toLanguageTag(),
|
||||
"locale" to Preferences.preferredSubtitleLocale.toLanguageTag()
|
||||
)
|
||||
|
||||
|
||||
return try {
|
||||
requestGet(playheadsEndpoint, parameters)
|
||||
} catch (ex: SerializationException) {
|
||||
Log.e(TAG, "SerializationException in playheads().", ex)
|
||||
emptyMap()
|
||||
} catch (ex: Throwable) {
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Exception in playheads().", ex.cause)
|
||||
emptyMap()
|
||||
NonePlayheads
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,9 +127,6 @@ typealias SearchResult = Collection<SearchCollection>
|
|||
typealias SearchCollection = Collection<Item>
|
||||
typealias BrowseResult = Collection<Item>
|
||||
typealias SimilarToResult = Collection<Item>
|
||||
typealias Watchlist = Collection2<WatchlistItem>
|
||||
typealias HistoryList = Collection2<UpNextAccountItem>
|
||||
typealias UpNextSeriesList = Collection2<UpNextSeriesItem>
|
||||
typealias RecommendationsList = Collection<Item>
|
||||
typealias Benefits = Collection<Benefit>
|
||||
|
||||
|
@ -159,9 +156,13 @@ data class Images(val poster_tall: List<List<Poster>>, val poster_wide: List<Lis
|
|||
data class Poster(val height: Int, val width: Int, val source: String, val type: String)
|
||||
|
||||
/**
|
||||
* continue_watching_item data classes
|
||||
* up next & watchlist data classes
|
||||
*/
|
||||
|
||||
typealias Watchlist = Collection2<WatchlistItem>
|
||||
typealias HistoryList = Collection2<UpNextAccountItem>
|
||||
typealias UpNextSeriesList = Collection2<UpNextSeriesItem>
|
||||
|
||||
@Serializable
|
||||
data class WatchlistItem(
|
||||
@SerialName("panel") val panel: EpisodePanel,
|
||||
|
@ -352,7 +353,7 @@ val NoneVersion = Version(
|
|||
variant = ""
|
||||
)
|
||||
|
||||
typealias PlayheadsMap = Map<String, PlayheadObject>
|
||||
typealias Playheads = Collection2<PlayheadObject>
|
||||
|
||||
@Serializable
|
||||
data class PlayheadObject(
|
||||
|
@ -362,6 +363,8 @@ data class PlayheadObject(
|
|||
@SerialName("last_modified") val lastModified: String,
|
||||
)
|
||||
|
||||
val NonePlayheads = Playheads(0, emptyList())
|
||||
|
||||
/**
|
||||
* Meta data for a episode intro. All time values are in seconds.
|
||||
*/
|
||||
|
|
|
@ -3,11 +3,13 @@ package org.mosad.teapod.ui.activity.main.viewmodel
|
|||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.launch
|
||||
import org.mosad.teapod.parser.crunchyroll.*
|
||||
import org.mosad.teapod.util.DataTypes.MediaType
|
||||
import org.mosad.teapod.util.tmdb.*
|
||||
import org.mosad.teapod.util.toPlayheadsMap
|
||||
|
||||
/**
|
||||
* handle media, next ep and tmdb
|
||||
|
@ -25,7 +27,8 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
|||
internal set
|
||||
val currentEpisodesCrunchy = arrayListOf<Episode>() // used for EpisodeItemAdapter (easier updates)
|
||||
|
||||
// additional media info
|
||||
// additional media info, might change during during user interaction
|
||||
// use a map to update the episode adapter values
|
||||
val currentPlayheads: MutableMap<String, PlayheadObject> = mutableMapOf()
|
||||
var isWatchlist = false
|
||||
internal set
|
||||
|
@ -80,12 +83,7 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
|||
|
||||
// load playheads and tmdb in parallel
|
||||
listOf(
|
||||
viewModelScope.launch {
|
||||
// get playheads (including fully watched state)
|
||||
val episodeIDs = episodesCrunchy.data.map { it.id }
|
||||
currentPlayheads.clear()
|
||||
currentPlayheads.putAll(Crunchyroll.playheads(episodeIDs))
|
||||
},
|
||||
updatePlayheadsAsync(),
|
||||
viewModelScope.launch { loadTmdbInfo() } // use tmdb search to get media info
|
||||
).joinAll()
|
||||
}
|
||||
|
@ -117,6 +115,16 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
|||
// } else NoneTMDBTVSeason
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current playheads for all episodes
|
||||
*/
|
||||
private fun updatePlayheadsAsync() = viewModelScope.async {
|
||||
currentPlayheads.clear()
|
||||
currentPlayheads.putAll(
|
||||
Crunchyroll.playheads(episodesCrunchy.data.map { it.id }).toPlayheadsMap()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set currentSeasonCrunchy based on the season id. Also set the new seasons episodes.
|
||||
*
|
||||
|
@ -137,9 +145,7 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
|||
currentEpisodesCrunchy.addAll(episodesCrunchy.data)
|
||||
|
||||
// update playheads playheads (including fully watched state)
|
||||
val episodeIDs = episodesCrunchy.data.map { it.id }
|
||||
currentPlayheads.clear()
|
||||
currentPlayheads.putAll(Crunchyroll.playheads(episodeIDs))
|
||||
updatePlayheadsAsync().await()
|
||||
}
|
||||
|
||||
suspend fun setWatchlist() {
|
||||
|
@ -154,11 +160,7 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic
|
|||
|
||||
suspend fun updateOnResume() {
|
||||
joinAll(
|
||||
viewModelScope.launch {
|
||||
val episodeIDs = episodesCrunchy.data.map { it.id }
|
||||
currentPlayheads.clear()
|
||||
currentPlayheads.putAll(Crunchyroll.playheads(episodeIDs))
|
||||
},
|
||||
updatePlayheadsAsync(),
|
||||
viewModelScope.launch { upNextSeries = Crunchyroll.upNextSeries(seriesCrunchy.id) }
|
||||
)
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.mosad.teapod.util.metadb.EpisodeMeta
|
|||
import org.mosad.teapod.util.metadb.Meta
|
||||
import org.mosad.teapod.util.metadb.MetaDBController
|
||||
import org.mosad.teapod.util.metadb.TVShowMeta
|
||||
import org.mosad.teapod.util.toPlayheadsMap
|
||||
import java.util.*
|
||||
import kotlin.concurrent.scheduleAtFixedRate
|
||||
|
||||
|
@ -63,7 +64,7 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
|||
internal set
|
||||
var currentEpisodeMeta: EpisodeMeta? = null
|
||||
internal set
|
||||
var currentPlayheads: PlayheadsMap = mutableMapOf()
|
||||
var currentPlayheads = mapOf<String, PlayheadObject>()
|
||||
internal set
|
||||
var currentIntroMetadata: DatalabIntro = NoneDatalabIntro
|
||||
internal set
|
||||
|
@ -142,7 +143,7 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
|||
viewModelScope.launch { mediaMeta = loadMediaMeta(episodes.data.first().seriesId) },
|
||||
viewModelScope.launch {
|
||||
val episodeIDs = episodes.data.map { it.id }
|
||||
currentPlayheads = Crunchyroll.playheads(episodeIDs)
|
||||
currentPlayheads = Crunchyroll.playheads(episodeIDs).toPlayheadsMap()
|
||||
}
|
||||
).joinAll()
|
||||
Log.d(classTag, "meta: $mediaMeta")
|
||||
|
@ -233,7 +234,9 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
|||
Log.d(classTag, currentVersion.toString())
|
||||
},
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
Crunchyroll.playheads(listOf(currentEpisode.id))[currentEpisode.id]?.let {
|
||||
Crunchyroll.playheads(listOf(currentEpisode.id)).data.firstOrNull {
|
||||
it.contentId == currentEpisode.id
|
||||
}?.let {
|
||||
// if the episode was fully watched, start at the beginning
|
||||
currentPlayhead = if (it.fullyWatched) {
|
||||
0
|
||||
|
@ -330,7 +333,7 @@ class PlayerViewModel(application: Application) : AndroidViewModel(application)
|
|||
|
||||
viewModelScope.launch {
|
||||
val episodeIDs = episodes.data.map { it.id }
|
||||
currentPlayheads = Crunchyroll.playheads(episodeIDs)
|
||||
currentPlayheads = Crunchyroll.playheads(episodeIDs).toPlayheadsMap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ class EpisodeListDialogFragment : DialogFragment() {
|
|||
val adapterRecEpisodes = EpisodeItemAdapter(
|
||||
model.episodes.data,
|
||||
null,
|
||||
model.currentPlayheads.toMap(),
|
||||
model.currentPlayheads,
|
||||
EpisodeItemAdapter.OnClickListener { episode ->
|
||||
dismiss()
|
||||
// TODO make this none blocking, if necessary?
|
||||
|
|
|
@ -10,7 +10,9 @@ import androidx.core.view.WindowInsetsControllerCompat
|
|||
import androidx.fragment.app.Fragment
|
||||
import org.mosad.teapod.R
|
||||
import org.mosad.teapod.parser.crunchyroll.Collection
|
||||
import org.mosad.teapod.parser.crunchyroll.Collection2
|
||||
import org.mosad.teapod.parser.crunchyroll.Item
|
||||
import org.mosad.teapod.parser.crunchyroll.PlayheadObject
|
||||
import org.mosad.teapod.ui.activity.player.PlayerActivity
|
||||
import java.util.*
|
||||
|
||||
|
@ -57,6 +59,10 @@ fun Locale.toDisplayString(fallback: String): String {
|
|||
}
|
||||
}
|
||||
|
||||
fun Collection2<PlayheadObject>.toPlayheadsMap(): Map<String, PlayheadObject> {
|
||||
return this.data.associateBy { it.contentId }
|
||||
}
|
||||
|
||||
fun hideBars(window: Window?, root: View) {
|
||||
if (window != null) {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
|
|
@ -16,13 +16,12 @@ 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
|
||||
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 playheads: Map<String, PlayheadObject>,
|
||||
private val onClickListener: OnClickListener,
|
||||
private val viewType: ViewType
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
|
Loading…
Reference in New Issue