Merge pull request #4312 from vector-im/feature/fga/hilt_app_migration

Migrate App DI framework to Hilt
This commit is contained in:
Benoit Marty 2021-10-25 12:41:02 +02:00 committed by GitHub
commit 3354cd1760
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
261 changed files with 1864 additions and 2864 deletions

View File

@ -17,6 +17,7 @@ buildscript {
// https://developer.android.com/studio/releases/gradle-plugin
classpath libs.gradle.gradlePlugin
classpath libs.gradle.kotlinPlugin
classpath libs.gradle.hiltPlugin
classpath 'com.google.gms:google-services:4.3.10'
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.4'

1
changelog.d/3888.misc Normal file
View File

@ -0,0 +1 @@
Migrate app DI framework to Hilt

View File

@ -34,7 +34,9 @@ def androidxTest = "1.4.0"
ext.libs = [
gradle : [
'gradlePlugin' : "com.android.tools.build:gradle:$gradle",
'kotlinPlugin' : "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin"
'kotlinPlugin' : "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin",
'hiltPlugin' : "com.google.dagger:hilt-android-gradle-plugin:$dagger"
],
jetbrains : [
'coroutinesCore' : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines",
@ -72,7 +74,9 @@ ext.libs = [
],
dagger : [
'dagger' : "com.google.dagger:dagger:$dagger",
'daggerCompiler' : "com.google.dagger:dagger-compiler:$dagger"
'daggerCompiler' : "com.google.dagger:dagger-compiler:$dagger",
'hilt' : "com.google.dagger:hilt-android:$dagger",
'hiltCompiler' : "com.google.dagger:hilt-compiler:$dagger"
],
squareup : [
'moshi' : "com.squareup.moshi:moshi-adapters:$moshi",

33
docs/hilt_migration.md Normal file
View File

@ -0,0 +1,33 @@
Useful links:
- https://dagger.dev/hilt/migration-guide
- https://dagger.dev/hilt/quick-start
Hilt is built on top of Dagger 2 and simplify usage by removing needs to create components manually.
When you create a new feature, you should have the following:
Annotate your Activity with @AndroidEntryPoint
If you have a BottomSheetFragment => Annotate it with @AndroidEntryPoint
Otherwise => Add your Fragment to the FragmentModule
Add your ViewModel.Factory to the MavericksViewModelModule
Makes sure your ViewModel as the following code:
```
@AssistedFactory
interface Factory: MavericksAssistedViewModelFactory<MyViewModel, MyViewState> {
override fun create(initialState: MyViewState): MyViewModel
}
companion object : MavericksViewModelFactory<MyViewModel, MyViewState> by hiltMavericksViewModelFactory()
```
## Some remarks
@MavericksViewModelScope dependencies can't be injected inside Fragments/Activities
You can only inject @Singleton, @MavericksViewModelScope or unscoped dependencies inside Maverick ViewModels
You can access some specific dependencies from Singleton component by using
```
context.singletonEntryPoint()
```
Be aware that only the app has been migrated to Hilt and not the SDK.

View File

@ -6,6 +6,7 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'placeholder-resolver'
apply plugin: 'dagger.hilt.android.plugin'
kapt {
correctErrorTypes = true
@ -456,8 +457,8 @@ dependencies {
implementation 'nl.dionsegijn:konfetti:1.3.2'
implementation 'com.github.jetradarmobile:android-snowfall:1.2.1'
// DI
implementation libs.dagger.dagger
kapt libs.dagger.daggerCompiler
implementation libs.dagger.hilt
kapt libs.dagger.hiltCompiler
// gplay flavor only
gplayImplementation('com.google.firebase:firebase-messaging:22.0.0') {

View File

@ -24,9 +24,9 @@ import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.Person
import androidx.core.content.getSystemService
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
@ -50,6 +50,7 @@ import org.matrix.android.sdk.internal.crypto.verification.qrcode.toQrCodeData
import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
class DebugMenuActivity : VectorBaseActivity<ActivityDebugMenuBinding>() {
override fun getBinding() = ActivityDebugMenuBinding.inflate(layoutInflater)
@ -57,10 +58,6 @@ class DebugMenuActivity : VectorBaseActivity<ActivityDebugMenuBinding>() {
@Inject
lateinit var activeSessionHolder: ActiveSessionHolder
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
private lateinit var buffer: ByteArray
override fun initUiAndData() {

View File

@ -18,15 +18,15 @@ package im.vector.app.fdroid.features.settings.troubleshoot
import android.content.Intent
import android.net.ConnectivityManager
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.getSystemService
import androidx.core.net.ConnectivityManagerCompat
import androidx.fragment.app.FragmentActivity
import im.vector.app.R
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.settings.troubleshoot.TroubleshootTest
import javax.inject.Inject
class TestBackgroundRestrictions @Inject constructor(private val context: AppCompatActivity,
class TestBackgroundRestrictions @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider) :
TroubleshootTest(R.string.settings_troubleshoot_test_bg_restricted_title) {

View File

@ -17,7 +17,7 @@ package im.vector.app.fdroid.features.settings.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import im.vector.app.R
import im.vector.app.core.resources.StringProvider
import im.vector.app.core.utils.isIgnoringBatteryOptimizations
@ -26,7 +26,7 @@ import im.vector.app.features.settings.troubleshoot.TroubleshootTest
import javax.inject.Inject
class TestBatteryOptimization @Inject constructor(
private val context: AppCompatActivity,
private val context: FragmentActivity,
private val stringProvider: StringProvider
) : TroubleshootTest(R.string.settings_troubleshoot_test_battery_title) {

View File

@ -24,7 +24,7 @@ import android.content.Intent
import android.os.Build
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import im.vector.app.core.di.HasVectorInjector
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.core.services.VectorSyncService
import org.matrix.android.sdk.internal.session.sync.job.SyncService
import timber.log.Timber
@ -33,9 +33,8 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Timber.d("## Sync: AlarmSyncBroadcastReceiver received intent")
val vectorPreferences = (context.applicationContext as? HasVectorInjector)
?.injector()
?.takeIf { it.activeSessionHolder().getSafeActiveSession() != null }
val vectorPreferences = context.singletonEntryPoint()
.takeIf { it.activeSessionHolder().getSafeActiveSession() != null }
?.vectorPreferences()
?: return Unit.also { Timber.v("No active session, so don't launch sync service.") }

View File

@ -20,8 +20,7 @@ package im.vector.app.fdroid.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import im.vector.app.core.di.HasVectorInjector
import im.vector.app.core.extensions.vectorComponent
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.fdroid.BackgroundSyncStarter
import timber.log.Timber
@ -29,13 +28,11 @@ class OnApplicationUpgradeOrRebootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Timber.v("## onReceive() ${intent.action}")
val appContext = context.applicationContext
if (appContext is HasVectorInjector) {
val singletonEntryPoint = context.singletonEntryPoint()
BackgroundSyncStarter.start(
context,
appContext.vectorComponent().vectorPreferences(),
appContext.injector().activeSessionHolder()
singletonEntryPoint.vectorPreferences(),
singletonEntryPoint.activeSessionHolder()
)
}
}
}

View File

@ -17,7 +17,7 @@ package im.vector.app.gplay.features.settings.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import com.google.firebase.messaging.FirebaseMessaging
import im.vector.app.R
import im.vector.app.core.resources.StringProvider
@ -30,7 +30,7 @@ import javax.inject.Inject
/*
* Test that app can successfully retrieve a token via firebase
*/
class TestFirebaseToken @Inject constructor(private val context: AppCompatActivity,
class TestFirebaseToken @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider) : TroubleshootTest(R.string.settings_troubleshoot_test_fcm_title) {
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {

View File

@ -17,7 +17,7 @@ package im.vector.app.gplay.features.settings.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import im.vector.app.R
@ -29,7 +29,7 @@ import javax.inject.Inject
/*
* Check that the play services APK is available an up-to-date. If needed provide quick fix to install it.
*/
class TestPlayServices @Inject constructor(private val context: AppCompatActivity,
class TestPlayServices @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider) :
TroubleshootTest(R.string.settings_troubleshoot_test_play_services_title) {

View File

@ -17,7 +17,7 @@ package im.vector.app.gplay.features.settings.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.error.ErrorFormatter
@ -36,7 +36,7 @@ import javax.inject.Inject
/**
* Test Push by asking the Push Gateway to send a Push back
*/
class TestPushFromPushGateway @Inject constructor(private val context: AppCompatActivity,
class TestPushFromPushGateway @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider,
private val errorFormatter: ErrorFormatter,
private val pushersManager: PushersManager,

View File

@ -17,7 +17,7 @@ package im.vector.app.gplay.features.settings.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Observer
import androidx.work.WorkInfo
import androidx.work.WorkManager
@ -33,7 +33,7 @@ import javax.inject.Inject
/**
* Force registration of the token to HomeServer
*/
class TestTokenRegistration @Inject constructor(private val context: AppCompatActivity,
class TestTokenRegistration @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider,
private val pushersManager: PushersManager,
private val activeSessionHolder: ActiveSessionHolder) :

View File

@ -27,10 +27,10 @@ import androidx.lifecycle.ProcessLifecycleOwner
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.BuildConfig
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.extensions.vectorComponent
import im.vector.app.core.network.WifiDetector
import im.vector.app.core.pushers.PushersManager
import im.vector.app.features.badge.BadgeProxy
@ -52,21 +52,23 @@ import org.matrix.android.sdk.api.pushrules.Action
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.Event
import timber.log.Timber
import javax.inject.Inject
private val loggerTag = LoggerTag("Push", LoggerTag.SYNC)
/**
* Class extending FirebaseMessagingService.
*/
@AndroidEntryPoint
class VectorFirebaseMessagingService : FirebaseMessagingService() {
private lateinit var notificationDrawerManager: NotificationDrawerManager
private lateinit var notifiableEventResolver: NotifiableEventResolver
private lateinit var pusherManager: PushersManager
private lateinit var activeSessionHolder: ActiveSessionHolder
private lateinit var vectorPreferences: VectorPreferences
private lateinit var vectorDataStore: VectorDataStore
private lateinit var wifiDetector: WifiDetector
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
@Inject lateinit var notifiableEventResolver: NotifiableEventResolver
@Inject lateinit var pusherManager: PushersManager
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
@Inject lateinit var vectorPreferences: VectorPreferences
@Inject lateinit var vectorDataStore: VectorDataStore
@Inject lateinit var wifiDetector: WifiDetector
private val coroutineScope = CoroutineScope(SupervisorJob())
@ -75,19 +77,6 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
Handler(Looper.getMainLooper())
}
override fun onCreate() {
super.onCreate()
with(vectorComponent()) {
notificationDrawerManager = notificationDrawerManager()
notifiableEventResolver = notifiableEventResolver()
pusherManager = pusherManager()
activeSessionHolder = activeSessionHolder()
vectorPreferences = vectorPreferences()
vectorDataStore = vectorDataStore()
wifiDetector = wifiDetector()
}
}
/**
* Called when message is received.
*

View File

@ -39,10 +39,8 @@ import com.facebook.stetho.Stetho
import com.gabrielittner.threetenbp.LazyThreeTen
import com.vanniktech.emoji.EmojiManager
import com.vanniktech.emoji.google.GoogleEmojiProvider
import dagger.hilt.android.HiltAndroidApp
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.DaggerVectorComponent
import im.vector.app.core.di.HasVectorInjector
import im.vector.app.core.di.VectorComponent
import im.vector.app.core.extensions.configureAndStart
import im.vector.app.core.extensions.startSyncing
import im.vector.app.core.rx.RxConfig
@ -55,6 +53,7 @@ import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.pin.PinLocker
import im.vector.app.features.popup.PopupAlertManager
import im.vector.app.features.rageshake.VectorFileLogger
import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler
import im.vector.app.features.room.VectorRoomDisplayNameFallbackProvider
import im.vector.app.features.settings.VectorLocale
@ -75,9 +74,9 @@ import java.util.concurrent.Executors
import javax.inject.Inject
import androidx.work.Configuration as WorkConfiguration
@HiltAndroidApp
class VectorApplication :
Application(),
HasVectorInjector,
MatrixConfiguration.Provider,
WorkConfiguration.Provider {
@ -99,8 +98,7 @@ class VectorApplication :
@Inject lateinit var pinLocker: PinLocker
@Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var invitesAcceptor: InvitesAcceptor
lateinit var vectorComponent: VectorComponent
@Inject lateinit var vectorFileLogger: VectorFileLogger
// font thread handler
private var fontThreadHandler: Handler? = null
@ -118,8 +116,6 @@ class VectorApplication :
enableStrictModeIfNeeded()
super.onCreate()
appContext = this
vectorComponent = DaggerVectorComponent.factory().create(this)
vectorComponent.inject(this)
invitesAcceptor.initialize()
vectorUncaughtExceptionHandler.activate(this)
rxConfig.setupRxPlugin()
@ -132,7 +128,7 @@ class VectorApplication :
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
Timber.plant(vectorComponent.vectorFileLogger())
Timber.plant(vectorFileLogger)
if (BuildConfig.DEBUG) {
Stetho.initializeWithDefaults(this)
@ -236,10 +232,6 @@ class VectorApplication :
.build()
}
override fun injector(): VectorComponent {
return vectorComponent
}
private fun logInfo() {
val appVersion = versionProvider.getVersion(longFormat = true, useBuildNumber = true)
val sdkVersion = Matrix.getSdkVersion()

View File

@ -1,11 +1,11 @@
/*
* Copyright 2019 New Vector Ltd
* 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
* 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,
@ -16,7 +16,15 @@
package im.vector.app.core.di
interface HasScreenInjector {
import androidx.fragment.app.FragmentFactory
import androidx.lifecycle.ViewModelProvider
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
fun injector(): ScreenComponent
@InstallIn(ActivityComponent::class)
@EntryPoint
interface ActivityEntryPoint {
fun fragmentFactory(): FragmentFactory
fun viewModelFactory(): ViewModelProvider.Factory
}

View File

@ -21,6 +21,8 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.multibindings.IntoMap
import im.vector.app.features.attachments.preview.AttachmentsPreviewFragment
import im.vector.app.features.contactsbook.ContactsBookFragment
@ -157,6 +159,7 @@ import im.vector.app.features.usercode.ShowUserCodeFragment
import im.vector.app.features.userdirectory.UserListFragment
import im.vector.app.features.widgets.WidgetFragment
@InstallIn(ActivityComponent::class)
@Module
interface FragmentModule {
/**

View File

@ -0,0 +1,92 @@
/*
* 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
}
override fun initialState(viewModelContext: ViewModelContext): S? {
return super.initialState(viewModelContext)
}
}
/**
* 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<*, *>>
}

View File

@ -0,0 +1,36 @@
/*
* 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 android.os.Handler
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import im.vector.app.features.home.room.detail.timeline.TimelineEventControllerHandler
import im.vector.app.features.home.room.detail.timeline.helper.TimelineAsyncHelper
@Module
@InstallIn(ActivityComponent::class)
object HomeModule {
@Provides
@JvmStatic
@TimelineEventControllerHandler
fun providesTimelineBackgroundHandler(): Handler {
return TimelineAsyncHelper.getBackgroundHandler()
}
}

View File

@ -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(initialState: S): VM
}

View File

@ -0,0 +1,543 @@
/*
* 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.core.di
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.multibindings.IntoMap
import im.vector.app.features.auth.ReAuthViewModel
import im.vector.app.features.call.VectorCallViewModel
import im.vector.app.features.call.conference.JitsiCallViewModel
import im.vector.app.features.call.transfer.CallTransferViewModel
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
import im.vector.app.features.home.UnreadMessagesSharedViewModel
import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsViewModel
import im.vector.app.features.home.room.detail.composer.TextComposerViewModel
import im.vector.app.features.home.room.detail.search.SearchViewModel
import im.vector.app.features.home.room.detail.timeline.action.MessageActionsViewModel
import im.vector.app.features.home.room.detail.timeline.edithistory.ViewEditHistoryViewModel
import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsViewModel
import im.vector.app.features.home.room.detail.upgrade.MigrateRoomViewModel
import im.vector.app.features.home.room.list.RoomListViewModel
import im.vector.app.features.homeserver.HomeServerCapabilitiesViewModel
import im.vector.app.features.invite.InviteUsersToRoomViewModel
import im.vector.app.features.login.LoginViewModel
import im.vector.app.features.login2.LoginViewModel2
import im.vector.app.features.login2.created.AccountCreatedViewModel
import im.vector.app.features.matrixto.MatrixToBottomSheetViewModel
import im.vector.app.features.rageshake.BugReportViewModel
import im.vector.app.features.reactions.EmojiSearchResultViewModel
import im.vector.app.features.room.RequireActiveMembershipViewModel
import im.vector.app.features.roomdirectory.RoomDirectoryViewModel
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
import im.vector.app.features.roomprofile.banned.RoomBannedMemberListViewModel
import im.vector.app.features.roomprofile.members.RoomMemberListViewModel
import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewModel
import im.vector.app.features.roomprofile.permissions.RoomPermissionsViewModel
import im.vector.app.features.roomprofile.settings.RoomSettingsViewModel
import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedViewModel
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
import im.vector.app.features.settings.devtools.KeyRequestListViewModel
import im.vector.app.features.settings.homeserver.HomeserverSettingsViewModel
import im.vector.app.features.settings.ignored.IgnoredUsersViewModel
import im.vector.app.features.settings.locale.LocalePickerViewModel
import im.vector.app.features.settings.push.PushGatewaysViewModel
import im.vector.app.features.settings.threepids.ThreePidsSettingsViewModel
import im.vector.app.features.share.IncomingShareViewModel
import im.vector.app.features.signout.soft.SoftLogoutViewModel
import im.vector.app.features.spaces.SpaceListViewModel
import im.vector.app.features.spaces.SpaceMenuViewModel
import im.vector.app.features.spaces.create.CreateSpaceViewModel
import im.vector.app.features.spaces.explore.SpaceDirectoryViewModel
import im.vector.app.features.spaces.invite.SpaceInviteBottomSheetViewModel
import im.vector.app.features.spaces.leave.SpaceLeaveAdvancedViewModel
import im.vector.app.features.spaces.manage.SpaceAddRoomsViewModel
import im.vector.app.features.spaces.manage.SpaceManageRoomsViewModel
import im.vector.app.features.spaces.manage.SpaceManageSharedViewModel
import im.vector.app.features.spaces.people.SpacePeopleViewModel
import im.vector.app.features.spaces.preview.SpacePreviewViewModel
import im.vector.app.features.spaces.share.ShareSpaceViewModel
import im.vector.app.features.terms.ReviewTermsViewModel
import im.vector.app.features.usercode.UserCodeSharedViewModel
import im.vector.app.features.userdirectory.UserListViewModel
import im.vector.app.features.widgets.WidgetViewModel
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewModel
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
import im.vector.app.features.workers.signout.SignoutCheckViewModel
@InstallIn(MavericksViewModelComponent::class)
@Module
interface MavericksViewModelModule {
@Binds
@IntoMap
@MavericksViewModelKey(RoomListViewModel::class)
fun roomListViewModelFactory(factory: RoomListViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpaceManageRoomsViewModel::class)
fun spaceManageRoomsViewModelFactory(factory: SpaceManageRoomsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpaceManageSharedViewModel::class)
fun spaceManageSharedViewModelFactory(factory: SpaceManageSharedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpaceListViewModel::class)
fun spaceListViewModelFactory(factory: SpaceListViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(ReAuthViewModel::class)
fun reAuthViewModelFactory(factory: ReAuthViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(VectorCallViewModel::class)
fun vectorCallViewModelFactory(factory: VectorCallViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(JitsiCallViewModel::class)
fun jitsiCallViewModelFactory(factory: JitsiCallViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomDirectoryViewModel::class)
fun roomDirectoryViewModelFactory(factory: RoomDirectoryViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(ViewReactionsViewModel::class)
fun viewReactionsViewModelFactory(factory: ViewReactionsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomWidgetPermissionViewModel::class)
fun roomWidgetPermissionViewModelFactory(factory: RoomWidgetPermissionViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(WidgetViewModel::class)
fun widgetViewModelFactory(factory: WidgetViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(ServerBackupStatusViewModel::class)
fun serverBackupStatusViewModelFactory(factory: ServerBackupStatusViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SignoutCheckViewModel::class)
fun signoutCheckViewModelFactory(factory: SignoutCheckViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomDirectoryPickerViewModel::class)
fun roomDirectoryPickerViewModelFactory(factory: RoomDirectoryPickerViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomDevToolViewModel::class)
fun roomDevToolViewModelFactory(factory: RoomDevToolViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(MigrateRoomViewModel::class)
fun migrateRoomViewModelFactory(factory: MigrateRoomViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(IgnoredUsersViewModel::class)
fun ignoredUsersViewModelFactory(factory: IgnoredUsersViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(CallTransferViewModel::class)
fun callTransferViewModelFactory(factory: CallTransferViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(ContactsBookViewModel::class)
fun contactsBookViewModelFactory(factory: ContactsBookViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(CreateDirectRoomViewModel::class)
fun createDirectRoomViewModelFactory(factory: CreateDirectRoomViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomNotificationSettingsViewModel::class)
fun roomNotificationSettingsViewModelFactory(factory: RoomNotificationSettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(KeysBackupSettingsViewModel::class)
fun keysBackupSettingsViewModelFactory(factory: KeysBackupSettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SharedSecureStorageViewModel::class)
fun sharedSecureStorageViewModelFactory(factory: SharedSecureStorageViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(PromoteRestrictedViewModel::class)
fun promoteRestrictedViewModelFactory(factory: PromoteRestrictedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(UserListViewModel::class)
fun userListViewModelFactory(factory: UserListViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(UserCodeSharedViewModel::class)
fun userCodeSharedViewModelFactory(factory: UserCodeSharedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(ReviewTermsViewModel::class)
fun reviewTermsViewModelFactory(factory: ReviewTermsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(ShareSpaceViewModel::class)
fun shareSpaceViewModelFactory(factory: ShareSpaceViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpacePreviewViewModel::class)
fun spacePreviewViewModelFactory(factory: SpacePreviewViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpacePeopleViewModel::class)
fun spacePeopleViewModelFactory(factory: SpacePeopleViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpaceAddRoomsViewModel::class)
fun spaceAddRoomsViewModelFactory(factory: SpaceAddRoomsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpaceLeaveAdvancedViewModel::class)
fun spaceLeaveAdvancedViewModelFactory(factory: SpaceLeaveAdvancedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpaceInviteBottomSheetViewModel::class)
fun spaceInviteBottomSheetViewModelFactory(factory: SpaceInviteBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpaceDirectoryViewModel::class)
fun spaceDirectoryViewModelFactory(factory: SpaceDirectoryViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(CreateSpaceViewModel::class)
fun createSpaceViewModelFactory(factory: CreateSpaceViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SpaceMenuViewModel::class)
fun spaceMenuViewModelFactory(factory: SpaceMenuViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SoftLogoutViewModel::class)
fun softLogoutViewModelFactory(factory: SoftLogoutViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(IncomingShareViewModel::class)
fun incomingShareViewModelFactory(factory: IncomingShareViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(ThreePidsSettingsViewModel::class)
fun threePidsSettingsViewModelFactory(factory: ThreePidsSettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(PushGatewaysViewModel::class)
fun pushGatewaysViewModelFactory(factory: PushGatewaysViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(HomeserverSettingsViewModel::class)
fun homeserverSettingsViewModelFactory(factory: HomeserverSettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(LocalePickerViewModel::class)
fun localePickerViewModelFactory(factory: LocalePickerViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(GossipingEventsPaperTrailViewModel::class)
fun gossipingEventsPaperTrailViewModelFactory(factory: GossipingEventsPaperTrailViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(AccountDataViewModel::class)
fun accountDataViewModelFactory(factory: AccountDataViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(DevicesViewModel::class)
fun devicesViewModelFactory(factory: DevicesViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(KeyRequestListViewModel::class)
fun keyRequestListViewModelFactory(factory: KeyRequestListViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(CrossSigningSettingsViewModel::class)
fun crossSigningSettingsViewModelFactory(factory: CrossSigningSettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(DeactivateAccountViewModel::class)
fun deactivateAccountViewModelFactory(factory: DeactivateAccountViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomUploadsViewModel::class)
fun roomUploadsViewModelFactory(factory: RoomUploadsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomJoinRuleChooseRestrictedViewModel::class)
fun roomJoinRuleChooseRestrictedViewModelFactory(factory: RoomJoinRuleChooseRestrictedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomSettingsViewModel::class)
fun roomSettingsViewModelFactory(factory: RoomSettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomPermissionsViewModel::class)
fun roomPermissionsViewModelFactory(factory: RoomPermissionsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomMemberListViewModel::class)
fun roomMemberListViewModelFactory(factory: RoomMemberListViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomBannedMemberListViewModel::class)
fun roomBannedMemberListViewModelFactory(factory: RoomBannedMemberListViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomAliasViewModel::class)
fun roomAliasViewModelFactory(factory: RoomAliasViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomAliasBottomSheetViewModel::class)
fun roomAliasBottomSheetViewModelFactory(factory: RoomAliasBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomProfileViewModel::class)
fun roomProfileViewModelFactory(factory: RoomProfileViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomMemberProfileViewModel::class)
fun roomMemberProfileViewModelFactory(factory: RoomMemberProfileViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RoomPreviewViewModel::class)
fun roomPreviewViewModelFactory(factory: RoomPreviewViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(CreateRoomViewModel::class)
fun createRoomViewModelFactory(factory: CreateRoomViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(RequireActiveMembershipViewModel::class)
fun requireActiveMembershipViewModelFactory(factory: RequireActiveMembershipViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(EmojiSearchResultViewModel::class)
fun emojiSearchResultViewModelFactory(factory: EmojiSearchResultViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(BugReportViewModel::class)
fun bugReportViewModelFactory(factory: BugReportViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(MatrixToBottomSheetViewModel::class)
fun matrixToBottomSheetViewModelFactory(factory: MatrixToBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(AccountCreatedViewModel::class)
fun accountCreatedViewModelFactory(factory: AccountCreatedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(LoginViewModel2::class)
fun loginViewModel2Factory(factory: LoginViewModel2.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(LoginViewModel::class)
fun loginViewModelFactory(factory: LoginViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(HomeServerCapabilitiesViewModel::class)
fun homeServerCapabilitiesViewModelFactory(factory: HomeServerCapabilitiesViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(InviteUsersToRoomViewModel::class)
fun inviteUsersToRoomViewModelFactory(factory: InviteUsersToRoomViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(ViewEditHistoryViewModel::class)
fun viewEditHistoryViewModelFactory(factory: ViewEditHistoryViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(MessageActionsViewModel::class)
fun messageActionsViewModelFactory(factory: MessageActionsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(VerificationChooseMethodViewModel::class)
fun verificationChooseMethodViewModelFactory(factory: VerificationChooseMethodViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(VerificationEmojiCodeViewModel::class)
fun verificationEmojiCodeViewModelFactory(factory: VerificationEmojiCodeViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SearchViewModel::class)
fun searchViewModelFactory(factory: SearchViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(UnreadMessagesSharedViewModel::class)
fun unreadMessagesSharedViewModelFactory(factory: UnreadMessagesSharedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(UnknownDeviceDetectorSharedViewModel::class)
fun unknownDeviceDetectorSharedViewModelFactory(factory: UnknownDeviceDetectorSharedViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(DiscoverySettingsViewModel::class)
fun discoverySettingsViewModelFactory(factory: DiscoverySettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(TextComposerViewModel::class)
fun textComposerViewModelFactory(factory: TextComposerViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(SetIdentityServerViewModel::class)
fun setIdentityServerViewModelFactory(factory: SetIdentityServerViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@MavericksViewModelKey(BreadcrumbsViewModel::class)
fun breadcrumbsViewModelFactory(factory: BreadcrumbsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
@Binds
@IntoMap
@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<*, *>
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019 New Vector Ltd
* 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.
@ -16,7 +16,10 @@
package im.vector.app.core.di
interface HasVectorInjector {
import javax.inject.Scope
fun injector(): VectorComponent
}
/**
* Scope annotation for bindings that should exist for the life of an MavericksViewModel.
*/
@Scope
annotation class MavericksViewModelScoped

View File

@ -1,225 +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.core.di
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentFactory
import androidx.lifecycle.ViewModelProvider
import dagger.BindsInstance
import dagger.Component
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.preference.UserAvatarPreference
import im.vector.app.features.MainActivity
import im.vector.app.features.auth.ReAuthActivity
import im.vector.app.features.call.CallControlsBottomSheet
import im.vector.app.features.call.VectorCallActivity
import im.vector.app.features.call.conference.VectorJitsiActivity
import im.vector.app.features.call.transfer.CallTransferActivity
import im.vector.app.features.createdirect.CreateDirectRoomActivity
import im.vector.app.features.crypto.keysbackup.settings.KeysBackupManageActivity
import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity
import im.vector.app.features.crypto.quads.SharedSecureStorageActivity
import im.vector.app.features.crypto.recover.BootstrapBottomSheet
import im.vector.app.features.crypto.verification.VerificationBottomSheet
import im.vector.app.features.debug.DebugMenuActivity
import im.vector.app.features.devtools.RoomDevToolActivity
import im.vector.app.features.home.HomeActivity
import im.vector.app.features.home.HomeModule
import im.vector.app.features.home.room.detail.JoinReplacementRoomBottomSheet
import im.vector.app.features.home.room.detail.RoomDetailActivity
import im.vector.app.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet
import im.vector.app.features.home.room.detail.search.SearchActivity
import im.vector.app.features.home.room.detail.timeline.action.MessageActionsBottomSheet
import im.vector.app.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet
import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet
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.invite.AutoAcceptInvites
import im.vector.app.features.invite.InviteUsersToRoomActivity
import im.vector.app.features.invite.VectorInviteView
import im.vector.app.features.link.LinkHandlerActivity
import im.vector.app.features.login.LoginActivity
import im.vector.app.features.login2.LoginActivity2
import im.vector.app.features.matrixto.MatrixToBottomSheet
import im.vector.app.features.media.BigImageViewerActivity
import im.vector.app.features.media.VectorAttachmentViewerActivity
import im.vector.app.features.navigation.Navigator
import im.vector.app.features.pin.PinLocker
import im.vector.app.features.qrcode.QrCodeScannerActivity
import im.vector.app.features.rageshake.BugReportActivity
import im.vector.app.features.rageshake.BugReporter
import im.vector.app.features.rageshake.RageShake
import im.vector.app.features.reactions.EmojiReactionPickerActivity
import im.vector.app.features.reactions.widget.ReactionButton
import im.vector.app.features.roomdirectory.RoomDirectoryActivity
import im.vector.app.features.roomdirectory.createroom.CreateRoomActivity
import im.vector.app.features.roommemberprofile.RoomMemberProfileActivity
import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet
import im.vector.app.features.roomprofile.RoomProfileActivity
import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheet
import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistoryVisibilityBottomSheet
import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleActivity
import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleBottomSheet
import im.vector.app.features.settings.VectorSettingsActivity
import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheet
import im.vector.app.features.share.IncomingShareActivity
import im.vector.app.features.signout.soft.SoftLogoutActivity
import im.vector.app.features.spaces.InviteRoomSpaceChooserBottomSheet
import im.vector.app.features.spaces.LeaveSpaceBottomSheet
import im.vector.app.features.spaces.SpaceCreationActivity
import im.vector.app.features.spaces.SpaceExploreActivity
import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet
import im.vector.app.features.spaces.invite.SpaceInviteBottomSheet
import im.vector.app.features.spaces.leave.SpaceLeaveAdvancedActivity
import im.vector.app.features.spaces.manage.SpaceManageActivity
import im.vector.app.features.spaces.share.ShareSpaceBottomSheet
import im.vector.app.features.terms.ReviewTermsActivity
import im.vector.app.features.ui.UiStateRepository
import im.vector.app.features.usercode.UserCodeActivity
import im.vector.app.features.widgets.WidgetActivity
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet
import im.vector.app.features.workers.signout.SignOutBottomSheetDialogFragment
import kotlinx.coroutines.CoroutineScope
@Component(
dependencies = [
VectorComponent::class
],
modules = [
ViewModelModule::class,
FragmentModule::class,
HomeModule::class,
RoomListModule::class,
ScreenModule::class
]
)
@ScreenScope
interface ScreenComponent {
/* ==========================================================================================
* Shortcut to VectorComponent elements
* ========================================================================================== */
fun activeSessionHolder(): ActiveSessionHolder
fun fragmentFactory(): FragmentFactory
fun viewModelFactory(): ViewModelProvider.Factory
fun bugReporter(): BugReporter
fun rageShake(): RageShake
fun navigator(): Navigator
fun pinLocker(): PinLocker
fun errorFormatter(): ErrorFormatter
fun uiStateRepository(): UiStateRepository
fun unrecognizedCertificateDialog(): UnrecognizedCertificateDialog
fun autoAcceptInvites(): AutoAcceptInvites
fun appCoroutineScope(): CoroutineScope
/* ==========================================================================================
* Activities
* ========================================================================================== */
fun inject(activity: HomeActivity)
fun inject(activity: RoomDetailActivity)
fun inject(activity: RoomProfileActivity)
fun inject(activity: RoomMemberProfileActivity)
fun inject(activity: VectorSettingsActivity)
fun inject(activity: KeysBackupManageActivity)
fun inject(activity: EmojiReactionPickerActivity)
fun inject(activity: LoginActivity)
fun inject(activity: LoginActivity2)
fun inject(activity: LinkHandlerActivity)
fun inject(activity: MainActivity)
fun inject(activity: RoomDirectoryActivity)
fun inject(activity: KeysBackupSetupActivity)
fun inject(activity: BugReportActivity)
fun inject(activity: FilteredRoomsActivity)
fun inject(activity: CreateRoomActivity)
fun inject(activity: CreateDirectRoomActivity)
fun inject(activity: IncomingShareActivity)
fun inject(activity: SoftLogoutActivity)
fun inject(activity: QrCodeScannerActivity)
fun inject(activity: DebugMenuActivity)
fun inject(activity: SharedSecureStorageActivity)
fun inject(activity: BigImageViewerActivity)
fun inject(activity: InviteUsersToRoomActivity)
fun inject(activity: ReviewTermsActivity)
fun inject(activity: WidgetActivity)
fun inject(activity: VectorCallActivity)
fun inject(activity: VectorAttachmentViewerActivity)
fun inject(activity: VectorJitsiActivity)
fun inject(activity: SearchActivity)
fun inject(activity: UserCodeActivity)
fun inject(activity: CallTransferActivity)
fun inject(activity: ReAuthActivity)
fun inject(activity: RoomDevToolActivity)
fun inject(activity: SpaceCreationActivity)
fun inject(activity: SpaceExploreActivity)
fun inject(activity: SpaceManageActivity)
fun inject(activity: RoomJoinRuleActivity)
fun inject(activity: SpaceLeaveAdvancedActivity)
/* ==========================================================================================
* BottomSheets
* ========================================================================================== */
fun inject(bottomSheet: MessageActionsBottomSheet)
fun inject(bottomSheet: ViewReactionsBottomSheet)
fun inject(bottomSheet: ViewEditHistoryBottomSheet)
fun inject(bottomSheet: DisplayReadReceiptsBottomSheet)
fun inject(bottomSheet: RoomListQuickActionsBottomSheet)
fun inject(bottomSheet: RoomAliasBottomSheet)
fun inject(bottomSheet: RoomHistoryVisibilityBottomSheet)
fun inject(bottomSheet: RoomJoinRuleBottomSheet)
fun inject(bottomSheet: VerificationBottomSheet)
fun inject(bottomSheet: DeviceVerificationInfoBottomSheet)
fun inject(bottomSheet: DeviceListBottomSheet)
fun inject(bottomSheet: BootstrapBottomSheet)
fun inject(bottomSheet: RoomWidgetPermissionBottomSheet)
fun inject(bottomSheet: RoomWidgetsBottomSheet)
fun inject(bottomSheet: CallControlsBottomSheet)
fun inject(bottomSheet: SignOutBottomSheetDialogFragment)
fun inject(bottomSheet: MatrixToBottomSheet)
fun inject(bottomSheet: ShareSpaceBottomSheet)
fun inject(bottomSheet: SpaceSettingsMenuBottomSheet)
fun inject(bottomSheet: InviteRoomSpaceChooserBottomSheet)
fun inject(bottomSheet: SpaceInviteBottomSheet)
fun inject(bottomSheet: JoinReplacementRoomBottomSheet)
fun inject(bottomSheet: MigrateRoomBottomSheet)
fun inject(bottomSheet: LeaveSpaceBottomSheet)
/* ==========================================================================================
* Others
* ========================================================================================== */
fun inject(view: VectorInviteView)
fun inject(preference: UserAvatarPreference)
fun inject(button: ReactionButton)
/* ==========================================================================================
* Factory
* ========================================================================================== */
@Component.Factory
interface Factory {
fun create(vectorComponent: VectorComponent,
@BindsInstance context: AppCompatActivity
): ScreenComponent
}
}

View File

@ -1,11 +1,11 @@
/*
* Copyright 2019 New Vector Ltd
* 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
* 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,
@ -20,9 +20,13 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityScoped
import im.vector.app.core.glide.GlideApp
@Module
@InstallIn(ActivityComponent::class)
object ScreenModule {
@Provides
@ -31,6 +35,6 @@ object ScreenModule {
@Provides
@JvmStatic
@ScreenScope
@ActivityScoped
fun providesSharedViewPool() = RecyclerView.RecycledViewPool()
}

View File

@ -1,24 +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.core.di
import javax.inject.Scope
@Scope
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class ScreenScope

View File

@ -0,0 +1,61 @@
/*
* 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 dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.navigation.Navigator
import im.vector.app.features.pin.PinLocker
import im.vector.app.features.rageshake.BugReporter
import im.vector.app.features.session.SessionListener
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.ui.UiStateRepository
import kotlinx.coroutines.CoroutineScope
@InstallIn(SingletonComponent::class)
@EntryPoint
interface SingletonEntryPoint {
fun sessionListener(): SessionListener
fun avatarRenderer(): AvatarRenderer
fun activeSessionHolder(): ActiveSessionHolder
fun unrecognizedCertificateDialog(): UnrecognizedCertificateDialog
fun navigator(): Navigator
fun errorFormatter(): ErrorFormatter
fun bugReporter(): BugReporter
fun vectorPreferences(): VectorPreferences
fun uiStateRepository(): UiStateRepository
fun pinLocker(): PinLocker
fun webRtcCallManager(): WebRtcCallManager
fun appCoroutineScope(): CoroutineScope
}

View File

@ -16,6 +16,7 @@
package im.vector.app.core.di
import android.app.Application
import android.content.Context
import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences
@ -23,6 +24,8 @@ import android.content.res.Resources
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import im.vector.app.core.dispatchers.CoroutineDispatchers
import im.vector.app.core.error.DefaultErrorFormatter
import im.vector.app.core.error.ErrorFormatter
@ -45,74 +48,9 @@ import org.matrix.android.sdk.api.raw.RawService
import org.matrix.android.sdk.api.session.Session
import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
@Module
abstract class VectorModule {
@Module
companion object {
@Provides
@JvmStatic
fun providesResources(context: Context): Resources {
return context.resources
}
@Provides
@JvmStatic
fun providesSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences("im.vector.riot", MODE_PRIVATE)
}
@Provides
@JvmStatic
fun providesMatrix(context: Context): Matrix {
return Matrix.getInstance(context)
}
@Provides
@JvmStatic
fun providesCurrentSession(activeSessionHolder: ActiveSessionHolder): Session {
// TODO: handle session injection better
return activeSessionHolder.getActiveSession()
}
@Provides
@JvmStatic
fun providesLegacySessionImporter(matrix: Matrix): LegacySessionImporter {
return matrix.legacySessionImporter()
}
@Provides
@JvmStatic
fun providesAuthenticationService(matrix: Matrix): AuthenticationService {
return matrix.authenticationService()
}
@Provides
@JvmStatic
fun providesRawService(matrix: Matrix): RawService {
return matrix.rawService()
}
@Provides
@JvmStatic
fun providesHomeServerHistoryService(matrix: Matrix): HomeServerHistoryService {
return matrix.homeServerHistoryService()
}
@Provides
@JvmStatic
@Singleton
fun providesApplicationCoroutineScope(): CoroutineScope {
return CoroutineScope(SupervisorJob() + Dispatchers.Main)
}
@Provides
@JvmStatic
fun providesCoroutineDispatchers(): CoroutineDispatchers {
return CoroutineDispatchers(io = Dispatchers.IO)
}
}
abstract class VectorBindModule {
@Binds
abstract fun bindNavigator(navigator: DefaultNavigator): Navigator
@ -129,3 +67,76 @@ abstract class VectorModule {
@Binds
abstract fun bindAutoAcceptInvites(autoAcceptInvites: CompileTimeAutoAcceptInvites): AutoAcceptInvites
}
@InstallIn(SingletonComponent::class)
@Module
object VectorStaticModule {
@Provides
@JvmStatic
fun providesContext(application: Application): Context {
return application.applicationContext
}
@Provides
@JvmStatic
fun providesResources(context: Context): Resources {
return context.resources
}
@Provides
@JvmStatic
fun providesSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences("im.vector.riot", MODE_PRIVATE)
}
@Provides
@JvmStatic
fun providesMatrix(context: Context): Matrix {
return Matrix.getInstance(context)
}
@Provides
@JvmStatic
fun providesCurrentSession(activeSessionHolder: ActiveSessionHolder): Session {
// TODO: handle session injection better
return activeSessionHolder.getActiveSession()
}
@Provides
@JvmStatic
fun providesLegacySessionImporter(matrix: Matrix): LegacySessionImporter {
return matrix.legacySessionImporter()
}
@Provides
@JvmStatic
fun providesAuthenticationService(matrix: Matrix): AuthenticationService {
return matrix.authenticationService()
}
@Provides
@JvmStatic
fun providesRawService(matrix: Matrix): RawService {
return matrix.rawService()
}
@Provides
@JvmStatic
fun providesHomeServerHistoryService(matrix: Matrix): HomeServerHistoryService {
return matrix.homeServerHistoryService()
}
@Provides
@JvmStatic
@Singleton
fun providesApplicationCoroutineScope(): CoroutineScope {
return CoroutineScope(SupervisorJob() + Dispatchers.Main)
}
@Provides
@JvmStatic
fun providesCoroutineDispatchers(): CoroutineDispatchers {
return CoroutineDispatchers(io = Dispatchers.IO)
}
}

View File

@ -1,183 +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.core.di
import android.content.Context
import android.content.res.Resources
import dagger.BindsInstance
import dagger.Component
import im.vector.app.ActiveSessionDataSource
import im.vector.app.AppStateHandler
import im.vector.app.EmojiCompatFontProvider
import im.vector.app.EmojiCompatWrapper
import im.vector.app.VectorApplication
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
import im.vector.app.core.dispatchers.CoroutineDispatchers
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.network.WifiDetector
import im.vector.app.core.pushers.PushersManager
import im.vector.app.core.utils.AssetReader
import im.vector.app.core.utils.DimensionConverter
import im.vector.app.features.call.conference.JitsiActiveConferenceHolder
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.configuration.VectorConfiguration
import im.vector.app.features.crypto.keysrequest.KeyRequestHandler
import im.vector.app.features.crypto.verification.IncomingVerificationRequestHandler
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.CurrentSpaceSuggestedRoomListDataSource
import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
import im.vector.app.features.html.EventHtmlRenderer
import im.vector.app.features.html.VectorHtmlCompressor
import im.vector.app.features.invite.AutoAcceptInvites
import im.vector.app.features.login.ReAuthHelper
import im.vector.app.features.navigation.Navigator
import im.vector.app.features.notifications.NotifiableEventResolver
import im.vector.app.features.notifications.NotificationBroadcastReceiver
import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.notifications.PushRuleTriggerListener
import im.vector.app.features.pin.PinCodeStore
import im.vector.app.features.pin.PinLocker
import im.vector.app.features.popup.PopupAlertManager
import im.vector.app.features.rageshake.BugReporter
import im.vector.app.features.rageshake.VectorFileLogger
import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler
import im.vector.app.features.reactions.data.EmojiDataSource
import im.vector.app.features.session.SessionListener
import im.vector.app.features.settings.VectorDataStore
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.ui.UiStateRepository
import kotlinx.coroutines.CoroutineScope
import org.matrix.android.sdk.api.Matrix
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
import org.matrix.android.sdk.api.raw.RawService
import org.matrix.android.sdk.api.session.Session
import javax.inject.Singleton
@Component(modules = [VectorModule::class])
@Singleton
interface VectorComponent {
fun inject(notificationBroadcastReceiver: NotificationBroadcastReceiver)
fun inject(vectorApplication: VectorApplication)
fun matrix(): Matrix
fun matrixItemColorProvider(): MatrixItemColorProvider
fun sessionListener(): SessionListener
fun currentSession(): Session
fun notificationUtils(): NotificationUtils
fun notificationDrawerManager(): NotificationDrawerManager
fun appContext(): Context
fun resources(): Resources
fun assetReader(): AssetReader
fun dimensionConverter(): DimensionConverter
fun vectorConfiguration(): VectorConfiguration
fun avatarRenderer(): AvatarRenderer
fun activeSessionHolder(): ActiveSessionHolder
fun unrecognizedCertificateDialog(): UnrecognizedCertificateDialog
fun emojiCompatFontProvider(): EmojiCompatFontProvider
fun emojiCompatWrapper(): EmojiCompatWrapper
fun eventHtmlRenderer(): EventHtmlRenderer
fun vectorHtmlCompressor(): VectorHtmlCompressor
fun navigator(): Navigator
fun errorFormatter(): ErrorFormatter
fun appStateHandler(): AppStateHandler
fun currentSpaceSuggestedRoomListDataSource(): CurrentSpaceSuggestedRoomListDataSource
fun roomDetailPendingActionStore(): RoomDetailPendingActionStore
fun activeSessionObservableStore(): ActiveSessionDataSource
fun incomingVerificationRequestHandler(): IncomingVerificationRequestHandler
fun incomingKeyRequestHandler(): KeyRequestHandler
fun authenticationService(): AuthenticationService
fun rawService(): RawService
fun homeServerHistoryService(): HomeServerHistoryService
fun bugReporter(): BugReporter
fun vectorUncaughtExceptionHandler(): VectorUncaughtExceptionHandler
fun pushRuleTriggerListener(): PushRuleTriggerListener
fun pusherManager(): PushersManager
fun notifiableEventResolver(): NotifiableEventResolver
fun vectorPreferences(): VectorPreferences
fun vectorDataStore(): VectorDataStore
fun wifiDetector(): WifiDetector
fun vectorFileLogger(): VectorFileLogger
fun uiStateRepository(): UiStateRepository
fun pinCodeStore(): PinCodeStore
fun emojiDataSource(): EmojiDataSource
fun alertManager(): PopupAlertManager
fun reAuthHelper(): ReAuthHelper
fun pinLocker(): PinLocker
fun autoAcceptInvites(): AutoAcceptInvites
fun webRtcCallManager(): WebRtcCallManager
fun appCoroutineScope(): CoroutineScope
fun coroutineDispatchers(): CoroutineDispatchers
fun jitsiActiveConferenceHolder(): JitsiActiveConferenceHolder
@Component.Factory
interface Factory {
fun create(@BindsInstance context: Context): VectorComponent
}
}

View File

@ -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<*>>)

View File

@ -20,6 +20,8 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.multibindings.IntoMap
import im.vector.app.core.platform.ConfigurationViewModel
import im.vector.app.features.call.SharedKnownCallsViewModel
@ -42,6 +44,7 @@ import im.vector.app.features.spaces.SpacePreviewSharedActionViewModel
import im.vector.app.features.spaces.people.SpacePeopleSharedActionViewModel
import im.vector.app.features.userdirectory.UserListSharedActionViewModel
@InstallIn(ActivityComponent::class)
@Module
interface ViewModelModule {

View File

@ -17,14 +17,9 @@
package im.vector.app.core.extensions
import android.content.Context
import im.vector.app.core.di.HasVectorInjector
import im.vector.app.core.di.VectorComponent
import dagger.hilt.EntryPoints
import im.vector.app.core.di.SingletonEntryPoint
fun Context.vectorComponent(): VectorComponent {
val appContext = applicationContext
if (appContext is HasVectorInjector) {
return appContext.injector()
} else {
throw IllegalStateException("Your application context doesn't implement HasVectorInjector")
}
fun Context.singletonEntryPoint(): SingletonEntryPoint {
return EntryPoints.get(applicationContext, SingletonEntryPoint::class.java)
}

View File

@ -34,7 +34,7 @@ fun Session.configureAndStart(context: Context, startSyncing: Boolean = true) {
startSyncing(context)
}
refreshPushers()
context.vectorComponent().webRtcCallManager().checkForProtocolsSupportIfNeeded()
context.singletonEntryPoint().webRtcCallManager().checkForProtocolsSupportIfNeeded()
}
fun Session.startSyncing(context: Context) {

View File

@ -26,7 +26,7 @@ import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.bumptech.glide.signature.ObjectKey
import im.vector.app.core.extensions.vectorComponent
import im.vector.app.core.extensions.singletonEntryPoint
import org.matrix.android.sdk.api.util.MatrixItem
data class AvatarPlaceholder(val matrixItem: MatrixItem)
@ -57,7 +57,7 @@ class AvatarPlaceholderModelLoader(private val context: Context) :
class AvatarPlaceholderDataFetcher(context: Context, private val data: AvatarPlaceholder) :
DataFetcher<Drawable> {
private val avatarRenderer = context.vectorComponent().avatarRenderer()
private val avatarRenderer = context.singletonEntryPoint().avatarRenderer()
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in Drawable>) {
val avatarPlaceholder = avatarRenderer.getPlaceholderDrawable(data.matrixItem)

View File

@ -25,7 +25,7 @@ import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.bumptech.glide.signature.ObjectKey
import im.vector.app.core.extensions.vectorComponent
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.core.files.LocalFilesHelper
import im.vector.app.features.media.ImageContentRenderer
import im.vector.app.features.session.coroutineScope
@ -67,7 +67,7 @@ class VectorGlideDataFetcher(context: Context,
DataFetcher<InputStream> {
private val localFilesHelper = LocalFilesHelper(context)
private val activeSessionHolder = context.vectorComponent().activeSessionHolder()
private val activeSessionHolder = context.singletonEntryPoint().activeSessionHolder()
private val client = activeSessionHolder.getSafeActiveSession()?.getOkHttpClient() ?: OkHttpClient()

View File

@ -15,13 +15,10 @@
*/
package im.vector.app.core.platform
import androidx.annotation.CallSuper
import androidx.core.view.isGone
import androidx.core.view.isVisible
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.databinding.ActivityBinding
import org.matrix.android.sdk.api.session.Session
/**
* Simple activity with a toolbar, a waiting overlay, and a fragment container and a session.
@ -32,13 +29,6 @@ abstract class SimpleFragmentActivity : VectorBaseActivity<ActivityBinding>() {
final override fun getCoordinatorLayout() = views.coordinatorLayout
lateinit var session: Session
@CallSuper
override fun injectWith(injector: ScreenComponent) {
session = injector.activeSessionHolder().getActiveSession()
}
override fun initUiAndData() {
configureToolbar(views.toolbar)
waitingView = views.waitingView.waitingView

View File

@ -45,14 +45,11 @@ import com.bumptech.glide.util.Util
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.snackbar.Snackbar
import com.jakewharton.rxbinding3.view.clicks
import dagger.hilt.android.EntryPointAccessors
import im.vector.app.BuildConfig
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.DaggerScreenComponent
import im.vector.app.core.di.HasScreenInjector
import im.vector.app.core.di.HasVectorInjector
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.di.VectorComponent
import im.vector.app.core.di.ActivityEntryPoint
import im.vector.app.core.dialogs.DialogLocker
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
import im.vector.app.core.extensions.exhaustive
@ -61,7 +58,7 @@ import im.vector.app.core.extensions.observeNotNull
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.restart
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.extensions.vectorComponent
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.core.utils.toast
import im.vector.app.features.MainActivity
import im.vector.app.features.MainActivityArgs
@ -87,9 +84,9 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.failure.GlobalError
import timber.log.Timber
import java.util.concurrent.TimeUnit
import kotlin.system.measureTimeMillis
import javax.inject.Inject
abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), HasScreenInjector, MavericksView {
abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), MavericksView {
/* ==========================================================================================
* View
* ========================================================================================== */
@ -136,8 +133,8 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), HasSc
private lateinit var sessionListener: SessionListener
protected lateinit var bugReporter: BugReporter
private lateinit var pinLocker: PinLocker
@Inject
lateinit var rageShake: RageShake
lateinit var navigator: Navigator
private set
private lateinit var fragmentFactory: FragmentFactory
@ -156,8 +153,6 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), HasSc
private val uiDisposables = CompositeDisposable()
private val restorables = ArrayList<Restorable>()
private lateinit var screenComponent: ScreenComponent
override fun attachBaseContext(base: Context) {
val vectorConfiguration = VectorConfiguration(this)
super.attachBaseContext(vectorConfiguration.getLocalisedContext(base))
@ -187,25 +182,19 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), HasSc
@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
Timber.i("onCreate Activity ${javaClass.simpleName}")
val vectorComponent = getVectorComponent()
screenComponent = DaggerScreenComponent.factory().create(vectorComponent, this)
val timeForInjection = measureTimeMillis {
injectWith(screenComponent)
}
Timber.v("Injecting dependencies into ${javaClass.simpleName} took $timeForInjection ms")
val singletonEntryPoint = singletonEntryPoint()
val activityEntryPoint = EntryPointAccessors.fromActivity(this, ActivityEntryPoint::class.java)
ThemeUtils.setActivityTheme(this, getOtherThemes())
fragmentFactory = screenComponent.fragmentFactory()
fragmentFactory = activityEntryPoint.fragmentFactory()
supportFragmentManager.fragmentFactory = fragmentFactory
viewModelFactory = activityEntryPoint.viewModelFactory()
super.onCreate(savedInstanceState)
viewModelFactory = screenComponent.viewModelFactory()
configurationViewModel = viewModelProvider.get(ConfigurationViewModel::class.java)
bugReporter = screenComponent.bugReporter()
pinLocker = screenComponent.pinLocker()
// Shake detector
rageShake = screenComponent.rageShake()
navigator = screenComponent.navigator()
activeSessionHolder = screenComponent.activeSessionHolder()
vectorPreferences = vectorComponent.vectorPreferences()
bugReporter = singletonEntryPoint.bugReporter()
pinLocker = singletonEntryPoint.pinLocker()
navigator = singletonEntryPoint.navigator()
activeSessionHolder = singletonEntryPoint.activeSessionHolder()
vectorPreferences = singletonEntryPoint.vectorPreferences()
configurationViewModel.activityRestarter.observe(this) {
if (!it.hasBeenHandled) {
// Recreate the Activity because configuration has changed
@ -217,7 +206,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), HasSc
navigator.openPinCode(this, pinStartForActivityResult, PinMode.AUTH)
}
}
sessionListener = vectorComponent.sessionListener()
sessionListener = singletonEntryPoint.sessionListener()
sessionListener.globalErrorLiveData.observeEvent(this) {
handleGlobalError(it)
}
@ -273,7 +262,7 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), HasSc
}
private fun handleCertificateError(certificateError: GlobalError.CertificateError) {
vectorComponent()
singletonEntryPoint()
.unrecognizedCertificateDialog()
.show(this,
certificateError.fingerprint,
@ -403,12 +392,6 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), HasSc
bugReporter.inMultiWindowMode = isInMultiWindowMode
}
override fun injector(): ScreenComponent {
return screenComponent
}
protected open fun injectWith(injector: ScreenComponent) = Unit
protected fun createFragment(fragmentClass: Class<out Fragment>, args: Bundle?): Fragment {
return fragmentFactory.instantiate(classLoader, fragmentClass.name).apply {
arguments = args
@ -419,10 +402,6 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), HasSc
* PRIVATE METHODS
* ========================================================================================== */
internal fun getVectorComponent(): VectorComponent {
return (application as HasVectorInjector).injector()
}
/**
* Force to render the activity in fullscreen
*/

View File

@ -33,8 +33,8 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.jakewharton.rxbinding3.view.clicks
import im.vector.app.core.di.DaggerScreenComponent
import im.vector.app.core.di.ScreenComponent
import dagger.hilt.android.EntryPointAccessors
import im.vector.app.core.di.ActivityEntryPoint
import im.vector.app.core.utils.DimensionConverter
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
@ -47,8 +47,6 @@ import java.util.concurrent.TimeUnit
*/
abstract class VectorBaseBottomSheetDialogFragment<VB : ViewBinding> : BottomSheetDialogFragment(), MavericksView {
private lateinit var screenComponent: ScreenComponent
/* ==========================================================================================
* View
* ========================================================================================== */
@ -122,14 +120,11 @@ abstract class VectorBaseBottomSheetDialogFragment<VB : ViewBinding> : BottomShe
}
override fun onAttach(context: Context) {
screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity)
viewModelFactory = screenComponent.viewModelFactory()
val activityEntryPoint = EntryPointAccessors.fromActivity(vectorBaseActivity, ActivityEntryPoint::class.java)
viewModelFactory = activityEntryPoint.viewModelFactory()
super.onAttach(context)
injectWith(screenComponent)
}
protected open fun injectWith(injector: ScreenComponent) = Unit
override fun onResume() {
super.onResume()
Timber.i("onResume BottomSheet ${javaClass.simpleName}")

View File

@ -35,12 +35,12 @@ import com.bumptech.glide.util.Util.assertMainThread
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.jakewharton.rxbinding3.view.clicks
import dagger.hilt.android.EntryPointAccessors
import im.vector.app.R
import im.vector.app.core.di.DaggerScreenComponent
import im.vector.app.core.di.HasScreenInjector
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.di.ActivityEntryPoint
import im.vector.app.core.dialogs.UnrecognizedCertificateDialog
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.core.extensions.toMvRxBundle
import im.vector.app.features.navigation.Navigator
import im.vector.lib.ui.styles.dialogs.MaterialProgressDialog
@ -50,7 +50,7 @@ import io.reactivex.disposables.Disposable
import timber.log.Timber
import java.util.concurrent.TimeUnit
abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView, HasScreenInjector {
abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView {
protected val vectorBaseActivity: VectorBaseActivity<*> by lazy {
activity as VectorBaseActivity<*>
@ -60,8 +60,6 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView,
* Navigator and other common objects
* ========================================================================================== */
private lateinit var screenComponent: ScreenComponent
protected lateinit var navigator: Navigator
protected lateinit var errorFormatter: ErrorFormatter
protected lateinit var unrecognizedCertificateDialog: UnrecognizedCertificateDialog
@ -95,12 +93,13 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView,
* ========================================================================================== */
override fun onAttach(context: Context) {
screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity)
navigator = screenComponent.navigator()
errorFormatter = screenComponent.errorFormatter()
unrecognizedCertificateDialog = screenComponent.unrecognizedCertificateDialog()
viewModelFactory = screenComponent.viewModelFactory()
childFragmentManager.fragmentFactory = screenComponent.fragmentFactory()
val singletonEntryPoint = context.singletonEntryPoint()
val activityEntryPoint = EntryPointAccessors.fromActivity(vectorBaseActivity, ActivityEntryPoint::class.java)
navigator = singletonEntryPoint.navigator()
errorFormatter = singletonEntryPoint.errorFormatter()
unrecognizedCertificateDialog = singletonEntryPoint.unrecognizedCertificateDialog()
viewModelFactory = activityEntryPoint.viewModelFactory()
childFragmentManager.fragmentFactory = activityEntryPoint.fragmentFactory()
super.onAttach(context)
}
@ -161,10 +160,6 @@ abstract class VectorBaseFragment<VB : ViewBinding> : Fragment(), MavericksView,
super.onDestroy()
}
override fun injector(): ScreenComponent {
return screenComponent
}
/* ==========================================================================================
* Restorable
* ========================================================================================== */

View File

@ -23,7 +23,7 @@ import android.widget.ProgressBar
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import im.vector.app.R
import im.vector.app.core.extensions.vectorComponent
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.session.user.model.User
import org.matrix.android.sdk.api.util.MatrixItem
@ -33,7 +33,7 @@ class UserAvatarPreference : Preference {
private var mAvatarView: ImageView? = null
private var mLoadingProgressBar: ProgressBar? = null
private var avatarRenderer: AvatarRenderer = context.vectorComponent().avatarRenderer()
private var avatarRenderer: AvatarRenderer = context.singletonEntryPoint().avatarRenderer()
private var userItem: MatrixItem.UserItem? = null

View File

@ -26,7 +26,8 @@ import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.media.session.MediaButtonReceiver
import com.airbnb.mvrx.Mavericks
import im.vector.app.core.extensions.vectorComponent
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.features.call.CallArgs
import im.vector.app.features.call.VectorCallActivity
import im.vector.app.features.call.telecom.CallConnection
@ -42,23 +43,25 @@ import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.session.room.model.call.EndCallReason
import org.matrix.android.sdk.api.util.MatrixItem
import timber.log.Timber
import javax.inject.Inject
private val loggerTag = LoggerTag("CallService", LoggerTag.VOIP)
/**
* Foreground service to manage calls
*/
@AndroidEntryPoint
class CallService : VectorService() {
private val connections = mutableMapOf<String, CallConnection>()
private val knownCalls = mutableMapOf<String, CallInformation>()
private val connectedCallIds = mutableSetOf<String>()
private lateinit var notificationManager: NotificationManagerCompat
private lateinit var notificationUtils: NotificationUtils
private lateinit var callManager: WebRtcCallManager
private lateinit var avatarRenderer: AvatarRenderer
private lateinit var alertManager: PopupAlertManager
lateinit var notificationManager: NotificationManagerCompat
@Inject lateinit var notificationUtils: NotificationUtils
@Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var avatarRenderer: AvatarRenderer
@Inject lateinit var alertManager: PopupAlertManager
private var callRingPlayerIncoming: CallRingPlayerIncoming? = null
private var callRingPlayerOutgoing: CallRingPlayerOutgoing? = null
@ -80,10 +83,6 @@ class CallService : VectorService() {
override fun onCreate() {
super.onCreate()
notificationManager = NotificationManagerCompat.from(this)
notificationUtils = vectorComponent().notificationUtils()
callManager = vectorComponent().webRtcCallManager()
avatarRenderer = vectorComponent().avatarRenderer()
alertManager = vectorComponent().alertManager()
callRingPlayerIncoming = CallRingPlayerIncoming(applicationContext, notificationUtils)
callRingPlayerOutgoing = CallRingPlayerOutgoing(applicationContext)
}
@ -298,7 +297,7 @@ class CallService : VectorService() {
callId = this.callId,
nativeRoomId = this.nativeRoomId,
opponentUserId = this.mxCall.opponentUserId,
opponentMatrixItem = vectorComponent().activeSessionHolder().getSafeActiveSession()?.let {
opponentMatrixItem = singletonEntryPoint().activeSessionHolder().getSafeActiveSession()?.let {
this.getOpponentAsMatrixItem(it)
},
isVideoCall = this.mxCall.isVideoCall,

View File

@ -30,13 +30,15 @@ import androidx.work.WorkManager
import androidx.work.WorkRequest
import androidx.work.Worker
import androidx.work.WorkerParameters
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.extensions.vectorComponent
import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.settings.BackgroundSyncMode
import org.matrix.android.sdk.internal.session.sync.job.SyncService
import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
class VectorSyncService : SyncService() {
companion object {
@ -71,12 +73,7 @@ class VectorSyncService : SyncService() {
}
}
private lateinit var notificationUtils: NotificationUtils
override fun onCreate() {
super.onCreate()
notificationUtils = vectorComponent().notificationUtils()
}
@Inject lateinit var notificationUtils: NotificationUtils
override fun getDefaultSyncDelaySeconds() = BackgroundSyncMode.DEFAULT_SYNC_DELAY_SECONDS

View File

@ -24,9 +24,9 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import com.bumptech.glide.Glide
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.startSyncing
import im.vector.app.core.platform.VectorBaseActivity
@ -67,6 +67,7 @@ data class MainActivityArgs(
* This Activity, when started with argument, is also doing some cleanup when user signs out,
* clears cache, is logged out, or is soft logged out
*/
@AndroidEntryPoint
class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity {
companion object {
@ -98,10 +99,6 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
@Inject lateinit var pinLocker: PinLocker
@Inject lateinit var popupAlertManager: PopupAlertManager
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
args = parseArgs()

View File

@ -20,6 +20,7 @@ package im.vector.app.features.attachments.preview
import android.content.Context
import android.content.Intent
import com.google.android.material.appbar.MaterialToolbar
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.ToolbarConfigurable
@ -28,6 +29,7 @@ import im.vector.app.databinding.ActivitySimpleBinding
import im.vector.app.features.themes.ActivityOtherThemes
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
@AndroidEntryPoint
class AttachmentsPreviewActivity : VectorBaseActivity<ActivitySimpleBinding>(), ToolbarConfigurable {
companion object {

View File

@ -29,8 +29,8 @@ import androidx.browser.customtabs.CustomTabsSession
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.viewModel
import com.airbnb.mvrx.withState
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.SimpleFragmentActivity
import im.vector.app.core.utils.openUrlInChromeCustomTab
@ -42,7 +42,8 @@ import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
import timber.log.Timber
import javax.inject.Inject
class ReAuthActivity : SimpleFragmentActivity(), ReAuthViewModel.Factory {
@AndroidEntryPoint
class ReAuthActivity : SimpleFragmentActivity() {
@Parcelize
data class Args(
@ -59,14 +60,6 @@ class ReAuthActivity : SimpleFragmentActivity(), ReAuthViewModel.Factory {
private var customTabsSession: CustomTabsSession? = null
@Inject lateinit var authenticationService: AuthenticationService
@Inject lateinit var reAuthViewModelFactory: ReAuthViewModel.Factory
override fun create(initialState: ReAuthState) = reAuthViewModelFactory.create(initialState)
override fun injectWith(injector: ScreenComponent) {
super.injectWith(injector)
injector.inject(this)
}
private val sharedViewModel: ReAuthViewModel by viewModel()

View File

@ -16,13 +16,12 @@
package im.vector.app.features.auth
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.FragmentViewModelContext
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.VectorViewModel
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
import org.matrix.android.sdk.api.session.Session
@ -35,20 +34,11 @@ class ReAuthViewModel @AssistedInject constructor(
) : VectorViewModel<ReAuthState, ReAuthActions, ReAuthEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: ReAuthState): ReAuthViewModel
interface Factory : MavericksAssistedViewModelFactory<ReAuthViewModel, ReAuthState> {
override fun create(initialState: ReAuthState): ReAuthViewModel
}
companion object : MavericksViewModelFactory<ReAuthViewModel, ReAuthState> {
override fun create(viewModelContext: ViewModelContext, state: ReAuthState): ReAuthViewModel? {
val factory = when (viewModelContext) {
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
is ActivityViewModelContext -> viewModelContext.activity as? Factory
}
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
}
}
companion object : MavericksViewModelFactory<ReAuthViewModel, ReAuthState> by hiltMavericksViewModelFactory()
override fun handle(action: ReAuthActions) = withState { state ->
when (action) {

View File

@ -23,10 +23,12 @@ import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import com.airbnb.mvrx.activityViewModel
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.databinding.BottomSheetCallControlsBinding
@AndroidEntryPoint
class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetCallControlsBinding>() {
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetCallControlsBinding {
return BottomSheetCallControlsBinding.inflate(inflater, container, false)

View File

@ -41,8 +41,8 @@ import com.airbnb.mvrx.viewModel
import com.airbnb.mvrx.withState
import com.google.android.material.card.MaterialCardView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL
@ -85,21 +85,16 @@ data class CallArgs(
private val loggerTag = LoggerTag("VectorCallActivity", LoggerTag.VOIP)
@AndroidEntryPoint
class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallControlsView.InteractionListener {
override fun getBinding() = ActivityCallBinding.inflate(layoutInflater)
@Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var avatarRenderer: AvatarRenderer
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
private val callViewModel: VectorCallViewModel by viewModel()
@Inject lateinit var callManager: WebRtcCallManager
@Inject lateinit var viewModelFactory: VectorCallViewModel.Factory
private val dialPadCallback = object : DialPadFragment.Callback {
override fun onDigitAppended(digit: String) {
callViewModel.handle(VectorCallViewActions.SendDtmfDigit(digit))

View File

@ -21,10 +21,11 @@ import com.airbnb.mvrx.Fail
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.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.call.audio.CallAudioManager
@ -341,16 +342,9 @@ class VectorCallViewModel @AssistedInject constructor(
}
@AssistedFactory
interface Factory {
fun create(initialState: VectorCallViewState): VectorCallViewModel
interface Factory : MavericksAssistedViewModelFactory<VectorCallViewModel, VectorCallViewState> {
override fun create(initialState: VectorCallViewState): VectorCallViewModel
}
companion object : MavericksViewModelFactory<VectorCallViewModel, VectorCallViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: VectorCallViewState): VectorCallViewModel {
val callActivity: VectorCallActivity = viewModelContext.activity()
return callActivity.viewModelFactory.create(state)
}
}
companion object : MavericksViewModelFactory<VectorCallViewModel, VectorCallViewState> by hiltMavericksViewModelFactory()
}

View File

@ -22,10 +22,11 @@ import com.airbnb.mvrx.Fail
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.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 kotlinx.coroutines.Job
@ -46,8 +47,8 @@ class JitsiCallViewModel @AssistedInject constructor(
) : VectorViewModel<JitsiCallViewState, JitsiCallViewActions, JitsiCallViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: JitsiCallViewState): JitsiCallViewModel
interface Factory : MavericksAssistedViewModelFactory<JitsiCallViewModel, JitsiCallViewState> {
override fun create(initialState: JitsiCallViewState): JitsiCallViewModel
}
private var currentWidgetObserver: Job? = null
@ -143,24 +144,7 @@ class JitsiCallViewModel @AssistedInject constructor(
}
}
companion object : MavericksViewModelFactory<JitsiCallViewModel, JitsiCallViewState> {
companion object : MavericksViewModelFactory<JitsiCallViewModel, JitsiCallViewState> by hiltMavericksViewModelFactory() {
const val ENABLE_VIDEO_OPTION = "ENABLE_VIDEO_OPTION"
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: JitsiCallViewState): JitsiCallViewModel? {
val callActivity: VectorJitsiActivity = viewModelContext.activity()
return callActivity.viewModelFactory.create(state)
}
override fun initialState(viewModelContext: ViewModelContext): JitsiCallViewState? {
val args: VectorJitsiActivity.Args = viewModelContext.args()
return JitsiCallViewState(
roomId = args.roomId,
widgetId = args.widgetId,
enableVideo = args.enableVideo
)
}
}
}

View File

@ -26,4 +26,11 @@ data class JitsiCallViewState(
val widgetId: String = "",
val enableVideo: Boolean = false,
val widget: Async<Widget> = Uninitialized
) : MavericksState
) : MavericksState {
constructor(args: VectorJitsiActivity.Args) : this(
roomId = args.roomId,
widgetId = args.widgetId,
enableVideo = args.enableVideo
)
}

View File

@ -33,8 +33,8 @@ import com.airbnb.mvrx.Success
import com.airbnb.mvrx.viewModel
import com.facebook.react.modules.core.PermissionListener
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityJitsiBinding
@ -48,8 +48,8 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.util.JsonDict
import timber.log.Timber
import java.net.URL
import javax.inject.Inject
@AndroidEntryPoint
class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMeetActivityInterface {
@Parcelize
@ -61,16 +61,10 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
override fun getBinding() = ActivityJitsiBinding.inflate(layoutInflater)
@Inject lateinit var viewModelFactory: JitsiCallViewModel.Factory
private var jitsiMeetView: JitsiMeetView? = null
private val jitsiViewModel: JitsiCallViewModel by viewModel()
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@ -19,7 +19,7 @@ package im.vector.app.features.call.service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import im.vector.app.core.di.HasVectorInjector
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.features.call.webrtc.WebRtcCallManager
import timber.log.Timber
@ -32,11 +32,7 @@ class CallHeadsUpActionReceiver : BroadcastReceiver() {
}
override fun onReceive(context: Context, intent: Intent?) {
val webRtcCallManager = (context.applicationContext as? HasVectorInjector)
?.injector()
?.webRtcCallManager()
?: return
val webRtcCallManager = context.singletonEntryPoint().webRtcCallManager()
when (intent?.getIntExtra(EXTRA_CALL_ACTION_KEY, 0)) {
CALL_ACTION_REJECT -> {
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: return

View File

@ -23,15 +23,11 @@ import android.os.Parcelable
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.viewModel
import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityCallTransferBinding
import im.vector.app.features.contactsbook.ContactsBookViewModel
import im.vector.app.features.contactsbook.ContactsBookViewState
import im.vector.app.features.userdirectory.UserListViewModel
import im.vector.app.features.userdirectory.UserListViewState
import kotlinx.parcelize.Parcelize
import javax.inject.Inject
@ -40,14 +36,9 @@ data class CallTransferArgs(val callId: String) : Parcelable
private const val USER_LIST_FRAGMENT_TAG = "USER_LIST_FRAGMENT_TAG"
class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>(),
CallTransferViewModel.Factory,
UserListViewModel.Factory,
ContactsBookViewModel.Factory {
@AndroidEntryPoint
class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>() {
@Inject lateinit var userListViewModelFactory: UserListViewModel.Factory
@Inject lateinit var callTransferViewModelFactory: CallTransferViewModel.Factory
@Inject lateinit var contactsBookViewModelFactory: ContactsBookViewModel.Factory
@Inject lateinit var errorFormatter: ErrorFormatter
private lateinit var sectionsPagerAdapter: CallTransferPagerAdapter
@ -58,22 +49,6 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>(),
override fun getCoordinatorLayout() = views.vectorCoordinatorLayout
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun create(initialState: UserListViewState): UserListViewModel {
return userListViewModelFactory.create(initialState)
}
override fun create(initialState: CallTransferViewState): CallTransferViewModel {
return callTransferViewModelFactory.create(initialState)
}
override fun create(initialState: ContactsBookViewState): ContactsBookViewModel {
return contactsBookViewModelFactory.create(initialState)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
waitingView = views.waitingView.waitingView

View File

@ -16,13 +16,12 @@
package im.vector.app.features.call.transfer
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.ActivityViewModelContext
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.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.call.dialpad.DialPadLookup
@ -41,18 +40,11 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState:
VectorViewModel<CallTransferViewState, CallTransferAction, CallTransferViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: CallTransferViewState): CallTransferViewModel
interface Factory : MavericksAssistedViewModelFactory<CallTransferViewModel, CallTransferViewState> {
override fun create(initialState: CallTransferViewState): CallTransferViewModel
}
companion object : MavericksViewModelFactory<CallTransferViewModel, CallTransferViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: CallTransferViewState): CallTransferViewModel? {
val activity: CallTransferActivity = (viewModelContext as ActivityViewModelContext).activity()
return activity.callTransferViewModelFactory.create(state)
}
}
companion object : MavericksViewModelFactory<CallTransferViewModel, CallTransferViewState> by hiltMavericksViewModelFactory()
private val call = callManager.getCallById(initialState.callId)
private val callListener = object : WebRtcCall.Listener {

View File

@ -43,9 +43,8 @@ import java.util.concurrent.TimeUnit
import javax.inject.Inject
class ContactsBookFragment @Inject constructor(
private val contactsBookViewModelFactory: ContactsBookViewModel.Factory,
private val contactsBookController: ContactsBookController
) : VectorBaseFragment<FragmentContactsBookBinding>(), ContactsBookController.Callback, ContactsBookViewModel.Factory {
) : VectorBaseFragment<FragmentContactsBookBinding>(), ContactsBookController.Callback {
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentContactsBookBinding {
return FragmentContactsBookBinding.inflate(inflater, container, false)
@ -58,10 +57,6 @@ class ContactsBookFragment @Inject constructor(
private lateinit var sharedActionViewModel: UserListSharedActionViewModel
override fun create(initialState: ContactsBookViewState): ContactsBookViewModel {
return contactsBookViewModelFactory.create(initialState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
sharedActionViewModel = activityViewModelProvider.get(UserListSharedActionViewModel::class.java)

View File

@ -17,17 +17,16 @@
package im.vector.app.features.contactsbook
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.FragmentViewModelContext
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.core.contacts.ContactsDataSource
import im.vector.app.core.contacts.MappedContact
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.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
@ -45,20 +44,11 @@ class ContactsBookViewModel @AssistedInject constructor(@Assisted
VectorViewModel<ContactsBookViewState, ContactsBookAction, EmptyViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: ContactsBookViewState): ContactsBookViewModel
interface Factory : MavericksAssistedViewModelFactory<ContactsBookViewModel, ContactsBookViewState> {
override fun create(initialState: ContactsBookViewState): ContactsBookViewModel
}
companion object : MavericksViewModelFactory<ContactsBookViewModel, ContactsBookViewState> {
override fun create(viewModelContext: ViewModelContext, state: ContactsBookViewState): ContactsBookViewModel? {
val factory = when (viewModelContext) {
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
is ActivityViewModelContext -> viewModelContext.activity as? Factory
}
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
}
}
companion object : MavericksViewModelFactory<ContactsBookViewModel, ContactsBookViewState> by hiltMavericksViewModelFactory()
private var allContacts: List<MappedContact> = emptyList()
private var mappedContacts: List<MappedContact> = emptyList()

View File

@ -28,8 +28,8 @@ import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.viewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.extensions.addFragmentToBackstack
@ -42,39 +42,22 @@ import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.onPermissionDeniedSnackbar
import im.vector.app.core.utils.registerForPermissionsResult
import im.vector.app.features.contactsbook.ContactsBookFragment
import im.vector.app.features.contactsbook.ContactsBookViewModel
import im.vector.app.features.contactsbook.ContactsBookViewState
import im.vector.app.features.userdirectory.UserListFragment
import im.vector.app.features.userdirectory.UserListFragmentArgs
import im.vector.app.features.userdirectory.UserListSharedAction
import im.vector.app.features.userdirectory.UserListSharedActionViewModel
import im.vector.app.features.userdirectory.UserListViewModel
import im.vector.app.features.userdirectory.UserListViewState
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
import java.net.HttpURLConnection
import javax.inject.Inject
class CreateDirectRoomActivity : SimpleFragmentActivity(), UserListViewModel.Factory, CreateDirectRoomViewModel.Factory, ContactsBookViewModel.Factory {
@AndroidEntryPoint
class CreateDirectRoomActivity : SimpleFragmentActivity() {
private val viewModel: CreateDirectRoomViewModel by viewModel()
private lateinit var sharedActionViewModel: UserListSharedActionViewModel
@Inject lateinit var userListViewModelFactory: UserListViewModel.Factory
@Inject lateinit var createDirectRoomViewModelFactory: CreateDirectRoomViewModel.Factory
@Inject lateinit var contactsBookViewModelFactory: ContactsBookViewModel.Factory
@Inject lateinit var errorFormatter: ErrorFormatter
override fun injectWith(injector: ScreenComponent) {
super.injectWith(injector)
injector.inject(this)
}
override fun create(initialState: UserListViewState) = userListViewModelFactory.create(initialState)
override fun create(initialState: CreateDirectRoomViewState) = createDirectRoomViewModelFactory.create(initialState)
override fun create(initialState: ContactsBookViewState) = contactsBookViewModelFactory.create(initialState)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
views.toolbar.visibility = View.GONE

View File

@ -16,16 +16,14 @@
package im.vector.app.features.createdirect
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.FragmentViewModelContext
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.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.mvrx.runCatchingToAsync
import im.vector.app.core.platform.VectorViewModel
@ -45,21 +43,11 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted
VectorViewModel<CreateDirectRoomViewState, CreateDirectRoomAction, CreateDirectRoomViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: CreateDirectRoomViewState): CreateDirectRoomViewModel
interface Factory : MavericksAssistedViewModelFactory<CreateDirectRoomViewModel, CreateDirectRoomViewState> {
override fun create(initialState: CreateDirectRoomViewState): CreateDirectRoomViewModel
}
companion object : MavericksViewModelFactory<CreateDirectRoomViewModel, CreateDirectRoomViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: CreateDirectRoomViewState): CreateDirectRoomViewModel? {
val factory = when (viewModelContext) {
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
is ActivityViewModelContext -> viewModelContext.activity as? Factory
}
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
}
}
companion object : MavericksViewModelFactory<CreateDirectRoomViewModel, CreateDirectRoomViewState> by hiltMavericksViewModelFactory()
override fun handle(action: CreateDirectRoomAction) {
when (action) {

View File

@ -19,7 +19,9 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.extensions.addFragmentToBackstack
import im.vector.app.core.extensions.observeEvent
import im.vector.app.core.extensions.registerStartForActivityResult
@ -28,7 +30,9 @@ import im.vector.app.core.platform.SimpleFragmentActivity
import im.vector.app.core.ui.views.KeysBackupBanner
import im.vector.app.features.crypto.quads.SharedSecureStorageActivity
import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
import javax.inject.Inject
@AndroidEntryPoint
class KeysBackupRestoreActivity : SimpleFragmentActivity() {
companion object {
@ -48,10 +52,12 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
super.onBackPressed()
}
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
override fun initUiAndData() {
super.initUiAndData()
viewModel = viewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java)
viewModel.initSession(session)
viewModel.initSession(activeSessionHolder.getActiveSession())
viewModel.keySourceModel.observe(this) { keySource ->
if (keySource != null && !keySource.isInQuadS && supportFragmentManager.fragments.isEmpty()) {

View File

@ -21,13 +21,13 @@ import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.viewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.SimpleFragmentActivity
import im.vector.app.core.platform.WaitingViewData
import javax.inject.Inject
@AndroidEntryPoint
class KeysBackupManageActivity : SimpleFragmentActivity() {
companion object {
@ -40,12 +40,6 @@ class KeysBackupManageActivity : SimpleFragmentActivity() {
override fun getTitleRes() = R.string.encryption_message_recovery
private val viewModel: KeysBackupSettingsViewModel by viewModel()
@Inject lateinit var keysBackupSettingsViewModelFactory: KeysBackupSettingsViewModel.Factory
override fun injectWith(injector: ScreenComponent) {
super.injectWith(injector)
injector.inject(this)
}
override fun initUiAndData() {
super.initUiAndData()

View File

@ -15,16 +15,16 @@
*/
package im.vector.app.features.crypto.keysbackup.settings
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
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.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import org.matrix.android.sdk.api.MatrixCallback
@ -41,18 +41,11 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS
KeysBackupStateListener {
@AssistedFactory
interface Factory {
fun create(initialState: KeysBackupSettingViewState): KeysBackupSettingsViewModel
interface Factory : MavericksAssistedViewModelFactory<KeysBackupSettingsViewModel, KeysBackupSettingViewState> {
override fun create(initialState: KeysBackupSettingViewState): KeysBackupSettingsViewModel
}
companion object : MavericksViewModelFactory<KeysBackupSettingsViewModel, KeysBackupSettingViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: KeysBackupSettingViewState): KeysBackupSettingsViewModel? {
val activity: KeysBackupManageActivity = (viewModelContext as ActivityViewModelContext).activity()
return activity.keysBackupSettingsViewModelFactory.create(state)
}
}
companion object : MavericksViewModelFactory<KeysBackupSettingsViewModel, KeysBackupSettingViewState> by hiltMavericksViewModelFactory()
private val keysBackupService: KeysBackupService = session.cryptoService().keysBackupService()

View File

@ -23,8 +23,9 @@ import androidx.core.view.isVisible
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.dialogs.ExportKeysDialog
import im.vector.app.core.extensions.observeEvent
import im.vector.app.core.extensions.queryExportKeys
@ -36,6 +37,7 @@ import im.vector.app.features.crypto.keys.KeysExporter
import kotlinx.coroutines.launch
import javax.inject.Inject
@AndroidEntryPoint
class KeysBackupSetupActivity : SimpleFragmentActivity() {
override fun getTitleRes() = R.string.title_activity_keys_backup_setup
@ -43,10 +45,10 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
private lateinit var viewModel: KeysBackupSetupSharedViewModel
@Inject lateinit var keysExporter: KeysExporter
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
override fun injectWith(injector: ScreenComponent) {
super.injectWith(injector)
injector.inject(this)
private val session by lazy {
activeSessionHolder.getActiveSession()
}
override fun initUiAndData() {

View File

@ -28,8 +28,8 @@ import androidx.fragment.app.FragmentOnAttachListener
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.viewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.extensions.commitTransaction
import im.vector.app.core.platform.SimpleFragmentActivity
@ -39,6 +39,7 @@ import kotlinx.parcelize.Parcelize
import javax.inject.Inject
import kotlin.reflect.KClass
@AndroidEntryPoint
class SharedSecureStorageActivity :
SimpleFragmentActivity(),
VectorBaseBottomSheetDialogFragment.ResultListener,
@ -52,14 +53,8 @@ class SharedSecureStorageActivity :
) : Parcelable
private val viewModel: SharedSecureStorageViewModel by viewModel()
@Inject lateinit var viewModelFactory: SharedSecureStorageViewModel.Factory
@Inject lateinit var errorFormatter: ErrorFormatter
override fun injectWith(injector: ScreenComponent) {
super.injectWith(injector)
injector.inject(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager.addFragmentOnAttachListener(this)

View File

@ -19,16 +19,16 @@ package im.vector.app.features.crypto.quads
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Mavericks
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.platform.WaitingViewData
@ -54,8 +54,18 @@ data class SharedSecureStorageViewState(
val step: Step = Step.EnterPassphrase,
val activeDeviceCount: Int = 0,
val showResetAllAction: Boolean = false,
val userId: String = ""
val userId: String = "",
val keyId: String?,
val requestedSecrets: List<String>,
val resultKeyStoreAlias: String
) : MavericksState {
constructor(args: SharedSecureStorageActivity.Args) : this(
keyId = args.keyId,
requestedSecrets = args.requestedSecrets,
resultKeyStoreAlias = args.resultKeyStoreAlias
)
enum class Step {
EnterPassphrase,
EnterKey,
@ -64,23 +74,22 @@ data class SharedSecureStorageViewState(
}
class SharedSecureStorageViewModel @AssistedInject constructor(
@Assisted initialState: SharedSecureStorageViewState,
@Assisted val args: SharedSecureStorageActivity.Args,
@Assisted private val initialState: SharedSecureStorageViewState,
private val stringProvider: StringProvider,
private val session: Session) :
VectorViewModel<SharedSecureStorageViewState, SharedSecureStorageAction, SharedSecureStorageViewEvent>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: SharedSecureStorageViewState, args: SharedSecureStorageActivity.Args): SharedSecureStorageViewModel
interface Factory : MavericksAssistedViewModelFactory<SharedSecureStorageViewModel, SharedSecureStorageViewState> {
override fun create(initialState: SharedSecureStorageViewState): SharedSecureStorageViewModel
}
init {
setState {
copy(userId = session.myUserId)
}
val isValid = session.sharedSecretStorageService.checkShouldBeAbleToAccessSecrets(args.requestedSecrets, args.keyId) is IntegrityResult.Success
if (!isValid) {
val integrityResult = session.sharedSecretStorageService.checkShouldBeAbleToAccessSecrets(initialState.requestedSecrets, initialState.keyId)
if (integrityResult !is IntegrityResult.Success) {
_viewEvents.post(
SharedSecureStorageViewEvent.Error(
stringProvider.getString(R.string.enter_secret_storage_invalid),
@ -88,7 +97,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
)
)
}
val keyResult = args.keyId?.let { session.sharedSecretStorageService.getKey(it) }
val keyResult = initialState.keyId?.let { session.sharedSecretStorageService.getKey(it) }
?: session.sharedSecretStorageService.getDefaultKey()
if (!keyResult.isSuccess()) {
@ -218,7 +227,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
}
withContext(Dispatchers.IO) {
args.requestedSecrets.forEach {
initialState.requestedSecrets.forEach {
if (session.accountDataService().getUserAccountDataEvent(it) != null) {
val res = session.sharedSecretStorageService.getSecret(
name = it,
@ -235,7 +244,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
_viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading)
val safeForIntentCypher = ByteArrayOutputStream().also {
it.use {
session.securelyStoreObject(decryptedSecretMap as Map<String, String>, args.resultKeyStoreAlias, it)
session.securelyStoreObject(decryptedSecretMap as Map<String, String>, initialState.resultKeyStoreAlias, it)
}
}.toByteArray().toBase64NoPadding()
_viewEvents.post(SharedSecureStorageViewEvent.FinishSuccess(safeForIntentCypher))
@ -287,7 +296,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
)
withContext(Dispatchers.IO) {
args.requestedSecrets.forEach {
initialState.requestedSecrets.forEach {
if (session.accountDataService().getUserAccountDataEvent(it) != null) {
val res = session.sharedSecretStorageService.getSecret(
name = it,
@ -304,7 +313,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
_viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading)
val safeForIntentCypher = ByteArrayOutputStream().also {
it.use {
session.securelyStoreObject(decryptedSecretMap as Map<String, String>, args.resultKeyStoreAlias, it)
session.securelyStoreObject(decryptedSecretMap as Map<String, String>, initialState.resultKeyStoreAlias, it)
}
}.toByteArray().toBase64NoPadding()
_viewEvents.post(SharedSecureStorageViewEvent.FinishSuccess(safeForIntentCypher))
@ -320,13 +329,5 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
_viewEvents.post(SharedSecureStorageViewEvent.Dismiss)
}
companion object : MavericksViewModelFactory<SharedSecureStorageViewModel, SharedSecureStorageViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: SharedSecureStorageViewState): SharedSecureStorageViewModel? {
val activity: SharedSecureStorageActivity = viewModelContext.activity()
val args: SharedSecureStorageActivity.Args = activity.intent.getParcelableExtra(Mavericks.KEY_ARG) ?: error("Missing args")
return activity.viewModelFactory.create(state, args)
}
}
companion object : MavericksViewModelFactory<SharedSecureStorageViewModel, SharedSecureStorageViewState> by hiltMavericksViewModelFactory()
}

View File

@ -33,8 +33,8 @@ import androidx.fragment.app.FragmentManager
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.commitTransaction
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
@ -43,9 +43,9 @@ import im.vector.app.databinding.BottomSheetBootstrapBinding
import im.vector.app.features.auth.ReAuthActivity
import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
import javax.inject.Inject
import kotlin.reflect.KClass
@AndroidEntryPoint
class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetBootstrapBinding>() {
@Parcelize
@ -55,15 +55,8 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetBoot
override val showExpanded = true
@Inject
lateinit var bootstrapViewModelFactory: BootstrapSharedViewModel.Factory
private val viewModel by fragmentViewModel(BootstrapSharedViewModel::class)
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetBootstrapBinding {
return BottomSheetBootstrapBinding.inflate(inflater, container, false)
}

View File

@ -16,26 +16,24 @@
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
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.ViewModelContext
import com.nulabinc.zxcvbn.Zxcvbn
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
import im.vector.app.core.platform.WaitingViewData
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.auth.ReAuthActivity
import im.vector.app.features.login.ReAuthHelper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.auth.UIABaseAuth
@ -59,13 +57,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 +69,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 +82,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 +408,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 +514,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 +545,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)
}
}
}

View File

@ -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,7 @@ 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)
}

View File

@ -28,8 +28,8 @@ import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.commitTransaction
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
@ -61,6 +61,7 @@ import timber.log.Timber
import javax.inject.Inject
import kotlin.reflect.KClass
@AndroidEntryPoint
class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetVerificationBinding>() {
@Parcelize
@ -75,18 +76,11 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetV
override val showExpanded = true
@Inject
lateinit var verificationViewModelFactory: VerificationBottomSheetViewModel.Factory
@Inject
lateinit var avatarRenderer: AvatarRenderer
private val viewModel by fragmentViewModel(VerificationBottomSheetViewModel::class)
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationBinding {
return BottomSheetVerificationBinding.inflate(inflater, container, false)
}

View File

@ -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)
)
}

View File

@ -40,7 +40,6 @@ import timber.log.Timber
import javax.inject.Inject
class VerificationChooseMethodFragment @Inject constructor(
val verificationChooseMethodViewModelFactory: VerificationChooseMethodViewModel.Factory,
val controller: VerificationChooseMethodController
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
VerificationChooseMethodController.Listener {

View File

@ -15,14 +15,16 @@
*/
package im.vector.app.features.crypto.verification.choose
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MavericksState
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.HasScreenInjector
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.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
@ -50,6 +52,10 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
private val session: Session
) : VectorViewModel<VerificationChooseMethodViewState, EmptyAction, EmptyViewEvents>(initialState), VerificationService.Listener {
init {
session.cryptoService().verificationService().addListener(this)
}
override fun transactionCreated(tx: VerificationTransaction) {
transactionUpdated(tx)
}
@ -81,28 +87,15 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
}
@AssistedFactory
interface Factory {
fun create(initialState: VerificationChooseMethodViewState): VerificationChooseMethodViewModel
interface Factory : MavericksAssistedViewModelFactory<VerificationChooseMethodViewModel, VerificationChooseMethodViewState> {
override fun create(initialState: VerificationChooseMethodViewState): VerificationChooseMethodViewModel
}
init {
session.cryptoService().verificationService().addListener(this)
}
companion object : MavericksViewModelFactory<VerificationChooseMethodViewModel, VerificationChooseMethodViewState> by hiltMavericksViewModelFactory() {
override fun onCleared() {
session.cryptoService().verificationService().removeListener(this)
super.onCleared()
}
companion object : MavericksViewModelFactory<VerificationChooseMethodViewModel, VerificationChooseMethodViewState> {
override fun create(viewModelContext: ViewModelContext, state: VerificationChooseMethodViewState): VerificationChooseMethodViewModel? {
val fragment: VerificationChooseMethodFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.verificationChooseMethodViewModelFactory.create(state)
}
override fun initialState(viewModelContext: ViewModelContext): VerificationChooseMethodViewState? {
override fun initialState(viewModelContext: ViewModelContext): VerificationChooseMethodViewState {
val args: VerificationBottomSheet.VerificationArgs = viewModelContext.args()
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession()
val verificationService = session.cryptoService().verificationService()
val pvr = verificationService.getExistingVerificationRequest(args.otherUserId, args.verificationId)
@ -121,5 +114,10 @@ class VerificationChooseMethodViewModel @AssistedInject constructor(
}
}
override fun onCleared() {
session.cryptoService().verificationService().removeListener(this)
super.onCleared()
}
override fun handle(action: EmptyAction) {}
}

View File

@ -31,7 +31,6 @@ import im.vector.app.features.crypto.verification.VerificationBottomSheetViewMod
import javax.inject.Inject
class VerificationEmojiCodeFragment @Inject constructor(
val viewModelFactory: VerificationEmojiCodeViewModel.Factory,
val controller: VerificationEmojiCodeController
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
VerificationEmojiCodeController.Listener {

View File

@ -17,7 +17,6 @@ package im.vector.app.features.crypto.verification.emoji
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
@ -27,7 +26,10 @@ import com.airbnb.mvrx.ViewModelContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.core.di.HasScreenInjector
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.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
@ -151,20 +153,15 @@ class VerificationEmojiCodeViewModel @AssistedInject constructor(
}
@AssistedFactory
interface Factory {
fun create(initialState: VerificationEmojiCodeViewState): VerificationEmojiCodeViewModel
interface Factory : MavericksAssistedViewModelFactory<VerificationEmojiCodeViewModel, VerificationEmojiCodeViewState> {
override fun create(initialState: VerificationEmojiCodeViewState): VerificationEmojiCodeViewModel
}
companion object : MavericksViewModelFactory<VerificationEmojiCodeViewModel, VerificationEmojiCodeViewState> {
override fun create(viewModelContext: ViewModelContext, state: VerificationEmojiCodeViewState): VerificationEmojiCodeViewModel? {
val factory = (viewModelContext as FragmentViewModelContext).fragment<VerificationEmojiCodeFragment>().viewModelFactory
return factory.create(state)
}
companion object : MavericksViewModelFactory<VerificationEmojiCodeViewModel, VerificationEmojiCodeViewState> by hiltMavericksViewModelFactory() {
override fun initialState(viewModelContext: ViewModelContext): VerificationEmojiCodeViewState? {
val args = viewModelContext.args<VerificationBottomSheet.VerificationArgs>()
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession()
val matrixItem = session.getUser(args.otherUserId)?.toMatrixItem()
return VerificationEmojiCodeViewState(

View File

@ -33,8 +33,8 @@ import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.viewModel
import com.airbnb.mvrx.withState
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.extensions.toMvRxBundle
@ -45,10 +45,9 @@ import kotlinx.parcelize.Parcelize
import org.billcarsonfr.jsonviewer.JSonViewerFragment
import javax.inject.Inject
class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Factory,
FragmentManager.OnBackStackChangedListener {
@AndroidEntryPoint
class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStackChangedListener {
@Inject lateinit var viewModelFactory: RoomDevToolViewModel.Factory
@Inject lateinit var colorProvider: ColorProvider
// private lateinit var viewModel: RoomDevToolViewModel
@ -65,15 +64,6 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto
val roomId: String
) : Parcelable
override fun injectWith(injector: ScreenComponent) {
super.injectWith(injector)
injector.inject(this)
}
override fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel {
return viewModelFactory.create(initialState)
}
override fun initUiAndData() {
super.initUiAndData()
viewModel.subscribe(this) {

View File

@ -16,19 +16,17 @@
package im.vector.app.features.devtools
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.ViewModelContext
import com.squareup.moshi.Types
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.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
@ -51,21 +49,11 @@ class RoomDevToolViewModel @AssistedInject constructor(
) : VectorViewModel<RoomDevToolViewState, RoomDevToolAction, DevToolsViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel
interface Factory : MavericksAssistedViewModelFactory<RoomDevToolViewModel, RoomDevToolViewState> {
override fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel
}
companion object : MavericksViewModelFactory<RoomDevToolViewModel, RoomDevToolViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: RoomDevToolViewState): RoomDevToolViewModel {
val factory = when (viewModelContext) {
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
is ActivityViewModelContext -> viewModelContext.activity as? Factory
}
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
}
}
companion object : MavericksViewModelFactory<RoomDevToolViewModel, RoomDevToolViewState> by hiltMavericksViewModelFactory()
init {
session.getRoom(initialState.roomId)

View File

@ -45,8 +45,7 @@ import org.matrix.android.sdk.api.session.terms.TermsService
import javax.inject.Inject
class DiscoverySettingsFragment @Inject constructor(
private val controller: DiscoverySettingsController,
val viewModelFactory: DiscoverySettingsViewModel.Factory
private val controller: DiscoverySettingsController
) : VectorBaseFragment<FragmentGenericRecyclerBinding>(),
DiscoverySettingsController.Listener {

View File

@ -17,16 +17,16 @@ package im.vector.app.features.discovery
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.Loading
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
@ -49,18 +49,11 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
) : VectorViewModel<DiscoverySettingsState, DiscoverySettingsAction, DiscoverySettingsViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: DiscoverySettingsState): DiscoverySettingsViewModel
interface Factory : MavericksAssistedViewModelFactory<DiscoverySettingsViewModel, DiscoverySettingsState> {
override fun create(initialState: DiscoverySettingsState): DiscoverySettingsViewModel
}
companion object : MavericksViewModelFactory<DiscoverySettingsViewModel, DiscoverySettingsState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: DiscoverySettingsState): DiscoverySettingsViewModel? {
val fragment: DiscoverySettingsFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.viewModelFactory.create(state)
}
}
companion object : MavericksViewModelFactory<DiscoverySettingsViewModel, DiscoverySettingsState> by hiltMavericksViewModelFactory()
private val identityService = session.identityService()
private val termsService: TermsService = session

View File

@ -41,7 +41,6 @@ import org.matrix.android.sdk.api.session.terms.TermsService
import javax.inject.Inject
class SetIdentityServerFragment @Inject constructor(
val viewModelFactory: SetIdentityServerViewModel.Factory,
val colorProvider: ColorProvider
) : VectorBaseFragment<FragmentSetIdentityServerBinding>() {

View File

@ -15,15 +15,16 @@
*/
package im.vector.app.features.discovery.change
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.hilt.EntryPoints
import im.vector.app.R
import im.vector.app.core.di.HasScreenInjector
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 im.vector.app.core.resources.StringProvider
@ -42,26 +43,19 @@ class SetIdentityServerViewModel @AssistedInject constructor(
VectorViewModel<SetIdentityServerState, SetIdentityServerAction, SetIdentityServerViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: SetIdentityServerState): SetIdentityServerViewModel
interface Factory : MavericksAssistedViewModelFactory<SetIdentityServerViewModel, SetIdentityServerState> {
override fun create(initialState: SetIdentityServerState): SetIdentityServerViewModel
}
companion object : MavericksViewModelFactory<SetIdentityServerViewModel, SetIdentityServerState> {
override fun initialState(viewModelContext: ViewModelContext): SetIdentityServerState? {
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
companion object : MavericksViewModelFactory<SetIdentityServerViewModel, SetIdentityServerState> by hiltMavericksViewModelFactory() {
override fun initialState(viewModelContext: ViewModelContext): SetIdentityServerState {
val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession()
return SetIdentityServerState(
homeServerUrl = session.sessionParams.homeServerUrl,
defaultIdentityServerUrl = session.identityService().getDefaultIdentityServer()
)
}
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: SetIdentityServerState): SetIdentityServerViewModel? {
val fragment: SetIdentityServerFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.viewModelFactory.create(state)
}
}
var currentWantedUrl: String? = null

View File

@ -34,10 +34,10 @@ import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.viewModel
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.AppStateHandler
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.registerStartForActivityResult
@ -72,7 +72,6 @@ import im.vector.app.features.spaces.invite.SpaceInviteBottomSheet
import im.vector.app.features.spaces.share.ShareSpaceBottomSheet
import im.vector.app.features.themes.ThemeUtils
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
import im.vector.app.push.fcm.FcmHelper
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
@ -91,13 +90,10 @@ data class HomeActivityArgs(
val inviteNotificationRoomId: String? = null
) : Parcelable
@AndroidEntryPoint
class HomeActivity :
VectorBaseActivity<ActivityHomeBinding>(),
ToolbarConfigurable,
UnknownDeviceDetectorSharedViewModel.Factory,
ServerBackupStatusViewModel.Factory,
UnreadMessagesSharedViewModel.Factory,
PromoteRestrictedViewModel.Factory,
NavigationInterceptor,
SpaceInviteBottomSheet.InteractionListener,
MatrixToBottomSheet.InteractionListener {
@ -105,11 +101,8 @@ 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()
@Inject lateinit var serverBackupviewModelFactory: ServerBackupStatusViewModel.Factory
@Inject lateinit var promoteRestrictedViewModelFactory: PromoteRestrictedViewModel.Factory
private val promoteRestrictedViewModel: PromoteRestrictedViewModel by viewModel()
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
@ -119,8 +112,6 @@ class HomeActivity :
@Inject lateinit var vectorPreferences: VectorPreferences
@Inject lateinit var popupAlertManager: PopupAlertManager
@Inject lateinit var shortcutsHandler: ShortcutsHandler
@Inject lateinit var unknownDeviceViewModelFactory: UnknownDeviceDetectorSharedViewModel.Factory
@Inject lateinit var unreadMessagesSharedViewModelFactory: UnreadMessagesSharedViewModel.Factory
@Inject lateinit var permalinkHandler: PermalinkHandler
@Inject lateinit var avatarRenderer: AvatarRenderer
@Inject lateinit var initSyncStepFormatter: InitSyncStepFormatter
@ -175,22 +166,6 @@ class HomeActivity :
override fun getBinding() = ActivityHomeBinding.inflate(layoutInflater)
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun create(initialState: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel {
return unknownDeviceViewModelFactory.create(initialState)
}
override fun create(initialState: ServerBackupStatusViewState): ServerBackupStatusViewModel {
return serverBackupviewModelFactory.create(initialState)
}
override fun create(initialState: UnreadMessagesState): UnreadMessagesSharedViewModel {
return unreadMessagesSharedViewModelFactory.create(initialState)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
@ -590,8 +565,6 @@ class HomeActivity :
}
}
override fun create(initialState: ActiveSpaceViewState) = promoteRestrictedViewModelFactory.create(initialState)
override fun mxToBottomSheetNavigateToRoom(roomId: String) {
navigator.openRoom(this, roomId)
}

View File

@ -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

View File

@ -57,15 +57,12 @@ import im.vector.app.features.settings.VectorSettingsActivity.Companion.EXTRA_DI
import im.vector.app.features.themes.ThemeUtils
import im.vector.app.features.workers.signout.BannerState
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
import org.matrix.android.sdk.api.session.group.model.GroupSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import javax.inject.Inject
class HomeDetailFragment @Inject constructor(
val homeDetailViewModelFactory: HomeDetailViewModel.Factory,
private val serverBackupStatusViewModelFactory: ServerBackupStatusViewModel.Factory,
private val avatarRenderer: AvatarRenderer,
private val colorProvider: ColorProvider,
private val alertManager: PopupAlertManager,
@ -74,8 +71,7 @@ class HomeDetailFragment @Inject constructor(
private val appStateHandler: AppStateHandler
) : VectorBaseFragment<FragmentHomeDetailBinding>(),
KeysBackupBanner.Delegate,
CurrentCallsView.Callback,
ServerBackupStatusViewModel.Factory {
CurrentCallsView.Callback {
private val viewModel: HomeDetailViewModel by fragmentViewModel()
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
@ -503,8 +499,4 @@ class HomeDetailFragment @Inject constructor(
}
return this
}
override fun create(initialState: ServerBackupStatusViewState): ServerBackupStatusViewModel {
return serverBackupStatusViewModelFactory.create(initialState)
}
}

View File

@ -17,7 +17,6 @@
package im.vector.app.features.home
import androidx.lifecycle.asFlow
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MavericksViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import dagger.assisted.Assisted
@ -25,7 +24,9 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import im.vector.app.AppStateHandler
import im.vector.app.RoomGroupingMethod
import im.vector.app.core.di.HasScreenInjector
import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.extensions.singletonEntryPoint
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.call.dialpad.DialPadLookup
import im.vector.app.features.call.lookup.CallProtocolsChecker
@ -69,24 +70,18 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
CallProtocolsChecker.Listener {
@AssistedFactory
interface Factory {
fun create(initialState: HomeDetailViewState): HomeDetailViewModel
interface Factory : MavericksAssistedViewModelFactory<HomeDetailViewModel, HomeDetailViewState> {
override fun create(initialState: HomeDetailViewState): HomeDetailViewModel
}
companion object : MavericksViewModelFactory<HomeDetailViewModel, HomeDetailViewState> {
companion object : MavericksViewModelFactory<HomeDetailViewModel, HomeDetailViewState> by hiltMavericksViewModelFactory() {
override fun initialState(viewModelContext: ViewModelContext): HomeDetailViewState? {
val uiStateRepository = (viewModelContext.activity as HasScreenInjector).injector().uiStateRepository()
override fun initialState(viewModelContext: ViewModelContext): HomeDetailViewState {
val uiStateRepository = viewModelContext.activity.singletonEntryPoint().uiStateRepository()
return HomeDetailViewState(
currentTab = HomeTab.RoomList(uiStateRepository.getDisplayMode())
)
}
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: HomeDetailViewState): HomeDetailViewModel? {
val fragment: HomeDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.homeDetailViewModelFactory.create(state)
}
}
init {

View File

@ -19,9 +19,11 @@ package im.vector.app.features.home
import android.os.Handler
import dagger.Module
import dagger.Provides
import dagger.hilt.migration.DisableInstallInCheck
import im.vector.app.features.home.room.detail.timeline.TimelineEventControllerHandler
import im.vector.app.features.home.room.detail.timeline.helper.TimelineAsyncHelper
@DisableInstallInCheck
@Module
object HomeModule {

View File

@ -16,17 +16,16 @@
package im.vector.app.features.home
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MavericksState
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.AppStateHandler
import im.vector.app.RoomGroupingMethod
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.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
@ -72,21 +71,11 @@ class PromoteRestrictedViewModel @AssistedInject constructor(
}
@AssistedFactory
interface Factory {
fun create(initialState: ActiveSpaceViewState): PromoteRestrictedViewModel
interface Factory : MavericksAssistedViewModelFactory<PromoteRestrictedViewModel, ActiveSpaceViewState> {
override fun create(initialState: ActiveSpaceViewState): PromoteRestrictedViewModel
}
companion object : MavericksViewModelFactory<PromoteRestrictedViewModel, ActiveSpaceViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: ActiveSpaceViewState): PromoteRestrictedViewModel? {
val factory = when (viewModelContext) {
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
is ActivityViewModelContext -> viewModelContext.activity as? Factory
}
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
}
}
companion object : MavericksViewModelFactory<PromoteRestrictedViewModel, ActiveSpaceViewState> by hiltMavericksViewModelFactory()
override fun handle(action: EmptyAction) {}
}

View File

@ -16,17 +16,16 @@
package im.vector.app.features.home
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.FragmentViewModelContext
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.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.platform.VectorViewModelAction
@ -66,21 +65,11 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
}
@AssistedFactory
interface Factory {
fun create(initialState: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel
interface Factory : MavericksAssistedViewModelFactory<UnknownDeviceDetectorSharedViewModel, UnknownDevicesState> {
override fun create(initialState: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel
}
companion object : MavericksViewModelFactory<UnknownDeviceDetectorSharedViewModel, UnknownDevicesState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel? {
val factory = when (viewModelContext) {
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
is ActivityViewModelContext -> viewModelContext.activity as? Factory
}
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
}
}
companion object : MavericksViewModelFactory<UnknownDeviceDetectorSharedViewModel, UnknownDevicesState> by hiltMavericksViewModelFactory()
private val ignoredDeviceList = ArrayList<String>()

View File

@ -16,16 +16,15 @@
package im.vector.app.features.home
import com.airbnb.mvrx.ActivityViewModelContext
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MavericksState
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.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.platform.EmptyAction
import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel
@ -61,21 +60,11 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia
VectorViewModel<UnreadMessagesState, EmptyAction, EmptyViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: UnreadMessagesState): UnreadMessagesSharedViewModel
interface Factory : MavericksAssistedViewModelFactory<UnreadMessagesSharedViewModel, UnreadMessagesState> {
override fun create(initialState: UnreadMessagesState): UnreadMessagesSharedViewModel
}
companion object : MavericksViewModelFactory<UnreadMessagesSharedViewModel, UnreadMessagesState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: UnreadMessagesState): UnreadMessagesSharedViewModel? {
val factory = when (viewModelContext) {
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
is ActivityViewModelContext -> viewModelContext.activity as? Factory
}
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
}
}
companion object : MavericksViewModelFactory<UnreadMessagesSharedViewModel, UnreadMessagesState> by hiltMavericksViewModelFactory()
override fun handle(action: EmptyAction) {}

View File

@ -31,8 +31,7 @@ import im.vector.app.features.home.room.detail.RoomDetailSharedActionViewModel
import javax.inject.Inject
class BreadcrumbsFragment @Inject constructor(
private val breadcrumbsController: BreadcrumbsController,
val breadcrumbsViewModelFactory: BreadcrumbsViewModel.Factory
private val breadcrumbsController: BreadcrumbsController
) : VectorBaseFragment<FragmentBreadcrumbsBinding>(),
BreadcrumbsController.Listener {

View File

@ -16,12 +16,12 @@
package im.vector.app.features.home.room.breadcrumbs
import com.airbnb.mvrx.FragmentViewModelContext
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
@ -33,21 +33,14 @@ import org.matrix.android.sdk.flow.flow
class BreadcrumbsViewModel @AssistedInject constructor(@Assisted initialState: BreadcrumbsViewState,
private val session: Session) :
VectorViewModel<BreadcrumbsViewState, EmptyAction, EmptyViewEvents>(initialState) {
VectorViewModel<BreadcrumbsViewState, EmptyAction, EmptyViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: BreadcrumbsViewState): BreadcrumbsViewModel
interface Factory : MavericksAssistedViewModelFactory<BreadcrumbsViewModel, BreadcrumbsViewState> {
override fun create(initialState: BreadcrumbsViewState): BreadcrumbsViewModel
}
companion object : MavericksViewModelFactory<BreadcrumbsViewModel, BreadcrumbsViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: BreadcrumbsViewState): BreadcrumbsViewModel? {
val fragment: BreadcrumbsFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.breadcrumbsViewModelFactory.create(state)
}
}
companion object : MavericksViewModelFactory<BreadcrumbsViewModel, BreadcrumbsViewState> by hiltMavericksViewModelFactory()
init {
observeBreadcrumbs()

View File

@ -25,8 +25,8 @@ import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.parentFragmentViewModel
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.platform.ButtonStateView
@ -34,6 +34,7 @@ import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.databinding.BottomSheetTombstoneJoinBinding
import javax.inject.Inject
@AndroidEntryPoint
class JoinReplacementRoomBottomSheet :
VectorBaseBottomSheetDialogFragment<BottomSheetTombstoneJoinBinding>() {
@ -43,10 +44,6 @@ class JoinReplacementRoomBottomSheet :
@Inject
lateinit var errorFormatter: ErrorFormatter
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
private val viewModel: RoomDetailViewModel by parentFragmentViewModel()
override val showExpanded: Boolean

View File

@ -24,10 +24,11 @@ import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.viewModel
import com.google.android.material.appbar.MaterialToolbar
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.ToolbarConfigurable
@ -39,16 +40,11 @@ import im.vector.app.features.navigation.Navigator
import im.vector.app.features.room.RequireActiveMembershipAction
import im.vector.app.features.room.RequireActiveMembershipViewEvents
import im.vector.app.features.room.RequireActiveMembershipViewModel
import im.vector.app.features.room.RequireActiveMembershipViewState
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewModel
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewState
import javax.inject.Inject
@AndroidEntryPoint
class RoomDetailActivity :
VectorBaseActivity<ActivityRoomDetailBinding>(),
ToolbarConfigurable,
RequireActiveMembershipViewModel.Factory,
RoomWidgetPermissionViewModel.Factory,
MatrixToBottomSheet.InteractionListener {
override fun getBinding(): ActivityRoomDetailBinding {
@ -77,24 +73,6 @@ class RoomDetailActivity :
private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel
private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel()
@Inject
lateinit var requireActiveMembershipViewModelFactory: RequireActiveMembershipViewModel.Factory
override fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel {
// Due to shortcut, we cannot use MvRx args. Pass the first roomId here
return requireActiveMembershipViewModelFactory.create(initialState.copy(roomId = currentRoomId ?: ""))
}
@Inject
lateinit var permissionsViewModelFactory: RoomWidgetPermissionViewModel.Factory
override fun create(initialState: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel {
return permissionsViewModelFactory.create(initialState)
}
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
// Simple filter
var currentRoomId: String? = null
@ -108,6 +86,7 @@ class RoomDetailActivity :
intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS)
}
if (roomDetailArgs == null) return
intent.putExtra(Mavericks.KEY_ARG, roomDetailArgs)
currentRoomId = roomDetailArgs.roomId
if (isFirstCreation()) {

View File

@ -237,7 +237,6 @@ class RoomDetailFragment @Inject constructor(
private val permalinkHandler: PermalinkHandler,
private val notificationDrawerManager: NotificationDrawerManager,
val roomDetailViewModelFactory: RoomDetailViewModel.Factory,
val textComposerViewModelFactory: TextComposerViewModel.Factory,
private val eventHtmlRenderer: EventHtmlRenderer,
private val vectorPreferences: VectorPreferences,
private val colorProvider: ColorProvider,

View File

@ -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)
}
}

View File

@ -16,20 +16,19 @@
package im.vector.app.features.home.room.detail.composer
import com.airbnb.mvrx.FragmentViewModelContext
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.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
import im.vector.app.features.command.CommandParser
import im.vector.app.features.command.ParsedCommand
import im.vector.app.features.home.room.detail.ChatEffect
import im.vector.app.features.home.room.detail.RoomDetailFragment
import im.vector.app.features.home.room.detail.composer.rainbow.RainbowGenerator
import im.vector.app.features.home.room.detail.toMessageType
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
@ -710,16 +709,9 @@ class TextComposerViewModel @AssistedInject constructor(
}
@AssistedFactory
interface Factory {
fun create(initialState: TextComposerViewState): TextComposerViewModel
interface Factory : MavericksAssistedViewModelFactory<TextComposerViewModel, TextComposerViewState> {
override fun create(initialState: TextComposerViewState): TextComposerViewModel
}
companion object : MavericksViewModelFactory<TextComposerViewModel, TextComposerViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: TextComposerViewState): TextComposerViewModel {
val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.textComposerViewModelFactory.create(state)
}
}
companion object : MavericksViewModelFactory<TextComposerViewModel, TextComposerViewState> by hiltMavericksViewModelFactory()
}

View File

@ -23,8 +23,8 @@ import android.view.View
import android.view.ViewGroup
import com.airbnb.mvrx.Mavericks
import com.airbnb.mvrx.args
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
@ -43,6 +43,7 @@ data class DisplayReadReceiptArgs(
/**
* Bottom sheet displaying list of read receipts for a given event ordered by descending timestamp
*/
@AndroidEntryPoint
class DisplayReadReceiptsBottomSheet :
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListWithTitleBinding>(),
DisplayReadReceiptsController.Listener {
@ -53,10 +54,6 @@ class DisplayReadReceiptsBottomSheet :
private lateinit var sharedActionViewModel: MessageSharedActionViewModel
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding {
return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false)
}

View File

@ -21,12 +21,13 @@ import android.content.Intent
import android.os.Bundle
import androidx.appcompat.widget.SearchView
import com.airbnb.mvrx.Mavericks
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.R
import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySearchBinding
@AndroidEntryPoint
class SearchActivity : VectorBaseActivity<ActivitySearchBinding>() {
private val searchFragment: SearchFragment?
@ -38,10 +39,6 @@ class SearchActivity : VectorBaseActivity<ActivitySearchBinding>() {
override fun getCoordinatorLayout() = views.coordinatorLayout
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
configureToolbar(views.searchToolbar)

View File

@ -47,7 +47,6 @@ data class SearchArgs(
) : Parcelable
class SearchFragment @Inject constructor(
val viewModelFactory: SearchViewModel.Factory,
private val controller: SearchResultController
) : VectorBaseFragment<FragmentSearchBinding>(),
StateView.EventCallback,

View File

@ -16,16 +16,15 @@
package im.vector.app.features.home.room.detail.search
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.FragmentViewModelContext
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.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 kotlinx.coroutines.CancellationException
@ -46,18 +45,11 @@ class SearchViewModel @AssistedInject constructor(
private var nextBatch: String? = null
@AssistedFactory
interface Factory {
fun create(initialState: SearchViewState): SearchViewModel
interface Factory : MavericksAssistedViewModelFactory<SearchViewModel, SearchViewState> {
override fun create(initialState: SearchViewState): SearchViewModel
}
companion object : MavericksViewModelFactory<SearchViewModel, SearchViewState> {
@JvmStatic
override fun create(viewModelContext: ViewModelContext, state: SearchViewState): SearchViewModel? {
val fragment: SearchFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.viewModelFactory.create(state)
}
}
companion object : MavericksViewModelFactory<SearchViewModel, SearchViewState> by hiltMavericksViewModelFactory()
override fun handle(action: SearchAction) {
when (action) {

View File

@ -21,7 +21,7 @@ import android.view.View
import android.view.ViewGroup
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.withState
import im.vector.app.core.di.ScreenComponent
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
@ -32,11 +32,11 @@ import javax.inject.Inject
/**
* Bottom sheet fragment that shows a message preview with list of contextual actions
*/
@AndroidEntryPoint
class MessageActionsBottomSheet :
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListBinding>(),
MessageActionsEpoxyController.MessageActionsEpoxyControllerListener {
@Inject lateinit var messageActionViewModelFactory: MessageActionsViewModel.Factory
@Inject lateinit var messageActionsEpoxyController: MessageActionsEpoxyController
private val viewModel: MessageActionsViewModel by fragmentViewModel(MessageActionsViewModel::class)
@ -45,10 +45,6 @@ class MessageActionsBottomSheet :
private lateinit var sharedActionViewModel: MessageSharedActionViewModel
override fun injectWith(injector: ScreenComponent) {
injector.inject(this)
}
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding {
return BottomSheetGenericListBinding.inflate(inflater, container, false)
}

Some files were not shown because too many files have changed in this diff Show More