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

Commit e9fe55ba authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Skip the swipe animation if it already reached targetScene

Bug: 327249191
Test: DraggableHandlerTest
Flag: N/A
Change-Id: Ibd216b8af871cd2c31d3eb653c703f9c635c0ff1
parent 5385fc44
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -658,12 +658,28 @@ private class SwipeTransition(
        targetOffset: Float,
        targetScene: SceneKey,
    ): OffsetAnimation {
        // Skip the animation if we have already reached the target scene and the overscroll does
        // not animate anything.
        val hasReachedTargetScene =
            (targetScene == toScene && progress >= 1f) ||
                (targetScene == fromScene && progress <= 0f)
        val skipAnimation =
            hasReachedTargetScene &&
                currentOverscrollSpec?.transformationSpec?.transformations?.isEmpty() == true

        return startOffsetAnimation {
            val animatable = Animatable(dragOffset, OffsetVisibilityThreshold)
            val isTargetGreater = targetOffset > animatable.value
            val job =
                coroutineScope
                    .launch {
                        // TODO(b/327249191): Refactor the code so that we don't even launch a
                        // coroutine if we don't need to animate.
                        if (skipAnimation) {
                            snapToScene(targetScene)
                            return@launch
                        }

                        try {
                            val swipeSpec =
                                transformationSpec.swipeSpec
+19 −0
Original line number Diff line number Diff line
@@ -1007,4 +1007,23 @@ class DraggableHandlerTest {
        dragController.onDragStopped(velocity = 0f)
        assertTransition(isUserInputOngoing = false)
    }

    @Test
    fun emptyOverscrollImmediatelyAbortsSettleAnimationWhenOverProgress() = runGestureTest {
        // Overscrolling on scene B does nothing.
        layoutState.transitions = transitions { overscroll(SceneB, Orientation.Vertical) {} }

        // Swipe up to scene B at progress = 200%.
        val middle = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f)
        val dragController = onDragStarted(startedPosition = middle, overSlop = up(2f))
        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 2f)

        // Release the finger.
        dragController.onDragStopped(velocity = -velocityThreshold)

        // Exhaust all coroutines *without advancing the clock*. Given that we are at progress >=
        // 100% and that the overscroll on scene B is doing nothing, we are already idle.
        runCurrent()
        assertIdle(SceneB)
    }
}