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

Commit fc736be4 authored by Johannes Gallmann's avatar Johannes Gallmann Committed by Android (Google) Code Review
Browse files

Merge "[STL] Add default PredictiveBack transition key" into main

parents e7ba2085 22d74afe
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -153,4 +153,15 @@ class TransitionKey(debugName: String, identity: Any = Object()) : Key(debugName
    override fun toString(): String {
        return "TransitionKey(debugName=$debugName)"
    }

    companion object {
        /**
         * A special transition key indicating that the associated transition should be used for
         * Predictive Back gestures.
         *
         * Use this key when defining a transition that you want to be specifically triggered when
         * the user performs a Predictive Back gesture.
         */
        val PredictiveBack = TransitionKey("PredictiveBack")
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -43,7 +43,9 @@ internal fun PredictiveBackHandler(
            createSwipeAnimation(
                layoutImpl,
                layoutImpl.coroutineScope,
                result,
                result.userActionCopy(
                    transitionKey = result.transitionKey ?: TransitionKey.PredictiveBack
                ),
                isUpOrLeft = false,
                // Note that the orientation does not matter here given that it's only used to
                // compute the distance. In our case the distance is always 1f.
+20 −9
Original line number Diff line number Diff line
@@ -492,6 +492,17 @@ sealed class UserActionResult(
) {
    internal abstract fun toContent(currentScene: SceneKey): ContentKey

    internal fun userActionCopy(
        transitionKey: TransitionKey? = this.transitionKey
    ): UserActionResult {
        return when (this) {
            is ChangeScene -> copy(transitionKey = transitionKey)
            is ShowOverlay -> copy(transitionKey = transitionKey)
            is HideOverlay -> copy(transitionKey = transitionKey)
            is ReplaceByOverlay -> copy(transitionKey = transitionKey)
        }
    }

    data class ChangeScene
    internal constructor(
        /** The scene we should be transitioning to during the [UserAction]. */
@@ -503,19 +514,19 @@ sealed class UserActionResult(
    }

    /** A [UserActionResult] that shows [overlay]. */
    class ShowOverlay(
    data class ShowOverlay(
        val overlay: OverlayKey,
        transitionKey: TransitionKey? = null,
        requiresFullDistanceSwipe: Boolean = false,
        override val transitionKey: TransitionKey? = null,
        override val requiresFullDistanceSwipe: Boolean = false,
    ) : UserActionResult(transitionKey, requiresFullDistanceSwipe) {
        override fun toContent(currentScene: SceneKey): ContentKey = overlay
    }

    /** A [UserActionResult] that hides [overlay]. */
    class HideOverlay(
    data class HideOverlay(
        val overlay: OverlayKey,
        transitionKey: TransitionKey? = null,
        requiresFullDistanceSwipe: Boolean = false,
        override val transitionKey: TransitionKey? = null,
        override val requiresFullDistanceSwipe: Boolean = false,
    ) : UserActionResult(transitionKey, requiresFullDistanceSwipe) {
        override fun toContent(currentScene: SceneKey): ContentKey = currentScene
    }
@@ -526,10 +537,10 @@ sealed class UserActionResult(
     * Note: This result can only be used for user actions of overlays and an exception will be
     * thrown if it is used for a scene.
     */
    class ReplaceByOverlay(
    data class ReplaceByOverlay(
        val overlay: OverlayKey,
        transitionKey: TransitionKey? = null,
        requiresFullDistanceSwipe: Boolean = false,
        override val transitionKey: TransitionKey? = null,
        override val requiresFullDistanceSwipe: Boolean = false,
    ) : UserActionResult(transitionKey, requiresFullDistanceSwipe) {
        override fun toContent(currentScene: SceneKey): ContentKey = overlay
    }
+11 −2
Original line number Diff line number Diff line
@@ -90,10 +90,19 @@ internal constructor(
            return relaxedSpec
        }

        return transition(from, to, key) {
        val relaxedReversed =
            transition(from, to, key) {
                (it.from == to && it.to == null) || (it.to == from && it.from == null)
            }
            ?.reversed() ?: defaultTransition(from, to)
        if (relaxedReversed != null) {
            return relaxedReversed.reversed()
        }

        return if (key != null) {
            findSpec(from, to, null)
        } else {
            defaultTransition(from, to)
        }
    }

    private fun transition(
+41 −0
Original line number Diff line number Diff line
@@ -231,6 +231,47 @@ class TransitionDslTest {
            )
    }

    @Test
    fun defaultPredictiveBack() {
        val transitions = transitions {
            from(
                TestScenes.SceneA,
                to = TestScenes.SceneB,
                preview = { fractionRange(start = 0.1f, end = 0.8f) { fade(TestElements.Foo) } }
            ) {
                spec = tween(500)
                fractionRange(start = 0.1f, end = 0.8f) { fade(TestElements.Foo) }
                timestampRange(startMillis = 100, endMillis = 300) { fade(TestElements.Foo) }
            }
        }

        // Verify that fetching the transitionSpec with the PredictiveBack key defaults to the above
        // transition despite it not having the PredictiveBack key set.
        val transitionSpec =
            transitions.transitionSpec(
                from = TestScenes.SceneA,
                to = TestScenes.SceneB,
                key = TransitionKey.PredictiveBack
            )

        val transformations = transitionSpec.transformationSpec().transformations

        assertThat(transformations)
            .comparingElementsUsing(TRANSFORMATION_RANGE)
            .containsExactly(
                TransformationRange(start = 0.1f, end = 0.8f),
                TransformationRange(start = 100 / 500f, end = 300 / 500f),
            )

        val previewTransformations = transitionSpec.previewTransformationSpec()?.transformations

        assertThat(previewTransformations)
            .comparingElementsUsing(TRANSFORMATION_RANGE)
            .containsExactly(
                TransformationRange(start = 0.1f, end = 0.8f),
            )
    }

    @Test
    fun springSpec() {
        val defaultSpec = spring<Float>(stiffness = 1f)