Skip to content

Commit

Permalink
Add support to save non-mutable int in StateSnapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
jingwei99 committed Sep 22, 2023
1 parent a30f3a9 commit 859c946
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 16 deletions.
1 change: 1 addition & 0 deletions redwood-lazylayout-compose/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ kotlin {
commonMain {
dependencies {
api projects.redwoodLazylayoutWidget
implementation libs.jetbrains.compose.runtime.saveable
}
}
commonTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@
*/
package app.cash.redwood.lazylayout.compose

import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue

@Composable
public fun rememberLazyListState(
initialFirstVisibleItemIndex: Int = 0,
): LazyListState {
return remember {
return rememberSaveable(saver = LazyListState.Saver) {
LazyListState(
initialFirstVisibleItemIndex,
)
Expand All @@ -46,4 +47,17 @@ public class LazyListState(
firstVisibleItemIndex = index
scrollToItemTriggeredId++
}
public companion object {
/**
* The default [Saver] implementation for [LazyListState].
*/
public val Saver: Saver<LazyListState, *> = Saver(
save = { it.firstVisibleItemIndex },
restore = {
LazyListState(
firstVisibleItemIndex = it,
)
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ private class RedwoodZiplineTreehouseUi(
}

override fun snapshotState(): StateSnapshot? {
// performSave is not picking up other values, why?
val savedState = saveableStateRegistry.performSave()
return savedState.toStateSnapshot()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,28 @@ package app.cash.redwood.treehouse
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import kotlin.jvm.JvmInline
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.booleanOrNull
import kotlinx.serialization.json.doubleOrNull
import kotlinx.serialization.json.intOrNull

@Serializable
public class StateSnapshot(
public val content: Map<String, List<JsonElement?>>,
public val content: Map<String, List<@Contextual Saveable>>
) {
public fun toValuesMap(): Map<String, List<Any?>>? {
public fun toValuesMap(): Map<String, List<Any?>> {
return content.mapValues { entry ->
entry.value.map { mutableStateOf(it.fromJsonElement()) }
entry.value.map {
if (it.isMutableState) {
mutableStateOf(it.value)
} else {
it.value.fromJsonElement()
}
}
}
}

Expand All @@ -46,10 +54,10 @@ public class StateSnapshot(
*/
public fun Map<String, List<Any?>>.toStateSnapshot(): StateSnapshot = StateSnapshot(
mapValues { entry ->
entry.value.map { element ->
when (element) {
is MutableState<*> -> element.value.toJsonElement()
else -> error("unexpected type: $this")
entry.value.map {element ->
when(element) {
is MutableState<*> -> Saveable(true, element.value.toJsonElement())
else -> Saveable(false, element.toJsonElement())
}
}
},
Expand All @@ -58,6 +66,7 @@ public fun Map<String, List<Any?>>.toStateSnapshot(): StateSnapshot = StateSnaps
private fun Any?.toJsonElement(): JsonElement {
return when (this) {
is String -> JsonPrimitive(this)
is Int -> JsonPrimitive(this)
is List<*> -> JsonArray(map { it.toJsonElement() })
is JsonElement -> this
else -> error("unexpected type: $this")
Expand All @@ -68,11 +77,9 @@ private fun Any?.toJsonElement(): JsonElement {
private fun JsonElement?.fromJsonElement(): Any {
return when (this) {
is JsonPrimitive -> {
if (this.isString) {
return content
}
return booleanOrNull ?: doubleOrNull ?: error("unexpected type: $this")
// TODO add other primitive types (double, float, long) when needed
if (this.isString) { return content }
return booleanOrNull ?: doubleOrNull ?: intOrNull ?: error("unexpected type: $this")
// TODO add other primitive types (float, long) when needed
}

is JsonArray -> listOf({ this.forEach { it.toJsonElement() } })
Expand All @@ -81,3 +88,8 @@ private fun JsonElement?.fromJsonElement(): Any {
else -> error("unexpected type: $this")
}
}

public data class Saveable (
val isMutableState: Boolean,
val value: JsonElement
)
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import app.cash.redwood.layout.compose.Column
import app.cash.redwood.layout.compose.Row
import app.cash.redwood.lazylayout.compose.ExperimentalRedwoodLazyLayoutApi
import app.cash.redwood.lazylayout.compose.LazyColumn
import app.cash.redwood.lazylayout.compose.LazyListState
import app.cash.redwood.lazylayout.compose.items
import app.cash.redwood.lazylayout.compose.rememberLazyListState
import app.cash.redwood.ui.Margin
Expand Down Expand Up @@ -96,7 +97,9 @@ private fun LazyColumn(
override fun SaverScope.save(value: TextFieldState) = value.text
}

var searchTerm by rememberSaveable(stateSaver = searchTermSaver) { mutableStateOf(TextFieldState("")) }
var searchTerm by rememberSaveable(stateSaver = searchTermSaver) {
mutableStateOf(TextFieldState(""))
}

LaunchedEffect(refreshSignal) {
try {
Expand Down Expand Up @@ -173,7 +176,14 @@ private fun NestedFlexBoxContainers(httpClient: HttpClient, navigator: Navigator
override fun SaverScope.save(value: TextFieldState) = value.text
}

var searchTerm by rememberSaveable(stateSaver = searchTermSaver) { mutableStateOf(TextFieldState("")) }
var searchTerm by rememberSaveable(stateSaver = searchTermSaver) {
error("boom")
mutableStateOf(TextFieldState(""))
}
var searchTerm1 by rememberSaveable(stateSaver = searchTermSaver) {
error("boom")
mutableStateOf(TextFieldState("hhh"))
}

LaunchedEffect(Unit) {
try {
Expand Down

0 comments on commit 859c946

Please sign in to comment.