Skip to content

Commit

Permalink
Merge pull request #377 from KovalevAndrey/savable-state-holder-remov…
Browse files Browse the repository at this point in the history
…e-state

SaveableStateHolder remove state for destroyed elements
  • Loading branch information
KovalevAndrey authored Mar 15, 2023
2 parents 97fc82c + f15d226 commit dcf7147
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 5 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Pending changes

- [#375](https://github.com/bumble-tech/appyx/issues/375)**Fixed**: SaveableStateHolder does no longer save state for destroyed elements

---

Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ plugin-detekt = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", v
plugin-android = "com.android.tools.build:gradle:7.3.1"

detekt-compose = "com.twitter.compose.rules:detekt:0.0.26"
toolargetool = "com.gu.android:toolargetool:0.3.0"

[plugins]
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.navigation.NavElement
import com.bumble.appyx.core.navigation.NavElements
import com.bumble.appyx.core.navigation.NavModel
Expand All @@ -29,6 +27,8 @@ import com.bumble.appyx.core.navigation.transition.TransitionBounds
import com.bumble.appyx.core.navigation.transition.TransitionDescriptor
import com.bumble.appyx.core.navigation.transition.TransitionHandler
import com.bumble.appyx.core.navigation.transition.TransitionParams
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.node.ParentNode
import kotlinx.coroutines.flow.map

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.bumble.appyx.core.composable

import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
Expand All @@ -15,13 +16,14 @@ import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import com.bumble.appyx.core.node.ParentNode
import com.bumble.appyx.core.navigation.NavModel
import com.bumble.appyx.core.navigation.removedElementKeys
import com.bumble.appyx.core.navigation.transition.JumpToEndTransitionHandler
import com.bumble.appyx.core.navigation.transition.TransitionBounds
import com.bumble.appyx.core.navigation.transition.TransitionDescriptor
import com.bumble.appyx.core.navigation.transition.TransitionHandler
import com.bumble.appyx.core.navigation.transition.TransitionParams
import com.bumble.appyx.core.node.ParentNode
import kotlinx.coroutines.flow.map
import kotlin.reflect.KClass

Expand Down Expand Up @@ -123,6 +125,21 @@ class ChildrenTransitionScope<T : Any, S>(
transitionDescriptor: TransitionDescriptor<T, S>
) -> Unit
) {
val saveableStateHolder = rememberSaveableStateHolder()

LaunchedEffect(navModel) {
navModel
.removedElementKeys()
.map { list ->
list.filter { clazz.isInstance(it.navTarget) }
}
.collect { deletedKeys ->
deletedKeys.forEach { navKey ->
saveableStateHolder.removeState(navKey)
}
}
}

val visibleElementsFlow = remember {
this@ChildrenTransitionScope
.navModel
Expand All @@ -135,7 +152,7 @@ class ChildrenTransitionScope<T : Any, S>(
}
val children by visibleElementsFlow.collectAsState(emptyList())

val saveableStateHolder = rememberSaveableStateHolder()

children.forEach { navElement ->
key(navElement.key.id) {
Child(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.bumble.appyx.core.navigation

import com.bumble.appyx.core.withPrevious
import kotlinx.coroutines.flow.map

internal fun <NavTarget, State> NavModel<NavTarget, State>.removedElementKeys() =
this
.elements
.withPrevious()
.map { values ->
val previousKeys = values.previous?.map { it.key }.orEmpty()
val currentKeys = values.current.map { it.key }
previousKeys.filter { element ->
!currentKeys.contains(element)
}
}
1 change: 1 addition & 0 deletions samples/sandbox/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ dependencies {
implementation(libs.rxjava2)
implementation(libs.rxandroid2)
implementation(libs.rxrelay2)
implementation(libs.toolargetool)

testImplementation(libs.androidx.arch.core.testing)
testImplementation(libs.junit)
Expand Down
1 change: 1 addition & 0 deletions samples/sandbox/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:name=".sandbox.SandboxApplication"
android:supportsRtl="true"
android:theme="@style/Theme.Appyx">
<activity
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.bumble.appyx.sandbox

import android.app.Application
import com.gu.toolargetool.TooLargeTool

class SandboxApplication: Application() {

override fun onCreate() {
super.onCreate()
TooLargeTool.startLogging(this)
}
}

0 comments on commit dcf7147

Please sign in to comment.