diff --git a/app/src/main/kotlin/com/arflix/tv/ui/components/ContentRatingChip.kt b/app/src/main/kotlin/com/arflix/tv/ui/components/ContentRatingChip.kt new file mode 100644 index 000000000..ba1ae0f8d --- /dev/null +++ b/app/src/main/kotlin/com/arflix/tv/ui/components/ContentRatingChip.kt @@ -0,0 +1,51 @@ +package com.arflix.tv.ui.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shadow +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.arflix.tv.ui.theme.ArflixTypography + +/** + * Age certification in a small rounded chip — same shape and padding as the "In Cinema" + * pill on the details screen, on a neutral translucent surface instead of a solid colour. + * Deliberately not colour coded by age: the age is only unambiguous for a few numeric + * rating systems, so a colour would have to be guessed for the letter based ones. + */ +@Composable +fun ContentRatingChip( + text: String, + fontWeight: FontWeight, + textColor: Color, + textShadow: Shadow, + fontSize: TextUnit = 13.sp, + modifier: Modifier = Modifier +) { + Box( + modifier = modifier + .background(Color.White.copy(alpha = 0.14f), RoundedCornerShape(6.dp)) + .padding(horizontal = 10.dp, vertical = 4.dp) + ) { + Text( + text = text, + style = ArflixTypography.caption.copy( + fontSize = fontSize, + fontWeight = fontWeight, + shadow = textShadow + ), + color = textColor, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } +} diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/details/DetailsScreen.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/details/DetailsScreen.kt index 4d5f0db97..d38d790ac 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/details/DetailsScreen.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/details/DetailsScreen.kt @@ -152,23 +152,24 @@ import com.arflix.tv.data.model.MediaType import com.arflix.tv.data.model.Review import com.arflix.tv.data.repository.MdbExternalRating import com.arflix.tv.network.OkHttpProvider -import com.arflix.tv.ui.components.EpisodeContextMenu -import com.arflix.tv.ui.components.KeepScreenOn -import com.arflix.tv.ui.components.SeasonContextMenu -import com.arflix.tv.ui.components.LoadingIndicator import com.arflix.tv.ui.components.AppTopBar import com.arflix.tv.ui.components.AppTopBarContentTopInset import com.arflix.tv.ui.components.CardLayoutMode +import com.arflix.tv.ui.components.ContentRatingChip +import com.arflix.tv.ui.components.EpisodeContextMenu +import com.arflix.tv.ui.components.KeepScreenOn +import com.arflix.tv.ui.components.LoadingIndicator import com.arflix.tv.ui.components.MediaCard import com.arflix.tv.ui.components.PersonModal import com.arflix.tv.ui.components.PosterCard -import com.arflix.tv.ui.components.resolveDetailsBackdropHeightDp -import com.arflix.tv.ui.components.rememberCatalogueRowLayoutMode +import com.arflix.tv.ui.components.SeasonContextMenu import com.arflix.tv.ui.components.SidebarItem import com.arflix.tv.ui.components.SkeletonDetailsPage import com.arflix.tv.ui.components.SkeletonEpisodeCard import com.arflix.tv.ui.components.StreamSelector import com.arflix.tv.ui.components.TrailerPlayer +import com.arflix.tv.ui.components.rememberCatalogueRowLayoutMode +import com.arflix.tv.ui.components.resolveDetailsBackdropHeightDp import androidx.activity.compose.BackHandler import androidx.compose.material.icons.filled.ChevronLeft import androidx.compose.material.icons.filled.ChevronRight @@ -1578,19 +1579,11 @@ private fun DetailsContent( ) } item.contentRating?.let { contentRating -> - if (ratingValue > 0f || displayDate.isNotEmpty() || hasDuration) { - MobileMetadataSeparator() - } - Text( + ContentRatingChip( text = contentRating, - style = ArflixTypography.caption.copy( - fontSize = 13.sp, - fontWeight = FontWeight.SemiBold, - shadow = textShadow - ), - color = Color.White.copy(alpha = 0.78f), - maxLines = 1, - overflow = TextOverflow.Ellipsis + fontWeight = FontWeight.SemiBold, + textColor = Color.White.copy(alpha = 0.78f), + textShadow = textShadow ) } } @@ -2237,16 +2230,11 @@ private fun DetailsContent( } item.contentRating?.let { contentRating -> - Text(text = "|", style = separatorStyle, color = Color.White.copy(alpha = 0.7f)) - Text( + ContentRatingChip( text = contentRating, - style = ArflixTypography.caption.copy( - fontSize = 13.sp, - fontWeight = FontWeight.Bold, - shadow = textShadow - ), - color = Color.White, - maxLines = 1 + fontWeight = FontWeight.Bold, + textColor = Color.White, + textShadow = textShadow ) } } diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/home/HomeScreen.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/home/HomeScreen.kt index 7fcce0869..08e00afa0 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/home/HomeScreen.kt @@ -136,12 +136,13 @@ import com.arflix.tv.data.model.MediaItem import com.arflix.tv.data.model.MediaType import com.arflix.tv.data.model.isPortrait import com.arflix.tv.network.OkHttpProvider +import com.arflix.tv.ui.components.AppTopBar +import com.arflix.tv.ui.components.AppTopBarContentTopInset +import com.arflix.tv.ui.components.CardLayoutMode +import com.arflix.tv.ui.components.ContentRatingChip import com.arflix.tv.ui.components.FeaturedMediaCard import com.arflix.tv.ui.components.MediaCard as ArvioMediaCard import com.arflix.tv.ui.components.TrailerPlayer -import com.arflix.tv.ui.components.CardLayoutMode -import com.arflix.tv.ui.components.AppTopBar -import com.arflix.tv.ui.components.AppTopBarContentTopInset import com.arflix.tv.data.model.SportsAddonCapabilities import com.arflix.tv.ui.components.SkeletonMobileHeroBanner import com.arflix.tv.ui.components.SkeletonPosterCard @@ -1655,6 +1656,15 @@ private fun HeroSection( maxLines = 1 ) } + + currentItem.contentRating?.let { contentRating -> + ContentRatingChip( + text = contentRating, + fontWeight = FontWeight.Bold, + textColor = Color.White, + textShadow = textShadow + ) + } } if (hasSecondaryMetadata) { diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/home/HomeViewModel.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/home/HomeViewModel.kt index 4585f1a6e..a4b67d91e 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/home/HomeViewModel.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/home/HomeViewModel.kt @@ -212,6 +212,7 @@ class HomeViewModel @Inject constructor( val tmdbRating: String, val budget: Long?, val overview: String, + val contentRating: String? = null, val primaryNetworkLogo: String? = null, val fullyLoaded: Boolean = false ) @@ -677,6 +678,7 @@ class HomeViewModel @Inject constructor( tmdbRating = snapshot.tmdbRating.ifEmpty { tmdbRating }, budget = snapshot.budget ?: budget, overview = snapshot.overview.ifBlank { overview }, + contentRating = snapshot.contentRating ?: contentRating, primaryNetworkLogo = snapshot.primaryNetworkLogo ?: primaryNetworkLogo ) } @@ -690,6 +692,7 @@ class HomeViewModel @Inject constructor( tmdbRating = cached.tmdbRating, budget = cached.budget, overview = cached.overview, + contentRating = cached.contentRating, primaryNetworkLogo = cached.primaryNetworkLogo, fullyLoaded = false ) @@ -759,6 +762,7 @@ class HomeViewModel @Inject constructor( tmdbRating = details?.tmdbRating.orEmpty(), budget = details?.budget, overview = resolvedOverview, + contentRating = details?.contentRating, primaryNetworkLogo = primaryNetworkLogo, fullyLoaded = true )