diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/ChapterDownloadIndicator.kt b/app/src/main/java/eu/kanade/presentation/manga/components/ChapterDownloadIndicator.kt index 2b4ecd1b5..d48a5d848 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/ChapterDownloadIndicator.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/ChapterDownloadIndicator.kt @@ -5,12 +5,12 @@ import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.CircularWavyProgressIndicator import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.ProgressIndicatorDefaults import androidx.compose.material3.Text +import androidx.compose.material3.WavyProgressIndicatorDefaults import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -21,8 +21,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.hapticfeedback.HapticFeedback import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp @@ -127,39 +129,38 @@ private fun DownloadingIndicator( ), contentAlignment = Alignment.Center, ) { - val arrowColor: Color - val strokeColor = MaterialTheme.colorScheme.onSurfaceVariant + val color = MaterialTheme.colorScheme.onSurfaceVariant + val trackColor = color.copy(alpha = TRACK_ALPHA) + val stroke = Stroke(width = with(LocalDensity.current) { IndicatorStrokeWidth.toPx() }, cap = StrokeCap.Round) val downloadProgress = downloadProgressProvider() val indeterminate = downloadState == Download.State.QUEUE || (downloadState == Download.State.DOWNLOADING && downloadProgress == 0) if (indeterminate) { - arrowColor = strokeColor - CircularProgressIndicator( + CircularWavyProgressIndicator( modifier = IndicatorModifier, - color = strokeColor, - strokeWidth = IndicatorStrokeWidth, + color = color, trackColor = Color.Transparent, - strokeCap = StrokeCap.Butt, + stroke = stroke, + trackStroke = stroke, + // Only an active download waves, so a queued one reads as waiting + amplitude = if (downloadState == Download.State.DOWNLOADING) INDICATOR_AMPLITUDE else 0f, + wavelength = IndicatorWavelength, ) } else { val animatedProgress by animateFloatAsState( targetValue = downloadProgress / 100f, - animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec, + animationSpec = WavyProgressIndicatorDefaults.ProgressAnimationSpec, label = "progress", ) - arrowColor = if (animatedProgress < 0.5f) { - strokeColor - } else { - MaterialTheme.colorScheme.background - } - CircularProgressIndicator( + CircularWavyProgressIndicator( progress = { animatedProgress }, modifier = IndicatorModifier, - color = strokeColor, - strokeWidth = IndicatorSize / 2, - trackColor = Color.Transparent, - strokeCap = StrokeCap.Butt, - gapSize = 0.dp, + color = color, + trackColor = trackColor, + stroke = stroke, + trackStroke = stroke, + amplitude = { WavyProgressIndicatorDefaults.indicatorAmplitude(it) * INDICATOR_AMPLITUDE }, + wavelength = IndicatorWavelength, ) } DropdownMenu(expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false }) { @@ -182,7 +183,7 @@ private fun DownloadingIndicator( imageVector = CustomMaterialSymbols.Rounded.DownloadArrow, contentDescription = null, modifier = ArrowModifier, - tint = arrowColor, + tint = color, ) } } @@ -270,10 +271,12 @@ private fun Modifier.commonClickable( ) private val IndicatorSize = 26.dp -private val IndicatorPadding = 2.dp +private val IndicatorPadding = 1.dp +private val IndicatorWavelength = 7.dp +private const val INDICATOR_AMPLITUDE = 0.6f +private const val TRACK_ALPHA = 0.25f -// To match composable parameter name when used later -private val IndicatorStrokeWidth = IndicatorPadding +private val IndicatorStrokeWidth = 2.dp private val IndicatorModifier = Modifier .size(IndicatorSize)