From cd517b8b24ae3472b915ddeca3ee6f4d2902b8c0 Mon Sep 17 00:00:00 2001 From: rushiiMachine <33725716+rushiiMachine@users.noreply.github.com> Date: Wed, 7 Feb 2024 21:03:26 -0800 Subject: [PATCH] feat: animate step state icon changes --- .../install/components/StepGroupCard.kt | 2 +- .../ui/screens/install/components/StepItem.kt | 4 +- .../install/components/StepStateIcon.kt | 88 +++++++++++++++++++ .../install/components/StepStatusIcon.kt | 85 ------------------ 4 files changed, 91 insertions(+), 88 deletions(-) create mode 100644 app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepStateIcon.kt delete mode 100644 app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepStatusIcon.kt diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepGroupCard.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepGroupCard.kt index 1d1471e..39b99fd 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepGroupCard.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepGroupCard.kt @@ -62,7 +62,7 @@ fun StepGroupCard( .fillMaxWidth() .padding(16.dp) ) { - StepStatusIcon(groupState, 24.dp) + StepStateIcon(groupState, 24.dp) Text(text = name) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepItem.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepItem.kt index 911223c..d2f82f8 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepItem.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepItem.kt @@ -22,9 +22,9 @@ fun StepItem( horizontalArrangement = Arrangement.spacedBy(16.dp), modifier = modifier, ) { - StepStatusIcon( + StepStateIcon( size = 18.dp, - status = step.state, + state = step.state, stepProgress = step.progress, ) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepStateIcon.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepStateIcon.kt new file mode 100644 index 0000000..cfb2173 --- /dev/null +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepStateIcon.kt @@ -0,0 +1,88 @@ +package com.aliucord.manager.ui.screens.install.components + +import androidx.compose.animation.Crossfade +import androidx.compose.animation.core.* +import androidx.compose.foundation.layout.size +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.unit.Dp +import com.aliucord.manager.R +import com.aliucord.manager.installer.steps.base.StepState +import kotlin.math.floor +import kotlin.math.roundToInt + +@Composable +fun StepStateIcon( + state: StepState, + size: Dp, + stepProgress: Float = -1f, +) { + val animatedProgress by animateFloatAsState( + targetValue = stepProgress, + animationSpec = spring(stiffness = Spring.StiffnessVeryLow), + label = "Progress", + ) + + Crossfade(targetState = state, label = "State CrossFade") { animatedState -> + when (animatedState) { + StepState.Pending -> Icon( + painter = painterResource(R.drawable.ic_circle), + contentDescription = stringResource(R.string.status_queued), + tint = MaterialTheme.colorScheme.onSurface.copy(0.4f), + modifier = Modifier.size(size) + ) + + StepState.Running -> { + val strokeWidth = Dp(floor(size.value / 10) + 1) + + if (stepProgress > .05f) { + CircularProgressIndicator( + progress = { animatedProgress }, + strokeWidth = strokeWidth, + modifier = Modifier + .size(size) + .semantics { contentDescription = "${(stepProgress * 100).roundToInt()}%" }, + ) + } else { + val description = stringResource(R.string.status_ongoing) + + // Infinite spinner + CircularProgressIndicator( + strokeWidth = strokeWidth, + modifier = Modifier + .size(size) + .semantics { contentDescription = description }, + ) + } + } + + StepState.Success -> Icon( + painter = painterResource(R.drawable.ic_check_circle), + contentDescription = stringResource(R.string.status_success), + tint = Color(0xFF59B463), + modifier = Modifier.size(size) + ) + + StepState.Error -> Icon( + painter = painterResource(R.drawable.ic_canceled), + contentDescription = stringResource(R.string.status_failed), + tint = MaterialTheme.colorScheme.error, + modifier = Modifier.size(size) + ) + + StepState.Skipped -> Icon( + painter = painterResource(R.drawable.ic_check_circle), + contentDescription = stringResource(R.string.status_skipped), + tint = Color(0xFFAEAEAE), + modifier = Modifier.size(size) + ) + } + } +} diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepStatusIcon.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepStatusIcon.kt deleted file mode 100644 index b6ba0f8..0000000 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/install/components/StepStatusIcon.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.aliucord.manager.ui.screens.install.components - -import androidx.compose.animation.core.* -import androidx.compose.foundation.layout.size -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.unit.Dp -import com.aliucord.manager.R -import com.aliucord.manager.installer.steps.base.StepState -import kotlin.math.floor -import kotlin.math.roundToInt - -@Composable -fun StepStatusIcon( - status: StepState, - size: Dp, - stepProgress: Float = -1f, -) { - val strokeWidth = Dp(floor(size.value / 10) + 1) - val context = LocalContext.current - - when (status) { - StepState.Pending -> Icon( - painter = painterResource(R.drawable.ic_circle), - contentDescription = stringResource(R.string.status_queued), - tint = MaterialTheme.colorScheme.onSurface.copy(0.4f), - modifier = Modifier.size(size) - ) - - StepState.Running -> { - val animatedProgress by animateFloatAsState( - targetValue = stepProgress, - animationSpec = spring(stiffness = Spring.StiffnessVeryLow), - label = "Progress", - ) - - if (stepProgress > .1f) { - CircularProgressIndicator( - progress = { animatedProgress }, - strokeWidth = strokeWidth, - modifier = Modifier - .size(size) - .semantics { contentDescription = "${(stepProgress * 100).roundToInt()}%" }, - ) - } else { - // Infinite spinner - CircularProgressIndicator( - strokeWidth = strokeWidth, - modifier = Modifier - .size(size) - .semantics { contentDescription = context.getString(R.string.status_ongoing) }, - ) - } - } - - StepState.Success -> Icon( - painter = painterResource(R.drawable.ic_check_circle), - contentDescription = stringResource(R.string.status_success), - tint = Color(0xFF59B463), - modifier = Modifier.size(size) - ) - - StepState.Error -> Icon( - painter = painterResource(R.drawable.ic_canceled), - contentDescription = stringResource(R.string.status_failed), - tint = MaterialTheme.colorScheme.error, - modifier = Modifier.size(size) - ) - - StepState.Skipped -> Icon( - painter = painterResource(R.drawable.ic_check_circle), - contentDescription = stringResource(R.string.status_skipped), - tint = Color(0xFFAEAEAE), - modifier = Modifier.size(size) - ) - } -}