Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ee468ae authored by Anton Potapov's avatar Anton Potapov
Browse files

Refine volume sliders expand collapse animation

Flag: aconfig new_volume_panel TRUNKFOOD
Test: manual on the phone. Expand and collapse volume sliders
Fixes: 330808535
Change-Id: Id43569acf6ab04476ef70e0622bb55a676ca1439
parent 07fc46a1
Loading
Loading
Loading
Loading
+34 −44
Original line number Original line Diff line number Diff line
@@ -28,9 +28,8 @@ import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.scaleOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.fillMaxWidth
@@ -57,6 +56,8 @@ import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.Sl


private const val EXPAND_DURATION_MILLIS = 500
private const val EXPAND_DURATION_MILLIS = 500
private const val COLLAPSE_DURATION_MILLIS = 300
private const val COLLAPSE_DURATION_MILLIS = 300
private const val SHRINK_FRACTION = 0.55f
private const val SCALE_FRACTION = 0.9f


/** Volume sliders laid out in a collapsable column */
/** Volume sliders laid out in a collapsable column */
@OptIn(ExperimentalAnimationApi::class)
@OptIn(ExperimentalAnimationApi::class)
@@ -107,27 +108,25 @@ fun ColumnVolumeSliders(
        transition.AnimatedVisibility(
        transition.AnimatedVisibility(
            visible = { it },
            visible = { it },
            enter =
            enter =
                expandVertically(
                expandVertically(animationSpec = tween(durationMillis = EXPAND_DURATION_MILLIS)),
                    animationSpec = tween(durationMillis = EXPAND_DURATION_MILLIS),
                    expandFrom = Alignment.CenterVertically,
                ),
            exit =
            exit =
                shrinkVertically(
                shrinkVertically(animationSpec = tween(durationMillis = COLLAPSE_DURATION_MILLIS)),
                    animationSpec = tween(durationMillis = COLLAPSE_DURATION_MILLIS),
                    shrinkTowards = Alignment.CenterVertically,
                ),
        ) {
        ) {
            Column(modifier = Modifier.fillMaxWidth()) {
            // This box allows sliders to slide towards top when the container is shrinking and
            // slide from top when the container is expanding.
            Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.BottomCenter) {
                Column {
                    for (index in 1..viewModels.lastIndex) {
                    for (index in 1..viewModels.lastIndex) {
                        val sliderViewModel: SliderViewModel = viewModels[index]
                        val sliderViewModel: SliderViewModel = viewModels[index]
                        val sliderState by sliderViewModel.slider.collectAsState()
                        val sliderState by sliderViewModel.slider.collectAsState()
                        transition.AnimatedVisibility(
                        transition.AnimatedVisibility(
                            modifier = Modifier.padding(top = 16.dp),
                            visible = { it },
                            visible = { it },
                            enter = enterTransition(index = index, totalCount = viewModels.size),
                            enter = enterTransition(index = index, totalCount = viewModels.size),
                            exit = exitTransition(index = index, totalCount = viewModels.size)
                            exit = exitTransition(index = index, totalCount = viewModels.size)
                        ) {
                        ) {
                            VolumeSlider(
                            VolumeSlider(
                            modifier = Modifier.fillMaxWidth().padding(top = 16.dp),
                                modifier = Modifier.fillMaxWidth(),
                                state = sliderState,
                                state = sliderState,
                                onValueChange = { newValue: Float ->
                                onValueChange = { newValue: Float ->
                                    sliderViewModel.onValueChanged(sliderState, newValue)
                                    sliderViewModel.onValueChanged(sliderState, newValue)
@@ -141,6 +140,7 @@ fun ColumnVolumeSliders(
            }
            }
        }
        }
    }
    }
}


@Composable
@Composable
private fun ExpandButton(
private fun ExpandButton(
@@ -175,19 +175,14 @@ private fun ExpandButton(
private fun enterTransition(index: Int, totalCount: Int): EnterTransition {
private fun enterTransition(index: Int, totalCount: Int): EnterTransition {
    val enterDelay = ((totalCount - index + 1) * 10).coerceAtLeast(0)
    val enterDelay = ((totalCount - index + 1) * 10).coerceAtLeast(0)
    val enterDuration = (EXPAND_DURATION_MILLIS - enterDelay).coerceAtLeast(100)
    val enterDuration = (EXPAND_DURATION_MILLIS - enterDelay).coerceAtLeast(100)
    return slideInVertically(
    return scaleIn(
        initialOffsetY = { (it * 0.25).toInt() },
        initialScale = SCALE_FRACTION,
        animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
    ) +
        scaleIn(
            initialScale = 0.9f,
        animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
        animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
    ) +
    ) +
        expandVertically(
        expandVertically(
            initialHeight = { (it * 0.65).toInt() },
            initialHeight = { (it * SHRINK_FRACTION).toInt() },
            animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
            animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
            clip = false,
            clip = false,
            expandFrom = Alignment.CenterVertically,
        ) +
        ) +
        fadeIn(
        fadeIn(
            animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
            animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
@@ -196,19 +191,14 @@ private fun enterTransition(index: Int, totalCount: Int): EnterTransition {


private fun exitTransition(index: Int, totalCount: Int): ExitTransition {
private fun exitTransition(index: Int, totalCount: Int): ExitTransition {
    val exitDuration = (COLLAPSE_DURATION_MILLIS - (totalCount - index + 1) * 10).coerceAtLeast(100)
    val exitDuration = (COLLAPSE_DURATION_MILLIS - (totalCount - index + 1) * 10).coerceAtLeast(100)
    return slideOutVertically(
    return scaleOut(
        targetOffsetY = { (it * 0.25).toInt() },
        targetScale = SCALE_FRACTION,
        animationSpec = tween(durationMillis = exitDuration),
    ) +
        scaleOut(
            targetScale = 0.9f,
        animationSpec = tween(durationMillis = exitDuration),
        animationSpec = tween(durationMillis = exitDuration),
    ) +
    ) +
        shrinkVertically(
        shrinkVertically(
            targetHeight = { (it * 0.65).toInt() },
            targetHeight = { (it * SHRINK_FRACTION).toInt() },
            animationSpec = tween(durationMillis = exitDuration),
            animationSpec = tween(durationMillis = exitDuration),
            clip = false,
            clip = false,
            shrinkTowards = Alignment.CenterVertically,
        ) +
        ) +
        fadeOut(animationSpec = tween(durationMillis = exitDuration))
        fadeOut(animationSpec = tween(durationMillis = exitDuration))
}
}