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

Commit 3418ac93 authored by Omar Miatello's avatar Omar Miatello Committed by Android (Google) Code Review
Browse files

Merge "Forced to max one offsetAnimationJob in progress" into main

parents 49371e5a 5111d79c
Loading
Loading
Loading
Loading
+41 −39
Original line number Diff line number Diff line
@@ -150,14 +150,18 @@ private class SwipeTransition(initialScene: Scene) : TransitionState.Transition
    /** The animatable used to animate the offset once the user lifted its finger. */
    val offsetAnimatable = Animatable(0f, visibilityThreshold = OffsetVisibilityThreshold)

    /**
     * The job currently animating [offsetAnimatable], if it is animating. Note that setting this to
     * a new job will automatically cancel the previous one.
     */
    var offsetAnimationJob: Job? = null
        set(value) {
            field?.cancel()
            field = value
    /** Job to check that there is at most one offset animation in progress. */
    private var offsetAnimationJob: Job? = null

    /** Ends any previous [offsetAnimationJob] and runs the new [job]. */
    fun startOffsetAnimation(job: () -> Job) {
        stopOffsetAnimation()
        offsetAnimationJob = job()
    }

    /** Stops any ongoing offset animation. */
    fun stopOffsetAnimation() {
        offsetAnimationJob?.cancel()
    }

    /** The absolute distance between [fromScene] and [toScene]. */
@@ -210,8 +214,7 @@ private fun onDragStarted(
        if (transition.isAnimatingOffset) {
            // Stop animating and start from where the current offset. Setting the animation job to
            // `null` will effectively cancel the animation.
            transition.isAnimatingOffset = false
            transition.offsetAnimationJob = null
            transition.stopOffsetAnimation()
            transition.dragOffset = transition.offsetAnimatable.value
        }

@@ -229,9 +232,8 @@ private fun onDragStarted(
    // to fromScene, which will effectively be treated the same as Idle(fromScene).
    transition._toScene = fromScene

    transition.stopOffsetAnimation()
    transition.dragOffset = 0f
    transition.isAnimatingOffset = false
    transition.offsetAnimationJob = null

    // Use the layout size in the swipe orientation for swipe distance.
    // TODO(b/290184746): Also handle custom distances for transitions. With smaller distances, we
@@ -452,7 +454,8 @@ private fun CoroutineScope.animateOffset(
    targetOffset: Float,
    targetScene: SceneKey,
) {
    transition.offsetAnimationJob = launch {
    transition.startOffsetAnimation {
        launch {
                if (!transition.isAnimatingOffset) {
                    transition.offsetAnimatable.snapTo(transition.dragOffset)
                }
@@ -468,15 +471,15 @@ private fun CoroutineScope.animateOffset(
                    initialVelocity = initialVelocity,
                )

        // Now that the animation is done, the state should be idle. Note that if the state was
        // changed since this animation started, some external code changed it and we shouldn't do
        // anything here. Note also that this job will be cancelled in the case where the user
        // intercepts this swipe.
                // Now that the animation is done, the state should be idle. Note that if the state
                // was changed since this animation started, some external code changed it and we
                // shouldn't do anything here. Note also that this job will be cancelled in the case
                // where the user intercepts this swipe.
                if (layoutImpl.state.transitionState == transition) {
                    layoutImpl.state.transitionState = TransitionState.Idle(targetScene)
                }

        transition.offsetAnimationJob = null
            }
            .also { it.invokeOnCompletion { transition.isAnimatingOffset = false } }
    }
}

@@ -511,9 +514,8 @@ private fun CoroutineScope.animateOverscroll(
    transition._toScene = layoutImpl.scene(target.sceneKey)
    transition._distance = target.distance
    transition.absoluteDistance = target.distance.absoluteValue
    transition.stopOffsetAnimation()
    transition.dragOffset = 0f
    transition.isAnimatingOffset = false
    transition.offsetAnimationJob = null

    layoutImpl.state.transitionState = transition