Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change rememberRetain not to retain the value of removed node #1794

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
019c8cc
Added navigableCircuitContentRetainTest
vulpeszerda Nov 8, 2024
5b279d4
Added condition retain test
vulpeszerda Nov 13, 2024
4b0cc82
Changed rememberRetained to be cleared when node removed
vulpeszerda Nov 12, 2024
d769169
Changed AndroidContinuity to save values on stopped
vulpeszerda Nov 12, 2024
465f98f
Fixed recreation test scenario
vulpeszerda Nov 12, 2024
24d8547
Replaced registry usage with RetainedStateProvider
vulpeszerda Nov 12, 2024
affec25
Fixed retainedTest to use RetainedStateProvider
vulpeszerda Nov 12, 2024
c42dd26
Merge branch 'main' into remember-retained-redesigned
vulpeszerda Nov 21, 2024
67d156f
Generate apiDumps
vulpeszerda Nov 21, 2024
ff654b4
Replaced RetainedStateProvider with RetainedStateHolder
vulpeszerda Nov 22, 2024
5d30dd7
Removed duplicated codes
vulpeszerda Nov 22, 2024
a367cbb
Changed to use record.registryKey
vulpeszerda Nov 22, 2024
0e4e8e3
Moved RetainedStateProvider to inner of movableContentOf
vulpeszerda Nov 22, 2024
9fbc2df
Restored un-intended changes
vulpeszerda Nov 22, 2024
fb672cf
Added removeState in RetainedStateHolder
vulpeszerda Nov 23, 2024
b6b0cec
Merge branch 'main' into remember-retained-redesigned
vulpeszerda Dec 17, 2024
16cf579
Changed RetainedStateHolder to use ReusableContent
vulpeszerda Jan 11, 2025
ff477ad
Changed RetainedStateHolderWithReturn to use key (instead of Reusable…
vulpeszerda Jan 12, 2025
7900ffb
Changed test method names for more readability
vulpeszerda Jan 12, 2025
df33d07
Added saveAll return value
vulpeszerda Jan 12, 2025
82e84a1
Changed RetainedStateRegistry not to save empty registry
vulpeszerda Jan 12, 2025
1e8083e
Add RetainedStateHolderTests (cherry-pick)
ZacSweers Feb 2, 2024
afebc7a
Added default RetainedStateRegistry
vulpeszerda Jan 12, 2025
9714ce3
Added RetainedStateHolder to star sample
vulpeszerda Jan 12, 2025
0c3c6b1
spotless
vulpeszerda Jan 12, 2025
ffcf6f6
apiDump
vulpeszerda Jan 12, 2025
91c2fcd
Fixed lint
vulpeszerda Jan 12, 2025
b726772
Moved rememberRetainedStateHolder declaration in NavigableCircuitContent
vulpeszerda Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import com.slack.circuit.backstack.providedValuesForBackStack
import com.slack.circuit.retained.CanRetainChecker
import com.slack.circuit.retained.LocalCanRetainChecker
import com.slack.circuit.retained.LocalRetainedStateRegistry
import com.slack.circuit.retained.RetainedStateProvider
import com.slack.circuit.retained.RetainedStateRegistry
import com.slack.circuit.retained.rememberRetained
import com.slack.circuit.runtime.InternalCircuitApi
Expand Down Expand Up @@ -179,21 +180,16 @@ private fun <R : Record> buildCircuitContentProviders(
// Now provide a new registry to the content for it to store any retained state in,
// along with a retain checker which is always true (as upstream registries will
// maintain the lifetime), and the other provided values
val recordRetainedStateRegistry =
rememberRetained(key = record.registryKey) { RetainedStateRegistry() }

CompositionLocalProvider(
LocalRetainedStateRegistry provides recordRetainedStateRegistry,
LocalCanRetainChecker provides CanRetainChecker.Always,
LocalRecordLifecycle provides lifecycle,
) {
CircuitContent(
screen = record.screen,
navigator = lastNavigator,
circuit = lastCircuit,
unavailableContent = lastUnavailableRoute,
key = record.key,
)
RetainedStateProvider(record.registryKey) {
CompositionLocalProvider(LocalRecordLifecycle provides lifecycle) {
CircuitContent(
screen = record.screen,
navigator = lastNavigator,
circuit = lastCircuit,
unavailableContent = lastUnavailableRoute,
key = record.key,
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ package com.slack.circuit.foundation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
import com.slack.circuit.foundation.internal.withCompositionLocalProvider
import com.slack.circuit.retained.LocalRetainedStateRegistry
import com.slack.circuit.retained.RetainedStateRegistry
import com.slack.circuit.retained.rememberRetained
import com.slack.circuit.foundation.internal.withRetainedStateProvider
import com.slack.circuit.runtime.CircuitUiState
import com.slack.circuit.runtime.presenter.Presenter

Expand Down Expand Up @@ -62,12 +59,9 @@ public fun <T> pausableState(
val saveableStateHolder = rememberSaveableStateHolderWithReturn()

return if (isActive || state.value == null) {
val retainedStateRegistry = rememberRetained(key = key) { RetainedStateRegistry() }
withCompositionLocalProvider(LocalRetainedStateRegistry provides retainedStateRegistry) {
saveableStateHolder.SaveableStateProvider(
key = key ?: "pausable_state",
content = produceState,
)
val finalKey = key ?: "pausable_state"
withRetainedStateProvider(finalKey) {
saveableStateHolder.SaveableStateProvider(key = finalKey, content = produceState)
}
.also {
// Store the last emitted state
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2024 Slack Technologies, LLC
// SPDX-License-Identifier: Apache-2.0
package com.slack.circuit.foundation.internal

import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import com.slack.circuit.retained.CanRetainChecker
import com.slack.circuit.retained.LocalCanRetainChecker
import com.slack.circuit.retained.LocalRetainedStateRegistry
import com.slack.circuit.retained.RetainedStateProvider
import com.slack.circuit.retained.RetainedStateRegistry
import com.slack.circuit.retained.rememberRetained

/** Copy of [RetainedStateProvider] to return content value */
@Composable
internal fun <T> withRetainedStateProvider(key: String, content: @Composable () -> T): T {
val canRetainChecker = LocalCanRetainChecker.current ?: CanRetainChecker.Always
val parentRegistry = LocalRetainedStateRegistry.current
val registry = rememberRetained(key = key) { RetainedStateRegistry() }
return withCompositionLocalProvider(
LocalRetainedStateRegistry provides registry,
LocalCanRetainChecker provides CanRetainChecker.Always,
) {
content()
}
.also {
DisposableEffect(key, registry) {
onDispose {
registry.saveAll()
if (canRetainChecker.canRetain(registry)) {
parentRegistry.saveValue(key)
}
}
}
}
}
Loading