From 0870e8aee4f44d6ed5fdaa9c9c075f30e8d04b5e Mon Sep 17 00:00:00 2001 From: Barnabas Balogh Date: Mon, 6 Apr 2026 19:38:27 +0200 Subject: [PATCH] Remove status and progress overlays from TV hero section Removes eyebrow text, watched status chips, and progress bars from the focused hero component on the TV home screen. The underlying model and UI are simplified to display only the title and basic metadata. --- .../purefin/tv/home/ui/TvFocusedHeroModel.kt | 36 +++------- .../purefin/tv/home/ui/TvFocusedItemHero.kt | 65 ------------------- 2 files changed, 9 insertions(+), 92 deletions(-) diff --git a/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvFocusedHeroModel.kt b/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvFocusedHeroModel.kt index 6860b22a..014e8db0 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvFocusedHeroModel.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvFocusedHeroModel.kt @@ -16,12 +16,8 @@ import kotlin.math.roundToInt internal data class TvFocusedHeroModel( val id: UUID, val backdropImageUrl: String, - val eyebrowText: String, val title: String, val metadata: List, - val watchedText: String?, - val progressFraction: Float?, - val progressLabel: String?, ) { val metadataText: String? get() = metadata.takeIf { it.isNotEmpty() }?.joinToString(" • ") @@ -30,16 +26,16 @@ internal data class TvFocusedHeroModel( internal fun FocusableItem.toTvFocusedHeroModel(): TvFocusedHeroModel { return when (this) { is ContinueWatchingItem -> when (type) { - BaseItemKind.MOVIE -> movie!!.toTvFocusedHeroModel(sourceLabel = "Continue watching") - BaseItemKind.EPISODE -> episode!!.toTvFocusedHeroModel(sourceLabel = "Continue watching") + BaseItemKind.MOVIE -> movie!!.toTvFocusedHeroModel() + BaseItemKind.EPISODE -> episode!!.toTvFocusedHeroModel() else -> unsupportedType(type) } - is NextUpItem -> episode.toTvFocusedHeroModel(sourceLabel = "Next up") + is NextUpItem -> episode.toTvFocusedHeroModel() is PosterItem -> when (type) { - BaseItemKind.MOVIE -> movie!!.toTvFocusedHeroModel(sourceLabel = "Movie") - BaseItemKind.EPISODE -> episode!!.toTvFocusedHeroModel(sourceLabel = "Episode") - BaseItemKind.SERIES -> series!!.toTvFocusedHeroModel(sourceLabel = "Series") + BaseItemKind.MOVIE -> movie!!.toTvFocusedHeroModel() + BaseItemKind.EPISODE -> episode!!.toTvFocusedHeroModel() + BaseItemKind.SERIES -> series!!.toTvFocusedHeroModel() else -> unsupportedType(type) } } @@ -50,32 +46,25 @@ internal fun backdropImageUrl(imageUrlPrefix: String?, fallbackImageUrl: String) return backdropImageUrl.ifBlank { fallbackImageUrl } } -private fun Movie.toTvFocusedHeroModel(sourceLabel: String): TvFocusedHeroModel { - val progressFraction = progressFraction(progress) +private fun Movie.toTvFocusedHeroModel(): TvFocusedHeroModel { return TvFocusedHeroModel( id = id, backdropImageUrl = backdropImageUrl( imageUrlPrefix = imageUrlPrefix, fallbackImageUrl = JellyfinImageHelper.finishImageUrl(imageUrlPrefix, ImageType.PRIMARY) ), - eyebrowText = sourceLabel, title = title, metadata = listOf(year, rating, runtime, format).compactMetadata(), - watchedText = "Watched".takeIf { watched }, - progressFraction = progressFraction.takeIf { !watched && it != null }, - progressLabel = progressLabel(progressFraction).takeIf { !watched && progressFraction != null }, ) } -private fun Episode.toTvFocusedHeroModel(sourceLabel: String): TvFocusedHeroModel { - val progressFraction = progressFraction(progress) +private fun Episode.toTvFocusedHeroModel(): TvFocusedHeroModel { return TvFocusedHeroModel( id = id, backdropImageUrl = backdropImageUrl( imageUrlPrefix = imageUrlPrefix, fallbackImageUrl = JellyfinImageHelper.finishImageUrl(imageUrlPrefix, ImageType.PRIMARY) ), - eyebrowText = sourceLabel, title = title, metadata = listOf( "Episode $index", @@ -84,13 +73,10 @@ private fun Episode.toTvFocusedHeroModel(sourceLabel: String): TvFocusedHeroMode rating, format ).compactMetadata(), - watchedText = "Watched".takeIf { watched }, - progressFraction = progressFraction.takeIf { !watched && it != null }, - progressLabel = progressLabel(progressFraction).takeIf { !watched && progressFraction != null }, ) } -private fun Series.toTvFocusedHeroModel(sourceLabel: String): TvFocusedHeroModel { +private fun Series.toTvFocusedHeroModel(): TvFocusedHeroModel { val unwatchedText = if (unwatchedEpisodeCount > 0) { "$unwatchedEpisodeCount unwatched" } else { @@ -103,12 +89,8 @@ private fun Series.toTvFocusedHeroModel(sourceLabel: String): TvFocusedHeroModel imageUrlPrefix = imageUrlPrefix, fallbackImageUrl = JellyfinImageHelper.finishImageUrl(imageUrlPrefix, ImageType.PRIMARY) ), - eyebrowText = sourceLabel, title = name, metadata = listOf(year, seasonLabel(seasonCount), unwatchedText).compactMetadata(), - watchedText = null, - progressFraction = null, - progressLabel = null, ) } diff --git a/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvFocusedItemHero.kt b/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvFocusedItemHero.kt index 3ae02002..db75345d 100644 --- a/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvFocusedItemHero.kt +++ b/app-tv/src/main/java/hu/bbara/purefin/tv/home/ui/TvFocusedItemHero.kt @@ -3,39 +3,29 @@ package hu.bbara.purefin.tv.home.ui import androidx.compose.animation.Crossfade import androidx.compose.animation.core.tween import androidx.compose.foundation.background -import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import hu.bbara.purefin.common.ui.components.MediaProgressBar import hu.bbara.purefin.common.ui.components.PurefinAsyncImage internal const val TvHomeHeroTitleTag = "tv-home-hero-title" -internal const val TvHomeHeroStatusTag = "tv-home-hero-status" internal const val TvHomeHeroProgressLabelTag = "tv-home-hero-progress-label" private const val TvHomeHeroAnimationMillis = 180 @@ -107,13 +97,6 @@ internal fun TvFocusedItemHero( verticalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.widthIn(max = 720.dp) ) { - Text( - text = hero.eyebrowText.uppercase(), - color = scheme.primary, - fontSize = 10.sp, - letterSpacing = 1.2.sp, - fontWeight = FontWeight.Bold - ) Text( text = hero.title, color = scheme.onBackground, @@ -134,54 +117,6 @@ internal fun TvFocusedItemHero( overflow = TextOverflow.Ellipsis ) } - if (hero.watchedText != null || hero.progressFraction != null) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(10.dp), - modifier = Modifier - .clip(RoundedCornerShape(22.dp)) - .background(scheme.surfaceContainerHigh.copy(alpha = 0.92f)) - .border(1.dp, scheme.outlineVariant.copy(alpha = 0.6f), RoundedCornerShape(22.dp)) - .padding(horizontal = 12.dp, vertical = 10.dp) - ) { - hero.watchedText?.let { watchedText -> - TvHomeMetaChip( - text = watchedText, - highlighted = true, - modifier = Modifier.testTag(TvHomeHeroStatusTag) - ) - } - if (hero.progressFraction != null && hero.progressLabel != null) { - Column( - verticalArrangement = Arrangement.spacedBy(4.dp), - modifier = Modifier.width(188.dp) - ) { - Text( - text = "Progress", - color = scheme.onSurfaceVariant.copy(alpha = 0.85f), - fontSize = 10.sp, - fontWeight = FontWeight.Medium - ) - MediaProgressBar( - progress = hero.progressFraction, - foregroundColor = scheme.primary, - backgroundColor = scheme.surfaceVariant, - contentPadding = PaddingValues(0.dp), - barHeight = 6.dp, - modifier = Modifier - ) - } - Text( - text = hero.progressLabel, - color = scheme.onBackground, - fontSize = 14.sp, - fontWeight = FontWeight.SemiBold, - textAlign = TextAlign.End, - modifier = Modifier.testTag(TvHomeHeroProgressLabelTag) - ) - } - } - } } } }