mirror of
https://github.com/jlengrand/compose-multiplatform.git
synced 2026-05-17 08:11:21 +00:00
TodoApp. Updated Decompose to 0.5.1 and MVIKotlin to 3.0.0-beta01. (#1896)
This commit is contained in:
@@ -34,7 +34,7 @@ class MainActivity : AppCompatActivity() {
|
||||
private fun todoRoot(componentContext: ComponentContext): TodoRoot =
|
||||
TodoRootComponent(
|
||||
componentContext = componentContext,
|
||||
storeFactory = LoggingStoreFactory(TimeTravelStoreFactory(DefaultStoreFactory())),
|
||||
storeFactory = LoggingStoreFactory(TimeTravelStoreFactory()),
|
||||
database = DefaultTodoSharedDatabase(TodoDatabaseDriver(context = this))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ object Deps {
|
||||
|
||||
object ArkIvanov {
|
||||
object MVIKotlin {
|
||||
private const val VERSION = "3.0.0-alpha01"
|
||||
private const val VERSION = "3.0.0-beta01"
|
||||
const val rx = "com.arkivanov.mvikotlin:rx:$VERSION"
|
||||
const val mvikotlin = "com.arkivanov.mvikotlin:mvikotlin:$VERSION"
|
||||
const val mvikotlinMain = "com.arkivanov.mvikotlin:mvikotlin-main:$VERSION"
|
||||
@@ -56,10 +56,15 @@ object Deps {
|
||||
}
|
||||
|
||||
object Decompose {
|
||||
private const val VERSION = "0.3.1"
|
||||
private const val VERSION = "0.5.1"
|
||||
const val decompose = "com.arkivanov.decompose:decompose:$VERSION"
|
||||
const val extensionsCompose = "com.arkivanov.decompose:extensions-compose-jetbrains:$VERSION"
|
||||
}
|
||||
|
||||
object Essenty {
|
||||
private const val VERSION = "0.2.2"
|
||||
const val lifecycle = "com.arkivanov.essenty:lifecycle:$VERSION"
|
||||
}
|
||||
}
|
||||
|
||||
object Badoo {
|
||||
|
||||
@@ -30,17 +30,17 @@ internal class TodoEditStoreProvider(
|
||||
reducer = ReducerImpl
|
||||
) {}
|
||||
|
||||
private sealed class Result {
|
||||
data class Loaded(val item: TodoItem) : Result()
|
||||
data class TextChanged(val text: String) : Result()
|
||||
data class DoneChanged(val isDone: Boolean) : Result()
|
||||
private sealed class Msg {
|
||||
data class Loaded(val item: TodoItem) : Msg()
|
||||
data class TextChanged(val text: String) : Msg()
|
||||
data class DoneChanged(val isDone: Boolean) : Msg()
|
||||
}
|
||||
|
||||
private inner class ExecutorImpl : ReaktiveExecutor<Intent, Unit, State, Result, Label>() {
|
||||
private inner class ExecutorImpl : ReaktiveExecutor<Intent, Unit, State, Msg, Label>() {
|
||||
override fun executeAction(action: Unit, getState: () -> State) {
|
||||
database
|
||||
.load(id = id)
|
||||
.map(Result::Loaded)
|
||||
.map(Msg::Loaded)
|
||||
.observeOn(mainScheduler)
|
||||
.subscribeScoped(onSuccess = ::dispatch)
|
||||
}
|
||||
@@ -52,24 +52,24 @@ internal class TodoEditStoreProvider(
|
||||
}
|
||||
|
||||
private fun setText(text: String, state: State) {
|
||||
dispatch(Result.TextChanged(text = text))
|
||||
dispatch(Msg.TextChanged(text = text))
|
||||
publish(Label.Changed(TodoItem(text = text, isDone = state.isDone)))
|
||||
database.setText(id = id, text = text).subscribeScoped()
|
||||
}
|
||||
|
||||
private fun setDone(isDone: Boolean, state: State) {
|
||||
dispatch(Result.DoneChanged(isDone = isDone))
|
||||
dispatch(Msg.DoneChanged(isDone = isDone))
|
||||
publish(Label.Changed(TodoItem(text = state.text, isDone = isDone)))
|
||||
database.setDone(id = id, isDone = isDone).subscribeScoped()
|
||||
}
|
||||
}
|
||||
|
||||
private object ReducerImpl : Reducer<State, Result> {
|
||||
override fun State.reduce(result: Result): State =
|
||||
when (result) {
|
||||
is Result.Loaded -> copy(text = result.item.text, isDone = result.item.isDone)
|
||||
is Result.TextChanged -> copy(text = result.text)
|
||||
is Result.DoneChanged -> copy(isDone = result.isDone)
|
||||
private object ReducerImpl : Reducer<State, Msg> {
|
||||
override fun State.reduce(msg: Msg): State =
|
||||
when (msg) {
|
||||
is Msg.Loaded -> copy(text = msg.item.text, isDone = msg.item.isDone)
|
||||
is Msg.TextChanged -> copy(text = msg.text)
|
||||
is Msg.DoneChanged -> copy(isDone = msg.isDone)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,19 +28,19 @@ internal class TodoMainStoreProvider(
|
||||
reducer = ReducerImpl
|
||||
) {}
|
||||
|
||||
private sealed class Result {
|
||||
data class ItemsLoaded(val items: List<TodoItem>) : Result()
|
||||
data class ItemDoneChanged(val id: Long, val isDone: Boolean) : Result()
|
||||
data class ItemDeleted(val id: Long) : Result()
|
||||
data class TextChanged(val text: String) : Result()
|
||||
private sealed class Msg {
|
||||
data class ItemsLoaded(val items: List<TodoItem>) : Msg()
|
||||
data class ItemDoneChanged(val id: Long, val isDone: Boolean) : Msg()
|
||||
data class ItemDeleted(val id: Long) : Msg()
|
||||
data class TextChanged(val text: String) : Msg()
|
||||
}
|
||||
|
||||
private inner class ExecutorImpl : ReaktiveExecutor<Intent, Unit, State, Result, Nothing>() {
|
||||
private inner class ExecutorImpl : ReaktiveExecutor<Intent, Unit, State, Msg, Nothing>() {
|
||||
override fun executeAction(action: Unit, getState: () -> State) {
|
||||
database
|
||||
.updates
|
||||
.observeOn(mainScheduler)
|
||||
.map(Result::ItemsLoaded)
|
||||
.map(Msg::ItemsLoaded)
|
||||
.subscribeScoped(onNext = ::dispatch)
|
||||
}
|
||||
|
||||
@@ -48,35 +48,35 @@ internal class TodoMainStoreProvider(
|
||||
when (intent) {
|
||||
is Intent.SetItemDone -> setItemDone(id = intent.id, isDone = intent.isDone)
|
||||
is Intent.DeleteItem -> deleteItem(id = intent.id)
|
||||
is Intent.SetText -> dispatch(Result.TextChanged(text = intent.text))
|
||||
is Intent.SetText -> dispatch(Msg.TextChanged(text = intent.text))
|
||||
is Intent.AddItem -> addItem(state = getState())
|
||||
}
|
||||
|
||||
private fun setItemDone(id: Long, isDone: Boolean) {
|
||||
dispatch(Result.ItemDoneChanged(id = id, isDone = isDone))
|
||||
dispatch(Msg.ItemDoneChanged(id = id, isDone = isDone))
|
||||
database.setDone(id = id, isDone = isDone).subscribeScoped()
|
||||
}
|
||||
|
||||
private fun deleteItem(id: Long) {
|
||||
dispatch(Result.ItemDeleted(id = id))
|
||||
dispatch(Msg.ItemDeleted(id = id))
|
||||
database.delete(id = id).subscribeScoped()
|
||||
}
|
||||
|
||||
private fun addItem(state: State) {
|
||||
if (state.text.isNotEmpty()) {
|
||||
dispatch(Result.TextChanged(text = ""))
|
||||
dispatch(Msg.TextChanged(text = ""))
|
||||
database.add(text = state.text).subscribeScoped()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object ReducerImpl : Reducer<State, Result> {
|
||||
override fun State.reduce(result: Result): State =
|
||||
when (result) {
|
||||
is Result.ItemsLoaded -> copy(items = result.items.sorted())
|
||||
is Result.ItemDoneChanged -> update(id = result.id) { copy(isDone = result.isDone) }
|
||||
is Result.ItemDeleted -> copy(items = items.filterNot { it.id == result.id })
|
||||
is Result.TextChanged -> copy(text = result.text)
|
||||
private object ReducerImpl : Reducer<State, Msg> {
|
||||
override fun State.reduce(msg: Msg): State =
|
||||
when (msg) {
|
||||
is Msg.ItemsLoaded -> copy(items = msg.items.sorted())
|
||||
is Msg.ItemDoneChanged -> update(id = msg.id) { copy(isDone = msg.isDone) }
|
||||
is Msg.ItemDeleted -> copy(items = items.filterNot { it.id == msg.id })
|
||||
is Msg.TextChanged -> copy(text = msg.text)
|
||||
}
|
||||
|
||||
private inline fun State.update(id: Long, func: TodoItem.() -> TodoItem): State {
|
||||
|
||||
@@ -11,13 +11,13 @@ kotlin {
|
||||
binaries {
|
||||
framework {
|
||||
baseName = "Todo"
|
||||
transitiveExport = true
|
||||
linkerOpts.add("-lsqlite3")
|
||||
export(project(":common:database"))
|
||||
export(project(":common:main"))
|
||||
export(project(":common:edit"))
|
||||
export(Deps.ArkIvanov.Decompose.decompose)
|
||||
export(Deps.ArkIvanov.MVIKotlin.mvikotlinMain)
|
||||
export(Deps.ArkIvanov.Essenty.lifecycle)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ kotlin {
|
||||
api(project(":common:edit"))
|
||||
api(Deps.ArkIvanov.Decompose.decompose)
|
||||
api(Deps.ArkIvanov.MVIKotlin.mvikotlinMain)
|
||||
api(Deps.ArkIvanov.Essenty.lifecycle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package example.todo.common.root
|
||||
|
||||
import com.arkivanov.decompose.RouterState
|
||||
import com.arkivanov.decompose.router.RouterState
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import example.todo.common.edit.TodoEdit
|
||||
import example.todo.common.main.TodoMain
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package example.todo.common.root.integration
|
||||
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.RouterState
|
||||
import com.arkivanov.decompose.pop
|
||||
import com.arkivanov.decompose.push
|
||||
import com.arkivanov.decompose.router
|
||||
import com.arkivanov.decompose.router.RouterState
|
||||
import com.arkivanov.decompose.router.pop
|
||||
import com.arkivanov.decompose.router.push
|
||||
import com.arkivanov.decompose.router.router
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import com.arkivanov.essenty.parcelable.Parcelable
|
||||
import com.arkivanov.essenty.parcelable.Parcelize
|
||||
|
||||
Reference in New Issue
Block a user