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

Commit 1ac4aee9 authored by Anton Potapov's avatar Anton Potapov
Browse files

Snap Slider on finish editing.

This creates a behaviour when
 - Volume Dialog snaps to minimum value when released so that the slider
   matches the icon state;
 - Volume Panel always snaps to immediate state;

Flag: com.android.systemui.volume_redesign
Fixes: 415246619
Test: atest VolumeDialogScreenshotTest
Test: atest VolumePanelScreenshotTest
Test: manual on foldable. Adjust volume using slider in Volume Panel and
Volume Dialog.

Change-Id: I377de7700b32bd9a481945d7b8415c43a2bb271c
parent 5a02a939
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -109,14 +109,19 @@ constructor(
                },
                userVolumeUpdates,
            ) { isDisabledByZenMode, model, icon, currentVolumeUpdate ->
                val shouldIgnoreUpdates =
                val isInGracePeriod =
                    currentVolumeUpdate != null &&
                        getTimestampMillis() - currentVolumeUpdate.timestampMillis <
                            VOLUME_UPDATE_GRACE_PERIOD
                val isMinimumVolume = model.levelMin == currentVolumeUpdate?.level
                VolumeDialogSliderStateModel(
                    value =
                        if (currentVolumeUpdate != null && shouldIgnoreUpdates) {
                            currentVolumeUpdate.newVolumeLevel
                        if (currentVolumeUpdate != null && isInGracePeriod) {
                            if (isMinimumVolume) {
                                model.levelMin.toFloat()
                            } else {
                                currentVolumeUpdate.volume
                            }
                        } else {
                            model.level.toFloat()
                        },
@@ -131,7 +136,7 @@ constructor(

    init {
        userVolumeUpdates
            .mapNotNull { it?.newVolumeLevel?.roundToInt() }
            .mapNotNull { it?.level }
            .distinctUntilChanged()
            .mapLatest { volume ->
                interactor.setStreamVolume(volume)
@@ -144,7 +149,7 @@ constructor(
        if (fromUser) {
            visibilityInteractor.resetDismissTimeout()
            userVolumeUpdates.value =
                VolumeUpdate(newVolumeLevel = volume, timestampMillis = getTimestampMillis())
                VolumeUpdate(volume = volume, timestampMillis = getTimestampMillis())
        }
    }

@@ -190,5 +195,9 @@ constructor(

    private fun getTimestampMillis(): Long = systemClock.uptimeMillis()

    private data class VolumeUpdate(val newVolumeLevel: Float, val timestampMillis: Long)
    private data class VolumeUpdate(val volume: Float, val timestampMillis: Long) {

        val level: Int
            get() = volume.roundToInt()
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.ProgressBarRangeInfo
@@ -83,6 +84,7 @@ fun Slider(
    },
) {
    require(stepDistance >= 0f) { "stepDistance must not be negative" }
    val coroutineScope = rememberCoroutineScope()
    var animationJob: Job? by remember { mutableStateOf(null) }
    val sliderState = remember(valueRange) { SliderState(value = value, valueRange = valueRange) }
    LaunchedEffect(value) {
@@ -123,6 +125,19 @@ fun Slider(
    sliderState.onValueChangeFinished = {
        hapticsViewModel?.onValueChangeEnded()
        onValueChangeFinished?.invoke(sliderState.value)
        if (sliderState.value != value) {
            animationJob?.cancel()
            animationJob =
                coroutineScope.launchTraced("Slider#animateValue") {
                    animate(
                        initialValue = sliderState.value,
                        targetValue = value,
                        animationSpec = animationSpec,
                    ) { animatedValue, _ ->
                        sliderState.value = animatedValue
                    }
                }
        }
    }
    sliderState.onValueChange = valueChange