Show a wavy progress ring while a chapter downloads

This commit is contained in:
AntsyLich
2026-10-11 21:33:35 +06:00
parent ba44815254
commit e562a9b4f8
@@ -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)