diff --git a/CHANGELOG.md b/CHANGELOG.md index 410164a10..4faafb48e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Pending changes +- [#287](https://github.com/bumble-tech/appyx/pull/287) – **Added**: Introduced a new `rememberCombinedHandler` implementation that takes an immutable list to avoid non-skippable compositions. The previous implementation is now deprecated. +- [#287](https://github.com/bumble-tech/appyx/pull/287) – **Added**: `ImmutableList` has been added to avoid non-skippable compositions. - [#289](https://github.com/bumble-tech/appyx/issues/289) – **Added**: Introduced `interop-rx3` for RxJava 3 support. This has identical functionality to `interop-rx2`. --- diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 386f83c26..871a58f31 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -73,7 +73,7 @@ plugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version. plugin-detekt = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" } plugin-android = "com.android.tools.build:gradle:7.3.1" -detekt-compose = "com.twitter.compose.rules:detekt:0.0.18" +detekt-compose = "com.twitter.compose.rules:detekt:0.0.26" [plugins] detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } diff --git a/libraries/core/src/main/kotlin/com/bumble/appyx/core/collections/ImmutableList.kt b/libraries/core/src/main/kotlin/com/bumble/appyx/core/collections/ImmutableList.kt new file mode 100644 index 000000000..8f48c9b9c --- /dev/null +++ b/libraries/core/src/main/kotlin/com/bumble/appyx/core/collections/ImmutableList.kt @@ -0,0 +1,12 @@ +package com.bumble.appyx.core.collections + +import androidx.compose.runtime.Immutable + +@Immutable +data class ImmutableList(private val list: List) : List by list + +fun immutableListOf(vararg items: E): ImmutableList = + ImmutableList(listOf(*items)) + +fun List.toImmutableList(): ImmutableList = + ImmutableList(ArrayList(this)) // make a copy as list might be also mutable diff --git a/libraries/core/src/main/kotlin/com/bumble/appyx/core/navigation/transition/CombinedHandler.kt b/libraries/core/src/main/kotlin/com/bumble/appyx/core/navigation/transition/CombinedHandler.kt index 3907c71f7..f11c5af6d 100644 --- a/libraries/core/src/main/kotlin/com/bumble/appyx/core/navigation/transition/CombinedHandler.kt +++ b/libraries/core/src/main/kotlin/com/bumble/appyx/core/navigation/transition/CombinedHandler.kt @@ -5,6 +5,7 @@ import androidx.compose.animation.core.Transition import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import com.bumble.appyx.core.collections.ImmutableList class CombinedHandler( private val handlers: List> @@ -23,6 +24,20 @@ class CombinedHandler( } } +@Suppress("UnstableCollections") +@Deprecated( + message = "Use rememberCombinedHandler with immutable handlers instead. This function will be removed in 1.1", + replaceWith = ReplaceWith( + "rememberCombinedHandler(handlers.toImmutableList())", + "com.bumble.appyx.core.collections.toImmutableList", + ) +) @Composable fun rememberCombinedHandler(handlers: List>): ModifierTransitionHandler = remember { CombinedHandler(handlers = handlers) } + +@Composable +fun rememberCombinedHandler( + handlers: ImmutableList> +): ModifierTransitionHandler = + remember(handlers) { CombinedHandler(handlers = handlers) } diff --git a/samples/app/src/main/kotlin/com/bumble/appyx/app/node/slideshow/slide/app/StatefulNode2.kt b/samples/app/src/main/kotlin/com/bumble/appyx/app/node/slideshow/slide/app/StatefulNode2.kt index a09f8405a..b203eb918 100644 --- a/samples/app/src/main/kotlin/com/bumble/appyx/app/node/slideshow/slide/app/StatefulNode2.kt +++ b/samples/app/src/main/kotlin/com/bumble/appyx/app/node/slideshow/slide/app/StatefulNode2.kt @@ -53,7 +53,7 @@ class StatefulNode2( val shape = RoundedCornerShape(16.dp) Column( - modifier = modifier + modifier = Modifier .size(200.dp) .align(Alignment.Center) .background( diff --git a/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/container/ContainerNode.kt b/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/container/ContainerNode.kt index 37b6eb220..4cf85ee68 100644 --- a/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/container/ContainerNode.kt +++ b/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/container/ContainerNode.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import com.bumble.appyx.core.collections.immutableListOf import com.bumble.appyx.core.composable.Children import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.navigation.transition.rememberCombinedHandler @@ -99,7 +100,7 @@ class ContainerNode internal constructor( .background(MaterialTheme.colors.background), navModel = backStack, transitionHandler = rememberCombinedHandler( - handlers = listOf(rememberBackstackSlider(), rememberBackstackFader()) + handlers = immutableListOf(rememberBackstackSlider(), rememberBackstackFader()) ) ) } diff --git a/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/list/LazyListContainerNode.kt b/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/list/LazyListContainerNode.kt index e664bb3d9..bad357f18 100644 --- a/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/list/LazyListContainerNode.kt +++ b/samples/sandbox/src/main/kotlin/com/bumble/appyx/sandbox/client/list/LazyListContainerNode.kt @@ -25,6 +25,8 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import com.bumble.appyx.core.collections.ImmutableList +import com.bumble.appyx.core.collections.toImmutableList import com.bumble.appyx.core.composable.Child import com.bumble.appyx.core.composable.visibleChildrenAsState import com.bumble.appyx.core.modality.BuildContext @@ -73,7 +75,7 @@ class LazyListContainerNode constructor( } } - val children by navModel.visibleChildrenAsState() + val children = navModel.visibleChildrenAsState().value.toImmutableList() when (selectedMode) { Column -> ColumnExample(children) Row -> RowExample(children) @@ -83,7 +85,7 @@ class LazyListContainerNode constructor( } @Composable - private fun ColumnExample(elements: List>) { + private fun ColumnExample(elements: ImmutableList>) { LazyColumn( modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(horizontal = 16.dp), @@ -97,7 +99,7 @@ class LazyListContainerNode constructor( } @Composable - private fun RowExample(elements: List>) { + private fun RowExample(elements: ImmutableList>) { LazyRow( modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(vertical = 16.dp), @@ -110,7 +112,7 @@ class LazyListContainerNode constructor( } @Composable - private fun GridExample(elements: List>) { + private fun GridExample(elements: ImmutableList>) { LazyVerticalGrid( columns = Fixed(2), modifier = Modifier.fillMaxSize(),