diff --git a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt index ffffacf..b3fa4ee 100644 --- a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt +++ b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/Crunchyroll.kt @@ -458,7 +458,7 @@ object Crunchyroll { } /** - * Additional media functions: watchlist (series), playhead + * Additional media functions: watchlist (series), playhead, similar to */ /** @@ -546,6 +546,22 @@ object Crunchyroll { requestPost(playheadsEndpoint, parameters, json) } + suspend fun similarTo(seriesId: String, n: Int = 10): SimilarToResult { + val similarToEndpoint = "/content/v1/$accountID/similar_to" + val parameters = listOf( + "guid" to seriesId, + "locale" to Preferences.preferredLocale.toLanguageTag(), + "n" to n + ) + + return try { + requestGet(similarToEndpoint, parameters) + }catch (ex: SerializationException) { + Log.e(TAG, "SerializationException in similarTo().", ex) + NoneSimilarToResult + } + } + /** * Listing functions: watchlist (list), up_next_account */ diff --git a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt index 73481aa..b1d39b8 100644 --- a/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt +++ b/app/src/main/java/org/mosad/teapod/parser/crunchyroll/DataTypes.kt @@ -101,6 +101,7 @@ data class Collection( typealias SearchResult = Collection typealias SearchCollection = Collection typealias BrowseResult = Collection +typealias SimilarToResult = Collection typealias DiscSeasonList = Collection typealias Watchlist = Collection typealias ContinueWatchingList = Collection @@ -117,7 +118,7 @@ data class UpNextSeriesItem( * panel data classes */ -// the data class Item is used in browse and search +// the data class Item is used in browse, search, watchlist and similar to // TODO rename to MediaPanel @Serializable data class Item( @@ -128,6 +129,7 @@ data class Item( val description: String, val images: Images // TODO series_metadata etc. + // TODO add slug_title if present in search, browse, similar to ) @Serializable @@ -197,13 +199,14 @@ val NoneEpisodePanel = EpisodePanel("", "", "", "", "", NoneEpisodeMetadata, Thu val NoneCollection = Collection(0, emptyList()) val NoneSearchResult = SearchResult(0, emptyList()) val NoneBrowseResult = BrowseResult(0, emptyList()) +val NoneSimilarToResult = SimilarToResult(0, emptyList()) val NoneDiscSeasonList = DiscSeasonList(0, emptyList()) val NoneContinueWatchingList = ContinueWatchingList(0, emptyList()) val NoneUpNextSeriesItem = UpNextSeriesItem(0, false, false, NoneEpisodePanel) /** - * Series data type + * series data class */ @Serializable data class Series( @@ -216,7 +219,7 @@ data class Series( val NoneSeries = Series("", "", "", Images(emptyList(), emptyList()), emptyList()) /** - * Seasons data type + * Seasons data classes */ @Serializable data class Seasons( @@ -250,7 +253,7 @@ val NoneSeason = Season("", "", "", "", 0, isSubbed = false, isDubbed = false) /** - * Episodes data type + * Episodes data classes */ @Serializable data class Episodes( @@ -314,7 +317,7 @@ data class PlayheadObject( ) /** - * Playback/stream data type + * playback/stream data classes */ @Serializable data class Playback( @@ -362,6 +365,9 @@ val NonePlayback = Playback( ) ) +/** + * profile data class + */ @Serializable data class Profile( @SerialName("avatar") val avatar: String, diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/MediaFragment.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/MediaFragment.kt index d9f9677..c65fd6f 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/MediaFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/MediaFragment.kt @@ -170,8 +170,7 @@ class MediaFragment(private val mediaIdStr: String) : Fragment() { } // if has similar titles - // TODO reimplement -// if (media.similar.isNotEmpty()) { +// if (model.similarTo.total > 0) { // MediaFragmentSimilar().also { // fragments.add(it) // pagerAdapter.notifyItemInserted(fragments.indexOf(it)) diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/MediaFragmentSimilar.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/MediaFragmentSimilar.kt index 052ec89..b39d602 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/MediaFragmentSimilar.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/MediaFragmentSimilar.kt @@ -11,6 +11,7 @@ import org.mosad.teapod.ui.activity.main.viewmodel.MediaFragmentViewModel import org.mosad.teapod.util.adapter.MediaItemAdapter import org.mosad.teapod.util.decoration.MediaItemDecoration import org.mosad.teapod.util.showFragment +import org.mosad.teapod.util.toItemMediaList class MediaFragmentSimilar : Fragment() { @@ -27,14 +28,14 @@ class MediaFragmentSimilar : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - adapterSimilar = MediaItemAdapter(emptyList()) //(model.media.similar) + adapterSimilar = MediaItemAdapter(model.similarTo.toItemMediaList()) binding.recyclerMediaSimilar.adapter = adapterSimilar binding.recyclerMediaSimilar.addItemDecoration(MediaItemDecoration(9)) // set onItemClick only in adapter is initialized if (this::adapterSimilar.isInitialized) { adapterSimilar.onItemClick = { mediaId, _ -> - activity?.showFragment(MediaFragment("")) //(mediaId)) + activity?.showFragment(MediaFragment(mediaId)) } } } diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/viewmodel/MediaFragmentViewModel.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/viewmodel/MediaFragmentViewModel.kt index 98f566d..18361e2 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/viewmodel/MediaFragmentViewModel.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/viewmodel/MediaFragmentViewModel.kt @@ -16,8 +16,6 @@ import org.mosad.teapod.util.tmdb.* */ class MediaFragmentViewModel(application: Application) : AndroidViewModel(application) { -// var mediaCrunchy = NoneItem -// internal set var seriesCrunchy = NoneSeries // movies are also series internal set var seasonsCrunchy = NoneSeasons @@ -33,6 +31,9 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic var isWatchlist = false internal set var upNextSeries = NoneUpNextSeriesItem + internal set + var similarTo = NoneSimilarToResult + internal set // TMDB stuff var mediaType = MediaType.OTHER @@ -52,7 +53,8 @@ class MediaFragmentViewModel(application: Application) : AndroidViewModel(applic viewModelScope.launch { seriesCrunchy = Crunchyroll.series(crunchyId) }, viewModelScope.launch { seasonsCrunchy = Crunchyroll.seasons(crunchyId) }, viewModelScope.launch { isWatchlist = Crunchyroll.isWatchlist(crunchyId) }, - viewModelScope.launch { upNextSeries = Crunchyroll.upNextSeries(crunchyId) } + viewModelScope.launch { upNextSeries = Crunchyroll.upNextSeries(crunchyId) }, + viewModelScope.launch { similarTo = Crunchyroll.similarTo(crunchyId) } ).joinAll() // load the preferred season (preferred language, language per season, not per stream)