Browse Source

TodoApp. Get rid of Dependencies interfaces. (#480)

pull/500/head
Arkadii Ivanov 4 years ago committed by GitHub
parent
commit
8d6be48499
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      examples/todoapp/android/src/main/java/example/todo/android/MainActivity.kt
  2. 17
      examples/todoapp/common/edit/src/commonMain/kotlin/example/todo/common/edit/TodoEdit.kt
  3. 15
      examples/todoapp/common/edit/src/commonMain/kotlin/example/todo/common/edit/integration/TodoEditComponent.kt
  4. 16
      examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/TodoMain.kt
  5. 14
      examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/integration/TodoMainComponent.kt
  6. 13
      examples/todoapp/common/main/src/commonTest/kotlin/example/todo/common/main/integration/TodoMainTest.kt
  7. 34
      examples/todoapp/common/root/src/commonMain/kotlin/example/todo/common/root/TodoRoot.kt
  8. 31
      examples/todoapp/common/root/src/commonMain/kotlin/example/todo/common/root/integration/TodoRootComponent.kt
  9. 2
      examples/todoapp/common/root/src/commonTest/kotlin/example/todo/common/root/integration/TodoRootTest.kt
  10. 9
      examples/todoapp/desktop/src/jvmMain/kotlin/example/todo/desktop/Main.kt
  11. 11
      examples/todoapp/ios/ios/ContentView.swift

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

@ -7,12 +7,12 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetbrains.rememberRootComponent
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.arkivanov.mvikotlin.logging.store.LoggingStoreFactory
import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
import com.arkivanov.mvikotlin.timetravel.store.TimeTravelStoreFactory
import example.todo.common.database.TodoDatabaseDriver
import example.todo.common.root.TodoRoot
import example.todo.common.root.integration.TodoRootComponent
import example.todo.common.ui.TodoRootContent
import example.todo.database.TodoDatabase
@ -30,12 +30,9 @@ class MainActivity : AppCompatActivity() {
}
private fun todoRoot(componentContext: ComponentContext): TodoRoot =
TodoRoot(
TodoRootComponent(
componentContext = componentContext,
dependencies = object : TodoRoot.Dependencies {
// You can play with time travel using IDEA plugin: https://arkivanov.github.io/MVIKotlin/time_travel.html
override val storeFactory: StoreFactory = LoggingStoreFactory(TimeTravelStoreFactory(DefaultStoreFactory))
override val database: TodoDatabase = TodoDatabase(TodoDatabaseDriver(this@MainActivity))
}
storeFactory = LoggingStoreFactory(TimeTravelStoreFactory(DefaultStoreFactory)),
database = TodoDatabase(TodoDatabaseDriver(context = this))
)
}

17
examples/todoapp/common/edit/src/commonMain/kotlin/example/todo/common/edit/TodoEdit.kt

@ -1,12 +1,6 @@
package example.todo.common.edit
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.value.Value
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.badoo.reaktive.base.Consumer
import example.todo.common.edit.TodoEdit.Dependencies
import example.todo.common.edit.integration.TodoEditImpl
import example.todo.database.TodoDatabase
interface TodoEdit {
@ -23,18 +17,7 @@ interface TodoEdit {
val isDone: Boolean
)
interface Dependencies {
val storeFactory: StoreFactory
val database: TodoDatabase
val itemId: Long
val editOutput: Consumer<Output>
}
sealed class Output {
object Finished : Output()
}
}
@Suppress("FunctionName") // Factory function
fun TodoEdit(componentContext: ComponentContext, dependencies: Dependencies): TodoEdit =
TodoEditImpl(componentContext, dependencies)

15
examples/todoapp/common/edit/src/commonMain/kotlin/example/todo/common/edit/integration/TodoEditImpl.kt → examples/todoapp/common/edit/src/commonMain/kotlin/example/todo/common/edit/integration/TodoEditComponent.kt

@ -3,20 +3,25 @@ package example.todo.common.edit.integration
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.value.Value
import com.arkivanov.decompose.value.operator.map
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.badoo.reaktive.base.Consumer
import com.badoo.reaktive.base.invoke
import example.todo.common.edit.TodoEdit
import example.todo.common.edit.TodoEdit.Dependencies
import example.todo.common.edit.TodoEdit.Model
import example.todo.common.edit.TodoEdit.Output
import example.todo.common.edit.store.TodoEditStore.Intent
import example.todo.common.edit.store.TodoEditStoreProvider
import example.todo.common.utils.asValue
import example.todo.common.utils.getStore
import example.todo.database.TodoDatabase
internal class TodoEditImpl(
class TodoEditComponent(
componentContext: ComponentContext,
dependencies: Dependencies
) : TodoEdit, ComponentContext by componentContext, Dependencies by dependencies {
storeFactory: StoreFactory,
database: TodoDatabase,
itemId: Long,
private val output: Consumer<Output>
) : TodoEdit, ComponentContext by componentContext {
private val store =
instanceKeeper.getStore {
@ -38,6 +43,6 @@ internal class TodoEditImpl(
}
override fun onCloseClicked() {
editOutput(Output.Finished)
output(Output.Finished)
}
}

16
examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/TodoMain.kt

@ -1,12 +1,6 @@
package example.todo.common.main
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.value.Value
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.badoo.reaktive.base.Consumer
import example.todo.common.main.TodoMain.Dependencies
import example.todo.common.main.integration.TodoMainImpl
import example.todo.database.TodoDatabase
interface TodoMain {
@ -27,17 +21,7 @@ interface TodoMain {
val text: String
)
interface Dependencies {
val storeFactory: StoreFactory
val database: TodoDatabase
val mainOutput: Consumer<Output>
}
sealed class Output {
data class Selected(val id: Long) : Output()
}
}
@Suppress("FunctionName") // Factory function
fun TodoMain(componentContext: ComponentContext, dependencies: Dependencies): TodoMain =
TodoMainImpl(componentContext, dependencies)

14
examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/integration/TodoMainImpl.kt → examples/todoapp/common/main/src/commonMain/kotlin/example/todo/common/main/integration/TodoMainComponent.kt

@ -3,20 +3,24 @@ package example.todo.common.main.integration
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.value.Value
import com.arkivanov.decompose.value.operator.map
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.badoo.reaktive.base.Consumer
import com.badoo.reaktive.base.invoke
import example.todo.common.main.TodoMain
import example.todo.common.main.TodoMain.Dependencies
import example.todo.common.main.TodoMain.Model
import example.todo.common.main.TodoMain.Output
import example.todo.common.main.store.TodoMainStore.Intent
import example.todo.common.main.store.TodoMainStoreProvider
import example.todo.common.utils.asValue
import example.todo.common.utils.getStore
import example.todo.database.TodoDatabase
internal class TodoMainImpl(
class TodoMainComponent(
componentContext: ComponentContext,
dependencies: Dependencies
) : TodoMain, ComponentContext by componentContext, Dependencies by dependencies {
storeFactory: StoreFactory,
database: TodoDatabase,
private val output: Consumer<Output>
) : TodoMain, ComponentContext by componentContext {
private val store =
instanceKeeper.getStore {
@ -29,7 +33,7 @@ internal class TodoMainImpl(
override val models: Value<Model> = store.asValue().map(stateToModel)
override fun onItemClicked(id: Long) {
mainOutput(Output.Selected(id = id))
output(Output.Selected(id = id))
}
override fun onItemDoneChanged(id: Long, isDone: Boolean) {

13
examples/todoapp/common/main/src/commonTest/kotlin/example/todo/common/main/integration/TodoMainTest.kt

@ -2,9 +2,7 @@ package example.todo.common.main.integration
import com.arkivanov.decompose.DefaultComponentContext
import com.arkivanov.decompose.lifecycle.LifecycleRegistry
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
import com.badoo.reaktive.base.Consumer
import com.badoo.reaktive.scheduler.overrideSchedulers
import com.badoo.reaktive.subject.publish.PublishSubject
import com.badoo.reaktive.test.observable.assertValue
@ -13,7 +11,6 @@ import com.badoo.reaktive.test.scheduler.TestScheduler
import example.todo.common.database.TestDatabaseDriver
import example.todo.common.database.TodoItemEntity
import example.todo.common.main.TodoItem
import example.todo.common.main.TodoMain.Dependencies
import example.todo.common.main.TodoMain.Model
import example.todo.common.main.TodoMain.Output
import example.todo.database.TodoDatabase
@ -35,13 +32,11 @@ class TodoMainTest {
private val queries = database.todoDatabaseQueries
private val impl by lazy {
TodoMainImpl(
TodoMainComponent(
componentContext = DefaultComponentContext(lifecycle = lifecycle),
dependencies = object : Dependencies {
override val storeFactory: StoreFactory = DefaultStoreFactory
override val database: TodoDatabase = this@TodoMainTest.database
override val mainOutput: Consumer<Output> = outputSubject
}
storeFactory = DefaultStoreFactory,
database = database,
output = outputSubject
)
}

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

@ -1,15 +1,9 @@
package example.todo.common.root
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.RouterState
import com.arkivanov.decompose.value.Value
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.badoo.reaktive.base.Consumer
import example.todo.common.edit.TodoEdit
import example.todo.common.main.TodoMain
import example.todo.common.root.TodoRoot.Dependencies
import example.todo.common.root.integration.TodoRootImpl
import example.todo.database.TodoDatabase
interface TodoRoot {
@ -19,32 +13,4 @@ interface TodoRoot {
data class Main(val component: TodoMain) : Child()
data class Edit(val component: TodoEdit) : Child()
}
interface Dependencies {
val storeFactory: StoreFactory
val database: TodoDatabase
}
}
@Suppress("FunctionName") // Factory function
fun TodoRoot(componentContext: ComponentContext, dependencies: Dependencies): TodoRoot =
TodoRootImpl(
componentContext = componentContext,
todoMain = { childContext, output ->
TodoMain(
componentContext = childContext,
dependencies = object : TodoMain.Dependencies, Dependencies by dependencies {
override val mainOutput: Consumer<TodoMain.Output> = output
}
)
},
todoEdit = { childContext, itemId, output ->
TodoEdit(
componentContext = childContext,
dependencies = object : TodoEdit.Dependencies, Dependencies by dependencies {
override val itemId: Long = itemId
override val editOutput: Consumer<TodoEdit.Output> = output
}
)
}
)

31
examples/todoapp/common/root/src/commonMain/kotlin/example/todo/common/root/integration/TodoRootImpl.kt → examples/todoapp/common/root/src/commonMain/kotlin/example/todo/common/root/integration/TodoRootComponent.kt

@ -8,19 +8,48 @@ import com.arkivanov.decompose.router
import com.arkivanov.decompose.statekeeper.Parcelable
import com.arkivanov.decompose.statekeeper.Parcelize
import com.arkivanov.decompose.value.Value
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.badoo.reaktive.base.Consumer
import example.todo.common.edit.TodoEdit
import example.todo.common.edit.integration.TodoEditComponent
import example.todo.common.main.TodoMain
import example.todo.common.main.integration.TodoMainComponent
import example.todo.common.root.TodoRoot
import example.todo.common.root.TodoRoot.Child
import example.todo.common.utils.Consumer
import example.todo.database.TodoDatabase
internal class TodoRootImpl(
class TodoRootComponent internal constructor(
componentContext: ComponentContext,
private val todoMain: (ComponentContext, Consumer<TodoMain.Output>) -> TodoMain,
private val todoEdit: (ComponentContext, itemId: Long, Consumer<TodoEdit.Output>) -> TodoEdit
) : TodoRoot, ComponentContext by componentContext {
constructor(
componentContext: ComponentContext,
storeFactory: StoreFactory,
database: TodoDatabase
) : this(
componentContext = componentContext,
todoMain = { childContext, output ->
TodoMainComponent(
componentContext = childContext,
storeFactory = storeFactory,
database = database,
output = output
)
},
todoEdit = { childContext, itemId, output ->
TodoEditComponent(
componentContext = childContext,
storeFactory = storeFactory,
database = database,
itemId = itemId,
output = output
)
}
)
private val router =
router<Configuration, Child>(
initialConfiguration = Configuration.Main,

2
examples/todoapp/common/root/src/commonTest/kotlin/example/todo/common/root/integration/TodoRootTest.kt

@ -45,7 +45,7 @@ class TodoRootTest {
}
private fun root(): TodoRoot =
TodoRootImpl(
TodoRootComponent(
componentContext = DefaultComponentContext(lifecycle = lifecycle),
todoMain = { _, output -> TodoMainFake(output) },
todoEdit = { _, itemId, output -> TodoEditFake(itemId, output) }

9
examples/todoapp/desktop/src/jvmMain/kotlin/example/todo/desktop/Main.kt

@ -13,6 +13,7 @@ import com.badoo.reaktive.coroutinesinterop.asScheduler
import com.badoo.reaktive.scheduler.overrideSchedulers
import example.todo.common.database.TodoDatabaseDriver
import example.todo.common.root.TodoRoot
import example.todo.common.root.integration.TodoRootComponent
import example.todo.common.ui.TodoRootContent
import example.todo.database.TodoDatabase
import kotlinx.coroutines.Dispatchers
@ -32,10 +33,8 @@ fun main() {
}
private fun todoRoot(componentContext: ComponentContext): TodoRoot =
TodoRoot(
TodoRootComponent(
componentContext = componentContext,
dependencies = object : TodoRoot.Dependencies {
override val storeFactory = DefaultStoreFactory
override val database = TodoDatabase(TodoDatabaseDriver())
}
storeFactory = DefaultStoreFactory,
database = TodoDatabase(TodoDatabaseDriver())
)

11
examples/todoapp/ios/ios/ContentView.swift

@ -5,9 +5,10 @@ struct ContentView: View {
@State
private var componentHolder =
ComponentHolder {
TodoRootKt.TodoRoot(
TodoRootComponent(
componentContext: $0,
dependencies: RootDependencies()
storeFactory: DefaultStoreFactory(),
database: TodoDatabaseCompanion().invoke(driver: TodoDatabaseDriverFactoryKt.TodoDatabaseDriver())
)
}
@ -18,12 +19,6 @@ struct ContentView: View {
}
}
private class RootDependencies: TodoRootDependencies {
let database: TodoDatabase = TodoDatabaseCompanion().invoke(driver: TodoDatabaseDriverFactoryKt.TodoDatabaseDriver())
let storeFactory: MvikotlinStoreFactory = DefaultStoreFactory()
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()

Loading…
Cancel
Save