mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-17 07:21:58 +00:00
Merge branch 'cmp-rewrite' of https://github.com/NuvioMedia/NuvioMobile into cmp-rewrite
This commit is contained in:
commit
efb23c2102
7 changed files with 96 additions and 3 deletions
|
|
@ -248,6 +248,19 @@
|
|||
<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_recent">Recent</string>
|
||||
<string name="collections_editor_tmdb_sort_vote_count">Most Voted</string>
|
||||
<string name="collections_editor_tmdb_watch_region">Watch region</string>
|
||||
<string name="collections_editor_tmdb_watch_region_helper">ISO 3166-1 country code where the title is available. Example: US, GB.</string>
|
||||
<string name="collections_editor_tmdb_quick_watch_regions">Quick watch regions</string>
|
||||
<string name="collections_editor_tmdb_watch_providers">Watch provider IDs</string>
|
||||
<string name="collections_editor_tmdb_watch_providers_helper">Use TMDB watch provider IDs. Separate multiple with commas for AND, or pipes for OR.</string>
|
||||
<string name="collections_editor_tmdb_watch_providers_placeholder">8|337|350</string>
|
||||
<string name="collections_editor_tmdb_quick_watch_providers">Quick watch providers</string>
|
||||
<string name="collections_editor_tmdb_watch_provider_netflix">Netflix</string>
|
||||
<string name="collections_editor_tmdb_watch_provider_prime">Prime Video</string>
|
||||
<string name="collections_editor_tmdb_watch_provider_disney">Disney+</string>
|
||||
<string name="collections_editor_tmdb_watch_provider_apple">Apple TV+</string>
|
||||
<string name="collections_editor_tmdb_watch_provider_hulu">Hulu</string>
|
||||
<string name="collections_editor_tmdb_subtitle_list">TMDB List</string>
|
||||
<string name="collections_editor_tmdb_subtitle_movie_collection">TMDB Movie Collection</string>
|
||||
<string name="collections_editor_tmdb_subtitle_production">Production</string>
|
||||
|
|
|
|||
|
|
@ -471,6 +471,11 @@ fun App() {
|
|||
AuthScreen(modifier = Modifier.fillMaxSize())
|
||||
}
|
||||
AppGateScreen.ProfileSelection.name -> {
|
||||
PlatformBackHandler(enabled = gateScreen == AppGateScreen.ProfileSelection.name) {
|
||||
if (!autoSkipProfileSelection) {
|
||||
gateScreen = AppGateScreen.Main.name
|
||||
}
|
||||
}
|
||||
ProfileSelectionScreen(
|
||||
onProfileSelected = { profile ->
|
||||
ProfileRepository.selectProfile(profile.profileIndex)
|
||||
|
|
@ -493,6 +498,9 @@ fun App() {
|
|||
)
|
||||
}
|
||||
AppGateScreen.ProfileEdit.name -> {
|
||||
PlatformBackHandler(enabled = gateScreen == AppGateScreen.ProfileEdit.name) {
|
||||
gateScreen = AppGateScreen.ProfileSelection.name
|
||||
}
|
||||
ProfileEditScreen(
|
||||
profile = editingProfile,
|
||||
onBack = { gateScreen = AppGateScreen.ProfileSelection.name },
|
||||
|
|
|
|||
|
|
@ -1125,6 +1125,7 @@ private fun TmdbSourcePickerScreen(
|
|||
val sorts = listOf(
|
||||
TmdbCollectionSort.POPULAR_DESC,
|
||||
TmdbCollectionSort.VOTE_AVERAGE_DESC,
|
||||
TmdbCollectionSort.VOTE_COUNT_DESC,
|
||||
if (state.tmdbMediaType == TmdbCollectionMediaType.TV && !state.tmdbMediaBoth) {
|
||||
TmdbCollectionSort.FIRST_AIR_DATE_DESC
|
||||
} else {
|
||||
|
|
@ -1353,6 +1354,54 @@ private fun TmdbSourcePickerScreen(
|
|||
}
|
||||
},
|
||||
)
|
||||
TmdbQuickChips(
|
||||
label = stringResource(Res.string.collections_editor_tmdb_quick_watch_providers),
|
||||
chips = listOf(
|
||||
stringResource(Res.string.collections_editor_tmdb_watch_provider_netflix) to "8",
|
||||
stringResource(Res.string.collections_editor_tmdb_watch_provider_prime) to "119",
|
||||
stringResource(Res.string.collections_editor_tmdb_watch_provider_disney) to "337",
|
||||
stringResource(Res.string.collections_editor_tmdb_watch_provider_apple) to "350",
|
||||
stringResource(Res.string.collections_editor_tmdb_watch_provider_hulu) to "15",
|
||||
),
|
||||
onSelect = { value ->
|
||||
CollectionEditorRepository.updateTmdbFilters { it.copy(withWatchProviders = value) }
|
||||
},
|
||||
)
|
||||
TmdbFilterField(
|
||||
label = stringResource(Res.string.collections_editor_tmdb_watch_providers),
|
||||
helper = stringResource(Res.string.collections_editor_tmdb_watch_providers_helper),
|
||||
value = state.tmdbFilters.withWatchProviders.orEmpty(),
|
||||
placeholder = stringResource(Res.string.collections_editor_tmdb_watch_providers_placeholder),
|
||||
onValueChange = { value ->
|
||||
CollectionEditorRepository.updateTmdbFilters {
|
||||
it.copy(withWatchProviders = value.ifBlank { null })
|
||||
}
|
||||
},
|
||||
)
|
||||
TmdbQuickChips(
|
||||
label = stringResource(Res.string.collections_editor_tmdb_quick_watch_regions),
|
||||
chips = listOf(
|
||||
stringResource(Res.string.collections_editor_tmdb_country_us) to "US",
|
||||
stringResource(Res.string.collections_editor_tmdb_country_uk) to "GB",
|
||||
"Canada" to "CA",
|
||||
"Australia" to "AU",
|
||||
"Germany" to "DE",
|
||||
),
|
||||
onSelect = { value ->
|
||||
CollectionEditorRepository.updateTmdbFilters { it.copy(watchRegion = value) }
|
||||
},
|
||||
)
|
||||
TmdbFilterField(
|
||||
label = stringResource(Res.string.collections_editor_tmdb_watch_region),
|
||||
helper = stringResource(Res.string.collections_editor_tmdb_watch_region_helper),
|
||||
value = state.tmdbFilters.watchRegion.orEmpty(),
|
||||
placeholder = "US",
|
||||
onValueChange = { value ->
|
||||
CollectionEditorRepository.updateTmdbFilters {
|
||||
it.copy(watchRegion = value.ifBlank { null })
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2255,6 +2304,7 @@ private fun tmdbSortLabel(sort: TmdbCollectionSort): String =
|
|||
TmdbCollectionSort.ORIGINAL -> stringResource(Res.string.collections_editor_tmdb_sort_original)
|
||||
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_COUNT_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_vote_count)
|
||||
TmdbCollectionSort.RELEASE_DATE_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_recent)
|
||||
TmdbCollectionSort.FIRST_AIR_DATE_DESC -> stringResource(Res.string.collections_editor_tmdb_sort_recent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ enum class TmdbCollectionSort(val value: String) {
|
|||
ORIGINAL("original"),
|
||||
POPULAR_DESC("popularity.desc"),
|
||||
VOTE_AVERAGE_DESC("vote_average.desc"),
|
||||
VOTE_COUNT_DESC("vote_count.desc"),
|
||||
RELEASE_DATE_DESC("primary_release_date.desc"),
|
||||
FIRST_AIR_DATE_DESC("first_air_date.desc"),
|
||||
}
|
||||
|
|
@ -149,6 +150,8 @@ data class TmdbCollectionFilters(
|
|||
val withCompanies: String? = null,
|
||||
val withNetworks: String? = null,
|
||||
val year: Int? = null,
|
||||
val watchRegion: String? = null,
|
||||
val withWatchProviders: String? = null,
|
||||
)
|
||||
|
||||
data class TmdbSourceImportMetadata(
|
||||
|
|
|
|||
|
|
@ -325,6 +325,11 @@ object TmdbCollectionSourceResolver {
|
|||
putIfNotBlank("with_original_language", filters.withOriginalLanguage)
|
||||
putIfNotBlank("with_origin_country", filters.withOriginCountry)
|
||||
putIfNotBlank("with_keywords", filters.withKeywords)
|
||||
if (!filters.withWatchProviders.isNullOrBlank()) {
|
||||
put("with_watch_providers", filters.withWatchProviders)
|
||||
put("watch_region", filters.watchRegion?.takeIf { it.isNotBlank() } ?: "US")
|
||||
put("with_watch_monetization_types", "flatrate|free|ads|rent|buy")
|
||||
}
|
||||
putIfNotBlank("year", filters.year?.takeIf { mediaType == TmdbCollectionMediaType.MOVIE }?.toString())
|
||||
putIfNotBlank("first_air_date_year", filters.year?.takeIf { mediaType == TmdbCollectionMediaType.TV }?.toString())
|
||||
putIfNotBlank(
|
||||
|
|
@ -358,6 +363,7 @@ object TmdbCollectionSourceResolver {
|
|||
compareByDescending<MetaPreview> { it.imdbRating?.toDoubleOrNull() ?: -1.0 }
|
||||
.thenByDescending { it.rawReleaseDate ?: it.releaseInfo.orEmpty() },
|
||||
)
|
||||
TmdbCollectionSort.VOTE_COUNT_DESC.value -> sortedByDescending { it.voteCount ?: 0 }
|
||||
TmdbCollectionSort.RELEASE_DATE_DESC.value,
|
||||
TmdbCollectionSort.FIRST_AIR_DATE_DESC.value -> sortedByDescending { it.rawReleaseDate ?: it.releaseInfo.orEmpty() }
|
||||
TmdbCollectionSort.POPULAR_DESC.value,
|
||||
|
|
@ -395,6 +401,7 @@ object TmdbCollectionSourceResolver {
|
|||
TmdbCollectionMediaType.TV -> firstAirDate
|
||||
},
|
||||
popularity = popularity,
|
||||
voteCount = voteCount,
|
||||
imdbRating = voteAverage?.let { ((it * 10).roundToInt() / 10.0).toString() },
|
||||
)
|
||||
}
|
||||
|
|
@ -412,6 +419,7 @@ object TmdbCollectionSourceResolver {
|
|||
releaseInfo = releaseDate?.take(4),
|
||||
rawReleaseDate = releaseDate,
|
||||
popularity = popularity,
|
||||
voteCount = voteCount,
|
||||
imdbRating = voteAverage?.let { ((it * 10).roundToInt() / 10.0).toString() },
|
||||
)
|
||||
}
|
||||
|
|
@ -440,6 +448,7 @@ object TmdbCollectionSourceResolver {
|
|||
TmdbCollectionMediaType.TV -> firstAirDate
|
||||
},
|
||||
popularity = popularity,
|
||||
voteCount = voteCount,
|
||||
imdbRating = voteAverage?.let { ((it * 10).roundToInt() / 10.0).toString() },
|
||||
)
|
||||
}
|
||||
|
|
@ -468,6 +477,7 @@ object TmdbCollectionSourceResolver {
|
|||
TmdbCollectionMediaType.TV -> firstAirDate
|
||||
},
|
||||
popularity = popularity,
|
||||
voteCount = voteCount,
|
||||
imdbRating = voteAverage?.let { ((it * 10).roundToInt() / 10.0).toString() },
|
||||
)
|
||||
}
|
||||
|
|
@ -508,6 +518,7 @@ object TmdbCollectionSourceResolver {
|
|||
when (sortBy) {
|
||||
TmdbCollectionSort.FIRST_AIR_DATE_DESC.value -> TmdbCollectionSort.RELEASE_DATE_DESC.value
|
||||
TmdbCollectionSort.ORIGINAL.value -> TmdbCollectionSort.POPULAR_DESC.value
|
||||
TmdbCollectionSort.VOTE_COUNT_DESC.value -> TmdbCollectionSort.VOTE_COUNT_DESC.value
|
||||
null, "" -> TmdbCollectionSort.POPULAR_DESC.value
|
||||
else -> sortBy
|
||||
}
|
||||
|
|
@ -516,6 +527,7 @@ object TmdbCollectionSourceResolver {
|
|||
when (sortBy) {
|
||||
TmdbCollectionSort.RELEASE_DATE_DESC.value -> TmdbCollectionSort.FIRST_AIR_DATE_DESC.value
|
||||
TmdbCollectionSort.ORIGINAL.value -> TmdbCollectionSort.POPULAR_DESC.value
|
||||
TmdbCollectionSort.VOTE_COUNT_DESC.value -> TmdbCollectionSort.VOTE_COUNT_DESC.value
|
||||
null, "" -> TmdbCollectionSort.POPULAR_DESC.value
|
||||
else -> sortBy
|
||||
}
|
||||
|
|
@ -640,6 +652,7 @@ private data class TmdbPersonCreditCast(
|
|||
@SerialName("release_date") val releaseDate: String? = null,
|
||||
@SerialName("first_air_date") val firstAirDate: String? = null,
|
||||
@SerialName("vote_average") val voteAverage: Double? = null,
|
||||
@SerialName("vote_count") val voteCount: Int? = null,
|
||||
val popularity: Double? = null,
|
||||
)
|
||||
|
||||
|
|
@ -658,6 +671,7 @@ private data class TmdbPersonCreditCrew(
|
|||
@SerialName("first_air_date") val firstAirDate: String? = null,
|
||||
val job: String? = null,
|
||||
@SerialName("vote_average") val voteAverage: Double? = null,
|
||||
@SerialName("vote_count") val voteCount: Int? = null,
|
||||
val popularity: Double? = null,
|
||||
)
|
||||
|
||||
|
|
@ -675,6 +689,7 @@ private data class TmdbListItem(
|
|||
@SerialName("release_date") val releaseDate: String? = null,
|
||||
@SerialName("first_air_date") val firstAirDate: String? = null,
|
||||
@SerialName("vote_average") val voteAverage: Double? = null,
|
||||
@SerialName("vote_count") val voteCount: Int? = null,
|
||||
val popularity: Double? = null,
|
||||
)
|
||||
|
||||
|
|
@ -687,5 +702,6 @@ private data class TmdbCollectionPart(
|
|||
@SerialName("backdrop_path") val backdropPath: String? = null,
|
||||
@SerialName("release_date") val releaseDate: String? = null,
|
||||
@SerialName("vote_average") val voteAverage: Double? = null,
|
||||
@SerialName("vote_count") val voteCount: Int? = null,
|
||||
val popularity: Double? = null,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -80,10 +80,12 @@ fun DetailMetaInfo(
|
|||
val runtimeText = formatRuntimeForDisplay(meta.runtime)
|
||||
val ageBadge = meta.ageRating?.trim()?.takeIf { it.isNotBlank() }
|
||||
val hasMdbImdbRating = meta.externalRatings.any { it.source == PROVIDER_IMDB }
|
||||
val validImdbRating = meta.imdbRating
|
||||
?.takeIf { raw -> raw.toDoubleOrNull()?.let { it > 0.0 } == true }
|
||||
val hasMetaRow = releaseLine != null ||
|
||||
runtimeText != null ||
|
||||
ageBadge != null ||
|
||||
(meta.imdbRating != null && !hasMdbImdbRating)
|
||||
(validImdbRating != null && !hasMdbImdbRating)
|
||||
if (hasMetaRow) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
|
|
@ -108,7 +110,7 @@ fun DetailMetaInfo(
|
|||
ageBadge?.let { badge ->
|
||||
DetailHeroMetaBadge(text = badge)
|
||||
}
|
||||
if (meta.imdbRating != null && !hasMdbImdbRating) {
|
||||
if (validImdbRating != null && !hasMdbImdbRating) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
|
|
@ -129,7 +131,7 @@ fun DetailMetaInfo(
|
|||
}
|
||||
Spacer(modifier = Modifier.width(5.dp))
|
||||
Text(
|
||||
text = meta.imdbRating,
|
||||
text = validImdbRating,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = ImdbYellow,
|
||||
fontWeight = FontWeight.Bold,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ data class MetaPreview(
|
|||
val releaseInfo: String? = null,
|
||||
val rawReleaseDate: String? = null,
|
||||
val popularity: Double? = null,
|
||||
val voteCount: Int? = null,
|
||||
val imdbRating: String? = null,
|
||||
val genres: List<String> = emptyList(),
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue