diff --git a/app/src/main/java/app/revanced/manager/ui/component/patcher/Steps.kt b/app/src/main/java/app/revanced/manager/ui/component/patcher/Steps.kt index d6c78263c2..1d41405b66 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/patcher/Steps.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/patcher/Steps.kt @@ -1,7 +1,7 @@ package app.revanced.manager.ui.component.patcher import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.animateColorAsState +import androidx.compose.animation.Crossfade import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Cancel import androidx.compose.material.icons.filled.CheckCircle @@ -21,6 +20,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -53,20 +53,10 @@ fun Steps( category: StepCategory, steps: List, stepCount: Pair? = null, - stepProgressProvider: StepProgressProvider + stepProgressProvider: StepProgressProvider, + isExpanded: Boolean = false, + onExpand: () -> Unit ) { - var expanded by rememberSaveable { mutableStateOf(true) } - - val categoryColor by animateColorAsState( - if (expanded) MaterialTheme.colorScheme.surfaceContainerHigh else Color.Transparent, - label = "category" - ) - - val cardColor by animateColorAsState( - if (expanded) MaterialTheme.colorScheme.surfaceContainer else Color.Transparent, - label = "card" - ) - val state = remember(steps) { when { steps.all { it.state == State.COMPLETED } -> State.COMPLETED @@ -76,23 +66,25 @@ fun Steps( } } + LaunchedEffect(state) { + if (state == State.RUNNING) + onExpand() + } + Column( modifier = Modifier - .clip(RoundedCornerShape(16.dp)) + .clip(MaterialTheme.shapes.large) .fillMaxWidth() - .background(cardColor) + .background(MaterialTheme.colorScheme.surfaceContainerLow) ) { Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(14.dp), modifier = Modifier - .clip(RoundedCornerShape(16.dp)) - .clickable { expanded = !expanded } - .background(categoryColor) + .clickable(true, onClick = onExpand) + .fillMaxWidth() + .padding(20.dp) ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp), - modifier = Modifier.padding(16.dp) - ) { StepIcon(state = state, size = 24.dp) Text(stringResource(category.displayName)) @@ -109,13 +101,17 @@ fun Steps( style = MaterialTheme.typography.labelSmall ) - ArrowButton(modifier = Modifier.size(24.dp), expanded = expanded, onClick = null) - } + ArrowButton(modifier = Modifier.size(24.dp), expanded = isExpanded, onClick = null) } - AnimatedVisibility(visible = expanded) { + AnimatedVisibility(visible = isExpanded) { Column( - modifier = Modifier.fillMaxWidth() + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier + .background(MaterialTheme.colorScheme.background.copy(0.6f)) + .fillMaxWidth() + .padding(start = 10.dp, end = 10.dp, top = 10.dp, bottom = 20.dp) + .padding(start = 4.dp) ) { steps.forEach { step -> val (progress, progressText) = when (step.progressKey) { @@ -155,23 +151,21 @@ fun SubStep( if (message != null) clickable { messageExpanded = !messageExpanded } else this - } + }.add ) { Row( verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp), - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) + horizontalArrangement = Arrangement.spacedBy(16.dp), ) { - Box( - modifier = Modifier.size(24.dp), - contentAlignment = Alignment.Center - ) { - StepIcon(state, progress, size = 20.dp) - } + StepIcon( + size = 18.dp, + state = state, + progress = progress, + ) Text( text = name, - style = MaterialTheme.typography.titleSmall, + style = MaterialTheme.typography.labelLarge, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f, true), @@ -211,40 +205,44 @@ fun SubStep( fun StepIcon(state: State, progress: Float? = null, size: Dp) { val strokeWidth = Dp(floor(size.value / 10) + 1) - when (state) { - State.COMPLETED -> Icon( - Icons.Filled.CheckCircle, - contentDescription = stringResource(R.string.step_completed), - tint = MaterialTheme.colorScheme.surfaceTint, - modifier = Modifier.size(size) - ) - - State.FAILED -> Icon( - Icons.Filled.Cancel, - contentDescription = stringResource(R.string.step_failed), - tint = MaterialTheme.colorScheme.error, - modifier = Modifier.size(size) - ) - - State.WAITING -> Icon( - Icons.Outlined.Circle, - contentDescription = stringResource(R.string.step_waiting), - tint = MaterialTheme.colorScheme.surfaceVariant, - modifier = Modifier.size(size) - ) - - State.RUNNING -> - LoadingIndicator( - modifier = stringResource(R.string.step_running).let { description -> - Modifier - .size(size) - .semantics { - contentDescription = description - } - }, - progress = { progress }, - strokeWidth = strokeWidth + Crossfade(targetState = state, label = "State CrossFade") { state -> + when (state) { + State.COMPLETED -> Icon( + Icons.Filled.CheckCircle, + contentDescription = stringResource(R.string.step_completed), + tint = Color(0xFF59B463), + modifier = Modifier.size(size) + ) + + State.FAILED -> Icon( + Icons.Filled.Cancel, + contentDescription = stringResource(R.string.step_failed), + tint = MaterialTheme.colorScheme.error, + modifier = Modifier.size(size) + ) + + State.WAITING -> Icon( + Icons.Outlined.Circle, + contentDescription = stringResource(R.string.step_waiting), + tint = MaterialTheme.colorScheme.onSurface.copy(.2f), + modifier = Modifier.size(size) ) + + State.RUNNING -> { + LoadingIndicator( + modifier = stringResource(R.string.step_running).let { description -> + Modifier + .size(size) + .semantics { + contentDescription = description + } + }, + + progress = { progress }, + strokeWidth = strokeWidth + ) + } + } } } diff --git a/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt index af09bfa593..6b3b4fdf36 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt @@ -213,7 +213,10 @@ fun PatcherScreen( .padding(paddingValues) .fillMaxSize() ) { - LinearProgressIndicator( + + var expandedCategory by rememberSaveable { mutableStateOf(StepCategory.PREPARING) } + + LinearProgressIndicator( progress = { viewModel.progress }, modifier = Modifier.fillMaxWidth() ) @@ -227,11 +230,14 @@ fun PatcherScreen( items = steps.toList(), key = { it.first } ) { (category, steps) -> + Steps( category = category, steps = steps, stepCount = if (category == StepCategory.PATCHING) viewModel.patchesProgress else null, - stepProgressProvider = viewModel + stepProgressProvider = viewModel, + isExpanded = expandedCategory == category, + onExpand = { expandedCategory = category }, ) } }