All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.arkivanov.decompose.extensions.compose.jetbrains.Children.kt Maven / Gradle / Ivy

package com.arkivanov.decompose.extensions.compose.jetbrains

import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.SaveableStateHolder
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.Child
import com.arkivanov.decompose.ExperimentalDecomposeApi
import com.arkivanov.decompose.extensions.compose.jetbrains.animation.child.ChildAnimation
import com.arkivanov.decompose.extensions.compose.jetbrains.animation.child.emptyChildAnimation
import com.arkivanov.decompose.router.RouterState
import com.arkivanov.decompose.value.Value

typealias ChildContent = @Composable (child: Child.Created) -> Unit

@OptIn(ExperimentalDecomposeApi::class)
@Composable
fun  Children(
    routerState: RouterState,
    modifier: Modifier = Modifier,
    animation: ChildAnimation = emptyChildAnimation(),
    content: ChildContent
) {
    val holder = rememberSaveableStateHolder()

    holder.retainStates(routerState.getConfigurations())

    animation(routerState, modifier) { child ->
        holder.SaveableStateProvider(child.configuration.key()) {
            content(child)
        }
    }
}

@OptIn(ExperimentalDecomposeApi::class)
@Composable
fun  Children(
    routerState: Value>,
    modifier: Modifier = Modifier,
    animation: ChildAnimation = emptyChildAnimation(),
    content: ChildContent
) {
    val state = routerState.subscribeAsState()

    Children(
        routerState = state.value,
        modifier = modifier,
        animation = animation,
        content = content
    )
}

private fun RouterState<*, *>.getConfigurations(): Set {
    val set = HashSet()
    backStack.forEach { set += it.configuration.key() }
    set += activeChild.configuration.key()

    return set
}

private fun Any.key(): String = "${this::class.simpleName}_${hashCode().toString(radix = 36)}"

@Composable
private fun SaveableStateHolder.retainStates(currentKeys: Set) {
    val keys = remember(this) { Keys(currentKeys) }

    DisposableEffect(this, currentKeys) {
        keys.set.forEach {
            if (it !in currentKeys) {
                removeState(it)
            }
        }

        keys.set = currentKeys

        onDispose {}
    }
}

private class Keys(
    var set: Set
)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy