From aa954ffc3e07436ccd18957934ede6b873dbad78 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Sun, 27 Sep 2026 12:06:08 +0000 Subject: [PATCH] desaturate the playing row's art behind the primary indicator Back to the primary border and glyph, and drop the playing cover's saturation so the accent reads against its own artwork. --- .../main/kotlin/com/subtracks/ui/components/Components.kt | 8 ++++++++ .../main/kotlin/com/subtracks/ui/library/SongsContent.kt | 8 ++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/subtracks/ui/components/Components.kt b/app/src/main/kotlin/com/subtracks/ui/components/Components.kt index 7147d781..b0196298 100644 --- a/app/src/main/kotlin/com/subtracks/ui/components/Components.kt +++ b/app/src/main/kotlin/com/subtracks/ui/components/Components.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.draw.shadow import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.FilterQuality import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalDensity @@ -70,6 +71,7 @@ fun CoverArt( showPlaceholder: Boolean = true, square: Boolean = true, elevation: Dp = 0.dp, + colorFilter: ColorFilter? = null, ) { val context = LocalPlatformContext.current var failed by remember(ref, thumbnailRef) { mutableStateOf(false) } @@ -93,6 +95,7 @@ fun CoverArt( onThumbnailLoaded = { thumbnailLoaded = true }, onThumbnailRatio = { thumbnailRatio = it }, contentScale = ContentScale.Crop, + colorFilter = colorFilter, ) { if (ref != null) { AsyncImage( @@ -100,6 +103,7 @@ fun CoverArt( contentDescription = null, contentScale = ContentScale.Crop, filterQuality = FilterQuality.High, + colorFilter = colorFilter, onSuccess = { success -> success.painter.intrinsicSize .ratioOrNull() @@ -154,12 +158,14 @@ fun CoverArt( onThumbnailLoaded = { thumbnailLoaded = true }, onThumbnailRatio = { thumbnailRatio = it }, contentScale = ContentScale.Fit, + colorFilter = colorFilter, ) { if (ref != null) { Image( painter = painter, contentDescription = null, contentScale = ContentScale.Fit, + colorFilter = colorFilter, modifier = Modifier.fillMaxSize(), ) } @@ -180,6 +186,7 @@ private fun BoxScope.CoverArtContent( onThumbnailLoaded: () -> Unit, onThumbnailRatio: (Float) -> Unit, contentScale: ContentScale, + colorFilter: ColorFilter?, main: @Composable () -> Unit, ) { val context = LocalPlatformContext.current @@ -196,6 +203,7 @@ private fun BoxScope.CoverArtContent( model = remember(thumbnailRef) { imageRequest(context, thumbnailRef, crossfade = false) }, contentDescription = null, contentScale = contentScale, + colorFilter = colorFilter, onSuccess = { success -> onThumbnailLoaded() success.painter.intrinsicSize diff --git a/app/src/main/kotlin/com/subtracks/ui/library/SongsContent.kt b/app/src/main/kotlin/com/subtracks/ui/library/SongsContent.kt index 95548ff9..3daa89d3 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/SongsContent.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/SongsContent.kt @@ -30,6 +30,8 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.RoundRect import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.ColorMatrix import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.PathOperation import androidx.compose.ui.graphics.asAndroidPath @@ -66,6 +68,7 @@ private val PLAY_SHADOW_RADIUS = 3.dp private val PLAY_SHADOW = Color.Black.copy(alpha = 0.6f) private val INNER_SHADOW_RADIUS = 8.dp private val INNER_SHADOW = Color.Black.copy(alpha = 0.85f) +private val DESATURATE = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0.45f) }) private val PLAY_ARROW = Icons.Rounded.PlayArrow private val PLAY_ARROW_PATH: Path by lazy { buildVectorPath(PLAY_ARROW) } @@ -168,13 +171,14 @@ private fun CoverArtCell( ref = ref, name = name, modifier = Modifier.size(48.dp).clip(shape), + colorFilter = if (isPlaying) DESATURATE else null, ) if (isPlaying) { Box(Modifier.matchParentSize().drawBehind { drawInnerShadow() }) Box( Modifier .matchParentSize() - .border(1.5.dp, Color.White, shape), + .border(1.5.dp, MaterialTheme.colorScheme.primary, shape), ) PlayIndicator( shadow = true, @@ -216,7 +220,7 @@ private fun PlayIndicator( shadow: Boolean, modifier: Modifier = Modifier, ) { - val tint = Color.White + val tint = MaterialTheme.colorScheme.primary if (shadow) { val radius = with(LocalDensity.current) { PLAY_SHADOW_RADIUS.toPx() } Canvas(modifier.semantics { contentDescription = "Playing" }) {