diff --git a/deps.versions.toml b/deps.versions.toml index 74125a759..681ffd86d 100644 --- a/deps.versions.toml +++ b/deps.versions.toml @@ -3,7 +3,7 @@ decompose = "3.2.0" kotlin = "2.0.20" essenty = "2.2.0" -reaktive = "1.2.3" +reaktive = "2.2.0" junit = "4.13.2" jetbrainsCompose = "1.7.0" jetbrainsKotlinWrappers = "1.0.0-pre.608" @@ -25,6 +25,7 @@ kotlin-kotlinGradlePlug = { group = "org.jetbrains.kotlin", name = "kotlin-gradl kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test", version.ref = "kotlin" } essenty-lifecycle = { group = "com.arkivanov.essenty", name = "lifecycle", version.ref = "essenty" } +essenty-lifecycleReaktive = { group = "com.arkivanov.essenty", name = "lifecycle-reaktive", version.ref = "essenty" } essenty-stateKeeper = { group = "com.arkivanov.essenty", name = "state-keeper", version.ref = "essenty" } essenty-instanceKeeper = { group = "com.arkivanov.essenty", name = "instance-keeper", version.ref = "essenty" } essenty-backHandler = { group = "com.arkivanov.essenty", name = "back-handler", version.ref = "essenty" } diff --git a/sample/shared/shared/build.gradle.kts b/sample/shared/shared/build.gradle.kts index 44a6542fb..5c425510e 100644 --- a/sample/shared/shared/build.gradle.kts +++ b/sample/shared/shared/build.gradle.kts @@ -60,6 +60,7 @@ kotlin { api(deps.essenty.lifecycle) api(deps.essenty.stateKeeper) api(deps.essenty.backHandler) + implementation(deps.essenty.lifecycleReaktive) implementation(deps.reaktive.reaktive) implementation(deps.jetbrains.kotlinx.kotlinxSerializationJson) } diff --git a/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/dynamicfeatures/dynamicfeature/DefaultFeatureInstaller.kt b/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/dynamicfeatures/dynamicfeature/DefaultFeatureInstaller.kt index 5b97d7aa4..ce23e1079 100644 --- a/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/dynamicfeatures/dynamicfeature/DefaultFeatureInstaller.kt +++ b/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/dynamicfeatures/dynamicfeature/DefaultFeatureInstaller.kt @@ -18,6 +18,7 @@ import com.google.android.play.core.splitinstall.SplitInstallRequest import com.google.android.play.core.splitinstall.SplitInstallSessionState import com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener import com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus +import kotlin.time.Duration.Companion.seconds class DefaultFeatureInstaller( context: Context @@ -34,7 +35,7 @@ class DefaultFeatureInstaller( // For testing purposes all dynamic features are configured as `install-time`, so simulating installation process private fun Single.simulateInstallationProcessIfNeeded(name: String): Single = takeUnless { name in installedFeatures } - ?.delaySubscription(delayMillis = 3000L, scheduler = mainScheduler) + ?.delaySubscription(delay = 3.seconds, scheduler = mainScheduler) ?.doOnBeforeSuccess { if (it is Result.Installed) { installedFeatures += name diff --git a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/cards/card/DefaultCardComponent.kt b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/cards/card/DefaultCardComponent.kt index 197911c55..50fb471b8 100644 --- a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/cards/card/DefaultCardComponent.kt +++ b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/cards/card/DefaultCardComponent.kt @@ -4,9 +4,9 @@ import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.value.MutableValue import com.arkivanov.decompose.value.Value import com.arkivanov.decompose.value.update -import com.arkivanov.essenty.instancekeeper.ExperimentalInstanceKeeperApi import com.arkivanov.essenty.instancekeeper.InstanceKeeper import com.arkivanov.essenty.instancekeeper.retainedInstance +import com.arkivanov.essenty.lifecycle.reaktive.disposableScope import com.arkivanov.essenty.lifecycle.subscribe import com.arkivanov.essenty.statekeeper.ExperimentalStateKeeperApi import com.arkivanov.essenty.statekeeper.saveable @@ -20,18 +20,19 @@ import com.badoo.reaktive.scheduler.mainScheduler import com.badoo.reaktive.subject.behavior.BehaviorObservable import com.badoo.reaktive.subject.behavior.BehaviorSubject import kotlinx.serialization.builtins.serializer +import kotlin.time.Duration.Companion.milliseconds class DefaultCardComponent( componentContext: ComponentContext, color: Long, number: Int, tickScheduler: Scheduler = mainScheduler, -) : CardComponent, ComponentContext by componentContext, DisposableScope by DisposableScope() { +) : CardComponent, ComponentContext by componentContext, DisposableScope by componentContext.disposableScope() { - @OptIn(ExperimentalStateKeeperApi::class, ExperimentalInstanceKeeperApi::class) + @OptIn(ExperimentalStateKeeperApi::class) private val handler: Handler by saveable(serializer = Int.serializer(), state = { it.count.value }) { savedState -> retainedInstance { - Handler(initialCount = savedState ?: 0, tickScheduler = tickScheduler) + Handler(savedState = savedState, tickScheduler = tickScheduler) } } @@ -43,15 +44,6 @@ class DefaultCardComponent( _model.update { it.copy(text = "Count: $count") } } - lifecycle.subscribe( - onCreate = { setStatus("Created") }, - onStart = { setStatus("Started") }, - onResume = { setStatus("Resumed") }, - onPause = { setStatus("Paused") }, - onStop = { setStatus("Stopped") }, - onDestroy = { setStatus("Destroyed") }, - ) - lifecycle.subscribe( onStart = handler::start, onStop = handler::stop, @@ -63,16 +55,16 @@ class DefaultCardComponent( } private class Handler( - initialCount: Int, + savedState: Int?, private val tickScheduler: Scheduler, ) : InstanceKeeper.Instance { - private val _count = BehaviorSubject(initialCount) + private val _count = BehaviorSubject(savedState ?: 0) val count: BehaviorObservable = _count private var disposable: Disposable? = null fun start() { disposable = - observableInterval(periodMillis = 250L, scheduler = tickScheduler) + observableInterval(period = 250.milliseconds, scheduler = tickScheduler) .subscribe { _count.onNext(_count.value + 1) } } diff --git a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/counters/counter/DefaultCounterComponent.kt b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/counters/counter/DefaultCounterComponent.kt index a0ad6c402..28122f599 100644 --- a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/counters/counter/DefaultCounterComponent.kt +++ b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/counters/counter/DefaultCounterComponent.kt @@ -20,6 +20,7 @@ import com.badoo.reaktive.observable.observableInterval import com.badoo.reaktive.scheduler.Scheduler import com.badoo.reaktive.scheduler.mainScheduler import kotlinx.serialization.Serializable +import kotlin.time.Duration.Companion.milliseconds internal class DefaultCounterComponent( componentContext: ComponentContext, @@ -105,7 +106,7 @@ internal class DefaultCounterComponent( val state: MutableValue = MutableValue(initialState) init { - observableInterval(periodMillis = 250L, scheduler = tickScheduler).subscribeScoped { + observableInterval(period = 250.milliseconds, scheduler = tickScheduler).subscribeScoped { state.update { it.copy(count = it.count + 1) } } } diff --git a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/customnavigation/DefaultKittenComponent.kt b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/customnavigation/DefaultKittenComponent.kt index 14ba77630..07a988152 100644 --- a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/customnavigation/DefaultKittenComponent.kt +++ b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/customnavigation/DefaultKittenComponent.kt @@ -15,6 +15,7 @@ import com.badoo.reaktive.observable.observableInterval import com.badoo.reaktive.observable.subscribe import com.badoo.reaktive.scheduler.mainScheduler import kotlinx.serialization.Serializable +import kotlin.time.Duration.Companion.milliseconds class DefaultKittenComponent( componentContext: ComponentContext, @@ -61,7 +62,7 @@ class DefaultKittenComponent( disposable?.dispose() disposable = - observableInterval(periodMillis = 250L, scheduler = mainScheduler).subscribe(isThreadLocal = true) { + observableInterval(period = 250.milliseconds, scheduler = mainScheduler).subscribe { state.update { it.copy(count = it.count + 1) } } } diff --git a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/DefaultMultiPaneComponent.kt b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/DefaultMultiPaneComponent.kt index 23d613ee0..8d45cae7c 100644 --- a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/DefaultMultiPaneComponent.kt +++ b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/DefaultMultiPaneComponent.kt @@ -14,6 +14,7 @@ import com.arkivanov.decompose.router.panels.isSingle import com.arkivanov.decompose.router.panels.navigate import com.arkivanov.decompose.router.panels.pop import com.arkivanov.decompose.value.Value +import com.arkivanov.essenty.lifecycle.reaktive.disposableScope import com.arkivanov.sample.shared.multipane.author.ArticleAuthorComponent import com.arkivanov.sample.shared.multipane.author.DefaultArticleAuthorComponent import com.arkivanov.sample.shared.multipane.database.DefaultArticleDatabase @@ -21,7 +22,6 @@ import com.arkivanov.sample.shared.multipane.details.ArticleDetailsComponent import com.arkivanov.sample.shared.multipane.details.DefaultArticleDetailsComponent import com.arkivanov.sample.shared.multipane.list.ArticleListComponent import com.arkivanov.sample.shared.multipane.list.DefaultArticleListComponent -import com.arkivanov.sample.shared.multipane.utils.disposableScope import com.badoo.reaktive.disposable.scope.DisposableScope import com.badoo.reaktive.observable.map import com.badoo.reaktive.observable.notNull diff --git a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/author/DefaultArticleAuthorComponent.kt b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/author/DefaultArticleAuthorComponent.kt index 66075e34c..2259da72f 100644 --- a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/author/DefaultArticleAuthorComponent.kt +++ b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/author/DefaultArticleAuthorComponent.kt @@ -4,11 +4,11 @@ import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.value.MutableValue import com.arkivanov.decompose.value.Value import com.arkivanov.decompose.value.update +import com.arkivanov.essenty.lifecycle.reaktive.disposableScope import com.arkivanov.sample.shared.multipane.author.ArticleAuthorComponent.Author import com.arkivanov.sample.shared.multipane.author.ArticleAuthorComponent.Model import com.arkivanov.sample.shared.multipane.database.ArticleDatabase import com.arkivanov.sample.shared.multipane.database.AuthorEntity -import com.arkivanov.sample.shared.multipane.utils.disposableScope import com.badoo.reaktive.disposable.scope.DisposableScope import com.badoo.reaktive.observable.Observable diff --git a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/details/DefaultArticleDetailsComponent.kt b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/details/DefaultArticleDetailsComponent.kt index 91c633aa9..343d0eb29 100644 --- a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/details/DefaultArticleDetailsComponent.kt +++ b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/details/DefaultArticleDetailsComponent.kt @@ -4,11 +4,11 @@ import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.value.MutableValue import com.arkivanov.decompose.value.Value import com.arkivanov.decompose.value.update +import com.arkivanov.essenty.lifecycle.reaktive.disposableScope import com.arkivanov.sample.shared.multipane.database.ArticleDatabase import com.arkivanov.sample.shared.multipane.database.ArticleEntity import com.arkivanov.sample.shared.multipane.details.ArticleDetailsComponent.Article import com.arkivanov.sample.shared.multipane.details.ArticleDetailsComponent.Model -import com.arkivanov.sample.shared.multipane.utils.disposableScope import com.badoo.reaktive.disposable.scope.DisposableScope import com.badoo.reaktive.observable.Observable diff --git a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/list/DefaultArticleListComponent.kt b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/list/DefaultArticleListComponent.kt index 73c5e6efe..86d6b74bf 100644 --- a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/list/DefaultArticleListComponent.kt +++ b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/list/DefaultArticleListComponent.kt @@ -4,11 +4,11 @@ import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.value.MutableValue import com.arkivanov.decompose.value.Value import com.arkivanov.decompose.value.update +import com.arkivanov.essenty.lifecycle.reaktive.disposableScope import com.arkivanov.sample.shared.multipane.database.ArticleDatabase import com.arkivanov.sample.shared.multipane.database.ArticleEntity import com.arkivanov.sample.shared.multipane.list.ArticleListComponent.Article import com.arkivanov.sample.shared.multipane.list.ArticleListComponent.Model -import com.arkivanov.sample.shared.multipane.utils.disposableScope import com.badoo.reaktive.disposable.scope.DisposableScope import com.badoo.reaktive.observable.Observable diff --git a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/utils/ComponentContextExt.kt b/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/utils/ComponentContextExt.kt deleted file mode 100644 index 7b877f3d1..000000000 --- a/sample/shared/shared/src/commonMain/kotlin/com/arkivanov/sample/shared/multipane/utils/ComponentContextExt.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.arkivanov.sample.shared.multipane.utils - -import com.arkivanov.decompose.ComponentContext -import com.arkivanov.essenty.lifecycle.doOnDestroy -import com.badoo.reaktive.disposable.scope.DisposableScope - -internal fun ComponentContext.disposableScope(): DisposableScope { - val scope = DisposableScope() - lifecycle.doOnDestroy(scope::dispose) - - return scope -}