mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-07 06:23:55 +01:00
Hilt: introduce MavericksComponent and try on RoomList
This commit is contained in:
parent
ff53cf4db9
commit
f8d208fb4f
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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 im.vector.app.core.di
|
||||
|
||||
import com.airbnb.mvrx.MavericksState
|
||||
import com.airbnb.mvrx.MavericksViewModel
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.hilt.DefineComponent
|
||||
import dagger.hilt.EntryPoint
|
||||
import dagger.hilt.EntryPoints
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
/**
|
||||
* To connect Mavericks ViewModel creation with Hilt's dependency injection, add the following Factory and companion object to your MavericksViewModel.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* class MyViewModel @AssistedInject constructor(...): MavericksViewModel<MyState>(...) {
|
||||
*
|
||||
* @AssistedFactory
|
||||
* interface Factory : AssistedViewModelFactory<MyViewModel, MyState> {
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* companion object : MavericksViewModelFactory<MyViewModel, MyState> by hiltMavericksViewModelFactory()
|
||||
* }
|
||||
*/
|
||||
|
||||
inline fun <reified VM : MavericksViewModel<S>, S : MavericksState> hiltMavericksViewModelFactory() = HiltMavericksViewModelFactory<VM, S>(VM::class.java)
|
||||
|
||||
class HiltMavericksViewModelFactory<VM : MavericksViewModel<S>, S : MavericksState>(
|
||||
private val viewModelClass: Class<out MavericksViewModel<S>>
|
||||
) : MavericksViewModelFactory<VM, S> {
|
||||
|
||||
override fun create(viewModelContext: ViewModelContext, state: S): VM {
|
||||
// We want to create the ViewModelComponent. In order to do that, we need to get its parent: ActivityComponent.
|
||||
val componentBuilder = EntryPoints.get(viewModelContext.app(), CreateMavericksViewModelComponent::class.java).mavericksViewModelComponentBuilder()
|
||||
val viewModelComponent = componentBuilder.build()
|
||||
val viewModelFactoryMap = EntryPoints.get(viewModelComponent, HiltMavericksEntryPoint::class.java).viewModelFactories
|
||||
val viewModelFactory = viewModelFactoryMap[viewModelClass]
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val castedViewModelFactory = viewModelFactory as? MavericksAssistedViewModelFactory<VM, S>
|
||||
return castedViewModelFactory?.create(state) as VM
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilt's ViewModelComponent's parent is ActivityRetainedComponent but there is no easy way to access it. SingletonComponent should be sufficient
|
||||
* because the ViewModel that gets created is the only object with a reference to the created component so the lifecycle of it will
|
||||
* still be correct.
|
||||
*/
|
||||
@MavericksViewModelScoped
|
||||
@DefineComponent(parent = SingletonComponent::class)
|
||||
interface MavericksViewModelComponent
|
||||
|
||||
@DefineComponent.Builder
|
||||
interface MavericksViewModelComponentBuilder {
|
||||
fun build(): MavericksViewModelComponent
|
||||
}
|
||||
|
||||
@EntryPoint
|
||||
@InstallIn(SingletonComponent::class)
|
||||
interface CreateMavericksViewModelComponent {
|
||||
fun mavericksViewModelComponentBuilder(): MavericksViewModelComponentBuilder
|
||||
}
|
||||
|
||||
@EntryPoint
|
||||
@InstallIn(MavericksViewModelComponent::class)
|
||||
interface HiltMavericksEntryPoint {
|
||||
val viewModelFactories: Map<Class<out MavericksViewModel<*>>, MavericksAssistedViewModelFactory<*, *>>
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 im.vector.app.core.di
|
||||
|
||||
import com.airbnb.mvrx.MavericksState
|
||||
import com.airbnb.mvrx.MavericksViewModel
|
||||
|
||||
/**
|
||||
* This factory allows Mavericks to supply the initial or restored [MavericksState] to Hilt.
|
||||
*
|
||||
* Add this interface inside of your [MavericksViewModel] class then create the following Hilt module:
|
||||
*
|
||||
* @Module
|
||||
* @InstallIn(MavericksViewModelComponent::class)
|
||||
* interface ViewModelsModule {
|
||||
* @Binds
|
||||
* @IntoMap
|
||||
* @ViewModelKey(MyViewModel::class)
|
||||
* fun myViewModelFactory(factory: MyViewModel.Factory): AssistedViewModelFactory<*, *>
|
||||
* }
|
||||
*
|
||||
* If you already have a ViewModelsModule then all you have to do is add the multibinding entry for your new [MavericksViewModel].
|
||||
*/
|
||||
interface MavericksAssistedViewModelFactory<VM : MavericksViewModel<S>, S : MavericksState> {
|
||||
fun create(state: S): VM
|
||||
}
|
@ -14,16 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.home.room.list
|
||||
package im.vector.app.core.di
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.migration.DisableInstallInCheck
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.multibindings.IntoMap
|
||||
import im.vector.app.features.home.room.list.RoomListViewModel
|
||||
|
||||
@DisableInstallInCheck
|
||||
@InstallIn(MavericksViewModelComponent::class)
|
||||
@Module
|
||||
abstract class RoomListModule {
|
||||
interface MavericksViewModelModule {
|
||||
|
||||
@Binds
|
||||
abstract fun providesRoomListViewModelFactory(factory: RoomListViewModelFactory): RoomListViewModel.Factory
|
||||
@IntoMap
|
||||
@MavericksViewModelKey(RoomListViewModel::class)
|
||||
fun roomListViewModelFactory(factory: RoomListViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 im.vector.app.core.di
|
||||
|
||||
import javax.inject.Scope
|
||||
|
||||
/**
|
||||
* Scope annotation for bindings that should exist for the life of an MavericksViewModel.
|
||||
*/
|
||||
@Scope
|
||||
annotation class MavericksViewModelScoped
|
@ -73,7 +73,6 @@ import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsB
|
||||
import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet
|
||||
import im.vector.app.features.home.room.detail.widget.RoomWidgetsBottomSheet
|
||||
import im.vector.app.features.home.room.filtered.FilteredRoomsActivity
|
||||
import im.vector.app.features.home.room.list.RoomListModule
|
||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
|
||||
import im.vector.app.features.html.EventHtmlRenderer
|
||||
import im.vector.app.features.html.VectorHtmlCompressor
|
||||
@ -253,7 +252,6 @@ interface ScreenComponentDependencies {
|
||||
ViewModelModule::class,
|
||||
FragmentModule::class,
|
||||
HomeModule::class,
|
||||
RoomListModule::class,
|
||||
ScreenModule::class
|
||||
]
|
||||
)
|
||||
|
@ -17,6 +17,7 @@
|
||||
package im.vector.app.core.di
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.airbnb.mvrx.MavericksViewModel
|
||||
import dagger.MapKey
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@ -24,3 +25,8 @@ import kotlin.reflect.KClass
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@MapKey
|
||||
annotation class ViewModelKey(val value: KClass<out ViewModel>)
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@MapKey
|
||||
annotation class MavericksViewModelKey(val value: KClass<out MavericksViewModel<*>>)
|
||||
|
@ -64,7 +64,6 @@ data class RoomListParams(
|
||||
|
||||
class RoomListFragment @Inject constructor(
|
||||
private val pagedControllerFactory: RoomSummaryPagedControllerFactory,
|
||||
val roomListViewModelFactory: RoomListViewModel.Factory,
|
||||
private val notificationDrawerManager: NotificationDrawerManager,
|
||||
private val footerController: RoomListFooterController,
|
||||
private val userPreferencesProvider: UserPreferencesProvider
|
||||
|
@ -24,8 +24,13 @@ import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import im.vector.app.AppStateHandler
|
||||
import im.vector.app.RoomGroupingMethod
|
||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||
import im.vector.app.core.extensions.exhaustive
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
@ -48,8 +53,8 @@ import org.matrix.android.sdk.flow.flow
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomListViewModel @Inject constructor(
|
||||
initialState: RoomListViewState,
|
||||
class RoomListViewModel @AssistedInject constructor(
|
||||
@Assisted initialState: RoomListViewState,
|
||||
private val session: Session,
|
||||
private val stringProvider: StringProvider,
|
||||
private val appStateHandler: AppStateHandler,
|
||||
@ -57,8 +62,9 @@ class RoomListViewModel @Inject constructor(
|
||||
private val autoAcceptInvites: AutoAcceptInvites
|
||||
) : VectorViewModel<RoomListViewState, RoomListAction, RoomListViewEvents>(initialState) {
|
||||
|
||||
interface Factory {
|
||||
fun create(initialState: RoomListViewState): RoomListViewModel
|
||||
@AssistedFactory
|
||||
interface Factory: MavericksAssistedViewModelFactory<RoomListViewModel, RoomListViewState> {
|
||||
override fun create(state: RoomListViewState): RoomListViewModel
|
||||
}
|
||||
|
||||
private var updatableQuery: UpdatableLivePageResult? = null
|
||||
@ -115,14 +121,7 @@ class RoomListViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
companion object : MavericksViewModelFactory<RoomListViewModel, RoomListViewState> {
|
||||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: RoomListViewState): RoomListViewModel {
|
||||
val fragment: RoomListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
return fragment.roomListViewModelFactory.create(state)
|
||||
}
|
||||
}
|
||||
companion object : MavericksViewModelFactory<RoomListViewModel, RoomListViewState> by hiltMavericksViewModelFactory()
|
||||
|
||||
private val roomListSectionBuilder = if (appStateHandler.getCurrentRoomGroupingMethod() is RoomGroupingMethod.BySpace) {
|
||||
RoomListSectionBuilderSpace(
|
||||
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 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 im.vector.app.features.home.room.list
|
||||
|
||||
import im.vector.app.AppStateHandler
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.invite.AutoAcceptInvites
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
class RoomListViewModelFactory @Inject constructor(private val session: Provider<Session>,
|
||||
private val appStateHandler: AppStateHandler,
|
||||
private val stringProvider: StringProvider,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val autoAcceptInvites: AutoAcceptInvites) :
|
||||
RoomListViewModel.Factory {
|
||||
|
||||
override fun create(initialState: RoomListViewState): RoomListViewModel {
|
||||
return RoomListViewModel(
|
||||
initialState = initialState,
|
||||
session = session.get(),
|
||||
stringProvider = stringProvider,
|
||||
appStateHandler = appStateHandler,
|
||||
vectorPreferences = vectorPreferences,
|
||||
autoAcceptInvites = autoAcceptInvites
|
||||
)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user