Browse Source

TodoApp. Updated Decompose to 0.5.1 and MVIKotlin to 3.0.0-beta01. (#1896)

pull/1922/head
Arkadii Ivanov 3 years ago committed by GitHub
parent
commit
265de0fc28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      examples/todoapp/android/src/main/java/example/todo/android/MainActivity.kt
  2. 9
      examples/todoapp/buildSrc/buildSrc/src/main/kotlin/Deps.kt
  3. 28
      examples/todoapp/common/edit/src/commonMain/kotlin/example/todo/common/edit/store/TodoEditStoreProvider.kt
  4. 36
      examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/store/TodoMainStoreProvider.kt
  5. 3
      examples/todoapp/common/root/build.gradle.kts
  6. 2
      examples/todoapp/common/root/src/commonMain/kotlin/example/todo/common/root/TodoRoot.kt
  7. 8
      examples/todoapp/common/root/src/commonMain/kotlin/example/todo/common/root/integration/TodoRootComponent.kt

2
examples/todoapp/android/src/main/java/example/todo/android/MainActivity.kt

@ -34,7 +34,7 @@ class MainActivity : AppCompatActivity() {
private fun todoRoot(componentContext: ComponentContext): TodoRoot = private fun todoRoot(componentContext: ComponentContext): TodoRoot =
TodoRootComponent( TodoRootComponent(
componentContext = componentContext, componentContext = componentContext,
storeFactory = LoggingStoreFactory(TimeTravelStoreFactory(DefaultStoreFactory())), storeFactory = LoggingStoreFactory(TimeTravelStoreFactory()),
database = DefaultTodoSharedDatabase(TodoDatabaseDriver(context = this)) database = DefaultTodoSharedDatabase(TodoDatabaseDriver(context = this))
) )
} }

9
examples/todoapp/buildSrc/buildSrc/src/main/kotlin/Deps.kt

@ -46,7 +46,7 @@ object Deps {
object ArkIvanov { object ArkIvanov {
object MVIKotlin { 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 rx = "com.arkivanov.mvikotlin:rx:$VERSION"
const val mvikotlin = "com.arkivanov.mvikotlin:mvikotlin:$VERSION" const val mvikotlin = "com.arkivanov.mvikotlin:mvikotlin:$VERSION"
const val mvikotlinMain = "com.arkivanov.mvikotlin:mvikotlin-main:$VERSION" const val mvikotlinMain = "com.arkivanov.mvikotlin:mvikotlin-main:$VERSION"
@ -56,10 +56,15 @@ object Deps {
} }
object Decompose { 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 decompose = "com.arkivanov.decompose:decompose:$VERSION"
const val extensionsCompose = "com.arkivanov.decompose:extensions-compose-jetbrains:$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 { object Badoo {

28
examples/todoapp/common/edit/src/commonMain/kotlin/example/todo/common/edit/store/TodoEditStoreProvider.kt

@ -30,17 +30,17 @@ internal class TodoEditStoreProvider(
reducer = ReducerImpl reducer = ReducerImpl
) {} ) {}
private sealed class Result { private sealed class Msg {
data class Loaded(val item: TodoItem) : Result() data class Loaded(val item: TodoItem) : Msg()
data class TextChanged(val text: String) : Result() data class TextChanged(val text: String) : Msg()
data class DoneChanged(val isDone: Boolean) : Result() 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) { override fun executeAction(action: Unit, getState: () -> State) {
database database
.load(id = id) .load(id = id)
.map(Result::Loaded) .map(Msg::Loaded)
.observeOn(mainScheduler) .observeOn(mainScheduler)
.subscribeScoped(onSuccess = ::dispatch) .subscribeScoped(onSuccess = ::dispatch)
} }
@ -52,24 +52,24 @@ internal class TodoEditStoreProvider(
} }
private fun setText(text: String, state: State) { 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))) publish(Label.Changed(TodoItem(text = text, isDone = state.isDone)))
database.setText(id = id, text = text).subscribeScoped() database.setText(id = id, text = text).subscribeScoped()
} }
private fun setDone(isDone: Boolean, state: State) { 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))) publish(Label.Changed(TodoItem(text = state.text, isDone = isDone)))
database.setDone(id = id, isDone = isDone).subscribeScoped() database.setDone(id = id, isDone = isDone).subscribeScoped()
} }
} }
private object ReducerImpl : Reducer<State, Result> { private object ReducerImpl : Reducer<State, Msg> {
override fun State.reduce(result: Result): State = override fun State.reduce(msg: Msg): State =
when (result) { when (msg) {
is Result.Loaded -> copy(text = result.item.text, isDone = result.item.isDone) is Msg.Loaded -> copy(text = msg.item.text, isDone = msg.item.isDone)
is Result.TextChanged -> copy(text = result.text) is Msg.TextChanged -> copy(text = msg.text)
is Result.DoneChanged -> copy(isDone = result.isDone) is Msg.DoneChanged -> copy(isDone = msg.isDone)
} }
} }

36
examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/store/TodoMainStoreProvider.kt

@ -28,19 +28,19 @@ internal class TodoMainStoreProvider(
reducer = ReducerImpl reducer = ReducerImpl
) {} ) {}
private sealed class Result { private sealed class Msg {
data class ItemsLoaded(val items: List<TodoItem>) : Result() data class ItemsLoaded(val items: List<TodoItem>) : Msg()
data class ItemDoneChanged(val id: Long, val isDone: Boolean) : Result() data class ItemDoneChanged(val id: Long, val isDone: Boolean) : Msg()
data class ItemDeleted(val id: Long) : Result() data class ItemDeleted(val id: Long) : Msg()
data class TextChanged(val text: String) : Result() 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) { override fun executeAction(action: Unit, getState: () -> State) {
database database
.updates .updates
.observeOn(mainScheduler) .observeOn(mainScheduler)
.map(Result::ItemsLoaded) .map(Msg::ItemsLoaded)
.subscribeScoped(onNext = ::dispatch) .subscribeScoped(onNext = ::dispatch)
} }
@ -48,35 +48,35 @@ internal class TodoMainStoreProvider(
when (intent) { when (intent) {
is Intent.SetItemDone -> setItemDone(id = intent.id, isDone = intent.isDone) is Intent.SetItemDone -> setItemDone(id = intent.id, isDone = intent.isDone)
is Intent.DeleteItem -> deleteItem(id = intent.id) 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()) is Intent.AddItem -> addItem(state = getState())
} }
private fun setItemDone(id: Long, isDone: Boolean) { 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() database.setDone(id = id, isDone = isDone).subscribeScoped()
} }
private fun deleteItem(id: Long) { private fun deleteItem(id: Long) {
dispatch(Result.ItemDeleted(id = id)) dispatch(Msg.ItemDeleted(id = id))
database.delete(id = id).subscribeScoped() database.delete(id = id).subscribeScoped()
} }
private fun addItem(state: State) { private fun addItem(state: State) {
if (state.text.isNotEmpty()) { if (state.text.isNotEmpty()) {
dispatch(Result.TextChanged(text = "")) dispatch(Msg.TextChanged(text = ""))
database.add(text = state.text).subscribeScoped() database.add(text = state.text).subscribeScoped()
} }
} }
} }
private object ReducerImpl : Reducer<State, Result> { private object ReducerImpl : Reducer<State, Msg> {
override fun State.reduce(result: Result): State = override fun State.reduce(msg: Msg): State =
when (result) { when (msg) {
is Result.ItemsLoaded -> copy(items = result.items.sorted()) is Msg.ItemsLoaded -> copy(items = msg.items.sorted())
is Result.ItemDoneChanged -> update(id = result.id) { copy(isDone = result.isDone) } is Msg.ItemDoneChanged -> update(id = msg.id) { copy(isDone = msg.isDone) }
is Result.ItemDeleted -> copy(items = items.filterNot { it.id == result.id }) is Msg.ItemDeleted -> copy(items = items.filterNot { it.id == msg.id })
is Result.TextChanged -> copy(text = result.text) is Msg.TextChanged -> copy(text = msg.text)
} }
private inline fun State.update(id: Long, func: TodoItem.() -> TodoItem): State { private inline fun State.update(id: Long, func: TodoItem.() -> TodoItem): State {

3
examples/todoapp/common/root/build.gradle.kts

@ -11,13 +11,13 @@ kotlin {
binaries { binaries {
framework { framework {
baseName = "Todo" baseName = "Todo"
transitiveExport = true
linkerOpts.add("-lsqlite3") linkerOpts.add("-lsqlite3")
export(project(":common:database")) export(project(":common:database"))
export(project(":common:main")) export(project(":common:main"))
export(project(":common:edit")) export(project(":common:edit"))
export(Deps.ArkIvanov.Decompose.decompose) export(Deps.ArkIvanov.Decompose.decompose)
export(Deps.ArkIvanov.MVIKotlin.mvikotlinMain) export(Deps.ArkIvanov.MVIKotlin.mvikotlinMain)
export(Deps.ArkIvanov.Essenty.lifecycle)
} }
} }
} }
@ -44,6 +44,7 @@ kotlin {
api(project(":common:edit")) api(project(":common:edit"))
api(Deps.ArkIvanov.Decompose.decompose) api(Deps.ArkIvanov.Decompose.decompose)
api(Deps.ArkIvanov.MVIKotlin.mvikotlinMain) api(Deps.ArkIvanov.MVIKotlin.mvikotlinMain)
api(Deps.ArkIvanov.Essenty.lifecycle)
} }
} }
} }

2
examples/todoapp/common/root/src/commonMain/kotlin/example/todo/common/root/TodoRoot.kt

@ -1,6 +1,6 @@
package example.todo.common.root package example.todo.common.root
import com.arkivanov.decompose.RouterState import com.arkivanov.decompose.router.RouterState
import com.arkivanov.decompose.value.Value import com.arkivanov.decompose.value.Value
import example.todo.common.edit.TodoEdit import example.todo.common.edit.TodoEdit
import example.todo.common.main.TodoMain import example.todo.common.main.TodoMain

8
examples/todoapp/common/root/src/commonMain/kotlin/example/todo/common/root/integration/TodoRootComponent.kt

@ -1,10 +1,10 @@
package example.todo.common.root.integration package example.todo.common.root.integration
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.RouterState import com.arkivanov.decompose.router.RouterState
import com.arkivanov.decompose.pop import com.arkivanov.decompose.router.pop
import com.arkivanov.decompose.push import com.arkivanov.decompose.router.push
import com.arkivanov.decompose.router import com.arkivanov.decompose.router.router
import com.arkivanov.decompose.value.Value import com.arkivanov.decompose.value.Value
import com.arkivanov.essenty.parcelable.Parcelable import com.arkivanov.essenty.parcelable.Parcelable
import com.arkivanov.essenty.parcelable.Parcelize import com.arkivanov.essenty.parcelable.Parcelize

Loading…
Cancel
Save