Other cleanup
This commit is contained in:
parent
ad8ad3d443
commit
8d533e8a20
11 changed files with 14 additions and 20 deletions
|
|
@ -36,7 +36,7 @@ import io.element.android.libraries.matrix.ui.media.ImageLoaderHolder
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `LoggedInAppScopeFlowNode` is a Node responsible to set up the Dagger
|
* `LoggedInAppScopeFlowNode` is a Node responsible to set up the Session graph.
|
||||||
* [io.element.android.libraries.di.SessionScope]. It has only one child: [LoggedInFlowNode].
|
* [io.element.android.libraries.di.SessionScope]. It has only one child: [LoggedInFlowNode].
|
||||||
* This allow to inject objects with SessionScope in the constructor of [LoggedInFlowNode].
|
* This allow to inject objects with SessionScope in the constructor of [LoggedInFlowNode].
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,7 @@ Here are the main points:
|
||||||
2. Views are compose first
|
2. Views are compose first
|
||||||
3. Presenters are also compose first, and have a single `present(): State` method. It's using the power of compose-runtime/compiler.
|
3. Presenters are also compose first, and have a single `present(): State` method. It's using the power of compose-runtime/compiler.
|
||||||
4. The point of connection between a `View` and a `Presenter` is a `Node`.
|
4. The point of connection between a `View` and a `Presenter` is a `Node`.
|
||||||
5. A `Node` is also responsible for managing Dagger components if any.
|
5. A `Node` is also responsible for managing DI graph if any, see for instance `LoggedInAppScopeFlowNode`.
|
||||||
6. A `ParentNode` has some children `Node` and only know about them.
|
6. A `ParentNode` has some children `Node` and only know about them.
|
||||||
7. This is a single activity full compose application. The `MainActivity` is responsible for holding and configuring the `RootNode`.
|
7. This is a single activity full compose application. The `MainActivity` is responsible for holding and configuring the `RootNode`.
|
||||||
8. There is no more needs for Android Architecture Component ViewModel as configuration change should be handled by Composable if needed.
|
8. There is no more needs for Android Architecture Component ViewModel as configuration change should be handled by Composable if needed.
|
||||||
|
|
@ -422,7 +422,7 @@ Rageshake can be very useful to get logs from a release version of the applicati
|
||||||
- When this is possible, prefer using `sealed interface` instead of `sealed class`;
|
- When this is possible, prefer using `sealed interface` instead of `sealed class`;
|
||||||
- When writing temporary code, using the string "DO NOT COMMIT" in a comment can help to avoid committing things by mistake. If committed and pushed, the CI
|
- When writing temporary code, using the string "DO NOT COMMIT" in a comment can help to avoid committing things by mistake. If committed and pushed, the CI
|
||||||
will detect this String and will warn the user about it. (TODO Not supported yet!)
|
will detect this String and will warn the user about it. (TODO Not supported yet!)
|
||||||
- Very occasionally the gradle cache misbehaves and causes problems with Dagger. Try building with `--no-build-cache` if Dagger isn't behaving how you expect.
|
- Very occasionally the gradle cache misbehaves and causes problems with code generation. Adding `--no-build-cache` to the `gradlew` command line can help to fix compilation issue.
|
||||||
|
|
||||||
## Happy coding!
|
## Happy coding!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation to add a factory of type [TimelineItemPresenterFactory] to a
|
* Annotation to add a factory of type [TimelineItemPresenterFactory] to a
|
||||||
* Dagger map multi binding keyed with a subclass of [TimelineItemEventContent].
|
* dependency injection map multi binding keyed with a subclass of [TimelineItemEventContent].
|
||||||
*/
|
*/
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
@MapKey
|
@MapKey
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import io.element.android.libraries.di.RoomScope
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dagger module that declares the [TimelineItemPresenterFactory] map multi binding.
|
* Container that declares the [TimelineItemPresenterFactory] map multi binding.
|
||||||
*
|
*
|
||||||
* Its sole purpose is to support the case of an empty map multibinding.
|
* Its sole purpose is to support the case of an empty map multibinding.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import io.element.android.libraries.architecture.Presenter
|
||||||
/**
|
/**
|
||||||
* A factory for a [Presenter] associated with a timeline item.
|
* A factory for a [Presenter] associated with a timeline item.
|
||||||
*
|
*
|
||||||
* Implementations should be annotated with [AssistedFactory] to be created by Dagger.
|
* Implementations should be annotated with [dev.zacsweers.metro.AssistedFactory] to be created by the dependency injection library.
|
||||||
*
|
*
|
||||||
* @param C The timeline item's [TimelineItemEventContent] subtype.
|
* @param C The timeline item's [TimelineItemEventContent] subtype.
|
||||||
* @param S The [Presenter]'s state class.
|
* @param S The [Presenter]'s state class.
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,11 @@ import android.content.ContextWrapper
|
||||||
import com.bumble.appyx.core.node.Node
|
import com.bumble.appyx.core.node.Node
|
||||||
import io.element.android.libraries.di.DependencyInjectionGraphOwner
|
import io.element.android.libraries.di.DependencyInjectionGraphOwner
|
||||||
|
|
||||||
inline fun <reified T : Any> Node.optionalBindings() = optionalBindings(T::class.java)
|
|
||||||
inline fun <reified T : Any> Node.bindings() = bindings(T::class.java)
|
inline fun <reified T : Any> Node.bindings() = bindings(T::class.java)
|
||||||
inline fun <reified T : Any> Context.bindings() = bindings(T::class.java)
|
inline fun <reified T : Any> Context.bindings() = bindings(T::class.java)
|
||||||
|
|
||||||
fun <T : Any> Context.bindings(klass: Class<T>): T {
|
fun <T : Any> Context.bindings(klass: Class<T>): T {
|
||||||
// search dagger components in the context hierarchy
|
// search the components in the dependency injection graph
|
||||||
return generateSequence(this) { (it as? ContextWrapper)?.baseContext }
|
return generateSequence(this) { (it as? ContextWrapper)?.baseContext }
|
||||||
.plus(applicationContext)
|
.plus(applicationContext)
|
||||||
.filterIsInstance<DependencyInjectionGraphOwner>()
|
.filterIsInstance<DependencyInjectionGraphOwner>()
|
||||||
|
|
@ -28,16 +27,13 @@ fun <T : Any> Context.bindings(klass: Class<T>): T {
|
||||||
?: error("Unable to find bindings for ${klass.name}")
|
?: error("Unable to find bindings for ${klass.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : Any> Node.optionalBindings(klass: Class<T>): T? {
|
fun <T : Any> Node.bindings(klass: Class<T>): T {
|
||||||
// search dagger components in node hierarchy
|
// search the components in the node hierarchy
|
||||||
return generateSequence(this, Node::parent)
|
return generateSequence(this, Node::parent)
|
||||||
.filterIsInstance<DependencyInjectionGraphOwner>()
|
.filterIsInstance<DependencyInjectionGraphOwner>()
|
||||||
.map { it.graph }
|
.map { it.graph }
|
||||||
.flatMap { it as? Collection<*> ?: listOf(it) }
|
.flatMap { it as? Collection<*> ?: listOf(it) }
|
||||||
.filterIsInstance(klass)
|
.filterIsInstance(klass)
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
}
|
?: error("Unable to find bindings for ${klass.name}")
|
||||||
|
|
||||||
fun <T : Any> Node.bindings(klass: Class<T>): T {
|
|
||||||
return optionalBindings(klass) ?: error("Unable to find bindings for ${klass.name}")
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ inline fun <reified N : Node> NodeFactoriesBindings.createNode(
|
||||||
val nodeClass = N::class
|
val nodeClass = N::class
|
||||||
val nodeFactoryMap = nodeFactories()
|
val nodeFactoryMap = nodeFactories()
|
||||||
// Note to developers: If you got the error below, make sure to build again after
|
// Note to developers: If you got the error below, make sure to build again after
|
||||||
// clearing the cache (sometimes several times) to let Dagger generate the NodeFactory.
|
// clearing the cache (sometimes several times) to let codegen generate the NodeFactory.
|
||||||
val nodeFactory = nodeFactoryMap[nodeClass] ?: error("Cannot find NodeFactory for ${nodeClass.java.name}.")
|
val nodeFactory = nodeFactoryMap[nodeClass] ?: error("Cannot find NodeFactory for ${nodeClass.java.name}.")
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation to add a factory of type [MediaItemPresenterFactory] to a
|
* Annotation to add a factory of type [MediaItemPresenterFactory] to a
|
||||||
* Dagger map multi binding keyed with a subclass of [MediaItem.Event].
|
* DI map multi binding keyed with a subclass of [MediaItem.Event].
|
||||||
*/
|
*/
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
@MapKey
|
@MapKey
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dagger module that declares the [MediaItemPresenterFactory] map multi binding.
|
* Container that declares the [MediaItemPresenterFactory] map multi binding.
|
||||||
*
|
*
|
||||||
* Its sole purpose is to support the case of an empty map multibinding.
|
* Its sole purpose is to support the case of an empty map multibinding.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import io.element.android.libraries.mediaviewer.impl.model.MediaItem
|
||||||
/**
|
/**
|
||||||
* A factory for a [Presenter] associated with a timeline item.
|
* A factory for a [Presenter] associated with a timeline item.
|
||||||
*
|
*
|
||||||
* Implementations should be annotated with [AssistedFactory] to be created by Dagger.
|
* Implementations should be annotated with [dev.zacsweers.metro.AssistedFactory] to be created.
|
||||||
*
|
*
|
||||||
* @param C The timeline item's [MediaItem.Event] subtype.
|
* @param C The timeline item's [MediaItem.Event] subtype.
|
||||||
* @param S The [Presenter]'s state class.
|
* @param S The [Presenter]'s state class.
|
||||||
|
|
|
||||||
|
|
@ -67,14 +67,12 @@ fun Project.setupKover() {
|
||||||
"*_ModuleKt",
|
"*_ModuleKt",
|
||||||
"com.airbnb.android.showkase*",
|
"com.airbnb.android.showkase*",
|
||||||
"io.element.android.libraries.designsystem.showkase.*",
|
"io.element.android.libraries.designsystem.showkase.*",
|
||||||
"io.element.android.x.di.DaggerAppComponent*",
|
|
||||||
"*_Factory",
|
"*_Factory",
|
||||||
"*_Factory_Impl",
|
"*_Factory_Impl",
|
||||||
"*_Factory$*",
|
"*_Factory$*",
|
||||||
"*_Module",
|
"*_Module",
|
||||||
"*_Module$*",
|
"*_Module$*",
|
||||||
"*Module_Provides*",
|
"*Module_Provides*",
|
||||||
"Dagger*Component*",
|
|
||||||
"*ComposableSingletons$*",
|
"*ComposableSingletons$*",
|
||||||
"*_AssistedFactory_Impl*",
|
"*_AssistedFactory_Impl*",
|
||||||
"*BuildConfig",
|
"*BuildConfig",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue