mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-17 07:21:58 +00:00
feat: add support for person and director (tmdb)
This commit is contained in:
parent
1781801ebe
commit
2771feab57
6 changed files with 232 additions and 3 deletions
|
|
@ -110,29 +110,38 @@
|
||||||
<string name="collections_editor_tmdb_production_mode">Production</string>
|
<string name="collections_editor_tmdb_production_mode">Production</string>
|
||||||
<string name="collections_editor_tmdb_network_mode">Network</string>
|
<string name="collections_editor_tmdb_network_mode">Network</string>
|
||||||
<string name="collections_editor_tmdb_collection_mode">Collection</string>
|
<string name="collections_editor_tmdb_collection_mode">Collection</string>
|
||||||
|
<string name="collections_editor_tmdb_person_mode">Person</string>
|
||||||
|
<string name="collections_editor_tmdb_director_mode">Director</string>
|
||||||
<string name="collections_editor_tmdb_custom_mode">Custom</string>
|
<string name="collections_editor_tmdb_custom_mode">Custom</string>
|
||||||
<string name="collections_editor_tmdb_help_presets">Pick a ready-made source. You can edit or remove it after adding.</string>
|
<string name="collections_editor_tmdb_help_presets">Pick a ready-made source. You can edit or remove it after adding.</string>
|
||||||
<string name="collections_editor_tmdb_help_list">Paste a public TMDB list URL or only the number from the URL.</string>
|
<string name="collections_editor_tmdb_help_list">Paste a public TMDB list URL or only the number from the URL.</string>
|
||||||
<string name="collections_editor_tmdb_help_production">Search by studio name, or paste a TMDB company ID/URL and add it directly.</string>
|
<string name="collections_editor_tmdb_help_production">Search by studio name, or paste a TMDB company ID/URL and add it directly.</string>
|
||||||
<string name="collections_editor_tmdb_help_network">Enter a network ID. Common networks are available in Presets and quick filters.</string>
|
<string name="collections_editor_tmdb_help_network">Enter a network ID. Common networks are available in Presets and quick filters.</string>
|
||||||
<string name="collections_editor_tmdb_help_collection">Search a movie collection name or paste the collection ID from TMDB.</string>
|
<string name="collections_editor_tmdb_help_collection">Search a movie collection name or paste the collection ID from TMDB.</string>
|
||||||
|
<string name="collections_editor_tmdb_help_person">Enter a TMDB person ID or URL to build a row from cast credits.</string>
|
||||||
|
<string name="collections_editor_tmdb_help_director">Enter a TMDB person ID or URL to build a row from director credits.</string>
|
||||||
<string name="collections_editor_tmdb_help_discover">Build a live TMDB row using optional filters. Leave fields empty when you do not need that filter.</string>
|
<string name="collections_editor_tmdb_help_discover">Build a live TMDB row using optional filters. Leave fields empty when you do not need that filter.</string>
|
||||||
<string name="collections_editor_tmdb_public_list">Public TMDB list</string>
|
<string name="collections_editor_tmdb_public_list">Public TMDB list</string>
|
||||||
<string name="collections_editor_tmdb_network_id">Network ID</string>
|
<string name="collections_editor_tmdb_network_id">Network ID</string>
|
||||||
<string name="collections_editor_tmdb_collection_id">Collection ID</string>
|
<string name="collections_editor_tmdb_collection_id">Collection ID</string>
|
||||||
|
<string name="collections_editor_tmdb_person_id">Person ID</string>
|
||||||
<string name="collections_editor_tmdb_company_search">Production company name, ID, or URL</string>
|
<string name="collections_editor_tmdb_company_search">Production company name, ID, or URL</string>
|
||||||
<string name="collections_editor_tmdb_id_or_url">TMDB ID or URL</string>
|
<string name="collections_editor_tmdb_id_or_url">TMDB ID or URL</string>
|
||||||
<string name="collections_editor_tmdb_list_placeholder">https://www.themoviedb.org/list/8504994 or 8504994</string>
|
<string name="collections_editor_tmdb_list_placeholder">https://www.themoviedb.org/list/8504994 or 8504994</string>
|
||||||
<string name="collections_editor_tmdb_network_placeholder">213 for Netflix, 49 for HBO, 2739 for Disney+</string>
|
<string name="collections_editor_tmdb_network_placeholder">213 for Netflix, 49 for HBO, 2739 for Disney+</string>
|
||||||
<string name="collections_editor_tmdb_collection_placeholder">10 for Star Wars Collection</string>
|
<string name="collections_editor_tmdb_collection_placeholder">10 for Star Wars Collection</string>
|
||||||
<string name="collections_editor_tmdb_company_placeholder">Marvel Studios, 420, or company URL</string>
|
<string name="collections_editor_tmdb_company_placeholder">Marvel Studios, 420, or company URL</string>
|
||||||
|
<string name="collections_editor_tmdb_person_placeholder">31 for Tom Hanks, or person URL</string>
|
||||||
<string name="collections_editor_tmdb_search_helper">Examples: Marvel Studios, 420, or https://www.themoviedb.org/company/420.</string>
|
<string name="collections_editor_tmdb_search_helper">Examples: Marvel Studios, 420, or https://www.themoviedb.org/company/420.</string>
|
||||||
<string name="collections_editor_tmdb_collection_helper">Example: Star Wars Collection, Harry Potter Collection, or a collection URL.</string>
|
<string name="collections_editor_tmdb_collection_helper">Example: Star Wars Collection, Harry Potter Collection, or a collection URL.</string>
|
||||||
<string name="collections_editor_tmdb_network_helper">Example IDs: Netflix 213, HBO 49, Disney+ 2739.</string>
|
<string name="collections_editor_tmdb_network_helper">Example IDs: Netflix 213, HBO 49, Disney+ 2739.</string>
|
||||||
<string name="collections_editor_tmdb_list_helper">Example: https://www.themoviedb.org/list/8504994 or 8504994.</string>
|
<string name="collections_editor_tmdb_list_helper">Example: https://www.themoviedb.org/list/8504994 or 8504994.</string>
|
||||||
|
<string name="collections_editor_tmdb_person_helper">Example: https://www.themoviedb.org/person/31-tom-hanks or 31.</string>
|
||||||
<string name="collections_editor_tmdb_display_title">Display title</string>
|
<string name="collections_editor_tmdb_display_title">Display title</string>
|
||||||
<string name="collections_editor_tmdb_title_helper">Shown as the row/tab name. If blank, Nuvio creates one from the source.</string>
|
<string name="collections_editor_tmdb_title_helper">Shown as the row/tab name. If blank, Nuvio creates one from the source.</string>
|
||||||
<string name="collections_editor_tmdb_title_placeholder">Marvel Movies, Netflix Originals, Pixar</string>
|
<string name="collections_editor_tmdb_title_placeholder">Marvel Movies, Netflix Originals, Pixar</string>
|
||||||
|
<string name="collections_editor_tmdb_person_title_placeholder">Tom Hanks Movies, Favorite Actors</string>
|
||||||
|
<string name="collections_editor_tmdb_director_title_placeholder">Christopher Nolan Movies, Favorite Directors</string>
|
||||||
<string name="collections_editor_tmdb_discover_title_placeholder">Best Action Movies, Korean Dramas, 2024 Animation</string>
|
<string name="collections_editor_tmdb_discover_title_placeholder">Best Action Movies, Korean Dramas, 2024 Animation</string>
|
||||||
<string name="collections_editor_tmdb_search_results">Search Results</string>
|
<string name="collections_editor_tmdb_search_results">Search Results</string>
|
||||||
<string name="collections_editor_tmdb_collection">TMDB Collection</string>
|
<string name="collections_editor_tmdb_collection">TMDB Collection</string>
|
||||||
|
|
@ -212,6 +221,7 @@
|
||||||
<string name="collections_editor_tmdb_network_disney_plus">Disney+</string>
|
<string name="collections_editor_tmdb_network_disney_plus">Disney+</string>
|
||||||
<string name="collections_editor_tmdb_network_prime_video">Prime Video</string>
|
<string name="collections_editor_tmdb_network_prime_video">Prime Video</string>
|
||||||
<string name="collections_editor_tmdb_network_hulu">Hulu</string>
|
<string name="collections_editor_tmdb_network_hulu">Hulu</string>
|
||||||
|
<string name="collections_editor_tmdb_sort_original">Original</string>
|
||||||
<string name="collections_editor_tmdb_sort_popular">Popular</string>
|
<string name="collections_editor_tmdb_sort_popular">Popular</string>
|
||||||
<string name="collections_editor_tmdb_sort_top_rated">Top Rated</string>
|
<string name="collections_editor_tmdb_sort_top_rated">Top Rated</string>
|
||||||
<string name="collections_editor_tmdb_sort_recent">Recent</string>
|
<string name="collections_editor_tmdb_sort_recent">Recent</string>
|
||||||
|
|
@ -219,6 +229,8 @@
|
||||||
<string name="collections_editor_tmdb_subtitle_movie_collection">TMDB Movie Collection</string>
|
<string name="collections_editor_tmdb_subtitle_movie_collection">TMDB Movie Collection</string>
|
||||||
<string name="collections_editor_tmdb_subtitle_production">Production</string>
|
<string name="collections_editor_tmdb_subtitle_production">Production</string>
|
||||||
<string name="collections_editor_tmdb_subtitle_network">Network</string>
|
<string name="collections_editor_tmdb_subtitle_network">Network</string>
|
||||||
|
<string name="collections_editor_tmdb_subtitle_person">Person</string>
|
||||||
|
<string name="collections_editor_tmdb_subtitle_director">Director</string>
|
||||||
<string name="collections_editor_tmdb_subtitle_discover">TMDB Discover</string>
|
<string name="collections_editor_tmdb_subtitle_discover">TMDB Discover</string>
|
||||||
<string name="collections_empty_subtitle">Create one to organize your catalogs.</string>
|
<string name="collections_empty_subtitle">Create one to organize your catalogs.</string>
|
||||||
<string name="collections_empty_title">No collections yet</string>
|
<string name="collections_empty_title">No collections yet</string>
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ enum class TmdbBuilderMode {
|
||||||
PRODUCTION,
|
PRODUCTION,
|
||||||
NETWORK,
|
NETWORK,
|
||||||
COLLECTION,
|
COLLECTION,
|
||||||
|
PERSON,
|
||||||
|
DIRECTOR,
|
||||||
DISCOVER,
|
DISCOVER,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,9 +342,15 @@ object CollectionEditorRepository {
|
||||||
} else {
|
} else {
|
||||||
_uiState.value.tmdbMediaType
|
_uiState.value.tmdbMediaType
|
||||||
}
|
}
|
||||||
|
val sortBy = when (mode) {
|
||||||
|
TmdbBuilderMode.LIST,
|
||||||
|
TmdbBuilderMode.COLLECTION -> TmdbCollectionSort.ORIGINAL.value
|
||||||
|
else -> TmdbCollectionSort.POPULAR_DESC.value
|
||||||
|
}
|
||||||
_uiState.value = _uiState.value.copy(
|
_uiState.value = _uiState.value.copy(
|
||||||
tmdbBuilderMode = mode,
|
tmdbBuilderMode = mode,
|
||||||
tmdbMediaType = mediaType,
|
tmdbMediaType = mediaType,
|
||||||
|
tmdbSortBy = sortBy,
|
||||||
tmdbMediaBoth = if (
|
tmdbMediaBoth = if (
|
||||||
mode == TmdbBuilderMode.NETWORK ||
|
mode == TmdbBuilderMode.NETWORK ||
|
||||||
mode == TmdbBuilderMode.LIST ||
|
mode == TmdbBuilderMode.LIST ||
|
||||||
|
|
@ -459,6 +467,8 @@ object CollectionEditorRepository {
|
||||||
TmdbBuilderMode.COLLECTION -> TmdbCollectionSourceType.COLLECTION
|
TmdbBuilderMode.COLLECTION -> TmdbCollectionSourceType.COLLECTION
|
||||||
TmdbBuilderMode.PRODUCTION -> TmdbCollectionSourceType.COMPANY
|
TmdbBuilderMode.PRODUCTION -> TmdbCollectionSourceType.COMPANY
|
||||||
TmdbBuilderMode.NETWORK -> TmdbCollectionSourceType.NETWORK
|
TmdbBuilderMode.NETWORK -> TmdbCollectionSourceType.NETWORK
|
||||||
|
TmdbBuilderMode.PERSON -> TmdbCollectionSourceType.PERSON
|
||||||
|
TmdbBuilderMode.DIRECTOR -> TmdbCollectionSourceType.DIRECTOR
|
||||||
TmdbBuilderMode.DISCOVER -> TmdbCollectionSourceType.DISCOVER
|
TmdbBuilderMode.DISCOVER -> TmdbCollectionSourceType.DISCOVER
|
||||||
}
|
}
|
||||||
val id = TmdbCollectionSourceResolver.parseTmdbId(state.tmdbInput)
|
val id = TmdbCollectionSourceResolver.parseTmdbId(state.tmdbInput)
|
||||||
|
|
@ -473,6 +483,8 @@ object CollectionEditorRepository {
|
||||||
TmdbCollectionSourceType.COLLECTION -> "TMDB Collection ${id ?: ""}".trim()
|
TmdbCollectionSourceType.COLLECTION -> "TMDB Collection ${id ?: ""}".trim()
|
||||||
TmdbCollectionSourceType.COMPANY -> "TMDB Production ${id ?: ""}".trim()
|
TmdbCollectionSourceType.COMPANY -> "TMDB Production ${id ?: ""}".trim()
|
||||||
TmdbCollectionSourceType.NETWORK -> "TMDB Network ${id ?: ""}".trim()
|
TmdbCollectionSourceType.NETWORK -> "TMDB Network ${id ?: ""}".trim()
|
||||||
|
TmdbCollectionSourceType.PERSON -> "TMDB Person ${id ?: ""}".trim()
|
||||||
|
TmdbCollectionSourceType.DIRECTOR -> "TMDB Director ${id ?: ""}".trim()
|
||||||
TmdbCollectionSourceType.DISCOVER -> "TMDB Discover"
|
TmdbCollectionSourceType.DISCOVER -> "TMDB Discover"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -561,6 +573,8 @@ private val coverMetadataSourceTypes = setOf(
|
||||||
TmdbCollectionSourceType.COLLECTION,
|
TmdbCollectionSourceType.COLLECTION,
|
||||||
TmdbCollectionSourceType.COMPANY,
|
TmdbCollectionSourceType.COMPANY,
|
||||||
TmdbCollectionSourceType.NETWORK,
|
TmdbCollectionSourceType.NETWORK,
|
||||||
|
TmdbCollectionSourceType.PERSON,
|
||||||
|
TmdbCollectionSourceType.DIRECTOR,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun CollectionCatalogSource.toCollectionSource(): CollectionSource =
|
private fun CollectionCatalogSource.toCollectionSource(): CollectionSource =
|
||||||
|
|
@ -591,6 +605,8 @@ private fun selectedMediaTypes(
|
||||||
): List<TmdbCollectionMediaType> =
|
): List<TmdbCollectionMediaType> =
|
||||||
when (sourceType) {
|
when (sourceType) {
|
||||||
TmdbCollectionSourceType.COMPANY,
|
TmdbCollectionSourceType.COMPANY,
|
||||||
|
TmdbCollectionSourceType.PERSON,
|
||||||
|
TmdbCollectionSourceType.DIRECTOR,
|
||||||
TmdbCollectionSourceType.DISCOVER -> if (state.tmdbMediaBoth) {
|
TmdbCollectionSourceType.DISCOVER -> if (state.tmdbMediaBoth) {
|
||||||
listOf(TmdbCollectionMediaType.MOVIE, TmdbCollectionMediaType.TV)
|
listOf(TmdbCollectionMediaType.MOVIE, TmdbCollectionMediaType.TV)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -897,13 +897,19 @@ private fun TmdbSourcePickerScreen(
|
||||||
TmdbBuilderMode.COLLECTION -> TmdbCollectionSourceType.COLLECTION
|
TmdbBuilderMode.COLLECTION -> TmdbCollectionSourceType.COLLECTION
|
||||||
TmdbBuilderMode.PRODUCTION -> TmdbCollectionSourceType.COMPANY
|
TmdbBuilderMode.PRODUCTION -> TmdbCollectionSourceType.COMPANY
|
||||||
TmdbBuilderMode.NETWORK -> TmdbCollectionSourceType.NETWORK
|
TmdbBuilderMode.NETWORK -> TmdbCollectionSourceType.NETWORK
|
||||||
|
TmdbBuilderMode.PERSON -> TmdbCollectionSourceType.PERSON
|
||||||
|
TmdbBuilderMode.DIRECTOR -> TmdbCollectionSourceType.DIRECTOR
|
||||||
TmdbBuilderMode.DISCOVER -> TmdbCollectionSourceType.DISCOVER
|
TmdbBuilderMode.DISCOVER -> TmdbCollectionSourceType.DISCOVER
|
||||||
}
|
}
|
||||||
val requiresId = sourceType != TmdbCollectionSourceType.DISCOVER
|
val requiresId = sourceType != TmdbCollectionSourceType.DISCOVER
|
||||||
val showMediaControls = state.tmdbBuilderMode == TmdbBuilderMode.PRODUCTION ||
|
val showMediaControls = state.tmdbBuilderMode == TmdbBuilderMode.PRODUCTION ||
|
||||||
|
state.tmdbBuilderMode == TmdbBuilderMode.PERSON ||
|
||||||
|
state.tmdbBuilderMode == TmdbBuilderMode.DIRECTOR ||
|
||||||
state.tmdbBuilderMode == TmdbBuilderMode.DISCOVER
|
state.tmdbBuilderMode == TmdbBuilderMode.DISCOVER
|
||||||
val showSortControls = state.tmdbBuilderMode == TmdbBuilderMode.PRODUCTION ||
|
val showSortControls = state.tmdbBuilderMode == TmdbBuilderMode.PRODUCTION ||
|
||||||
state.tmdbBuilderMode == TmdbBuilderMode.NETWORK ||
|
state.tmdbBuilderMode == TmdbBuilderMode.NETWORK ||
|
||||||
|
state.tmdbBuilderMode == TmdbBuilderMode.PERSON ||
|
||||||
|
state.tmdbBuilderMode == TmdbBuilderMode.DIRECTOR ||
|
||||||
state.tmdbBuilderMode == TmdbBuilderMode.DISCOVER
|
state.tmdbBuilderMode == TmdbBuilderMode.DISCOVER
|
||||||
val showFilterControls = state.tmdbBuilderMode == TmdbBuilderMode.DISCOVER
|
val showFilterControls = state.tmdbBuilderMode == TmdbBuilderMode.DISCOVER
|
||||||
|
|
||||||
|
|
@ -1892,6 +1898,8 @@ private fun tmdbBuilderModeLabel(mode: TmdbBuilderMode): String =
|
||||||
TmdbBuilderMode.PRODUCTION -> stringResource(Res.string.collections_editor_tmdb_production_mode)
|
TmdbBuilderMode.PRODUCTION -> stringResource(Res.string.collections_editor_tmdb_production_mode)
|
||||||
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_network_mode)
|
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_network_mode)
|
||||||
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_collection_mode)
|
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_collection_mode)
|
||||||
|
TmdbBuilderMode.PERSON -> stringResource(Res.string.collections_editor_tmdb_person_mode)
|
||||||
|
TmdbBuilderMode.DIRECTOR -> stringResource(Res.string.collections_editor_tmdb_director_mode)
|
||||||
TmdbBuilderMode.DISCOVER -> stringResource(Res.string.collections_editor_tmdb_custom_mode)
|
TmdbBuilderMode.DISCOVER -> stringResource(Res.string.collections_editor_tmdb_custom_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1903,6 +1911,8 @@ private fun tmdbModeHelpText(mode: TmdbBuilderMode): String =
|
||||||
TmdbBuilderMode.PRODUCTION -> stringResource(Res.string.collections_editor_tmdb_help_production)
|
TmdbBuilderMode.PRODUCTION -> stringResource(Res.string.collections_editor_tmdb_help_production)
|
||||||
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_help_network)
|
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_help_network)
|
||||||
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_help_collection)
|
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_help_collection)
|
||||||
|
TmdbBuilderMode.PERSON -> stringResource(Res.string.collections_editor_tmdb_help_person)
|
||||||
|
TmdbBuilderMode.DIRECTOR -> stringResource(Res.string.collections_editor_tmdb_help_director)
|
||||||
TmdbBuilderMode.DISCOVER -> stringResource(Res.string.collections_editor_tmdb_help_discover)
|
TmdbBuilderMode.DISCOVER -> stringResource(Res.string.collections_editor_tmdb_help_discover)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1913,6 +1923,8 @@ private fun tmdbInputLabel(mode: TmdbBuilderMode): String =
|
||||||
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_network_id)
|
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_network_id)
|
||||||
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_collection_id)
|
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_collection_id)
|
||||||
TmdbBuilderMode.PRODUCTION -> stringResource(Res.string.collections_editor_tmdb_company_search)
|
TmdbBuilderMode.PRODUCTION -> stringResource(Res.string.collections_editor_tmdb_company_search)
|
||||||
|
TmdbBuilderMode.PERSON,
|
||||||
|
TmdbBuilderMode.DIRECTOR -> stringResource(Res.string.collections_editor_tmdb_person_id)
|
||||||
else -> stringResource(Res.string.collections_editor_tmdb_id_or_url)
|
else -> stringResource(Res.string.collections_editor_tmdb_id_or_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1923,6 +1935,8 @@ private fun tmdbInputPlaceholder(mode: TmdbBuilderMode): String =
|
||||||
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_network_placeholder)
|
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_network_placeholder)
|
||||||
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_collection_placeholder)
|
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_collection_placeholder)
|
||||||
TmdbBuilderMode.PRODUCTION -> stringResource(Res.string.collections_editor_tmdb_company_placeholder)
|
TmdbBuilderMode.PRODUCTION -> stringResource(Res.string.collections_editor_tmdb_company_placeholder)
|
||||||
|
TmdbBuilderMode.PERSON,
|
||||||
|
TmdbBuilderMode.DIRECTOR -> stringResource(Res.string.collections_editor_tmdb_person_placeholder)
|
||||||
else -> stringResource(Res.string.collections_editor_tmdb_id_or_url)
|
else -> stringResource(Res.string.collections_editor_tmdb_id_or_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1933,6 +1947,8 @@ private fun tmdbInputHelper(mode: TmdbBuilderMode): String =
|
||||||
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_collection_helper)
|
TmdbBuilderMode.COLLECTION -> stringResource(Res.string.collections_editor_tmdb_collection_helper)
|
||||||
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_network_helper)
|
TmdbBuilderMode.NETWORK -> stringResource(Res.string.collections_editor_tmdb_network_helper)
|
||||||
TmdbBuilderMode.LIST -> stringResource(Res.string.collections_editor_tmdb_list_helper)
|
TmdbBuilderMode.LIST -> stringResource(Res.string.collections_editor_tmdb_list_helper)
|
||||||
|
TmdbBuilderMode.PERSON,
|
||||||
|
TmdbBuilderMode.DIRECTOR -> stringResource(Res.string.collections_editor_tmdb_person_helper)
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1940,12 +1956,15 @@ private fun tmdbInputHelper(mode: TmdbBuilderMode): String =
|
||||||
private fun tmdbTitlePlaceholder(mode: TmdbBuilderMode): String =
|
private fun tmdbTitlePlaceholder(mode: TmdbBuilderMode): String =
|
||||||
when (mode) {
|
when (mode) {
|
||||||
TmdbBuilderMode.DISCOVER -> stringResource(Res.string.collections_editor_tmdb_discover_title_placeholder)
|
TmdbBuilderMode.DISCOVER -> stringResource(Res.string.collections_editor_tmdb_discover_title_placeholder)
|
||||||
|
TmdbBuilderMode.PERSON -> stringResource(Res.string.collections_editor_tmdb_person_title_placeholder)
|
||||||
|
TmdbBuilderMode.DIRECTOR -> stringResource(Res.string.collections_editor_tmdb_director_title_placeholder)
|
||||||
else -> stringResource(Res.string.collections_editor_tmdb_title_placeholder)
|
else -> stringResource(Res.string.collections_editor_tmdb_title_placeholder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun tmdbSortLabel(sort: TmdbCollectionSort): String =
|
private fun tmdbSortLabel(sort: TmdbCollectionSort): String =
|
||||||
when (sort) {
|
when (sort) {
|
||||||
|
TmdbCollectionSort.ORIGINAL -> stringResource(Res.string.collections_editor_tmdb_sort_original)
|
||||||
TmdbCollectionSort.POPULAR_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_popular)
|
TmdbCollectionSort.POPULAR_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_popular)
|
||||||
TmdbCollectionSort.VOTE_AVERAGE_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_top_rated)
|
TmdbCollectionSort.VOTE_AVERAGE_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_top_rated)
|
||||||
TmdbCollectionSort.RELEASE_DATE_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_recent)
|
TmdbCollectionSort.RELEASE_DATE_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_recent)
|
||||||
|
|
@ -1979,6 +1998,16 @@ private fun tmdbSourceSubtitle(source: CollectionSource): String {
|
||||||
stringResource(Res.string.collections_editor_tmdb_series),
|
stringResource(Res.string.collections_editor_tmdb_series),
|
||||||
sort,
|
sort,
|
||||||
).joinToString(" • ")
|
).joinToString(" • ")
|
||||||
|
TmdbCollectionSourceType.PERSON -> listOf(
|
||||||
|
stringResource(Res.string.collections_editor_tmdb_subtitle_person),
|
||||||
|
media,
|
||||||
|
sort,
|
||||||
|
).joinToString(" • ")
|
||||||
|
TmdbCollectionSourceType.DIRECTOR -> listOf(
|
||||||
|
stringResource(Res.string.collections_editor_tmdb_subtitle_director),
|
||||||
|
media,
|
||||||
|
sort,
|
||||||
|
).joinToString(" • ")
|
||||||
TmdbCollectionSourceType.DISCOVER -> listOf(
|
TmdbCollectionSourceType.DISCOVER -> listOf(
|
||||||
stringResource(Res.string.collections_editor_tmdb_subtitle_discover),
|
stringResource(Res.string.collections_editor_tmdb_subtitle_discover),
|
||||||
media,
|
media,
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,8 @@ enum class TmdbCollectionSourceType {
|
||||||
COMPANY,
|
COMPANY,
|
||||||
NETWORK,
|
NETWORK,
|
||||||
DISCOVER,
|
DISCOVER,
|
||||||
|
PERSON,
|
||||||
|
DIRECTOR,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|
@ -86,6 +88,7 @@ enum class TmdbCollectionMediaType(val value: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class TmdbCollectionSort(val value: String) {
|
enum class TmdbCollectionSort(val value: String) {
|
||||||
|
ORIGINAL("original"),
|
||||||
POPULAR_DESC("popularity.desc"),
|
POPULAR_DESC("popularity.desc"),
|
||||||
VOTE_AVERAGE_DESC("vote_average.desc"),
|
VOTE_AVERAGE_DESC("vote_average.desc"),
|
||||||
RELEASE_DATE_DESC("primary_release_date.desc"),
|
RELEASE_DATE_DESC("primary_release_date.desc"),
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,11 @@ object FolderDetailRepository {
|
||||||
source = source,
|
source = source,
|
||||||
type = type,
|
type = type,
|
||||||
catalogId = tmdbCatalogId(source),
|
catalogId = tmdbCatalogId(source),
|
||||||
supportsPagination = source.tmdbSourceType != TmdbCollectionSourceType.COLLECTION.name,
|
supportsPagination = source.tmdbSourceType !in setOf(
|
||||||
|
TmdbCollectionSourceType.COLLECTION.name,
|
||||||
|
TmdbCollectionSourceType.PERSON.name,
|
||||||
|
TmdbCollectionSourceType.DIRECTOR.name,
|
||||||
|
),
|
||||||
isLoading = true,
|
isLoading = true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ object TmdbCollectionSourceResolver {
|
||||||
when (sourceType) {
|
when (sourceType) {
|
||||||
TmdbCollectionSourceType.LIST -> resolveList(source, apiKey, language, page)
|
TmdbCollectionSourceType.LIST -> resolveList(source, apiKey, language, page)
|
||||||
TmdbCollectionSourceType.COLLECTION -> resolveCollection(source, apiKey, language)
|
TmdbCollectionSourceType.COLLECTION -> resolveCollection(source, apiKey, language)
|
||||||
|
TmdbCollectionSourceType.PERSON,
|
||||||
|
TmdbCollectionSourceType.DIRECTOR -> resolvePersonCredits(source, apiKey, language)
|
||||||
TmdbCollectionSourceType.COMPANY,
|
TmdbCollectionSourceType.COMPANY,
|
||||||
TmdbCollectionSourceType.NETWORK,
|
TmdbCollectionSourceType.NETWORK,
|
||||||
TmdbCollectionSourceType.DISCOVER -> resolveDiscover(source, apiKey, language, page)
|
TmdbCollectionSourceType.DISCOVER -> resolveDiscover(source, apiKey, language, page)
|
||||||
|
|
@ -85,6 +87,19 @@ object TmdbCollectionSourceResolver {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TmdbCollectionSourceType.PERSON,
|
||||||
|
TmdbCollectionSourceType.DIRECTOR -> {
|
||||||
|
val body = fetch<TmdbPersonResponse>(
|
||||||
|
endpoint = "person/$id",
|
||||||
|
apiKey = apiKey,
|
||||||
|
query = mapOf("language" to language),
|
||||||
|
) ?: error("TMDB person not found")
|
||||||
|
TmdbSourceImportMetadata(
|
||||||
|
title = body.name?.takeIf { it.isNotBlank() },
|
||||||
|
coverImageUrl = imageUrl(body.profilePath, "w500"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
TmdbCollectionSourceType.DISCOVER -> TmdbSourceImportMetadata(title = "TMDB Discover")
|
TmdbCollectionSourceType.DISCOVER -> TmdbSourceImportMetadata(title = "TMDB Discover")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +168,7 @@ object TmdbCollectionSourceResolver {
|
||||||
fun parseTmdbId(input: String): Int? {
|
fun parseTmdbId(input: String): Int? {
|
||||||
val trimmed = input.trim()
|
val trimmed = input.trim()
|
||||||
trimmed.toIntOrNull()?.let { return it }
|
trimmed.toIntOrNull()?.let { return it }
|
||||||
return Regex("""(?:list|collection|company|network)/(\d+)""")
|
return Regex("""(?:list|collection|company|network|person)/(\d+)""")
|
||||||
.find(trimmed)
|
.find(trimmed)
|
||||||
?.groupValues
|
?.groupValues
|
||||||
?.getOrNull(1)
|
?.getOrNull(1)
|
||||||
|
|
@ -193,6 +208,7 @@ object TmdbCollectionSourceResolver {
|
||||||
) ?: error("TMDB list not found")
|
) ?: error("TMDB list not found")
|
||||||
val items = body.items.orEmpty()
|
val items = body.items.orEmpty()
|
||||||
.mapNotNull { it.toPreview() }
|
.mapNotNull { it.toPreview() }
|
||||||
|
.sortedFor(source.sortBy)
|
||||||
.distinctBy { "${it.type}:${it.id}" }
|
.distinctBy { "${it.type}:${it.id}" }
|
||||||
return CatalogPage(
|
return CatalogPage(
|
||||||
items = items,
|
items = items,
|
||||||
|
|
@ -213,12 +229,35 @@ object TmdbCollectionSourceResolver {
|
||||||
query = mapOf("language" to language),
|
query = mapOf("language" to language),
|
||||||
) ?: error("TMDB collection not found")
|
) ?: error("TMDB collection not found")
|
||||||
val items = body.parts.orEmpty()
|
val items = body.parts.orEmpty()
|
||||||
.sortedBy { it.releaseDate ?: "9999" }
|
|
||||||
.mapNotNull { it.toPreview(TmdbCollectionMediaType.MOVIE) }
|
.mapNotNull { it.toPreview(TmdbCollectionMediaType.MOVIE) }
|
||||||
|
.sortedFor(source.sortBy)
|
||||||
.distinctBy { it.id }
|
.distinctBy { it.id }
|
||||||
return CatalogPage(items = items, rawItemCount = items.size, nextSkip = null)
|
return CatalogPage(items = items, rawItemCount = items.size, nextSkip = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun resolvePersonCredits(
|
||||||
|
source: CollectionSource,
|
||||||
|
apiKey: String,
|
||||||
|
language: String,
|
||||||
|
): CatalogPage {
|
||||||
|
val id = source.tmdbId ?: error("Missing TMDB person ID")
|
||||||
|
val mediaType = source.tmdbMediaType()
|
||||||
|
val body = fetch<TmdbPersonCreditsResponse>(
|
||||||
|
endpoint = "person/$id/combined_credits",
|
||||||
|
apiKey = apiKey,
|
||||||
|
query = mapOf("language" to language),
|
||||||
|
) ?: error("TMDB person credits not found")
|
||||||
|
val items = when (source.tmdbType()) {
|
||||||
|
TmdbCollectionSourceType.DIRECTOR -> body.crew.orEmpty()
|
||||||
|
.filter { it.job.equals("Director", ignoreCase = true) }
|
||||||
|
.mapNotNull { it.toPreview(mediaType) }
|
||||||
|
else -> body.cast.orEmpty().mapNotNull { it.toPreview(mediaType) }
|
||||||
|
}
|
||||||
|
.distinctBy { "${it.type}:${it.id}" }
|
||||||
|
.sortedFor(source.sortBy)
|
||||||
|
return CatalogPage(items = items, rawItemCount = items.size, nextSkip = null)
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun resolveDiscover(
|
private suspend fun resolveDiscover(
|
||||||
source: CollectionSource,
|
source: CollectionSource,
|
||||||
apiKey: String,
|
apiKey: String,
|
||||||
|
|
@ -312,6 +351,21 @@ object TmdbCollectionSourceResolver {
|
||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun List<MetaPreview>.sortedFor(sortBy: String?): List<MetaPreview> =
|
||||||
|
when (sortBy) {
|
||||||
|
TmdbCollectionSort.ORIGINAL.value -> this
|
||||||
|
TmdbCollectionSort.VOTE_AVERAGE_DESC.value -> sortedWith(
|
||||||
|
compareByDescending<MetaPreview> { it.imdbRating?.toDoubleOrNull() ?: -1.0 }
|
||||||
|
.thenByDescending { it.rawReleaseDate ?: it.releaseInfo.orEmpty() },
|
||||||
|
)
|
||||||
|
TmdbCollectionSort.RELEASE_DATE_DESC.value,
|
||||||
|
TmdbCollectionSort.FIRST_AIR_DATE_DESC.value -> sortedByDescending { it.rawReleaseDate ?: it.releaseInfo.orEmpty() }
|
||||||
|
TmdbCollectionSort.POPULAR_DESC.value,
|
||||||
|
null,
|
||||||
|
"" -> this
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
|
||||||
private fun TmdbListItem.toPreview(): MetaPreview? {
|
private fun TmdbListItem.toPreview(): MetaPreview? {
|
||||||
val media = mediaType?.lowercase()
|
val media = mediaType?.lowercase()
|
||||||
val contentType = if (media == "tv") TmdbCollectionMediaType.TV else TmdbCollectionMediaType.MOVIE
|
val contentType = if (media == "tv") TmdbCollectionMediaType.TV else TmdbCollectionMediaType.MOVIE
|
||||||
|
|
@ -362,6 +416,62 @@ object TmdbCollectionSourceResolver {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun TmdbPersonCreditCast.toPreview(mediaType: TmdbCollectionMediaType): MetaPreview? {
|
||||||
|
if (!matchesMediaType(mediaType, this.mediaType)) return null
|
||||||
|
val title = title?.takeIf { it.isNotBlank() }
|
||||||
|
?: name?.takeIf { it.isNotBlank() }
|
||||||
|
?: originalTitle?.takeIf { it.isNotBlank() }
|
||||||
|
?: originalName?.takeIf { it.isNotBlank() }
|
||||||
|
?: return null
|
||||||
|
return MetaPreview(
|
||||||
|
id = "tmdb:$id",
|
||||||
|
type = if (mediaType == TmdbCollectionMediaType.TV) "series" else "movie",
|
||||||
|
name = title,
|
||||||
|
poster = imageUrl(posterPath, "w500") ?: imageUrl(backdropPath, "w780"),
|
||||||
|
banner = imageUrl(backdropPath, "w1280"),
|
||||||
|
posterShape = PosterShape.Poster,
|
||||||
|
description = overview?.takeIf { it.isNotBlank() },
|
||||||
|
releaseInfo = when (mediaType) {
|
||||||
|
TmdbCollectionMediaType.MOVIE -> releaseDate?.take(4)
|
||||||
|
TmdbCollectionMediaType.TV -> firstAirDate?.take(4)
|
||||||
|
},
|
||||||
|
rawReleaseDate = when (mediaType) {
|
||||||
|
TmdbCollectionMediaType.MOVIE -> releaseDate
|
||||||
|
TmdbCollectionMediaType.TV -> firstAirDate
|
||||||
|
},
|
||||||
|
popularity = popularity,
|
||||||
|
imdbRating = voteAverage?.let { ((it * 10).roundToInt() / 10.0).toString() },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TmdbPersonCreditCrew.toPreview(mediaType: TmdbCollectionMediaType): MetaPreview? {
|
||||||
|
if (!matchesMediaType(mediaType, this.mediaType)) return null
|
||||||
|
val title = title?.takeIf { it.isNotBlank() }
|
||||||
|
?: name?.takeIf { it.isNotBlank() }
|
||||||
|
?: originalTitle?.takeIf { it.isNotBlank() }
|
||||||
|
?: originalName?.takeIf { it.isNotBlank() }
|
||||||
|
?: return null
|
||||||
|
return MetaPreview(
|
||||||
|
id = "tmdb:$id",
|
||||||
|
type = if (mediaType == TmdbCollectionMediaType.TV) "series" else "movie",
|
||||||
|
name = title,
|
||||||
|
poster = imageUrl(posterPath, "w500") ?: imageUrl(backdropPath, "w780"),
|
||||||
|
banner = imageUrl(backdropPath, "w1280"),
|
||||||
|
posterShape = PosterShape.Poster,
|
||||||
|
description = overview?.takeIf { it.isNotBlank() },
|
||||||
|
releaseInfo = when (mediaType) {
|
||||||
|
TmdbCollectionMediaType.MOVIE -> releaseDate?.take(4)
|
||||||
|
TmdbCollectionMediaType.TV -> firstAirDate?.take(4)
|
||||||
|
},
|
||||||
|
rawReleaseDate = when (mediaType) {
|
||||||
|
TmdbCollectionMediaType.MOVIE -> releaseDate
|
||||||
|
TmdbCollectionMediaType.TV -> firstAirDate
|
||||||
|
},
|
||||||
|
popularity = popularity,
|
||||||
|
imdbRating = voteAverage?.let { ((it * 10).roundToInt() / 10.0).toString() },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun CollectionSource.tmdbType(): TmdbCollectionSourceType =
|
private fun CollectionSource.tmdbType(): TmdbCollectionSourceType =
|
||||||
tmdbSourceType
|
tmdbSourceType
|
||||||
?.let { raw -> runCatching { TmdbCollectionSourceType.valueOf(raw.uppercase()) }.getOrNull() }
|
?.let { raw -> runCatching { TmdbCollectionSourceType.valueOf(raw.uppercase()) }.getOrNull() }
|
||||||
|
|
@ -370,6 +480,12 @@ object TmdbCollectionSourceResolver {
|
||||||
private fun CollectionSource.tmdbMediaType(): TmdbCollectionMediaType =
|
private fun CollectionSource.tmdbMediaType(): TmdbCollectionMediaType =
|
||||||
TmdbCollectionMediaType.fromString(mediaType)
|
TmdbCollectionMediaType.fromString(mediaType)
|
||||||
|
|
||||||
|
private fun matchesMediaType(expected: TmdbCollectionMediaType, actual: String?): Boolean =
|
||||||
|
when (expected) {
|
||||||
|
TmdbCollectionMediaType.MOVIE -> actual == "movie"
|
||||||
|
TmdbCollectionMediaType.TV -> actual == "tv"
|
||||||
|
}
|
||||||
|
|
||||||
private fun company(title: String, id: Int) = CollectionSource(
|
private fun company(title: String, id: Int) = CollectionSource(
|
||||||
provider = "tmdb",
|
provider = "tmdb",
|
||||||
tmdbSourceType = TmdbCollectionSourceType.COMPANY.name,
|
tmdbSourceType = TmdbCollectionSourceType.COMPANY.name,
|
||||||
|
|
@ -391,6 +507,7 @@ object TmdbCollectionSourceResolver {
|
||||||
private fun movieSort(sortBy: String?): String =
|
private fun movieSort(sortBy: String?): String =
|
||||||
when (sortBy) {
|
when (sortBy) {
|
||||||
TmdbCollectionSort.FIRST_AIR_DATE_DESC.value -> TmdbCollectionSort.RELEASE_DATE_DESC.value
|
TmdbCollectionSort.FIRST_AIR_DATE_DESC.value -> TmdbCollectionSort.RELEASE_DATE_DESC.value
|
||||||
|
TmdbCollectionSort.ORIGINAL.value -> TmdbCollectionSort.POPULAR_DESC.value
|
||||||
null, "" -> TmdbCollectionSort.POPULAR_DESC.value
|
null, "" -> TmdbCollectionSort.POPULAR_DESC.value
|
||||||
else -> sortBy
|
else -> sortBy
|
||||||
}
|
}
|
||||||
|
|
@ -398,6 +515,7 @@ object TmdbCollectionSourceResolver {
|
||||||
private fun tvSort(sortBy: String?): String =
|
private fun tvSort(sortBy: String?): String =
|
||||||
when (sortBy) {
|
when (sortBy) {
|
||||||
TmdbCollectionSort.RELEASE_DATE_DESC.value -> TmdbCollectionSort.FIRST_AIR_DATE_DESC.value
|
TmdbCollectionSort.RELEASE_DATE_DESC.value -> TmdbCollectionSort.FIRST_AIR_DATE_DESC.value
|
||||||
|
TmdbCollectionSort.ORIGINAL.value -> TmdbCollectionSort.POPULAR_DESC.value
|
||||||
null, "" -> TmdbCollectionSort.POPULAR_DESC.value
|
null, "" -> TmdbCollectionSort.POPULAR_DESC.value
|
||||||
else -> sortBy
|
else -> sortBy
|
||||||
}
|
}
|
||||||
|
|
@ -449,6 +567,12 @@ private data class TmdbNetworkResponse(
|
||||||
@SerialName("logo_path") val logoPath: String? = null,
|
@SerialName("logo_path") val logoPath: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
private data class TmdbPersonResponse(
|
||||||
|
val name: String? = null,
|
||||||
|
@SerialName("profile_path") val profilePath: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class TmdbCompanySearchResult(
|
data class TmdbCompanySearchResult(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
|
|
@ -496,6 +620,47 @@ private data class TmdbGenreItem(
|
||||||
val name: String,
|
val name: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
private data class TmdbPersonCreditsResponse(
|
||||||
|
val cast: List<TmdbPersonCreditCast>? = null,
|
||||||
|
val crew: List<TmdbPersonCreditCrew>? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
private data class TmdbPersonCreditCast(
|
||||||
|
val id: Int,
|
||||||
|
@SerialName("media_type") val mediaType: String? = null,
|
||||||
|
val title: String? = null,
|
||||||
|
val name: String? = null,
|
||||||
|
@SerialName("original_title") val originalTitle: String? = null,
|
||||||
|
@SerialName("original_name") val originalName: String? = null,
|
||||||
|
val overview: String? = null,
|
||||||
|
@SerialName("poster_path") val posterPath: String? = null,
|
||||||
|
@SerialName("backdrop_path") val backdropPath: String? = null,
|
||||||
|
@SerialName("release_date") val releaseDate: String? = null,
|
||||||
|
@SerialName("first_air_date") val firstAirDate: String? = null,
|
||||||
|
@SerialName("vote_average") val voteAverage: Double? = null,
|
||||||
|
val popularity: Double? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
private data class TmdbPersonCreditCrew(
|
||||||
|
val id: Int,
|
||||||
|
@SerialName("media_type") val mediaType: String? = null,
|
||||||
|
val title: String? = null,
|
||||||
|
val name: String? = null,
|
||||||
|
@SerialName("original_title") val originalTitle: String? = null,
|
||||||
|
@SerialName("original_name") val originalName: String? = null,
|
||||||
|
val overview: String? = null,
|
||||||
|
@SerialName("poster_path") val posterPath: String? = null,
|
||||||
|
@SerialName("backdrop_path") val backdropPath: String? = null,
|
||||||
|
@SerialName("release_date") val releaseDate: String? = null,
|
||||||
|
@SerialName("first_air_date") val firstAirDate: String? = null,
|
||||||
|
val job: String? = null,
|
||||||
|
@SerialName("vote_average") val voteAverage: Double? = null,
|
||||||
|
val popularity: Double? = null,
|
||||||
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
private data class TmdbListItem(
|
private data class TmdbListItem(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue