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 d6c78263..537dd84c 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,11 @@ fun Steps( category: StepCategory, steps: List, stepCount: Pair? = null, - stepProgressProvider: StepProgressProvider + stepProgressProvider: StepProgressProvider, + isExpanded: Boolean = false, + onExpand: () -> Unit, + onClick: () -> 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,48 +67,52 @@ 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 = onClick) + .fillMaxWidth() + .padding(20.dp) ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp), - modifier = Modifier.padding(16.dp) - ) { - StepIcon(state = state, size = 24.dp) + StepIcon(state = state, size = 24.dp) - Text(stringResource(category.displayName)) + Text(stringResource(category.displayName)) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(1f)) - val stepProgress = remember(stepCount, steps) { - stepCount?.let { (current, total) -> "$current/$total" } - ?: "${steps.count { it.state == State.COMPLETED }}/${steps.size}" - } - - Text( - text = stepProgress, - style = MaterialTheme.typography.labelSmall - ) - - ArrowButton(modifier = Modifier.size(24.dp), expanded = expanded, onClick = null) + val stepProgress = remember(stepCount, steps) { + stepCount?.let { (current, total) -> "$current/$total" } + ?: "${steps.count { it.state == State.COMPLETED }}/${steps.size}" } + + Text( + text = stepProgress, + style = MaterialTheme.typography.labelSmall + ) + + ArrowButton(modifier = Modifier.size(24.dp), expanded = isExpanded, onClick = null) } - AnimatedVisibility(visible = expanded) { + AnimatedVisibility(visible = isExpanded) { Column( - modifier = Modifier.fillMaxWidth() + modifier = Modifier + .background(MaterialTheme.colorScheme.background.copy(0.6f)) + .fillMaxWidth() + .padding(top = 10.dp) ) { - steps.forEach { step -> + steps.forEachIndexed { index, step -> val (progress, progressText) = when (step.progressKey) { null -> null ProgressKey.DOWNLOAD -> stepProgressProvider.downloadProgress?.let { (downloaded, total) -> @@ -131,7 +126,9 @@ fun Steps( state = step.state, message = step.message, progress = progress, - progressText = progressText + progressText = progressText, + isFirst = index == 0, + isLast = index == steps.lastIndex, ) } } @@ -145,7 +142,9 @@ fun SubStep( state: State, message: String? = null, progress: Float? = null, - progressText: String? = null + progressText: String? = null, + isFirst: Boolean = false, + isLast: Boolean = false, ) { var messageExpanded by rememberSaveable { mutableStateOf(true) } @@ -156,22 +155,22 @@ fun SubStep( clickable { messageExpanded = !messageExpanded } else this } + .padding(top = if (isFirst) 10.dp else 8.dp, bottom = if (isLast) 20.dp else 8.dp) + .padding(horizontal = 20.dp) ) { 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), @@ -201,7 +200,7 @@ fun SubStep( text = message.orEmpty(), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.secondary, - modifier = Modifier.padding(horizontal = 52.dp, vertical = 8.dp) + modifier = Modifier.padding(horizontal = 36.dp, vertical = 8.dp) ) } } @@ -211,40 +210,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 a80b49a2..c3839551 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,6 +213,12 @@ fun PatcherScreen( .padding(paddingValues) .fillMaxSize() ) { + var expandedCategory by rememberSaveable { mutableStateOf(null) } + + val expandCategory: (StepCategory?) -> Unit = { category -> + expandedCategory = category + } + LinearProgressIndicator( progress = { viewModel.progress }, modifier = Modifier.fillMaxWidth() @@ -231,7 +237,12 @@ fun PatcherScreen( category = category, steps = steps, stepCount = if (category == StepCategory.PATCHING) viewModel.patchesProgress else null, - stepProgressProvider = viewModel + stepProgressProvider = viewModel, + isExpanded = expandedCategory == category, + onExpand = { expandCategory(category) }, + onClick = { + expandCategory(if (expandedCategory == category) null else category) + } ) } }