Make watched indicator more clear (#102)

Closes #89

Updates the watched indicator to be more clear. The checkmark is filled
in and there's a slight border to add contrast.

Also this PR makes the location of the watched indicator consistent
between card types and makes child counts always use a semi-transparent
black background.

## Before
<img width="451" height="260" alt="watched_before 2"
src="https://github.com/user-attachments/assets/734d1bb7-4604-4ef1-bb40-fc08403d58fe"
/>

## After
<img width="458" height="272" alt="watched_after 2"
src="https://github.com/user-attachments/assets/d39c4e8e-e483-4843-9083-33209302feb1"
/>
This commit is contained in:
damontecres 2025-10-28 20:47:17 -04:00 committed by GitHub
parent 06f2c1260d
commit d578dca0cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 70 additions and 42 deletions

View file

@ -11,8 +11,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -28,7 +26,6 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.tv.material3.Card import androidx.tv.material3.Card
import androidx.tv.material3.CardDefaults import androidx.tv.material3.CardDefaults
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
@ -100,14 +97,7 @@ fun BannerCard(
.padding(4.dp), .padding(4.dp),
) { ) {
if (played && (playPercent <= 0 || playPercent >= 100)) { if (played && (playPercent <= 0 || playPercent >= 100)) {
Icon( WatchedIcon(Modifier.size(24.dp))
imageVector = Icons.Default.CheckCircle,
contentDescription = null,
tint = MaterialTheme.colorScheme.border.copy(alpha = 1f),
modifier =
Modifier
.size(24.dp),
)
} }
if (cornerText.isNotNullOrBlank()) { if (cornerText.isNotNullOrBlank()) {
Box( Box(

View file

@ -5,15 +5,15 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -31,11 +31,11 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import coil3.compose.AsyncImage import coil3.compose.AsyncImage
import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.ui.AppColors
import com.github.damontecres.wholphin.ui.Cards import com.github.damontecres.wholphin.ui.Cards
import com.github.damontecres.wholphin.ui.FontAwesome import com.github.damontecres.wholphin.ui.FontAwesome
import com.github.damontecres.wholphin.ui.isNotNullOrBlank import com.github.damontecres.wholphin.ui.isNotNullOrBlank
@ -125,35 +125,34 @@ fun ItemCardImage(
fontFamily = FontAwesome, fontFamily = FontAwesome,
) )
} }
if (watched && (watchedPercent == null || watchedPercent <= 0.0 || watchedPercent >= 100.0)) { Row(
Icon( horizontalArrangement = Arrangement.spacedBy(4.dp),
imageVector = Icons.Default.CheckCircle, verticalAlignment = Alignment.CenterVertically,
contentDescription = null, modifier =
tint = MaterialTheme.colorScheme.border.copy(alpha = 1f), Modifier
modifier = .padding(4.dp)
Modifier .align(Alignment.TopEnd),
.align(Alignment.TopEnd) ) {
.size(36.dp) if (watched && (watchedPercent == null || watchedPercent <= 0.0 || watchedPercent >= 100.0)) {
.padding(4.dp), WatchedIcon(Modifier.size(24.dp))
) }
} if (unwatchedCount > 0) {
if (unwatchedCount > 0) { Box(
Box( modifier =
modifier = Modifier
Modifier .background(
.padding(4.dp) AppColors.TransparentBlack50,
.background( shape = RoundedCornerShape(25),
MaterialTheme.colorScheme.border, ),
shape = RoundedCornerShape(25), ) {
).align(Alignment.TopEnd), Text(
) { text = unwatchedCount.toString(),
Text( color = MaterialTheme.colorScheme.onSurface,
text = unwatchedCount.toString(), style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodyMedium,
// fontSize = 16.sp, // fontSize = 16.sp,
modifier = Modifier.padding(4.dp), modifier = Modifier.padding(4.dp),
) )
}
} }
} }

View file

@ -0,0 +1,39 @@
package com.github.damontecres.wholphin.ui.cards
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.tv.material3.Icon
import androidx.tv.material3.MaterialTheme
import com.github.damontecres.wholphin.ui.PreviewTvSpec
import com.github.damontecres.wholphin.ui.theme.WholphinTheme
@Composable
fun WatchedIcon(modifier: Modifier = Modifier) {
Icon(
imageVector = Icons.Default.Check,
contentDescription = null,
tint = Color.White,
modifier =
modifier
.background(MaterialTheme.colorScheme.border.copy(alpha = 1f), shape = CircleShape)
.border(.5.dp, Color.Black, CircleShape)
.padding(2.dp),
)
}
@PreviewTvSpec
@Composable
private fun WatchedIconPreview() {
WholphinTheme {
WatchedIcon(Modifier.size(64.dp))
}
}