From 7e75b5f8e0be8ba8df0d229a8d7c3cb58c5b7261 Mon Sep 17 00:00:00 2001 From: andreykovalev Date: Thu, 15 Feb 2024 19:37:09 +0000 Subject: [PATCH 1/2] Fix saveStateHolder issue --- .../composable/AppyxInteractionsContainer.kt | 65 +++++++++++-------- .../navigation/composable/ChildRenderer.kt | 2 + 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/appyx-interactions/common/src/commonMain/kotlin/com/bumble/appyx/interactions/composable/AppyxInteractionsContainer.kt b/appyx-interactions/common/src/commonMain/kotlin/com/bumble/appyx/interactions/composable/AppyxInteractionsContainer.kt index ce7120d0b..c31beeb99 100644 --- a/appyx-interactions/common/src/commonMain/kotlin/com/bumble/appyx/interactions/composable/AppyxInteractionsContainer.kt +++ b/appyx-interactions/common/src/commonMain/kotlin/com/bumble/appyx/interactions/composable/AppyxInteractionsContainer.kt @@ -16,6 +16,7 @@ import androidx.compose.runtime.key import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.SaveableStateHolder import androidx.compose.runtime.saveable.rememberSaveableStateHolder import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -34,12 +35,13 @@ import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.round -import com.bumble.appyx.interactions.model.Element +import com.bumble.appyx.interactions.gesture.GestureReferencePoint import com.bumble.appyx.interactions.gesture.GestureValidator import com.bumble.appyx.interactions.gesture.GestureValidator.Companion.defaultValidator import com.bumble.appyx.interactions.gesture.detectDragGesturesOrCancellation import com.bumble.appyx.interactions.gesture.onPointerEvent import com.bumble.appyx.interactions.model.BaseAppyxComponent +import com.bumble.appyx.interactions.model.Element import com.bumble.appyx.interactions.model.removedElements import com.bumble.appyx.interactions.ui.LocalBoxScope import com.bumble.appyx.interactions.ui.LocalMotionProperties @@ -48,7 +50,6 @@ import com.bumble.appyx.interactions.ui.context.UiContext import com.bumble.appyx.interactions.ui.output.ElementUiModel import com.bumble.appyx.interactions.ui.property.impl.position.PositionAlignment import com.bumble.appyx.interactions.ui.property.motionPropertyRenderValue -import com.bumble.appyx.interactions.gesture.GestureReferencePoint private val defaultExtraTouch = 48f.dp @@ -126,35 +127,37 @@ fun AppyxInteractionsContainer( key(elementUiModel.element.id) { val isVisible by elementUiModel.visibleState.collectAsState() elementUiModel.persistentContainer() - saveableStateHolder.SaveableStateProvider(key = elementUiModel.element) { - if (isVisible) { - CompositionLocalProvider( - LocalMotionProperties provides elementUiModel.motionProperties, - ) { - when { - !isGesturesEnabled -> { - Box(modifier = elementUiModel.modifier) { + if (isVisible) { + CompositionLocalProvider( + LocalMotionProperties provides elementUiModel.motionProperties, + ) { + when { + !isGesturesEnabled -> { + Box(modifier = elementUiModel.modifier) { + saveableStateHolder.SaveableStateProvider(key = elementUiModel.element) { elementUi(elementUiModel.element) } } + } - gestureRelativeTo == GestureReferencePoint.Element -> - ElementWithGestureTransformedBoundingBox( - appyxComponent = appyxComponent, - containerSize = containerSize, - gestureExtraTouchAreaPx = gestureExtraTouchAreaPx, - gestureValidator = gestureValidator, - elementUiModel = elementUiModel, - elementUi = elementUi - ) + gestureRelativeTo == GestureReferencePoint.Element -> + ElementWithGestureTransformedBoundingBox( + saveableStateHolder = saveableStateHolder, + appyxComponent = appyxComponent, + containerSize = containerSize, + gestureExtraTouchAreaPx = gestureExtraTouchAreaPx, + gestureValidator = gestureValidator, + elementUiModel = elementUiModel, + elementUi = elementUi + ) - gestureRelativeTo == GestureReferencePoint.Container -> - ElementWithGesture( - appyxComponent = appyxComponent, - elementUiModel = elementUiModel, - elementUi = elementUi - ) - } + gestureRelativeTo == GestureReferencePoint.Container -> + ElementWithGesture( + saveableStateHolder = saveableStateHolder, + appyxComponent = appyxComponent, + elementUiModel = elementUiModel, + elementUi = elementUi + ) } } } @@ -166,6 +169,7 @@ fun AppyxInteractionsContainer( @Composable private fun ElementWithGesture( + saveableStateHolder: SaveableStateHolder, appyxComponent: BaseAppyxComponent, elementUiModel: ElementUiModel, elementUi: @Composable BoxScope.(Element) -> Unit @@ -192,12 +196,15 @@ private fun ElementWithGesture( } .then(elementUiModel.modifier) ) { - elementUi(elementUiModel.element) + saveableStateHolder.SaveableStateProvider(key = elementUiModel.element) { + elementUi(elementUiModel.element) + } } } @Composable private fun ElementWithGestureTransformedBoundingBox( + saveableStateHolder: SaveableStateHolder, appyxComponent: BaseAppyxComponent, containerSize: State, gestureExtraTouchAreaPx: Float, @@ -257,7 +264,9 @@ private fun ElementWithGestureTransf transformedBoundingBox.center - localCenter } ) { - elementUi(elementUiModel.element) + saveableStateHolder.SaveableStateProvider(key = elementUiModel.element) { + elementUi(elementUiModel.element) + } } } diff --git a/appyx-navigation/common/src/commonMain/kotlin/com/bumble/appyx/navigation/composable/ChildRenderer.kt b/appyx-navigation/common/src/commonMain/kotlin/com/bumble/appyx/navigation/composable/ChildRenderer.kt index feebe09e3..7703fa5e8 100644 --- a/appyx-navigation/common/src/commonMain/kotlin/com/bumble/appyx/navigation/composable/ChildRenderer.kt +++ b/appyx-navigation/common/src/commonMain/kotlin/com/bumble/appyx/navigation/composable/ChildRenderer.kt @@ -1,8 +1,10 @@ package com.bumble.appyx.navigation.composable import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable import androidx.compose.ui.Modifier +@Stable interface ChildRenderer { @Suppress("ComposableNaming") // This wants to be 'Invoke' but that won't work with 'operator'. From 4f1f5015e9441546d0d29832de1cbf4ba02ae71d Mon Sep 17 00:00:00 2001 From: andreykovalev Date: Thu, 15 Feb 2024 19:39:57 +0000 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f19576063..23ec1740f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - [#670](https://github.com/bumble-tech/appyx/pull/670) - Fixes ios lifecycle - [#673](https://github.com/bumble-tech/appyx/pull/673) – Fix canHandeBackPress typo +- [#671](https://github.com/bumble-tech/appyx/issue/671) – Fix ui state saving issue ### Enhancement