From d724504662aac3a6320e27d9efa5bbbff70721c4 Mon Sep 17 00:00:00 2001
From: ganfra <francoisg@element.io>
Date: Thu, 21 Oct 2021 20:17:49 +0200
Subject: [PATCH] Hilt: finish migration of latest view models

---
 .../app/core/di/MavericksViewModelModule.kt   | 31 ++++++++
 .../crypto/recover/BootstrapBottomSheet.kt    |  3 -
 .../recover/BootstrapSharedViewModel.kt       | 31 +++-----
 .../crypto/recover/BootstrapViewState.kt      |  7 +-
 .../verification/VerificationBottomSheet.kt   |  3 -
 .../VerificationBottomSheetViewModel.kt       | 75 +++++++++----------
 .../vector/app/features/home/HomeActivity.kt  |  1 -
 .../features/home/HomeActivityViewModel.kt    | 20 ++---
 .../home/room/detail/RoomDetailViewModel.kt   |  6 +-
 .../devices/DeviceListBottomSheet.kt          |  4 -
 .../devices/DeviceListBottomSheetViewModel.kt | 62 +++++++--------
 .../DeviceVerificationInfoBottomSheet.kt      |  1 -
 ...iceVerificationInfoBottomSheetViewModel.kt | 26 ++-----
 ...iceVerificationInfoBottomSheetViewState.kt |  6 +-
 14 files changed, 133 insertions(+), 143 deletions(-)

diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
index c98acee64c..17c29eb706 100644
--- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
@@ -28,11 +28,14 @@ import im.vector.app.features.contactsbook.ContactsBookViewModel
 import im.vector.app.features.createdirect.CreateDirectRoomViewModel
 import im.vector.app.features.crypto.keysbackup.settings.KeysBackupSettingsViewModel
 import im.vector.app.features.crypto.quads.SharedSecureStorageViewModel
+import im.vector.app.features.crypto.recover.BootstrapSharedViewModel
+import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
 import im.vector.app.features.crypto.verification.choose.VerificationChooseMethodViewModel
 import im.vector.app.features.crypto.verification.emoji.VerificationEmojiCodeViewModel
 import im.vector.app.features.devtools.RoomDevToolViewModel
 import im.vector.app.features.discovery.DiscoverySettingsViewModel
 import im.vector.app.features.discovery.change.SetIdentityServerViewModel
+import im.vector.app.features.home.HomeActivityViewModel
 import im.vector.app.features.home.HomeDetailViewModel
 import im.vector.app.features.home.PromoteRestrictedViewModel
 import im.vector.app.features.home.UnknownDeviceDetectorSharedViewModel
@@ -60,6 +63,7 @@ import im.vector.app.features.roomdirectory.createroom.CreateRoomViewModel
 import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerViewModel
 import im.vector.app.features.roomdirectory.roompreview.RoomPreviewViewModel
 import im.vector.app.features.roommemberprofile.RoomMemberProfileViewModel
+import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheetViewModel
 import im.vector.app.features.roomprofile.RoomProfileViewModel
 import im.vector.app.features.roomprofile.alias.RoomAliasViewModel
 import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetViewModel
@@ -72,6 +76,7 @@ import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRul
 import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel
 import im.vector.app.features.settings.account.deactivation.DeactivateAccountViewModel
 import im.vector.app.features.settings.crosssigning.CrossSigningSettingsViewModel
+import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheetViewModel
 import im.vector.app.features.settings.devices.DevicesViewModel
 import im.vector.app.features.settings.devtools.AccountDataViewModel
 import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailViewModel
@@ -512,4 +517,30 @@ interface MavericksViewModelModule {
     @MavericksViewModelKey(HomeDetailViewModel::class)
     fun homeDetailViewModelFactory(factory: HomeDetailViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
 
+    @Binds
+    @IntoMap
+    @MavericksViewModelKey(DeviceVerificationInfoBottomSheetViewModel::class)
+    fun deviceVerificationInfoBottomSheetViewModelFactory(factory: DeviceVerificationInfoBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
+    @Binds
+    @IntoMap
+    @MavericksViewModelKey(DeviceListBottomSheetViewModel::class)
+    fun deviceListBottomSheetViewModelFactory(factory: DeviceListBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
+    @Binds
+    @IntoMap
+    @MavericksViewModelKey(HomeActivityViewModel::class)
+    fun homeActivityViewModelFactory(factory: HomeActivityViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
+    @Binds
+    @IntoMap
+    @MavericksViewModelKey(BootstrapSharedViewModel::class)
+    fun bootstrapSharedViewModelFactory(factory: BootstrapSharedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
+    @Binds
+    @IntoMap
+    @MavericksViewModelKey(VerificationBottomSheetViewModel::class)
+    fun verificationBottomSheetViewModelFactory(factory: VerificationBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
+
 }
diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
index d3e086f973..264f51f379 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt
@@ -57,9 +57,6 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetBoot
 
     override val showExpanded = true
 
-    @Inject
-    lateinit var bootstrapViewModelFactory: BootstrapSharedViewModel.Factory
-
     private val viewModel by fragmentViewModel(BootstrapSharedViewModel::class)
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetBootstrapBinding {
diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt
index d208a92545..69309a9ae4 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt
@@ -16,7 +16,6 @@
 
 package im.vector.app.features.crypto.recover
 
-import androidx.lifecycle.viewModelScope
 import com.airbnb.mvrx.Fail
 import com.airbnb.mvrx.FragmentViewModelContext
 import com.airbnb.mvrx.Loading
@@ -29,6 +28,8 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import im.vector.app.R
+import im.vector.app.core.di.MavericksAssistedViewModelFactory
+import im.vector.app.core.di.hiltMavericksViewModelFactory
 import im.vector.app.core.error.ErrorFormatter
 import im.vector.app.core.extensions.exhaustive
 import im.vector.app.core.platform.VectorViewModel
@@ -59,13 +60,11 @@ import kotlin.coroutines.resumeWithException
 
 class BootstrapSharedViewModel @AssistedInject constructor(
         @Assisted initialState: BootstrapViewState,
-        @Assisted val args: BootstrapBottomSheet.Args,
         private val stringProvider: StringProvider,
         private val errorFormatter: ErrorFormatter,
         private val session: Session,
         private val bootstrapTask: BootstrapCrossSigningTask,
         private val migrationTask: BackupToQuadSMigrationTask,
-        private val reAuthHelper: ReAuthHelper
 ) : VectorViewModel<BootstrapViewState, BootstrapActions, BootstrapViewEvents>(initialState) {
 
     private var doesKeyBackupExist: Boolean = false
@@ -73,10 +72,12 @@ class BootstrapSharedViewModel @AssistedInject constructor(
     private val zxcvbn = Zxcvbn()
 
     @AssistedFactory
-    interface Factory {
-        fun create(initialState: BootstrapViewState, args: BootstrapBottomSheet.Args): BootstrapSharedViewModel
+    interface Factory : MavericksAssistedViewModelFactory<BootstrapSharedViewModel, BootstrapViewState> {
+        override fun create(initialState: BootstrapViewState): BootstrapSharedViewModel
     }
 
+    companion object : MavericksViewModelFactory<BootstrapSharedViewModel, BootstrapViewState> by hiltMavericksViewModelFactory()
+
 //    private var _pendingSession: String? = null
 
     var uiaContinuation: Continuation<UIABaseAuth>? = null
@@ -84,7 +85,7 @@ class BootstrapSharedViewModel @AssistedInject constructor(
 
     init {
 
-        when (args.setUpMode) {
+        when (initialState.setupMode) {
             SetupMode.PASSPHRASE_RESET,
             SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET,
             SetupMode.HARD_RESET         -> {
@@ -410,7 +411,7 @@ class BootstrapSharedViewModel @AssistedInject constructor(
                             progressListener = progressListener,
                             passphrase = state.passphrase,
                             keySpec = state.migrationRecoveryKey?.let { extractCurveKeyFromRecoveryKey(it)?.let { RawBytesKeySpec(it) } },
-                            setupMode = args.setUpMode
+                            setupMode = state.setupMode
                     )
             ) { bootstrapResult ->
                 when (bootstrapResult) {
@@ -516,7 +517,7 @@ class BootstrapSharedViewModel @AssistedInject constructor(
             BootstrapStep.CheckingMigration                  -> Unit
             is BootstrapStep.FirstForm                       -> {
                 _viewEvents.post(
-                        when (args.setUpMode) {
+                        when (state.setupMode) {
                             SetupMode.CROSS_SIGNING_ONLY,
                             SetupMode.NORMAL -> BootstrapViewEvents.SkipBootstrap()
                             else             -> BootstrapViewEvents.Dismiss(success = false)
@@ -547,18 +548,4 @@ class BootstrapSharedViewModel @AssistedInject constructor(
             else                                                       -> stringProvider.getString(R.string.unexpected_error)
         }
     }
-
-    // ======================================
-    // Companion, view model assisted creation
-    // ======================================
-
-    companion object : MavericksViewModelFactory<BootstrapSharedViewModel, BootstrapViewState> {
-
-        override fun create(viewModelContext: ViewModelContext, state: BootstrapViewState): BootstrapSharedViewModel? {
-            val fragment: BootstrapBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
-            val args: BootstrapBottomSheet.Args = fragment.arguments?.getParcelable(BootstrapBottomSheet.EXTRA_ARGS)
-                    ?: BootstrapBottomSheet.Args(SetupMode.CROSS_SIGNING_ONLY)
-            return fragment.bootstrapViewModelFactory.create(state, args)
-        }
-    }
 }
diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt
index b8c9f10b49..380a2b5fb4 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt
@@ -24,6 +24,7 @@ import im.vector.app.core.platform.WaitingViewData
 import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
 
 data class BootstrapViewState(
+        val setupMode: SetupMode,
         val step: BootstrapStep = BootstrapStep.CheckingMigration,
         val passphrase: String? = null,
         val migrationRecoveryKey: String? = null,
@@ -34,4 +35,8 @@ data class BootstrapViewState(
         val recoveryKeyCreationInfo: SsssKeyCreationInfo? = null,
         val initializationWaitingViewData: WaitingViewData? = null,
         val recoverySaveFileProcess: Async<Unit> = Uninitialized
-) : MavericksState
+) : MavericksState {
+
+    constructor(args: BootstrapBottomSheet.Args): this(setupMode = args.setUpMode)
+
+}
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt
index fa86c76691..5a4a985e2d 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt
@@ -77,9 +77,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetV
 
     override val showExpanded = true
 
-    @Inject
-    lateinit var verificationViewModelFactory: VerificationBottomSheetViewModel.Factory
-
     @Inject
     lateinit var avatarRenderer: AvatarRenderer
 
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
index 702283061c..45f7f56957 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt
@@ -15,20 +15,19 @@
  */
 package im.vector.app.features.crypto.verification
 
-import androidx.lifecycle.viewModelScope
 import com.airbnb.mvrx.Async
 import com.airbnb.mvrx.Fail
-import com.airbnb.mvrx.FragmentViewModelContext
 import com.airbnb.mvrx.Loading
 import com.airbnb.mvrx.MavericksState
 import com.airbnb.mvrx.MavericksViewModelFactory
 import com.airbnb.mvrx.Success
 import com.airbnb.mvrx.Uninitialized
-import com.airbnb.mvrx.ViewModelContext
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import im.vector.app.R
+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
@@ -61,15 +60,17 @@ import org.matrix.android.sdk.internal.util.awaitCallback
 import timber.log.Timber
 
 data class VerificationBottomSheetViewState(
+        val otherUserId: String,
+        val verificationId: String?,
+        val roomId: String?,
+        // true when we display the loading and we wait for the other (incoming request)
+        val selfVerificationMode: Boolean,
         val otherUserMxItem: MatrixItem? = null,
-        val roomId: String? = null,
         val pendingRequest: Async<PendingVerificationRequest> = Uninitialized,
         val pendingLocalId: String? = null,
         val sasTransactionState: VerificationTxState? = null,
         val qrTransactionState: VerificationTxState? = null,
         val transactionId: String? = null,
-        // true when we display the loading and we wait for the other (incoming request)
-        val selfVerificationMode: Boolean = false,
         val verifiedFromPrivateKeys: Boolean = false,
         val verifyingFrom4S: Boolean = false,
         val isMe: Boolean = false,
@@ -79,29 +80,41 @@ data class VerificationBottomSheetViewState(
         val quadSContainsSecrets: Boolean = true,
         val quadSHasBeenReset: Boolean = false,
         val hasAnyOtherSession: Boolean = false
-) : MavericksState
+) : MavericksState {
+
+    constructor(args: VerificationBottomSheet.VerificationArgs) : this(
+            otherUserId = args.otherUserId,
+            verificationId = args.verificationId,
+            roomId = args.roomId,
+            selfVerificationMode = args.selfVerificationMode
+    )
+}
 
 class VerificationBottomSheetViewModel @AssistedInject constructor(
         @Assisted initialState: VerificationBottomSheetViewState,
-        @Assisted val args: VerificationBottomSheet.VerificationArgs,
         private val session: Session,
         private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider,
         private val stringProvider: StringProvider) :
-    VectorViewModel<VerificationBottomSheetViewState, VerificationAction, VerificationBottomSheetViewEvents>(initialState),
+        VectorViewModel<VerificationBottomSheetViewState, VerificationAction, VerificationBottomSheetViewEvents>(initialState),
         VerificationService.Listener {
 
+    @AssistedFactory
+    interface Factory : MavericksAssistedViewModelFactory<VerificationBottomSheetViewModel, VerificationBottomSheetViewState> {
+        override fun create(initialState: VerificationBottomSheetViewState): VerificationBottomSheetViewModel
+    }
+
+    companion object : MavericksViewModelFactory<VerificationBottomSheetViewModel, VerificationBottomSheetViewState> by hiltMavericksViewModelFactory()
+
     init {
         session.cryptoService().verificationService().addListener(this)
 
-        val userItem = session.getUser(args.otherUserId)
-
-        val selfVerificationMode = args.selfVerificationMode
+        val userItem = session.getUser(initialState.otherUserId)
 
         var autoReady = false
-        val pr = if (selfVerificationMode) {
+        val pr = if (initialState.selfVerificationMode) {
             // See if active tx for this user and take it
 
-            session.cryptoService().verificationService().getExistingVerificationRequests(args.otherUserId)
+            session.cryptoService().verificationService().getExistingVerificationRequests(initialState.otherUserId)
                     .lastOrNull { !it.isFinished }
                     ?.also { verificationRequest ->
                         if (verificationRequest.isIncoming && !verificationRequest.isReady) {
@@ -110,15 +123,15 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
                         }
                     }
         } else {
-            session.cryptoService().verificationService().getExistingVerificationRequest(args.otherUserId, args.verificationId)
+            session.cryptoService().verificationService().getExistingVerificationRequest(initialState.otherUserId, initialState.verificationId)
         }
 
-        val sasTx = (pr?.transactionId ?: args.verificationId)?.let {
-            session.cryptoService().verificationService().getExistingTransaction(args.otherUserId, it) as? SasVerificationTransaction
+        val sasTx = (pr?.transactionId ?: initialState.verificationId)?.let {
+            session.cryptoService().verificationService().getExistingTransaction(initialState.otherUserId, it) as? SasVerificationTransaction
         }
 
-        val qrTx = (pr?.transactionId ?: args.verificationId)?.let {
-            session.cryptoService().verificationService().getExistingTransaction(args.otherUserId, it) as? QrCodeVerificationTransaction
+        val qrTx = (pr?.transactionId ?: initialState.verificationId)?.let {
+            session.cryptoService().verificationService().getExistingTransaction(initialState.otherUserId, it) as? QrCodeVerificationTransaction
         }
 
         val hasAnyOtherSession = session.cryptoService()
@@ -132,11 +145,9 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
                     otherUserMxItem = userItem?.toMatrixItem(),
                     sasTransactionState = sasTx?.state,
                     qrTransactionState = qrTx?.state,
-                    transactionId = pr?.transactionId ?: args.verificationId,
+                    transactionId = pr?.transactionId ?: initialState.verificationId,
                     pendingRequest = if (pr != null) Success(pr) else Uninitialized,
-                    selfVerificationMode = selfVerificationMode,
-                    roomId = args.roomId,
-                    isMe = args.otherUserId == session.myUserId,
+                    isMe = initialState.otherUserId == session.myUserId,
                     currentDeviceCanCrossSign = session.cryptoService().crossSigningService().canCrossSign(),
                     quadSContainsSecrets = session.sharedSecretStorageService.isRecoverySetup(),
                     hasAnyOtherSession = hasAnyOtherSession
@@ -159,12 +170,6 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
         super.onCleared()
     }
 
-    @AssistedFactory
-    interface Factory {
-        fun create(initialState: VerificationBottomSheetViewState,
-                   args: VerificationBottomSheet.VerificationArgs): VerificationBottomSheetViewModel
-    }
-
     fun queryCancel() = withState { state ->
         if (state.userThinkItsNotHim) {
             setState {
@@ -223,16 +228,6 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
         _viewEvents.post(VerificationBottomSheetViewEvents.GoToSettings)
     }
 
-    companion object : MavericksViewModelFactory<VerificationBottomSheetViewModel, VerificationBottomSheetViewState> {
-
-        override fun create(viewModelContext: ViewModelContext, state: VerificationBottomSheetViewState): VerificationBottomSheetViewModel? {
-            val fragment: VerificationBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
-            val args: VerificationBottomSheet.VerificationArgs = viewModelContext.args()
-
-            return fragment.verificationViewModelFactory.create(state, args)
-        }
-    }
-
     override fun handle(action: VerificationAction) = withState { state ->
         val otherUserId = state.otherUserMxItem?.id ?: return@withState
         val roomId = state.roomId
@@ -542,7 +537,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
                 state.pendingRequest.invoke()?.transactionId == pr.transactionId) {
             setState {
                 copy(
-                        transactionId = args.verificationId ?: pr.transactionId,
+                        transactionId = state.verificationId ?: pr.transactionId,
                         pendingRequest = Success(pr)
                 )
             }
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
index e4b759284c..6e4b26cb9d 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt
@@ -103,7 +103,6 @@ class HomeActivity :
     private lateinit var sharedActionViewModel: HomeSharedActionViewModel
 
     private val homeActivityViewModel: HomeActivityViewModel by viewModel()
-    @Inject lateinit var viewModelFactory: HomeActivityViewModel.Factory
 
     private val serverBackupStatusViewModel: ServerBackupStatusViewModel by viewModel()
     private val promoteRestrictedViewModel: PromoteRestrictedViewModel by viewModel()
diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
index 627ff4be12..59b9cafd6e 100644
--- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt
@@ -17,14 +17,13 @@
 package im.vector.app.features.home
 
 import androidx.lifecycle.asFlow
-import androidx.lifecycle.viewModelScope
-import com.airbnb.mvrx.Mavericks
 import com.airbnb.mvrx.MavericksViewModelFactory
-import com.airbnb.mvrx.ViewModelContext
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import im.vector.app.core.di.ActiveSessionHolder
+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.features.login.ReAuthHelper
@@ -58,26 +57,17 @@ import kotlin.coroutines.resumeWithException
 
 class HomeActivityViewModel @AssistedInject constructor(
         @Assisted initialState: HomeActivityViewState,
-        @Assisted private val args: HomeActivityArgs,
         private val activeSessionHolder: ActiveSessionHolder,
         private val reAuthHelper: ReAuthHelper,
         private val vectorPreferences: VectorPreferences
 ) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
 
     @AssistedFactory
-    interface Factory {
-        fun create(initialState: HomeActivityViewState, args: HomeActivityArgs): HomeActivityViewModel
+    interface Factory : MavericksAssistedViewModelFactory<HomeActivityViewModel, HomeActivityViewState> {
+        override fun create(initialState: HomeActivityViewState): HomeActivityViewModel
     }
 
-    companion object : MavericksViewModelFactory<HomeActivityViewModel, HomeActivityViewState> {
-
-        @JvmStatic
-        override fun create(viewModelContext: ViewModelContext, state: HomeActivityViewState): HomeActivityViewModel? {
-            val activity: HomeActivity = viewModelContext.activity()
-            val args: HomeActivityArgs? = activity.intent.getParcelableExtra(Mavericks.KEY_ARG)
-            return activity.viewModelFactory.create(state, args ?: HomeActivityArgs(clearNotification = false, accountCreation = false))
-        }
-    }
+    companion object : MavericksViewModelFactory<HomeActivityViewModel, HomeActivityViewState> by hiltMavericksViewModelFactory()
 
     private var checkBootstrap = false
     private var onceTrusted = false
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt
index 0c0e5ee6cd..3873a2eb77 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt
@@ -147,14 +147,16 @@ class RoomDetailViewModel @AssistedInject constructor(
         fun create(initialState: RoomDetailViewState): RoomDetailViewModel
     }
 
+    /**
+     * Can't use the hiltMaverick here because some dependencies are injected here and in fragment but they don't share the graph.
+     */
     companion object : MavericksViewModelFactory<RoomDetailViewModel, RoomDetailViewState> {
 
         const val PAGINATION_COUNT = 50
 
         @JvmStatic
-        override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? {
+        override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel {
             val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
-
             return fragment.roomDetailViewModelFactory.create(state)
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt
index d156521690..f83ac8f19d 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt
@@ -29,14 +29,12 @@ import com.airbnb.mvrx.fragmentViewModel
 import com.airbnb.mvrx.withState
 import dagger.hilt.android.AndroidEntryPoint
 import im.vector.app.R
-
 import im.vector.app.core.extensions.commitTransaction
 import im.vector.app.core.extensions.exhaustive
 import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
 import im.vector.app.databinding.BottomSheetWithFragmentsBinding
 import im.vector.app.features.crypto.verification.VerificationBottomSheet
 import kotlinx.parcelize.Parcelize
-import javax.inject.Inject
 import kotlin.reflect.KClass
 
 @AndroidEntryPoint
@@ -49,8 +47,6 @@ class DeviceListBottomSheet :
 
     private val viewModel: DeviceListBottomSheetViewModel by fragmentViewModel(DeviceListBottomSheetViewModel::class)
 
-    @Inject lateinit var viewModelFactory: DeviceListBottomSheetViewModel.Factory
-
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
         viewModel.observeViewEvents {
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt
index 03b20bce40..d2491237ca 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt
@@ -17,7 +17,6 @@
 package im.vector.app.features.roommemberprofile.devices
 
 import com.airbnb.mvrx.Async
-import com.airbnb.mvrx.FragmentViewModelContext
 import com.airbnb.mvrx.Loading
 import com.airbnb.mvrx.MavericksState
 import com.airbnb.mvrx.MavericksViewModelFactory
@@ -26,7 +25,9 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import dagger.hilt.EntryPoints
+import im.vector.app.core.di.MavericksAssistedViewModelFactory
 import im.vector.app.core.di.SingletonEntryPoint
+import im.vector.app.core.di.hiltMavericksViewModelFactory
 import im.vector.app.core.extensions.exhaustive
 import im.vector.app.core.platform.VectorViewModel
 import org.matrix.android.sdk.api.session.Session
@@ -38,6 +39,8 @@ import org.matrix.android.sdk.flow.flow
 import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
 
 data class DeviceListViewState(
+        val userId: String,
+        val allowDeviceAction: Boolean,
         val userItem: MatrixItem? = null,
         val isMine: Boolean = false,
         val memberCrossSigningKey: MXCrossSigningInfo? = null,
@@ -46,24 +49,41 @@ data class DeviceListViewState(
 ) : MavericksState
 
 class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted private val initialState: DeviceListViewState,
-                                                                 @Assisted private val args: DeviceListBottomSheet.Args,
                                                                  private val session: Session) :
-    VectorViewModel<DeviceListViewState, DeviceListAction, DeviceListBottomSheetViewEvents>(initialState) {
+        VectorViewModel<DeviceListViewState, DeviceListAction, DeviceListBottomSheetViewEvents>(initialState) {
 
     @AssistedFactory
-    interface Factory {
-        fun create(initialState: DeviceListViewState, args: DeviceListBottomSheet.Args): DeviceListBottomSheetViewModel
+    interface Factory : MavericksAssistedViewModelFactory<DeviceListBottomSheetViewModel, DeviceListViewState> {
+        override fun create(initialState: DeviceListViewState): DeviceListBottomSheetViewModel
+    }
+
+    companion object : MavericksViewModelFactory<DeviceListBottomSheetViewModel, DeviceListViewState> by hiltMavericksViewModelFactory() {
+
+        override fun initialState(viewModelContext: ViewModelContext): DeviceListViewState? {
+            val args = viewModelContext.args<DeviceListBottomSheet.Args>()
+            val userId = args.userId
+            val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession()
+            return session.getUser(userId)?.toMatrixItem()?.let {
+                DeviceListViewState(
+                        userId = userId,
+                        allowDeviceAction = args.allowDeviceAction,
+                        userItem = it,
+                        isMine = userId == session.myUserId
+                )
+            } ?: return super.initialState(viewModelContext)
+        }
     }
 
     init {
-        session.flow().liveUserCryptoDevices(args.userId)
+
+        session.flow().liveUserCryptoDevices(initialState.userId)
                 .execute {
                     copy(cryptoDevices = it).also {
                         refreshSelectedId()
                     }
                 }
 
-        session.flow().liveCrossSigningInfo(args.userId)
+        session.flow().liveCrossSigningInfo(initialState.userId)
                 .execute {
                     copy(memberCrossSigningKey = it.invoke()?.getOrNull())
                 }
@@ -90,7 +110,7 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
     }
 
     private fun selectDevice(action: DeviceListAction.SelectDevice) {
-        if (!args.allowDeviceAction) return
+        if (!initialState.allowDeviceAction) return
         setState {
             copy(selectedDevice = action.device)
         }
@@ -103,29 +123,9 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva
     }
 
     private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) {
-        if (!args.allowDeviceAction) return
-        session.cryptoService().verificationService().beginKeyVerification(VerificationMethod.SAS, args.userId, action.deviceId, null)?.let { txID ->
-            _viewEvents.post(DeviceListBottomSheetViewEvents.Verify(args.userId, txID))
-        }
-    }
-
-    companion object : MavericksViewModelFactory<DeviceListBottomSheetViewModel, DeviceListViewState> {
-        @JvmStatic
-        override fun create(viewModelContext: ViewModelContext, state: DeviceListViewState): DeviceListBottomSheetViewModel? {
-            val fragment: DeviceListBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
-            val args = viewModelContext.args<DeviceListBottomSheet.Args>()
-            return fragment.viewModelFactory.create(state, args)
-        }
-
-        override fun initialState(viewModelContext: ViewModelContext): DeviceListViewState? {
-            val userId = viewModelContext.args<DeviceListBottomSheet.Args>().userId
-            val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession()
-            return session.getUser(userId)?.toMatrixItem()?.let {
-                DeviceListViewState(
-                        userItem = it,
-                        isMine = userId == session.myUserId
-                )
-            } ?: return super.initialState(viewModelContext)
+        if (!initialState.allowDeviceAction) return
+        session.cryptoService().verificationService().beginKeyVerification(VerificationMethod.SAS, initialState.userId, action.deviceId, null)?.let { txID ->
+            _viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID))
         }
     }
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt
index 66a9ca4943..31a6bbd295 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt
@@ -49,7 +49,6 @@ class DeviceVerificationInfoBottomSheet :
 
     private val sharedViewModel: DevicesViewModel by parentFragmentViewModel(DevicesViewModel::class)
 
-    @Inject lateinit var deviceVerificationInfoViewModelFactory: DeviceVerificationInfoBottomSheetViewModel.Factory
     @Inject lateinit var controller: DeviceVerificationInfoBottomSheetController
 
     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt
index e6cde74440..cb70ed4041 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt
@@ -15,13 +15,13 @@
  */
 package im.vector.app.features.settings.devices
 
-import com.airbnb.mvrx.FragmentViewModelContext
 import com.airbnb.mvrx.Loading
 import com.airbnb.mvrx.MavericksViewModelFactory
-import com.airbnb.mvrx.ViewModelContext
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import im.vector.app.core.di.MavericksAssistedViewModelFactory
+import im.vector.app.core.di.hiltMavericksViewModelFactory
 import im.vector.app.core.platform.EmptyAction
 import im.vector.app.core.platform.EmptyViewEvents
 import im.vector.app.core.platform.VectorViewModel
@@ -31,15 +31,16 @@ import org.matrix.android.sdk.flow.flow
 import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
 
 class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: DeviceVerificationInfoBottomSheetViewState,
-                                                                             @Assisted val deviceId: String,
                                                                              val session: Session
 ) : VectorViewModel<DeviceVerificationInfoBottomSheetViewState, EmptyAction, EmptyViewEvents>(initialState) {
 
     @AssistedFactory
-    interface Factory {
-        fun create(initialState: DeviceVerificationInfoBottomSheetViewState, deviceId: String): DeviceVerificationInfoBottomSheetViewModel
+    interface Factory: MavericksAssistedViewModelFactory<DeviceVerificationInfoBottomSheetViewModel,DeviceVerificationInfoBottomSheetViewState> {
+        override fun create(initialState: DeviceVerificationInfoBottomSheetViewState): DeviceVerificationInfoBottomSheetViewModel
     }
 
+    companion object : MavericksViewModelFactory<DeviceVerificationInfoBottomSheetViewModel, DeviceVerificationInfoBottomSheetViewState> by hiltMavericksViewModelFactory()
+
     init {
 
         setState {
@@ -59,7 +60,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
 
         session.flow().liveUserCryptoDevices(session.myUserId)
                 .map { list ->
-                    list.firstOrNull { it.deviceId == deviceId }
+                    list.firstOrNull { it.deviceId == initialState.deviceId }
                 }
                 .execute {
                     copy(
@@ -82,24 +83,13 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As
 
         session.flow().liveMyDevicesInfo()
                 .map { devices ->
-                    devices.firstOrNull { it.deviceId == deviceId } ?: DeviceInfo(deviceId = deviceId)
+                    devices.firstOrNull { it.deviceId == initialState.deviceId } ?: DeviceInfo(deviceId = initialState.deviceId)
                 }
                 .execute {
                     copy(deviceInfo = it)
                 }
     }
 
-    companion object : MavericksViewModelFactory<DeviceVerificationInfoBottomSheetViewModel, DeviceVerificationInfoBottomSheetViewState> {
-
-        @JvmStatic
-        override fun create(viewModelContext: ViewModelContext, state: DeviceVerificationInfoBottomSheetViewState):
-                DeviceVerificationInfoBottomSheetViewModel? {
-            val fragment: DeviceVerificationInfoBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
-            val args = viewModelContext.args<DeviceVerificationInfoArgs>()
-            return fragment.deviceVerificationInfoViewModelFactory.create(state, args.deviceId)
-        }
-    }
-
     override fun handle(action: EmptyAction) {
     }
 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt
index e320642ed0..32927ca068 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt
@@ -23,6 +23,7 @@ import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
 import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
 
 data class DeviceVerificationInfoBottomSheetViewState(
+        val deviceId: String,
         val cryptoDeviceInfo: Async<CryptoDeviceInfo?> = Uninitialized,
         val deviceInfo: Async<DeviceInfo> = Uninitialized,
         val hasAccountCrossSigning: Boolean = false,
@@ -32,6 +33,7 @@ data class DeviceVerificationInfoBottomSheetViewState(
         val isRecoverySetup: Boolean = false
 ) : MavericksState {
 
-    val canVerifySession: Boolean
-        get() = hasOtherSessions || isRecoverySetup
+    constructor(args: DeviceVerificationInfoArgs) : this(deviceId = args.deviceId)
+
+    val canVerifySession = hasOtherSessions || isRecoverySetup
 }