Branch on viewmodel...

This commit is contained in:
ganfra 2022-12-15 20:16:53 +01:00
parent 8620a86333
commit eba807e37a
15 changed files with 232 additions and 115 deletions

View file

@ -3,16 +3,6 @@ plugins {
alias(libs.plugins.kapt) alias(libs.plugins.kapt)
} }
/*
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
freeCompilerArgs += listOf(
"-opt-in=com.squareup.anvil.annotations.ExperimentalAnvilApi")
}
}
*/
dependencies { dependencies {
implementation(project(":anvilannotations")) implementation(project(":anvilannotations"))
api(libs.anvil.compiler.api) api(libs.anvil.compiler.api)

View file

@ -0,0 +1,122 @@
@file:OptIn(ExperimentalAnvilApi::class)
package io.element.android.x.anvilcodegen
import com.google.auto.service.AutoService
import com.squareup.anvil.annotations.ContributesTo
import com.squareup.anvil.annotations.ExperimentalAnvilApi
import com.squareup.anvil.compiler.api.AnvilCompilationException
import com.squareup.anvil.compiler.api.AnvilContext
import com.squareup.anvil.compiler.api.CodeGenerator
import com.squareup.anvil.compiler.api.GeneratedFile
import com.squareup.anvil.compiler.api.createGeneratedFile
import com.squareup.anvil.compiler.internal.asClassName
import com.squareup.anvil.compiler.internal.buildFile
import com.squareup.anvil.compiler.internal.fqName
import com.squareup.anvil.compiler.internal.reference.ClassReference
import com.squareup.anvil.compiler.internal.reference.asClassName
import com.squareup.anvil.compiler.internal.reference.classAndInnerClassReferences
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.STAR
import com.squareup.kotlinpoet.TypeSpec
import dagger.Binds
import dagger.Module
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.multibindings.IntoMap
import io.element.android.x.anvilannotations.ContributesViewModel
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import java.io.File
/**
* This is an anvil plugin that allows ViewModels to use [ContributesViewModel] alone and let this plugin automatically
* handle the rest of the Dagger wiring required for constructor injection.
*/
@AutoService(CodeGenerator::class)
class ContributesViewModelCodeGenerator : CodeGenerator {
override fun isApplicable(context: AnvilContext): Boolean = true
override fun generateCode(codeGenDir: File, module: ModuleDescriptor, projectFiles: Collection<KtFile>): Collection<GeneratedFile> {
return projectFiles.classAndInnerClassReferences(module)
.filter { it.isAnnotatedWith(ContributesViewModel::class.fqName) }
.flatMap { listOf(generateModule(it, codeGenDir, module), generateAssistedFactory(it, codeGenDir, module)) }
.toList()
}
private fun generateModule(vmClass: ClassReference.Psi, codeGenDir: File, module: ModuleDescriptor): GeneratedFile {
val generatedPackage = vmClass.packageFqName.toString()
val moduleClassName = "${vmClass.shortName}_Module"
val scope = vmClass.annotations.single { it.fqName == ContributesViewModel::class.fqName }.scope()
val content = FileSpec.buildFile(generatedPackage, moduleClassName) {
addType(
TypeSpec.classBuilder(moduleClassName)
.addModifiers(KModifier.ABSTRACT)
.addAnnotation(Module::class)
.addAnnotation(AnnotationSpec.builder(ContributesTo::class).addMember("%T::class", scope.asClassName()).build())
.addFunction(
FunSpec.builder("bind${vmClass.shortName}Factory")
.addModifiers(KModifier.ABSTRACT)
.addParameter("factory", ClassName(generatedPackage, "${vmClass.shortName}_AssistedFactory"))
.returns(assistedViewModelFactoryFqName.asClassName(module).parameterizedBy(STAR, STAR))
.addAnnotation(Binds::class)
.addAnnotation(IntoMap::class)
.addAnnotation(AnnotationSpec.Companion.builder(viewModelKeyFqName.asClassName(module)).addMember("%T::class", vmClass.asClassName()).build())
.build(),
)
.build(),
)
}
return createGeneratedFile(codeGenDir, generatedPackage, moduleClassName, content)
}
private fun generateAssistedFactory(vmClass: ClassReference.Psi, codeGenDir: File, module: ModuleDescriptor): GeneratedFile {
val generatedPackage = vmClass.packageFqName.toString()
val assistedFactoryClassName = "${vmClass.shortName}_AssistedFactory"
val constructor = vmClass.constructors.singleOrNull { it.isAnnotatedWith(AssistedInject::class.fqName) }
val assistedParameter = constructor?.parameters?.singleOrNull { it.isAnnotatedWith(Assisted::class.fqName) }
if (constructor == null || assistedParameter == null) {
throw AnvilCompilationException(
"${vmClass.fqName} must have an @AssistedInject constructor with @Assisted initialState: S parameter",
element = vmClass.clazz,
)
}
if (assistedParameter.name != "initialState") {
throw AnvilCompilationException(
"${vmClass.fqName} @Assisted parameter must be named initialState",
element = assistedParameter.parameter,
)
}
val vmClassName = vmClass.asClassName()
val stateClassName = assistedParameter.type().asTypeName()
val content = FileSpec.buildFile(generatedPackage, assistedFactoryClassName) {
addType(
TypeSpec.interfaceBuilder(assistedFactoryClassName)
.addSuperinterface(assistedViewModelFactoryFqName.asClassName(module).parameterizedBy(vmClassName, stateClassName))
.addAnnotation(AssistedFactory::class)
.addFunction(
FunSpec.builder("create")
.addModifiers(KModifier.OVERRIDE, KModifier.ABSTRACT)
.addParameter("initialState", stateClassName)
.returns(vmClassName)
.build(),
)
.build(),
)
}
return createGeneratedFile(codeGenDir, generatedPackage, assistedFactoryClassName, content)
}
companion object {
private val assistedViewModelFactoryFqName = FqName("io.element.android.x.core.di.AssistedViewModelFactory")
private val viewModelKeyFqName = FqName("io.element.android.x.core.di.ViewModelKey")
}
}

View file

@ -121,6 +121,8 @@ dependencies {
implementation(project(":features:roomlist")) implementation(project(":features:roomlist"))
implementation(project(":features:messages")) implementation(project(":features:messages"))
implementation(project(":libraries:di")) implementation(project(":libraries:di"))
implementation(project(":anvilannotations"))
anvil(project(":anvilcodegen"))
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.0") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.0")
implementation(libs.compose.destinations) implementation(libs.compose.destinations)

View file

@ -28,6 +28,8 @@ import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import com.airbnb.android.showkase.models.Showkase import com.airbnb.android.showkase.models.Showkase
import com.airbnb.mvrx.compose.mavericksActivityViewModel
import com.airbnb.mvrx.compose.mavericksViewModel
import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi
import com.ramcosta.composedestinations.DestinationsNavHost import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations
@ -46,14 +48,12 @@ private const val transitionAnimationDuration = 500
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
setContent { setContent {
ElementXTheme { ElementXTheme {
MainScreen(viewModel = viewModel) MainScreen(viewModel = mavericksActivityViewModel())
} }
} }
} }

View file

@ -1,26 +1,41 @@
package io.element.android.x package io.element.android.x
import androidx.lifecycle.ViewModel import com.airbnb.mvrx.MavericksState
import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.MavericksViewModel
import io.element.android.x.matrix.MatrixInstance import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.x.anvilannotations.ContributesViewModel
import io.element.android.x.core.di.daggerMavericksViewModelFactory
import io.element.android.x.di.AppScope
import io.element.android.x.features.messages.MessagesViewModel
import io.element.android.x.features.messages.model.MessagesViewState
import io.element.android.x.matrix.Matrix
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class MainViewModel : ViewModel() { data class MainState(val fake: Boolean = false) : MavericksState
private val matrix = MatrixInstance.getInstance()
@ContributesViewModel(AppScope::class)
class MainViewModel @AssistedInject constructor(
private val matrix: Matrix,
@Assisted initialState: MainState
) : MavericksViewModel<MainState>(initialState) {
companion object : MavericksViewModelFactory<MainViewModel, MainState> by daggerMavericksViewModelFactory()
suspend fun isLoggedIn(): Boolean { suspend fun isLoggedIn(): Boolean {
return matrix.isLoggedIn().first() return matrix.isLoggedIn().first()
} }
fun startSyncIfLogged(){ fun startSyncIfLogged() {
viewModelScope.launch { viewModelScope.launch {
if(!isLoggedIn()) return@launch if (!isLoggedIn()) return@launch
matrix.activeClient().startSync() matrix.activeClient().startSync()
} }
} }
fun stopSyncIfLogged(){ fun stopSyncIfLogged() {
viewModelScope.launch { viewModelScope.launch {
if (!isLoggedIn()) return@launch if (!isLoggedIn()) return@launch
matrix.activeClient().stopSync() matrix.activeClient().stopSync()

View file

@ -4,10 +4,11 @@ import android.content.Context
import com.squareup.anvil.annotations.MergeComponent import com.squareup.anvil.annotations.MergeComponent
import dagger.BindsInstance import dagger.BindsInstance
import dagger.Component import dagger.Component
import io.element.android.x.core.di.DaggerMavericksBindings
@SingleIn(AppScope::class) @SingleIn(AppScope::class)
@MergeComponent(AppScope::class) @MergeComponent(AppScope::class)
interface AppComponent { interface AppComponent: DaggerMavericksBindings {
@Component.Factory @Component.Factory
interface Factory { interface Factory {

View file

@ -1,13 +1,22 @@
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
alias(libs.plugins.anvil)
} }
android { android {
namespace = "io.element.android.x.features.login" namespace = "io.element.android.x.features.login"
} }
anvil {
generateDaggerFactories.set(true)
}
dependencies { dependencies {
implementation(project(":anvilannotations"))
anvil(project(":anvilcodegen"))
implementation(project(":libraries:di"))
implementation(project(":libraries:core")) implementation(project(":libraries:core"))
implementation(project(":libraries:matrix")) implementation(project(":libraries:matrix"))
implementation(project(":libraries:designsystem")) implementation(project(":libraries:designsystem"))

View file

@ -3,16 +3,27 @@ package io.element.android.x.features.login
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshotFlow import androidx.compose.runtime.snapshotFlow
import com.airbnb.mvrx.MavericksViewModel import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.Uninitialized
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.x.anvilannotations.ContributesViewModel
import io.element.android.x.core.di.daggerMavericksViewModelFactory
import io.element.android.x.di.AppScope
import io.element.android.x.matrix.Matrix
import io.element.android.x.matrix.MatrixInstance import io.element.android.x.matrix.MatrixInstance
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class LoginViewModel(initialState: LoginViewState) : @ContributesViewModel(AppScope::class)
class LoginViewModel @AssistedInject constructor(
private val matrix: Matrix,
@Assisted initialState: LoginViewState) :
MavericksViewModel<LoginViewState>(initialState) { MavericksViewModel<LoginViewState>(initialState) {
private val matrix = MatrixInstance.getInstance() companion object : MavericksViewModelFactory<LoginViewModel, LoginViewState> by daggerMavericksViewModelFactory()
var formState = mutableStateOf(LoginFormState.Default) var formState = mutableStateOf(LoginFormState.Default)
private set private set

View file

@ -1,13 +1,22 @@
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
alias(libs.plugins.anvil)
} }
android { android {
namespace = "io.element.android.x.features.messages" namespace = "io.element.android.x.features.messages"
} }
anvil {
generateDaggerFactories.set(true)
}
dependencies { dependencies {
implementation(project(":anvilannotations"))
anvil(project(":anvilcodegen"))
implementation(project(":libraries:di"))
implementation(project(":libraries:core")) implementation(project(":libraries:core"))
implementation(project(":libraries:matrix")) implementation(project(":libraries:matrix"))
implementation(project(":libraries:designsystem")) implementation(project(":libraries:designsystem"))

View file

@ -3,19 +3,21 @@ package io.element.android.x.features.messages
import com.airbnb.mvrx.MavericksViewModel import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.x.anvilannotations.ContributesViewModel
import io.element.android.x.core.di.daggerMavericksViewModelFactory
import io.element.android.x.designsystem.components.avatar.AvatarData import io.element.android.x.designsystem.components.avatar.AvatarData
import io.element.android.x.designsystem.components.avatar.AvatarSize import io.element.android.x.designsystem.components.avatar.AvatarSize
import io.element.android.x.di.AppScope
import io.element.android.x.features.messages.model.MessagesItemAction import io.element.android.x.features.messages.model.MessagesItemAction
import io.element.android.x.features.messages.model.MessagesItemActionsSheetState import io.element.android.x.features.messages.model.MessagesItemActionsSheetState
import io.element.android.x.features.messages.model.MessagesTimelineItemState import io.element.android.x.features.messages.model.MessagesTimelineItemState
import io.element.android.x.features.messages.model.MessagesViewState import io.element.android.x.features.messages.model.MessagesViewState
import io.element.android.x.features.messages.model.content.MessagesTimelineItemRedactedContent import io.element.android.x.features.messages.model.content.MessagesTimelineItemRedactedContent
import io.element.android.x.features.messages.model.content.MessagesTimelineItemTextBasedContent import io.element.android.x.features.messages.model.content.MessagesTimelineItemTextBasedContent
import io.element.android.x.matrix.MatrixClient import io.element.android.x.matrix.Matrix
import io.element.android.x.matrix.MatrixInstance
import io.element.android.x.matrix.media.MediaResolver import io.element.android.x.matrix.media.MediaResolver
import io.element.android.x.matrix.room.MatrixRoom
import io.element.android.x.matrix.timeline.MatrixTimeline import io.element.android.x.matrix.timeline.MatrixTimeline
import io.element.android.x.matrix.timeline.MatrixTimelineItem import io.element.android.x.matrix.timeline.MatrixTimelineItem
import io.element.android.x.textcomposer.MessageComposerMode import io.element.android.x.textcomposer.MessageComposerMode
@ -26,35 +28,20 @@ import kotlinx.coroutines.launch
private const val PAGINATION_COUNT = 50 private const val PAGINATION_COUNT = 50
class MessagesViewModel( @ContributesViewModel(AppScope::class)
private val client: MatrixClient, class MessagesViewModel @AssistedInject constructor(
private val room: MatrixRoom, matrix: Matrix,
private val timeline: MatrixTimeline, @Assisted private val initialState: MessagesViewState
private val messageTimelineItemStateFactory: MessageTimelineItemStateFactory,
private val initialState: MessagesViewState
) : ) :
MavericksViewModel<MessagesViewState>(initialState) { MavericksViewModel<MessagesViewState>(initialState) {
companion object : MavericksViewModelFactory<MessagesViewModel, MessagesViewState> { companion object : MavericksViewModelFactory<MessagesViewModel, MessagesViewState> by daggerMavericksViewModelFactory()
override fun create( private val client = matrix.activeClient()
viewModelContext: ViewModelContext, private val room = client.getRoom(initialState.roomId)!!
state: MessagesViewState private val messageTimelineItemStateFactory =
): MessagesViewModel? { MessageTimelineItemStateFactory(client, room, Dispatchers.Default)
val matrix = MatrixInstance.getInstance() private val timeline = room.timeline()
val client = matrix.activeClient()
val room = client.getRoom(state.roomId) ?: return null
val messageTimelineItemStateFactory =
MessageTimelineItemStateFactory(client, room, Dispatchers.Default)
return MessagesViewModel(
client,
room,
room.timeline(),
messageTimelineItemStateFactory,
state
)
}
}
private val timelineCallback = object : MatrixTimeline.Callback { private val timelineCallback = object : MatrixTimeline.Callback {
override fun onPushedTimelineItem(timelineItem: MatrixTimelineItem) { override fun onPushedTimelineItem(timelineItem: MatrixTimelineItem) {

View file

@ -2,32 +2,24 @@ package io.element.android.x.features.messages.textcomposer
import com.airbnb.mvrx.MavericksViewModel import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.x.anvilannotations.ContributesViewModel
import io.element.android.x.core.data.StableCharSequence import io.element.android.x.core.data.StableCharSequence
import io.element.android.x.matrix.MatrixClient import io.element.android.x.core.di.daggerMavericksViewModelFactory
import io.element.android.x.matrix.MatrixInstance import io.element.android.x.di.AppScope
import io.element.android.x.matrix.Matrix
@ContributesViewModel(AppScope::class)
class MessageComposerViewModel( class MessageComposerViewModel @AssistedInject constructor(
private val client: MatrixClient, private val matrix: Matrix,
private val initialState: MessageComposerViewState @Assisted private val initialState: MessageComposerViewState
) : MavericksViewModel<MessageComposerViewState>(initialState) { ) : MavericksViewModel<MessageComposerViewState>(initialState) {
companion object : companion object :
MavericksViewModelFactory<MessageComposerViewModel, MessageComposerViewState> { MavericksViewModelFactory<MessageComposerViewModel, MessageComposerViewState> by daggerMavericksViewModelFactory()
override fun create( private val client = matrix.activeClient()
viewModelContext: ViewModelContext,
state: MessageComposerViewState
): MessageComposerViewModel? {
val matrix = MatrixInstance.getInstance()
val client = matrix.activeClient()
return MessageComposerViewModel(
client,
state
)
}
}
fun onComposerFullScreenChange() { fun onComposerFullScreenChange() {
setState { setState {

View file

@ -1,13 +1,21 @@
plugins { plugins {
id("io.element.android-compose-library") id("io.element.android-compose-library")
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
alias(libs.plugins.anvil)
} }
android { android {
namespace = "io.element.android.x.features.roomlist" namespace = "io.element.android.x.features.roomlist"
} }
anvil {
generateDaggerFactories.set(true)
}
dependencies { dependencies {
implementation(project(":anvilannotations"))
anvil(project(":anvilcodegen"))
implementation(project(":libraries:di"))
implementation(project(":libraries:core")) implementation(project(":libraries:core"))
implementation(project(":libraries:matrix")) implementation(project(":libraries:matrix"))
implementation(project(":libraries:designsystem")) implementation(project(":libraries:designsystem"))

View file

@ -1,13 +1,19 @@
package io.element.android.x.features.roomlist package io.element.android.x.features.roomlist
import com.airbnb.mvrx.* import com.airbnb.mvrx.*
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import io.element.android.x.anvilannotations.ContributesViewModel
import io.element.android.x.core.data.parallelMap import io.element.android.x.core.data.parallelMap
import io.element.android.x.core.di.daggerMavericksViewModelFactory
import io.element.android.x.designsystem.components.avatar.AvatarData import io.element.android.x.designsystem.components.avatar.AvatarData
import io.element.android.x.designsystem.components.avatar.AvatarSize import io.element.android.x.designsystem.components.avatar.AvatarSize
import io.element.android.x.di.AppScope
import io.element.android.x.features.roomlist.model.MatrixUser import io.element.android.x.features.roomlist.model.MatrixUser
import io.element.android.x.features.roomlist.model.RoomListRoomSummary import io.element.android.x.features.roomlist.model.RoomListRoomSummary
import io.element.android.x.features.roomlist.model.RoomListRoomSummaryPlaceholders import io.element.android.x.features.roomlist.model.RoomListRoomSummaryPlaceholders
import io.element.android.x.features.roomlist.model.RoomListViewState import io.element.android.x.features.roomlist.model.RoomListViewState
import io.element.android.x.matrix.Matrix
import io.element.android.x.matrix.MatrixClient import io.element.android.x.matrix.MatrixClient
import io.element.android.x.matrix.MatrixInstance import io.element.android.x.matrix.MatrixInstance
import io.element.android.x.matrix.media.MediaResolver import io.element.android.x.matrix.media.MediaResolver
@ -22,28 +28,17 @@ import kotlinx.coroutines.launch
private const val extendedRangeSize = 40 private const val extendedRangeSize = 40
class RoomListViewModel( @ContributesViewModel(AppScope::class)
private val client: MatrixClient, class RoomListViewModel @AssistedInject constructor(
initialState: RoomListViewState matrix: Matrix,
@Assisted initialState: RoomListViewState
) : ) :
MavericksViewModel<RoomListViewState>(initialState) { MavericksViewModel<RoomListViewState>(initialState) {
companion object : MavericksViewModelFactory<RoomListViewModel, RoomListViewState> { companion object : MavericksViewModelFactory<RoomListViewModel, RoomListViewState> by daggerMavericksViewModelFactory()
override fun create(
viewModelContext: ViewModelContext,
state: RoomListViewState
): RoomListViewModel {
val matrix = MatrixInstance.getInstance()
val client = matrix.activeClient()
return RoomListViewModel(
client,
state
)
}
}
private val lastMessageFormatter = LastMessageFormatter() private val lastMessageFormatter = LastMessageFormatter()
private val client = matrix.activeClient()
init { init {
handleInit() handleInit()

View file

@ -1,19 +1,3 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.x.core.di package io.element.android.x.core.di
import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksState

View file

@ -22,7 +22,7 @@ import com.airbnb.mvrx.ViewModelContext
* } * }
*/ */
inline fun <reified VM : MavericksViewModel<S>, S : MavericksState> daggerMavericksViewModelFactory() = DaggerMavericksViewModelFactory<VM, S>(VM::class.java) inline fun <reified VM : MavericksViewModel<S>, S : MavericksState> daggerMavericksViewModelFactory() = DaggerMavericksViewModelFactory(VM::class.java)
/** /**
* A [MavericksViewModelFactory] makes it easy to create instances of a ViewModel * A [MavericksViewModelFactory] makes it easy to create instances of a ViewModel
@ -55,14 +55,6 @@ class DaggerMavericksViewModelFactory<VM : MavericksViewModel<S>, S : MavericksS
} }
} }
/**
* These Anvil/Dagger bindings are used by [DaggerMavericksViewModelFactory]. The factory will find the nearest [DaggerComponentOwner]
* that implements these bindings. It will then attempt to retrieve the [AssistedViewModelFactory] for the given ViewModel class.
*
* In this example, this bindings class is implemented by [com.airbnb.mvrx.sample.anvil.feature.ExampleFeatureComponent] because
* it provides the [com.airbnb.mvrx.sample.anvil.feature.ExampleFeatureViewModel]. Any component that will generate ViewModels should
* either implement this directly or have this added via `@ContributesTo(YourScope::class)`.
*/
interface DaggerMavericksBindings { interface DaggerMavericksBindings {
fun viewModelFactories(): Map<Class<out MavericksViewModel<*>>, AssistedViewModelFactory<*, *>> fun viewModelFactories(): Map<Class<out MavericksViewModel<*>>, AssistedViewModelFactory<*, *>>
} }