show only an in-flight ring on the library surfaces

A finished download no longer draws anything on album covers, artist rows or
playlist rows: the badge is the progress ring alone, so a fully downloaded tile
looks like any other. The ring takes the theme's primary for the arc over a
theme track, with the one soft shadow, instead of the white glyph and its
outline.
This commit is contained in:
austinried
2026-10-04 00:30:03 +00:00
parent dac56a7fcb
commit b324cbb6b9
2 changed files with 24 additions and 60 deletions
@@ -1,35 +1,27 @@
package com.subtracks.ui.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.DownloadDone
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import com.subtracks.data.model.ListDownloadStatus
const val DOWNLOADED_INDICATOR_TAG = "Downloaded"
const val DOWNLOADING_INDICATOR_TAG = "Downloading"
enum class DownloadIndicator { Hidden, InProgress, Complete }
enum class DownloadIndicator { Hidden, InProgress }
fun ListDownloadStatus.indicator(): DownloadIndicator =
when {
total == 0L -> DownloadIndicator.Hidden
complete -> DownloadIndicator.Complete
downloading > 0 -> DownloadIndicator.InProgress
else -> DownloadIndicator.Hidden
}
if (total > 0 && downloading > 0) DownloadIndicator.InProgress else DownloadIndicator.Hidden
@Composable
fun ListDownloadIndicator(
@@ -37,50 +29,22 @@ fun ListDownloadIndicator(
modifier: Modifier = Modifier,
) {
val current = status ?: return
val kind = current.indicator()
if (kind == DownloadIndicator.Hidden) return
Box(modifier = modifier.size(26.dp), contentAlignment = Alignment.Center) {
when (kind) {
DownloadIndicator.Complete -> {
Icon(
imageVector = Icons.Rounded.DownloadDone,
contentDescription = null,
tint = Color.Black.copy(alpha = 0.5f),
modifier = Modifier.size(22.dp).blur(4.dp).offset(y = 1.dp),
)
Icon(
imageVector = Icons.Rounded.DownloadDone,
contentDescription = null,
tint = Color.Black.copy(alpha = 0.85f),
modifier =
Modifier
.size(22.dp)
.graphicsLayer {
scaleX = 1.18f
scaleY = 1.18f
}.blur(1.dp),
)
Icon(
imageVector = Icons.Rounded.DownloadDone,
contentDescription = DOWNLOADED_INDICATOR_TAG,
tint = Color.White,
modifier = Modifier.size(22.dp),
)
}
DownloadIndicator.InProgress -> {
CircularProgressIndicator(
progress = { current.downloaded.toFloat() / current.total },
color = Color.White,
trackColor = Color.Black.copy(alpha = 0.45f),
strokeWidth = 2.5.dp,
modifier = Modifier.size(20.dp).semantics { contentDescription = DOWNLOADING_INDICATOR_TAG },
)
}
DownloadIndicator.Hidden -> {
Unit
}
}
if (current.indicator() == DownloadIndicator.Hidden) return
val progress = { current.downloaded.toFloat() / current.total }
Box(modifier = modifier.size(20.dp), contentAlignment = Alignment.Center) {
CircularProgressIndicator(
progress = progress,
color = Color.Black.copy(alpha = 0.5f),
trackColor = Color.Transparent,
strokeWidth = 2.5.dp,
modifier = Modifier.fillMaxSize().blur(2.dp).offset(y = 1.dp),
)
CircularProgressIndicator(
progress = progress,
color = MaterialTheme.colorScheme.primary,
trackColor = MaterialTheme.colorScheme.surfaceContainerHighest,
strokeWidth = 2.5.dp,
modifier = Modifier.fillMaxSize().semantics { contentDescription = DOWNLOADING_INDICATOR_TAG },
)
}
}
@@ -11,7 +11,7 @@ class DownloadIndicatorTest {
}
@Test
fun aListWithNothingStartedButNoSongsShowsNothing() {
fun aPopulatedButUnstartedListShowsNothing() {
assertEquals(DownloadIndicator.Hidden, ListDownloadStatus(total = 4).indicator())
}
@@ -31,7 +31,7 @@ class DownloadIndicatorTest {
}
@Test
fun aFullyDownloadedListShowsDone() {
assertEquals(DownloadIndicator.Complete, ListDownloadStatus(total = 4, downloaded = 4).indicator())
fun aFullyDownloadedListShowsNothing() {
assertEquals(DownloadIndicator.Hidden, ListDownloadStatus(total = 4, downloaded = 4).indicator())
}
}