From cbcb620ad1d5a449949ad430bb63ee643d0959d8 Mon Sep 17 00:00:00 2001 From: yostyle Date: Thu, 7 Oct 2021 11:36:29 +0200 Subject: [PATCH 001/413] Limit supported cipher suites --- changelog.d/4192.misc | 1 + .../android/sdk/api/MatrixConfiguration.kt | 5 +++++ .../auth/data/HomeServerConnectionConfig.kt | 18 ++++++------------ .../android/sdk/internal/di/NetworkModule.kt | 5 +++++ .../sdk/internal/network/ssl/CertUtil.kt | 14 ++++++-------- 5 files changed, 23 insertions(+), 20 deletions(-) create mode 100644 changelog.d/4192.misc diff --git a/changelog.d/4192.misc b/changelog.d/4192.misc new file mode 100644 index 0000000000..3587e3cb7c --- /dev/null +++ b/changelog.d/4192.misc @@ -0,0 +1 @@ +Limit supported TLS versions and cipher suites \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt index 3359e253f6..306ed45500 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.api +import okhttp3.ConnectionSpec import org.matrix.android.sdk.api.crypto.MXCryptoConfig import java.net.Proxy @@ -44,6 +45,10 @@ data class MatrixConfiguration( * You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port). */ val proxy: Proxy? = null, + /** + * TLS versions and cipher suites limitation for unauthenticated requests + */ + val connectionSpec: ConnectionSpec = ConnectionSpec.RESTRICTED_TLS, /** * True to advertise support for call transfers to other parties on Matrix calls. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt index 215f0a0351..e87824d6a5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.auth.data import android.net.Uri import com.squareup.moshi.JsonClass import okhttp3.CipherSuite +import okhttp3.ConnectionSpec import okhttp3.TlsVersion import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig.Builder import org.matrix.android.sdk.internal.network.ssl.Fingerprint @@ -191,32 +192,25 @@ data class HomeServerConnectionConfig( /** * Convenient method to limit the TLS versions and cipher suites for this Builder * Ref: - * - https://www.ssi.gouv.fr/uploads/2017/02/security-recommendations-for-tls_v1.1.pdf + * - https://www.ssi.gouv.fr/uploads/2017/07/anssi-guide-recommandations_de_securite_relatives_a_tls-v1.2.pdf * - https://developer.android.com/reference/javax/net/ssl/SSLEngine * * @param tlsLimitations true to use Tls limitations * @param enableCompatibilityMode set to true for Android < 20 * @return this builder */ + @Deprecated("TLS versions and cipher suites are limited by default") fun withTlsLimitations(tlsLimitations: Boolean, enableCompatibilityMode: Boolean): Builder { if (tlsLimitations) { withShouldAcceptTlsExtensions(false) - // Tls versions - addAcceptedTlsVersion(TlsVersion.TLS_1_2) - addAcceptedTlsVersion(TlsVersion.TLS_1_3) + // TlS versions + ConnectionSpec.RESTRICTED_TLS.tlsVersions?.let { this.tlsVersions.addAll(it) } forceUsageOfTlsVersions(enableCompatibilityMode) // Cipher suites - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) + ConnectionSpec.RESTRICTED_TLS.cipherSuites?.let { this.tlsCipherSuites.addAll(it) } if (enableCompatibilityMode) { // Adopt some preceding cipher suites for Android < 20 to be able to negotiate diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt index fa59b94c17..ad34a4d8a6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt @@ -20,6 +20,7 @@ import com.facebook.stetho.okhttp3.StethoInterceptor import com.squareup.moshi.Moshi import dagger.Module import dagger.Provides +import okhttp3.ConnectionSpec import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import org.matrix.android.sdk.BuildConfig @@ -29,6 +30,7 @@ import org.matrix.android.sdk.internal.network.TimeOutInterceptor import org.matrix.android.sdk.internal.network.UserAgentInterceptor import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor import org.matrix.android.sdk.internal.network.interceptors.FormattedJsonHttpLogger +import java.util.Collections import java.util.concurrent.TimeUnit @Module @@ -66,6 +68,8 @@ internal object NetworkModule { httpLoggingInterceptor: HttpLoggingInterceptor, curlLoggingInterceptor: CurlLoggingInterceptor, apiInterceptor: ApiInterceptor): OkHttpClient { + val spec = ConnectionSpec.Builder(matrixConfiguration.connectionSpec).build() + return OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) @@ -87,6 +91,7 @@ internal object NetworkModule { proxy(it) } } + .connectionSpecs(Collections.singletonList(spec)) .build() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt index 92c7f3f236..d8bdc5fc2b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt @@ -177,15 +177,13 @@ internal object CertUtil { val trustPinned = arrayOf(PinnedTrustManagerProvider.provide(hsConfig.allowedFingerprints, defaultTrustManager)) - val sslSocketFactory: SSLSocketFactory - - if (hsConfig.forceUsageTlsVersions && hsConfig.tlsVersions != null) { + val sslSocketFactory = if (hsConfig.forceUsageTlsVersions && !hsConfig.tlsVersions.isNullOrEmpty()) { // Force usage of accepted Tls Versions for Android < 20 - sslSocketFactory = TLSSocketFactory(trustPinned, hsConfig.tlsVersions) + TLSSocketFactory(trustPinned, hsConfig.tlsVersions) } else { val sslContext = SSLContext.getInstance("TLS") sslContext.init(null, trustPinned, java.security.SecureRandom()) - sslSocketFactory = sslContext.socketFactory + sslContext.socketFactory } return PinnedSSLSocketFactory(sslSocketFactory, defaultTrustManager!!) @@ -237,14 +235,14 @@ internal object CertUtil { * @return a list of accepted TLS specifications. */ fun newConnectionSpecs(hsConfig: HomeServerConnectionConfig): List { - val builder = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + val builder = ConnectionSpec.Builder(ConnectionSpec.RESTRICTED_TLS) val tlsVersions = hsConfig.tlsVersions - if (null != tlsVersions && tlsVersions.isNotEmpty()) { + if (!tlsVersions.isNullOrEmpty()) { builder.tlsVersions(*tlsVersions.toTypedArray()) } val tlsCipherSuites = hsConfig.tlsCipherSuites - if (null != tlsCipherSuites && tlsCipherSuites.isNotEmpty()) { + if (!tlsCipherSuites.isNullOrEmpty()) { builder.cipherSuites(*tlsCipherSuites.toTypedArray()) } From ff53cf4db996696d7cd2085aa75b90c599add796 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Oct 2021 18:47:28 +0200 Subject: [PATCH 002/413] Hilt: replace the VectorComponent --- build.gradle | 1 + dependencies.gradle | 8 +- vector/build.gradle | 5 +- .../java/im/vector/app/VectorApplication.kt | 21 +-- ...orComponent.kt => AggregatorEntryPoint.kt} | 27 +--- .../im/vector/app/core/di/FragmentModule.kt | 2 + .../vector/app/core/di/HasVectorInjector.kt | 2 +- .../im/vector/app/core/di/ScreenComponent.kt | 150 +++++++++++++++++- .../im/vector/app/core/di/ScreenModule.kt | 2 + .../im/vector/app/core/di/VectorModule.kt | 145 +++++++++-------- .../im/vector/app/core/di/ViewModelModule.kt | 2 + .../im/vector/app/core/extensions/Context.kt | 4 +- .../app/core/platform/VectorBaseActivity.kt | 11 +- .../VectorBaseBottomSheetDialogFragment.kt | 7 +- .../app/core/platform/VectorBaseFragment.kt | 7 +- .../im/vector/app/features/home/HomeModule.kt | 2 + .../features/home/room/list/RoomListModule.kt | 2 + .../media/VectorAttachmentViewerActivity.kt | 20 +-- .../NotificationBroadcastReceiver.kt | 3 +- .../settings/VectorSettingsBaseFragment.kt | 7 +- 20 files changed, 299 insertions(+), 129 deletions(-) rename vector/src/main/java/im/vector/app/core/di/{VectorComponent.kt => AggregatorEntryPoint.kt} (90%) diff --git a/build.gradle b/build.gradle index 93f3e17f34..e9045b99c7 100644 --- a/build.gradle +++ b/build.gradle @@ -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' diff --git a/dependencies.gradle b/dependencies.gradle index 1e3c492149..873aec162b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -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 : [ 'kotlinStdlibJdk7' : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin", @@ -74,7 +76,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", diff --git a/vector/build.gradle b/vector/build.gradle index d06779d61c..84cc706fa1 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -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 @@ -457,8 +458,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') { diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index c2fd4c92be..093362991f 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -39,10 +39,11 @@ import com.facebook.stetho.Stetho import com.gabrielittner.threetenbp.LazyThreeTen import com.vanniktech.emoji.EmojiManager import com.vanniktech.emoji.google.GoogleEmojiProvider +import dagger.hilt.EntryPoints +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.AggregatorEntryPoint 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 @@ -75,6 +76,7 @@ import java.util.concurrent.Executors import javax.inject.Inject import androidx.work.Configuration as WorkConfiguration +@HiltAndroidApp class VectorApplication : Application(), HasVectorInjector, @@ -100,8 +102,6 @@ class VectorApplication : @Inject lateinit var callManager: WebRtcCallManager @Inject lateinit var invitesAcceptor: InvitesAcceptor - lateinit var vectorComponent: VectorComponent - // font thread handler private var fontThreadHandler: Handler? = null @@ -114,12 +114,15 @@ class VectorApplication : } } + fun component(): AggregatorEntryPoint { + // Use EntryPoints to get an instance of the AggregatorEntryPoint. + return EntryPoints.get(this, AggregatorEntryPoint::class.java) + } + override fun onCreate() { enableStrictModeIfNeeded() super.onCreate() appContext = this - vectorComponent = DaggerVectorComponent.factory().create(this) - vectorComponent.inject(this) invitesAcceptor.initialize() vectorUncaughtExceptionHandler.activate(this) rxConfig.setupRxPlugin() @@ -132,7 +135,7 @@ class VectorApplication : if (BuildConfig.DEBUG) { Timber.plant(Timber.DebugTree()) } - Timber.plant(vectorComponent.vectorFileLogger()) + Timber.plant(component().vectorFileLogger()) if (BuildConfig.DEBUG) { Stetho.initializeWithDefaults(this) @@ -236,8 +239,8 @@ class VectorApplication : .build() } - override fun injector(): VectorComponent { - return vectorComponent + override fun injector(): AggregatorEntryPoint { + return component() } private fun logInfo() { diff --git a/vector/src/main/java/im/vector/app/core/di/VectorComponent.kt b/vector/src/main/java/im/vector/app/core/di/AggregatorEntryPoint.kt similarity index 90% rename from vector/src/main/java/im/vector/app/core/di/VectorComponent.kt rename to vector/src/main/java/im/vector/app/core/di/AggregatorEntryPoint.kt index a8bf128367..034607f741 100644 --- a/vector/src/main/java/im/vector/app/core/di/VectorComponent.kt +++ b/vector/src/main/java/im/vector/app/core/di/AggregatorEntryPoint.kt @@ -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, @@ -18,13 +18,13 @@ package im.vector.app.core.di import android.content.Context import android.content.res.Resources -import dagger.BindsInstance -import dagger.Component +import dagger.hilt.EntryPoint +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent 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 @@ -47,7 +47,6 @@ 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 @@ -68,15 +67,10 @@ 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) +@InstallIn(SingletonComponent::class) +@EntryPoint +interface AggregatorEntryPoint { fun matrix(): Matrix @@ -175,9 +169,4 @@ interface VectorComponent { fun coroutineDispatchers(): CoroutineDispatchers fun jitsiActiveConferenceHolder(): JitsiActiveConferenceHolder - - @Component.Factory - interface Factory { - fun create(@BindsInstance context: Context): VectorComponent - } } diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 3bc8e30851..d943a3806f 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -21,6 +21,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentFactory import dagger.Binds import dagger.Module +import dagger.hilt.migration.DisableInstallInCheck import dagger.multibindings.IntoMap import im.vector.app.features.attachments.preview.AttachmentsPreviewFragment import im.vector.app.features.contactsbook.ContactsBookFragment @@ -157,6 +158,7 @@ import im.vector.app.features.usercode.ShowUserCodeFragment import im.vector.app.features.userdirectory.UserListFragment import im.vector.app.features.widgets.WidgetFragment +@DisableInstallInCheck @Module interface FragmentModule { /** diff --git a/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt b/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt index 79254defcc..fcd489146d 100644 --- a/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt +++ b/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt @@ -18,5 +18,5 @@ package im.vector.app.core.di interface HasVectorInjector { - fun injector(): VectorComponent + fun injector(): AggregatorEntryPoint } diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt index 76b511d2bd..022d66f113 100644 --- a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt @@ -16,58 +16,93 @@ package im.vector.app.core.di +import android.content.Context +import android.content.res.Resources import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.FragmentFactory import androidx.lifecycle.ViewModelProvider import dagger.BindsInstance import dagger.Component +import dagger.hilt.EntryPoint +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import im.vector.app.ActiveSessionDataSource +import im.vector.app.AppStateHandler +import im.vector.app.EmojiCompatFontProvider +import im.vector.app.EmojiCompatWrapper 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.preference.UserAvatarPreference +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.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.JitsiActiveConferenceHolder import im.vector.app.features.call.conference.VectorJitsiActivity import im.vector.app.features.call.transfer.CallTransferActivity +import im.vector.app.features.call.webrtc.WebRtcCallManager +import im.vector.app.features.configuration.VectorConfiguration 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.keysrequest.KeyRequestHandler import im.vector.app.features.crypto.quads.SharedSecureStorageActivity import im.vector.app.features.crypto.recover.BootstrapBottomSheet +import im.vector.app.features.crypto.verification.IncomingVerificationRequestHandler 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.AvatarRenderer +import im.vector.app.features.home.CurrentSpaceSuggestedRoomListDataSource 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.RoomDetailPendingActionStore 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.helper.MatrixItemColorProvider 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.html.EventHtmlRenderer +import im.vector.app.features.html.VectorHtmlCompressor 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.login.ReAuthHelper 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.notifications.NotifiableEventResolver +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.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.rageshake.VectorFileLogger +import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler import im.vector.app.features.reactions.EmojiReactionPickerActivity +import im.vector.app.features.reactions.data.EmojiDataSource import im.vector.app.features.reactions.widget.ReactionButton import im.vector.app.features.roomdirectory.RoomDirectoryActivity import im.vector.app.features.roomdirectory.createroom.CreateRoomActivity @@ -78,6 +113,9 @@ 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.session.SessionListener +import im.vector.app.features.settings.VectorDataStore +import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheet import im.vector.app.features.share.IncomingShareActivity @@ -98,10 +136,118 @@ 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 +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 + +@InstallIn(SingletonComponent::class) +@EntryPoint +interface ScreenComponentDependencies { + 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( dependencies = [ - VectorComponent::class + ScreenComponentDependencies::class ], modules = [ ViewModelModule::class, @@ -218,7 +364,7 @@ interface ScreenComponent { @Component.Factory interface Factory { - fun create(vectorComponent: VectorComponent, + fun create(deps: ScreenComponentDependencies, @BindsInstance context: AppCompatActivity ): ScreenComponent } diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenModule.kt b/vector/src/main/java/im/vector/app/core/di/ScreenModule.kt index 5f50f186d0..a7b5f2cd5c 100644 --- a/vector/src/main/java/im/vector/app/core/di/ScreenModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/ScreenModule.kt @@ -20,9 +20,11 @@ import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.RecyclerView import dagger.Module import dagger.Provides +import dagger.hilt.migration.DisableInstallInCheck import im.vector.app.core.glide.GlideApp @Module +@DisableInstallInCheck object ScreenModule { @Provides diff --git a/vector/src/main/java/im/vector/app/core/di/VectorModule.kt b/vector/src/main/java/im/vector/app/core/di/VectorModule.kt index ddb765cef8..e89a060022 100644 --- a/vector/src/main/java/im/vector/app/core/di/VectorModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/VectorModule.kt @@ -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) + } +} diff --git a/vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt index 4e07c1e2ca..783c8432a3 100644 --- a/vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt @@ -20,6 +20,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import dagger.Binds import dagger.Module +import dagger.hilt.migration.DisableInstallInCheck import dagger.multibindings.IntoMap import im.vector.app.core.platform.ConfigurationViewModel import im.vector.app.features.call.SharedKnownCallsViewModel @@ -42,6 +43,7 @@ import im.vector.app.features.spaces.SpacePreviewSharedActionViewModel import im.vector.app.features.spaces.people.SpacePeopleSharedActionViewModel import im.vector.app.features.userdirectory.UserListSharedActionViewModel +@DisableInstallInCheck @Module interface ViewModelModule { diff --git a/vector/src/main/java/im/vector/app/core/extensions/Context.kt b/vector/src/main/java/im/vector/app/core/extensions/Context.kt index c1c435edf2..3ecae79ced 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Context.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Context.kt @@ -17,10 +17,10 @@ package im.vector.app.core.extensions import android.content.Context +import im.vector.app.core.di.AggregatorEntryPoint import im.vector.app.core.di.HasVectorInjector -import im.vector.app.core.di.VectorComponent -fun Context.vectorComponent(): VectorComponent { +fun Context.vectorComponent(): AggregatorEntryPoint { val appContext = applicationContext if (appContext is HasVectorInjector) { return appContext.injector() diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index fbfba10d21..22648b3196 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -45,14 +45,16 @@ 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.EntryPoints import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.di.AggregatorEntryPoint 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.ScreenComponentDependencies import im.vector.app.core.dialogs.DialogLocker import im.vector.app.core.dialogs.UnrecognizedCertificateDialog import im.vector.app.core.extensions.exhaustive @@ -188,7 +190,10 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasSc override fun onCreate(savedInstanceState: Bundle?) { Timber.i("onCreate Activity ${javaClass.simpleName}") val vectorComponent = getVectorComponent() - screenComponent = DaggerScreenComponent.factory().create(vectorComponent, this) + val screenComponentDeps = EntryPoints.get( + applicationContext, + ScreenComponentDependencies::class.java) + screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, this) val timeForInjection = measureTimeMillis { injectWith(screenComponent) } @@ -419,7 +424,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasSc * PRIVATE METHODS * ========================================================================================== */ - internal fun getVectorComponent(): VectorComponent { + internal fun getVectorComponent(): AggregatorEntryPoint { return (application as HasVectorInjector).injector() } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index 68765d615e..90147604e5 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -33,8 +33,10 @@ 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 dagger.hilt.EntryPoints import im.vector.app.core.di.DaggerScreenComponent import im.vector.app.core.di.ScreenComponent +import im.vector.app.core.di.ScreenComponentDependencies import im.vector.app.core.utils.DimensionConverter import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -122,7 +124,10 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe } override fun onAttach(context: Context) { - screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity) + val screenComponentDeps = EntryPoints.get( + vectorBaseActivity.applicationContext, + ScreenComponentDependencies::class.java) + screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, vectorBaseActivity) viewModelFactory = screenComponent.viewModelFactory() super.onAttach(context) injectWith(screenComponent) diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index 64b55291fb..de36473507 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -35,10 +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.EntryPoints 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.ScreenComponentDependencies import im.vector.app.core.dialogs.UnrecognizedCertificateDialog import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.toMvRxBundle @@ -95,7 +97,10 @@ abstract class VectorBaseFragment : Fragment(), MavericksView, * ========================================================================================== */ override fun onAttach(context: Context) { - screenComponent = DaggerScreenComponent.factory().create(vectorBaseActivity.getVectorComponent(), vectorBaseActivity) + val screenComponentDeps = EntryPoints.get( + vectorBaseActivity.applicationContext, + ScreenComponentDependencies::class.java) + screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, vectorBaseActivity) navigator = screenComponent.navigator() errorFormatter = screenComponent.errorFormatter() unrecognizedCertificateDialog = screenComponent.unrecognizedCertificateDialog() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeModule.kt b/vector/src/main/java/im/vector/app/features/home/HomeModule.kt index 5c34d0715d..0782bbb573 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeModule.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeModule.kt @@ -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 { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListModule.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListModule.kt index 5dcef663e6..a708f86b67 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListModule.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListModule.kt @@ -18,7 +18,9 @@ package im.vector.app.features.home.room.list import dagger.Binds import dagger.Module +import dagger.hilt.migration.DisableInstallInCheck +@DisableInstallInCheck @Module abstract class RoomListModule { diff --git a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt index bc3acf3eec..c2d7cac507 100644 --- a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt @@ -30,12 +30,9 @@ import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.transition.Transition +import dagger.hilt.android.AndroidEntryPoint 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.HasVectorInjector -import im.vector.app.core.di.ScreenComponent -import im.vector.app.core.di.VectorComponent import im.vector.app.core.intent.getMimeTypeFromUri import im.vector.app.core.utils.shareMedia import im.vector.app.features.themes.ActivityOtherThemes @@ -48,8 +45,8 @@ import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize import timber.log.Timber import javax.inject.Inject -import kotlin.system.measureTimeMillis +@AndroidEntryPoint class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmentProvider.InteractionListener { @Parcelize @@ -61,14 +58,11 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen @Inject lateinit var sessionHolder: ActiveSessionHolder - @Inject lateinit var dataSourceFactory: AttachmentProviderFactory - @Inject lateinit var imageContentRenderer: ImageContentRenderer - private lateinit var screenComponent: ScreenComponent private var initialIndex = 0 private var isAnimatingOut = false @@ -78,12 +72,6 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Timber.i("onCreate Activity ${javaClass.simpleName}") - val vectorComponent = getVectorComponent() - screenComponent = DaggerScreenComponent.factory().create(vectorComponent, this) - val timeForInjection = measureTimeMillis { - screenComponent.inject(this) - } - Timber.v("Injecting dependencies into ${javaClass.simpleName} took $timeForInjection ms") ThemeUtils.setActivityTheme(this, getOtherThemes()) val args = args() ?: throw IllegalArgumentException("Missing arguments") @@ -220,10 +208,6 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen private fun args() = intent.getParcelableExtra(EXTRA_ARGS) - private fun getVectorComponent(): VectorComponent { - return (application as HasVectorInjector).injector() - } - private fun scheduleStartPostponedTransition(sharedElement: View) { sharedElement.viewTreeObserver.addOnPreDrawListener( object : ViewTreeObserver.OnPreDrawListener { diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt index 2c4cdab25e..5f78ac8286 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt @@ -20,6 +20,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import androidx.core.app.RemoteInput +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.extensions.vectorComponent @@ -36,6 +37,7 @@ import javax.inject.Inject /** * Receives actions broadcast by notification (on click, on dismiss, inline replies, etc.) */ +@AndroidEntryPoint class NotificationBroadcastReceiver : BroadcastReceiver() { @Inject lateinit var notificationDrawerManager: NotificationDrawerManager @@ -44,7 +46,6 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent == null || context == null) return Timber.v("NotificationBroadcastReceiver received : $intent") - context.vectorComponent().inject(this) when (intent.action) { NotificationUtils.SMART_REPLY_ACTION -> handleSmartReply(intent, context) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index efbd1cd1b4..36af0f906d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -22,10 +22,12 @@ import android.view.View import androidx.annotation.CallSuper import androidx.preference.PreferenceFragmentCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder +import dagger.hilt.EntryPoints 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.ScreenComponentDependencies import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast @@ -56,7 +58,10 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScree } override fun onAttach(context: Context) { - screenComponent = DaggerScreenComponent.factory().create(vectorActivity.getVectorComponent(), vectorActivity) + val screenComponentDeps = EntryPoints.get( + vectorActivity.applicationContext, + ScreenComponentDependencies::class.java) + screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, vectorActivity) super.onAttach(context) session = screenComponent.activeSessionHolder().getActiveSession() errorFormatter = screenComponent.errorFormatter() From f8d208fb4f9ccf4ce76737675cc81a88c1951a15 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 15 Oct 2021 10:27:45 +0200 Subject: [PATCH 003/413] Hilt: introduce MavericksComponent and try on RoomList --- .../core/di/HiltMavericksViewModelFactory.kt | 88 +++++++++++++++++++ .../di/MavericksAssistedViewModelFactory.kt | 40 +++++++++ .../di/MavericksViewModelModule.kt} | 14 +-- .../app/core/di/MavericksViewModelScoped.kt | 25 ++++++ .../im/vector/app/core/di/ScreenComponent.kt | 2 - .../im/vector/app/core/di/ViewModelKey.kt | 6 ++ .../home/room/list/RoomListFragment.kt | 1 - .../home/room/list/RoomListViewModel.kt | 23 +++-- .../room/list/RoomListViewModelFactory.kt | 44 ---------- 9 files changed, 179 insertions(+), 64 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt create mode 100644 vector/src/main/java/im/vector/app/core/di/MavericksAssistedViewModelFactory.kt rename vector/src/main/java/im/vector/app/{features/home/room/list/RoomListModule.kt => core/di/MavericksViewModelModule.kt} (61%) create mode 100644 vector/src/main/java/im/vector/app/core/di/MavericksViewModelScoped.kt delete mode 100644 vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModelFactory.kt diff --git a/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt b/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt new file mode 100644 index 0000000000..d0dd4fa002 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.di + +import com.airbnb.mvrx.MavericksState +import com.airbnb.mvrx.MavericksViewModel +import com.airbnb.mvrx.MavericksViewModelFactory +import com.airbnb.mvrx.ViewModelContext +import dagger.hilt.DefineComponent +import dagger.hilt.EntryPoint +import dagger.hilt.EntryPoints +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +/** + * To connect Mavericks ViewModel creation with Hilt's dependency injection, add the following Factory and companion object to your MavericksViewModel. + * + * Example: + * + * class MyViewModel @AssistedInject constructor(...): MavericksViewModel(...) { + * + * @AssistedFactory + * interface Factory : AssistedViewModelFactory { + * ... + * } + * + * companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + * } + */ + +inline fun , S : MavericksState> hiltMavericksViewModelFactory() = HiltMavericksViewModelFactory(VM::class.java) + +class HiltMavericksViewModelFactory, S : MavericksState>( + private val viewModelClass: Class> +) : MavericksViewModelFactory { + + 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 + return castedViewModelFactory?.create(state) as VM + } +} + +/** + * Hilt's ViewModelComponent's parent is ActivityRetainedComponent but there is no easy way to access it. SingletonComponent should be sufficient + * because the ViewModel that gets created is the only object with a reference to the created component so the lifecycle of it will + * still be correct. + */ +@MavericksViewModelScoped +@DefineComponent(parent = SingletonComponent::class) +interface MavericksViewModelComponent + +@DefineComponent.Builder +interface MavericksViewModelComponentBuilder { + fun build(): MavericksViewModelComponent +} + +@EntryPoint +@InstallIn(SingletonComponent::class) +interface CreateMavericksViewModelComponent { + fun mavericksViewModelComponentBuilder(): MavericksViewModelComponentBuilder +} + +@EntryPoint +@InstallIn(MavericksViewModelComponent::class) +interface HiltMavericksEntryPoint { + val viewModelFactories: Map>, MavericksAssistedViewModelFactory<*, *>> +} diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksAssistedViewModelFactory.kt b/vector/src/main/java/im/vector/app/core/di/MavericksAssistedViewModelFactory.kt new file mode 100644 index 0000000000..4600ced00e --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/di/MavericksAssistedViewModelFactory.kt @@ -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, S : MavericksState> { + fun create(state: S): VM +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt similarity index 61% rename from vector/src/main/java/im/vector/app/features/home/room/list/RoomListModule.kt rename to vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index a708f86b67..e8eb1d0fd0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -14,16 +14,20 @@ * limitations under the License. */ -package im.vector.app.features.home.room.list +package im.vector.app.core.di import dagger.Binds import dagger.Module -import dagger.hilt.migration.DisableInstallInCheck +import dagger.hilt.InstallIn +import dagger.multibindings.IntoMap +import im.vector.app.features.home.room.list.RoomListViewModel -@DisableInstallInCheck +@InstallIn(MavericksViewModelComponent::class) @Module -abstract class RoomListModule { +interface MavericksViewModelModule { @Binds - abstract fun providesRoomListViewModelFactory(factory: RoomListViewModelFactory): RoomListViewModel.Factory + @IntoMap + @MavericksViewModelKey(RoomListViewModel::class) + fun roomListViewModelFactory(factory: RoomListViewModel.Factory): MavericksAssistedViewModelFactory<*, *> } diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelScoped.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelScoped.kt new file mode 100644 index 0000000000..58b9246fe5 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelScoped.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.di + +import javax.inject.Scope + +/** + * Scope annotation for bindings that should exist for the life of an MavericksViewModel. + */ +@Scope +annotation class MavericksViewModelScoped diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt index 022d66f113..f822644676 100644 --- a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt @@ -73,7 +73,6 @@ import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsB import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet import im.vector.app.features.home.room.detail.widget.RoomWidgetsBottomSheet import im.vector.app.features.home.room.filtered.FilteredRoomsActivity -import im.vector.app.features.home.room.list.RoomListModule import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.app.features.html.EventHtmlRenderer import im.vector.app.features.html.VectorHtmlCompressor @@ -253,7 +252,6 @@ interface ScreenComponentDependencies { ViewModelModule::class, FragmentModule::class, HomeModule::class, - RoomListModule::class, ScreenModule::class ] ) diff --git a/vector/src/main/java/im/vector/app/core/di/ViewModelKey.kt b/vector/src/main/java/im/vector/app/core/di/ViewModelKey.kt index 5f0ee30821..2782edd558 100644 --- a/vector/src/main/java/im/vector/app/core/di/ViewModelKey.kt +++ b/vector/src/main/java/im/vector/app/core/di/ViewModelKey.kt @@ -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) + +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.FUNCTION) +@MapKey +annotation class MavericksViewModelKey(val value: KClass>) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index c36836c87f..1c173e12e8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -64,7 +64,6 @@ data class RoomListParams( class RoomListFragment @Inject constructor( private val pagedControllerFactory: RoomSummaryPagedControllerFactory, - val roomListViewModelFactory: RoomListViewModel.Factory, private val notificationDrawerManager: NotificationDrawerManager, private val footerController: RoomListFooterController, private val userPreferencesProvider: UserPreferencesProvider diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 345c33ec18..81c887bd0e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -24,8 +24,13 @@ import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.AppStateHandler import im.vector.app.RoomGroupingMethod +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider @@ -48,8 +53,8 @@ import org.matrix.android.sdk.flow.flow import timber.log.Timber import javax.inject.Inject -class RoomListViewModel @Inject constructor( - initialState: RoomListViewState, +class RoomListViewModel @AssistedInject constructor( + @Assisted initialState: RoomListViewState, private val session: Session, private val stringProvider: StringProvider, private val appStateHandler: AppStateHandler, @@ -57,8 +62,9 @@ class RoomListViewModel @Inject constructor( private val autoAcceptInvites: AutoAcceptInvites ) : VectorViewModel(initialState) { - interface Factory { - fun create(initialState: RoomListViewState): RoomListViewModel + @AssistedFactory + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: RoomListViewState): RoomListViewModel } private var updatableQuery: UpdatableLivePageResult? = null @@ -115,14 +121,7 @@ class RoomListViewModel @Inject constructor( } } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomListViewState): RoomListViewModel { - val fragment: RoomListFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.roomListViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val roomListSectionBuilder = if (appStateHandler.getCurrentRoomGroupingMethod() is RoomGroupingMethod.BySpace) { RoomListSectionBuilderSpace( diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModelFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModelFactory.kt deleted file mode 100644 index e017a8fe08..0000000000 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModelFactory.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2019 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.app.features.home.room.list - -import im.vector.app.AppStateHandler -import im.vector.app.core.resources.StringProvider -import im.vector.app.features.invite.AutoAcceptInvites -import im.vector.app.features.settings.VectorPreferences -import org.matrix.android.sdk.api.session.Session -import javax.inject.Inject -import javax.inject.Provider - -class RoomListViewModelFactory @Inject constructor(private val session: Provider, - private val appStateHandler: AppStateHandler, - private val stringProvider: StringProvider, - private val vectorPreferences: VectorPreferences, - private val autoAcceptInvites: AutoAcceptInvites) : - RoomListViewModel.Factory { - - override fun create(initialState: RoomListViewState): RoomListViewModel { - return RoomListViewModel( - initialState = initialState, - session = session.get(), - stringProvider = stringProvider, - appStateHandler = appStateHandler, - vectorPreferences = vectorPreferences, - autoAcceptInvites = autoAcceptInvites - ) - } -} From 9dd701713146e058f6c3acfb58cc099a9c799df8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 15 Oct 2021 12:49:29 +0200 Subject: [PATCH 004/413] Hilt: continue migration --- .../core/di/HiltMavericksViewModelFactory.kt | 5 +++ .../app/core/di/MavericksViewModelModule.kt | 45 +++++++++++++++++++ .../app/features/auth/ReAuthActivity.kt | 5 +-- .../app/features/auth/ReAuthViewModel.kt | 17 +++---- .../app/features/call/VectorCallActivity.kt | 4 +- .../app/features/call/VectorCallViewModel.kt | 15 +++---- .../call/conference/JitsiCallViewModel.kt | 27 +++-------- .../call/conference/JitsiCallViewState.kt | 10 ++++- .../call/conference/VectorJitsiActivity.kt | 2 - .../roomdirectory/RoomDirectoryViewModel.kt | 14 +++--- .../app/features/spaces/SpaceListFragment.kt | 3 +- ...ListViewModel.kt => SpaceListViewModel.kt} | 27 +++++------ .../spaces/manage/SpaceManageActivity.kt | 6 +-- .../spaces/manage/SpaceManageRoomsFragment.kt | 4 -- .../manage/SpaceManageRoomsViewModel.kt | 20 +++------ .../manage/SpaceManageSharedViewModel.kt | 19 +++----- 16 files changed, 106 insertions(+), 117 deletions(-) rename vector/src/main/java/im/vector/app/features/spaces/{SpacesListViewModel.kt => SpaceListViewModel.kt} (92%) diff --git a/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt b/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt index d0dd4fa002..10485b8189 100644 --- a/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt +++ b/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt @@ -59,6 +59,11 @@ class HiltMavericksViewModelFactory, S : MavericksSta val castedViewModelFactory = viewModelFactory as? MavericksAssistedViewModelFactory return castedViewModelFactory?.create(state) as VM } + + override fun initialState(viewModelContext: ViewModelContext): S? { + return super.initialState(viewModelContext) + } + } /** diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index e8eb1d0fd0..430ecac83d 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -20,7 +20,14 @@ 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.home.room.list.RoomListViewModel +import im.vector.app.features.roomdirectory.RoomDirectoryViewModel +import im.vector.app.features.spaces.SpaceListViewModel +import im.vector.app.features.spaces.manage.SpaceManageRoomsViewModel +import im.vector.app.features.spaces.manage.SpaceManageSharedViewModel @InstallIn(MavericksViewModelComponent::class) @Module @@ -30,4 +37,42 @@ interface MavericksViewModelModule { @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<*, *> + + + } diff --git a/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt b/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt index b7f570672b..13e788d3a0 100644 --- a/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt +++ b/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt @@ -42,7 +42,7 @@ import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import timber.log.Timber import javax.inject.Inject -class ReAuthActivity : SimpleFragmentActivity(), ReAuthViewModel.Factory { +class ReAuthActivity : SimpleFragmentActivity(){ @Parcelize data class Args( @@ -59,9 +59,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) diff --git a/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt b/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt index 449270644e..a3d32ed13f 100644 --- a/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt @@ -23,6 +23,8 @@ 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 +37,11 @@ class ReAuthViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: ReAuthState): ReAuthViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: ReAuthState): ReAuthViewModel } - companion object : MavericksViewModelFactory { - - 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 by hiltMavericksViewModelFactory() override fun handle(action: ReAuthActions) = withState { state -> when (action) { diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index 0654942d4b..e54c04736b 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -41,6 +41,7 @@ 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 @@ -89,6 +90,7 @@ class VectorCallActivity : VectorBaseActivity(), CallContro override fun getBinding() = ActivityCallBinding.inflate(layoutInflater) + @Inject lateinit var callManager: WebRtcCallManager @Inject lateinit var avatarRenderer: AvatarRenderer override fun injectWith(injector: ScreenComponent) { @@ -97,8 +99,6 @@ class VectorCallActivity : VectorBaseActivity(), CallContro 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) { diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt index d8aaca9bd8..72b5f557dc 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt @@ -25,6 +25,8 @@ 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 +343,9 @@ class VectorCallViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: VectorCallViewState): VectorCallViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: VectorCallViewState): VectorCallViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: VectorCallViewState): VectorCallViewModel { - val callActivity: VectorCallActivity = viewModelContext.activity() - return callActivity.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt index c46b4e459d..7a9a9099b5 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt @@ -26,6 +26,8 @@ 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 +48,8 @@ class JitsiCallViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: JitsiCallViewState): JitsiCallViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: JitsiCallViewState): JitsiCallViewModel } private var currentWidgetObserver: Job? = null @@ -143,24 +145,9 @@ class JitsiCallViewModel @AssistedInject constructor( } } - companion object : MavericksViewModelFactory { - + companion object : MavericksViewModelFactory 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 - ) - } } + + } diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewState.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewState.kt index d4c70d7333..462e143fca 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewState.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewState.kt @@ -26,4 +26,12 @@ data class JitsiCallViewState( val widgetId: String = "", val enableVideo: Boolean = false, val widget: Async = Uninitialized -) : MavericksState +) : MavericksState { + + constructor(args: VectorJitsiActivity.Args): this( + roomId = args.roomId, + widgetId = args.widgetId, + enableVideo = args.enableVideo + ) + +} diff --git a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt index 62d017467f..a116d2ac34 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt @@ -61,8 +61,6 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMee override fun getBinding() = ActivityJitsiBinding.inflate(layoutInflater) - @Inject lateinit var viewModelFactory: JitsiCallViewModel.Factory - private var jitsiMeetView: JitsiMeetView? = null private val jitsiViewModel: JitsiCallViewModel by viewModel() diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt index a2089e6cd5..7b002c9631 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt @@ -26,6 +26,8 @@ import com.airbnb.mvrx.appendAt 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 im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.CancellationException @@ -49,18 +51,12 @@ class RoomDirectoryViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: PublicRoomsViewState): RoomDirectoryViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: PublicRoomsViewState): RoomDirectoryViewModel } - companion object : MavericksViewModelFactory { + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { private const val PUBLIC_ROOMS_LIMIT = 20 - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: PublicRoomsViewState): RoomDirectoryViewModel? { - val activity: RoomDirectoryActivity = (viewModelContext as ActivityViewModelContext).activity() - return activity.roomDirectoryViewModelFactory.create(state) - } } private val showAllRooms = vectorPreferences.showAllPublicRooms() diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt index 0a67977e6c..dff98722eb 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListFragment.kt @@ -39,12 +39,11 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject class SpaceListFragment @Inject constructor( - val spaceListViewModelFactory: SpacesListViewModel.Factory, private val spaceController: SpaceSummaryController ) : VectorBaseFragment(), SpaceSummaryController.Callback { private lateinit var sharedActionViewModel: HomeSharedActionViewModel - private val viewModel: SpacesListViewModel by fragmentViewModel() + private val viewModel: SpaceListViewModel by fragmentViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGroupListBinding { return FragmentGroupListBinding.inflate(inflater, container, false) diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpacesListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt similarity index 92% rename from vector/src/main/java/im/vector/app/features/spaces/SpacesListViewModel.kt rename to vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index fbbaeafe72..ed027702f2 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpacesListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -17,16 +17,16 @@ package im.vector.app.features.spaces import androidx.lifecycle.asFlow -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.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.VectorViewModel import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.session.coroutineScope @@ -59,26 +59,19 @@ import org.matrix.android.sdk.api.session.space.model.TopLevelSpaceComparator import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -class SpacesListViewModel @AssistedInject constructor(@Assisted initialState: SpaceListViewState, - private val appStateHandler: AppStateHandler, - private val session: Session, - private val vectorPreferences: VectorPreferences, - private val autoAcceptInvites: AutoAcceptInvites +class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: SpaceListViewState, + private val appStateHandler: AppStateHandler, + private val session: Session, + private val vectorPreferences: VectorPreferences, + private val autoAcceptInvites: AutoAcceptInvites ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SpaceListViewState): SpacesListViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SpaceListViewState): SpaceListViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: SpaceListViewState): SpacesListViewModel { - val groupListFragment: SpaceListFragment = (viewModelContext as FragmentViewModelContext).fragment() - return groupListFragment.spaceListViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() // private var currentGroupingMethod : RoomGroupingMethod? = null diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt index f45f9099bb..9566e4bad3 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt @@ -51,10 +51,8 @@ data class SpaceManageArgs( ) : Parcelable class SpaceManageActivity : VectorBaseActivity(), - ToolbarConfigurable, - SpaceManageSharedViewModel.Factory { + ToolbarConfigurable { - @Inject lateinit var sharedViewModelFactory: SpaceManageSharedViewModel.Factory private lateinit var sharedDirectoryActionViewModel: RoomDirectorySharedActionViewModel override fun injectWith(injector: ScreenComponent) { @@ -194,8 +192,6 @@ class SpaceManageActivity : VectorBaseActivity(), } } - override fun create(initialState: SpaceManageViewState) = sharedViewModelFactory.create(initialState) - override fun configure(toolbar: MaterialToolbar) { configureToolbar(toolbar) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsFragment.kt index 8e16784a6d..5fbac3bb6a 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsFragment.kt @@ -45,10 +45,8 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject class SpaceManageRoomsFragment @Inject constructor( - private val viewModelFactory: SpaceManageRoomsViewModel.Factory, private val epoxyController: SpaceManageRoomsController ) : VectorBaseFragment(), - SpaceManageRoomsViewModel.Factory, OnBackPressed, SpaceManageRoomsController.Listener, Callback { @@ -107,8 +105,6 @@ class SpaceManageRoomsFragment @Inject constructor( super.onDestroyView() } - override fun create(initialState: SpaceManageRoomViewState) = viewModelFactory.create(initialState) - override fun invalidate() = withState(viewModel) { state -> epoxyController.setData(state) diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt index d36e62db13..a0cc4dea5c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt @@ -16,18 +16,16 @@ package im.vector.app.features.spaces.manage -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.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.mvrx.runCatchingToAsync import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.session.coroutineScope @@ -56,19 +54,11 @@ class SpaceManageRoomsViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: SpaceManageRoomViewState): SpaceManageRoomsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SpaceManageRoomViewState): SpaceManageRoomsViewModel } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: SpaceManageRoomViewState): SpaceManageRoomsViewModel? { - 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 by hiltMavericksViewModelFactory() override fun handle(action: SpaceManageRoomViewAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt index 133054236e..925315b65c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt @@ -16,13 +16,12 @@ package im.vector.app.features.spaces.manage -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.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import org.matrix.android.sdk.api.session.Session @@ -33,19 +32,11 @@ class SpaceManageSharedViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SpaceManageViewState): SpaceManageSharedViewModel + interface Factory: MavericksAssistedViewModelFactory{ + override fun create(state: SpaceManageViewState): SpaceManageSharedViewModel } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: SpaceManageViewState): SpaceManageSharedViewModel? { - 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 by hiltMavericksViewModelFactory() override fun handle(action: SpaceManagedSharedAction) { when (action) { From 968c2e70d25806473101c9ab5b7e447a92f656f9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 15 Oct 2021 16:41:05 +0200 Subject: [PATCH 005/413] Hilt: continue migration VM --- .../app/core/di/MavericksViewModelModule.kt | 160 ++++++++++++++++++ .../call/transfer/CallTransferActivity.kt | 20 +-- .../call/transfer/CallTransferViewModel.kt | 18 +- .../contactsbook/ContactsBookFragment.kt | 7 +- .../contactsbook/ContactsBookViewModel.kt | 17 +- .../createdirect/CreateDirectRoomActivity.kt | 11 +- .../createdirect/CreateDirectRoomViewModel.kt | 22 +-- .../settings/KeysBackupManageActivity.kt | 1 - .../settings/KeysBackupSettingsViewModel.kt | 17 +- .../quads/SharedSecureStorageActivity.kt | 1 - .../quads/SharedSecureStorageViewModel.kt | 43 ++--- .../features/devtools/RoomDevToolActivity.kt | 8 +- .../features/devtools/RoomDevToolViewModel.kt | 22 +-- .../vector/app/features/home/HomeActivity.kt | 10 -- .../app/features/home/HomeDetailFragment.kt | 7 +- .../home/PromoteRestrictedViewModel.kt | 18 +- .../home/room/detail/RoomDetailActivity.kt | 7 - .../reactions/ViewReactionsBottomSheet.kt | 1 - .../reactions/ViewReactionsViewModel.kt | 15 +- .../detail/upgrade/MigrateRoomBottomSheet.kt | 10 +- .../detail/upgrade/MigrateRoomViewModel.kt | 20 +-- .../RoomListQuickActionsBottomSheet.kt | 1 - .../invite/InviteUsersToRoomActivity.kt | 8 +- .../picker/RoomDirectoryPickerFragment.kt | 3 +- .../picker/RoomDirectoryPickerViewModel.kt | 16 +- .../RoomNotificationSettingsViewModel.kt | 25 +-- .../settings/ignored/IgnoredUsersViewModel.kt | 15 +- .../VectorSettingsIgnoredUsersFragment.kt | 1 - .../features/spaces/SpaceCreationActivity.kt | 5 +- .../features/spaces/SpaceExploreActivity.kt | 7 +- .../spaces/create/CreateSpaceViewModel.kt | 21 +-- .../spaces/explore/SpaceDirectoryViewModel.kt | 19 +-- .../spaces/invite/SpaceInviteBottomSheet.kt | 6 +- .../invite/SpaceInviteBottomSheetViewModel.kt | 17 +- .../leave/SpaceLeaveAdvancedActivity.kt | 4 - .../leave/SpaceLeaveAdvancedViewModel.kt | 19 +-- .../spaces/manage/SpaceAddRoomFragment.kt | 6 +- .../spaces/manage/SpaceAddRoomsViewModel.kt | 18 +- .../spaces/people/SpacePeopleFragment.kt | 6 - .../spaces/people/SpacePeopleViewModel.kt | 20 +-- .../spaces/preview/SpacePreviewFragment.kt | 5 +- .../spaces/preview/SpacePreviewViewModel.kt | 16 +- .../spaces/share/ShareSpaceBottomSheet.kt | 6 +- .../spaces/share/ShareSpaceViewModel.kt | 19 +-- .../app/features/terms/ReviewTermsActivity.kt | 1 - .../features/terms/ReviewTermsViewModel.kt | 18 +- .../app/features/usercode/UserCodeActivity.kt | 6 - .../usercode/UserCodeSharedViewModel.kt | 20 +-- .../userdirectory/UserListViewModel.kt | 17 +- .../app/features/widgets/WidgetActivity.kt | 15 +- .../app/features/widgets/WidgetViewModel.kt | 18 +- .../RoomWidgetPermissionViewModel.kt | 19 +-- .../signout/ServerBackupStatusViewModel.kt | 18 +- .../SignOutBottomSheetDialogFragment.kt | 10 +- .../workers/signout/SignoutCheckViewModel.kt | 18 +- 55 files changed, 331 insertions(+), 527 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index 430ecac83d..6724954479 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -23,11 +23,38 @@ 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.devtools.RoomDevToolViewModel +import im.vector.app.features.home.PromoteRestrictedViewModel +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.roomdirectory.RoomDirectoryViewModel +import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerViewModel +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsViewModel +import im.vector.app.features.settings.ignored.IgnoredUsersViewModel import im.vector.app.features.spaces.SpaceListViewModel +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 @@ -73,6 +100,139 @@ interface MavericksViewModelModule { @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<*, *> } diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index 2a50dc85f9..a2e81e64fa 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -40,14 +40,8 @@ data class CallTransferArgs(val callId: String) : Parcelable private const val USER_LIST_FRAGMENT_TAG = "USER_LIST_FRAGMENT_TAG" -class CallTransferActivity : VectorBaseActivity(), - CallTransferViewModel.Factory, - UserListViewModel.Factory, - ContactsBookViewModel.Factory { +class CallTransferActivity : VectorBaseActivity() { - @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 @@ -62,18 +56,6 @@ class CallTransferActivity : VectorBaseActivity(), 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 diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt index a26b03a3aa..de352149a7 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt @@ -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(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: CallTransferViewState): CallTransferViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: CallTransferViewState): CallTransferViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: CallTransferViewState): CallTransferViewModel? { - val activity: CallTransferActivity = (viewModelContext as ActivityViewModelContext).activity() - return activity.callTransferViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val call = callManager.getCallById(initialState.callId) private val callListener = object : WebRtcCall.Listener { diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt index ea1841d870..d79ad308de 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt @@ -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(), ContactsBookController.Callback, ContactsBookViewModel.Factory { +) : VectorBaseFragment(), 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) diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt index 6b5a6465a6..05f98dedff 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt @@ -28,6 +28,8 @@ 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 +47,11 @@ class ContactsBookViewModel @AssistedInject constructor(@Assisted VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: ContactsBookViewState): ContactsBookViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: ContactsBookViewState): ContactsBookViewModel } - companion object : MavericksViewModelFactory { - - 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 by hiltMavericksViewModelFactory() private var allContacts: List = emptyList() private var mappedContacts: List = emptyList() diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index ae3af4b3e9..e310eb8e70 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -55,13 +55,10 @@ 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 { +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) { @@ -69,12 +66,6 @@ class CreateDirectRoomActivity : SimpleFragmentActivity(), UserListViewModel.Fac 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 diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt index 347dcdc410..0d75bb7ecb 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt @@ -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(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: CreateDirectRoomViewState): CreateDirectRoomViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: CreateDirectRoomViewState): CreateDirectRoomViewModel } - companion object : MavericksViewModelFactory { - - @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 by hiltMavericksViewModelFactory() override fun handle(action: CreateDirectRoomAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt index 716f02369a..29d513ced0 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt @@ -40,7 +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) diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index 6814b376c2..08d118c403 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -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 { + override fun create(state: KeysBackupSettingViewState): KeysBackupSettingsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: KeysBackupSettingViewState): KeysBackupSettingsViewModel? { - val activity: KeysBackupManageActivity = (viewModelContext as ActivityViewModelContext).activity() - return activity.keysBackupSettingsViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val keysBackupService: KeysBackupService = session.cryptoService().keysBackupService() diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt index bd7195ad1e..ad3e28c715 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt @@ -52,7 +52,6 @@ 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) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt index bb4d4ce99a..b93dac7c8c 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt @@ -29,6 +29,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.WaitingViewData @@ -54,8 +56,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, + val resultKeyStoreAlias: String ) : MavericksState { + + constructor(args: SharedSecureStorageActivity.Args): this( + keyId = args.keyId, + requestedSecrets = args.requestedSecrets, + resultKeyStoreAlias = args.resultKeyStoreAlias + ) + enum class Step { EnterPassphrase, EnterKey, @@ -64,22 +76,21 @@ 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(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SharedSecureStorageViewState, args: SharedSecureStorageActivity.Args): SharedSecureStorageViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SharedSecureStorageViewState): SharedSecureStorageViewModel } init { setState { copy(userId = session.myUserId) } - val isValid = session.sharedSecretStorageService.checkShouldBeAbleToAccessSecrets(args.requestedSecrets, args.keyId) is IntegrityResult.Success + val isValid = session.sharedSecretStorageService.checkShouldBeAbleToAccessSecrets(initialState.requestedSecrets, initialState.keyId) is IntegrityResult.Success if (!isValid) { _viewEvents.post( SharedSecureStorageViewEvent.Error( @@ -88,7 +99,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 +229,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 +246,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor( _viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading) val safeForIntentCypher = ByteArrayOutputStream().also { it.use { - session.securelyStoreObject(decryptedSecretMap as Map, args.resultKeyStoreAlias, it) + session.securelyStoreObject(decryptedSecretMap as Map, initialState.resultKeyStoreAlias, it) } }.toByteArray().toBase64NoPadding() _viewEvents.post(SharedSecureStorageViewEvent.FinishSuccess(safeForIntentCypher)) @@ -287,7 +298,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 +315,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor( _viewEvents.post(SharedSecureStorageViewEvent.HideModalLoading) val safeForIntentCypher = ByteArrayOutputStream().also { it.use { - session.securelyStoreObject(decryptedSecretMap as Map, args.resultKeyStoreAlias, it) + session.securelyStoreObject(decryptedSecretMap as Map, initialState.resultKeyStoreAlias, it) } }.toByteArray().toBase64NoPadding() _viewEvents.post(SharedSecureStorageViewEvent.FinishSuccess(safeForIntentCypher)) @@ -320,13 +331,5 @@ class SharedSecureStorageViewModel @AssistedInject constructor( _viewEvents.post(SharedSecureStorageViewEvent.Dismiss) } - companion object : MavericksViewModelFactory { - - @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 by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt index 2686722c6e..31880a66ab 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt @@ -45,10 +45,8 @@ import kotlinx.parcelize.Parcelize import org.billcarsonfr.jsonviewer.JSonViewerFragment import javax.inject.Inject -class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Factory, - FragmentManager.OnBackStackChangedListener { +class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStackChangedListener { - @Inject lateinit var viewModelFactory: RoomDevToolViewModel.Factory @Inject lateinit var colorProvider: ColorProvider // private lateinit var viewModel: RoomDevToolViewModel @@ -70,10 +68,6 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto injector.inject(this) } - override fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel { - return viewModelFactory.create(initialState) - } - override fun initUiAndData() { super.initUiAndData() viewModel.subscribe(this) { diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt index 023d1976c9..b17bb1d2b1 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt @@ -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(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(state: RoomDevToolViewState): RoomDevToolViewModel } - companion object : MavericksViewModelFactory { - - @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 by hiltMavericksViewModelFactory() init { session.getRoom(initialState.roomId) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index ff1154acc3..9894912884 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -95,9 +95,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDetectorSharedViewModel.Factory, - ServerBackupStatusViewModel.Factory, UnreadMessagesSharedViewModel.Factory, - PromoteRestrictedViewModel.Factory, NavigationInterceptor, SpaceInviteBottomSheet.InteractionListener, MatrixToBottomSheet.InteractionListener { @@ -108,8 +106,6 @@ class HomeActivity : @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 @@ -183,10 +179,6 @@ class HomeActivity : return unknownDeviceViewModelFactory.create(initialState) } - override fun create(initialState: ServerBackupStatusViewState): ServerBackupStatusViewModel { - return serverBackupviewModelFactory.create(initialState) - } - override fun create(initialState: UnreadMessagesState): UnreadMessagesSharedViewModel { return unreadMessagesSharedViewModelFactory.create(initialState) } @@ -590,8 +582,6 @@ class HomeActivity : } } - override fun create(initialState: ActiveSpaceViewState) = promoteRestrictedViewModelFactory.create(initialState) - override fun mxToBottomSheetNavigateToRoom(roomId: String) { navigator.openRoom(this, roomId) } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index c8fff5605b..5ea4855bbe 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -65,7 +65,6 @@ 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 +73,7 @@ class HomeDetailFragment @Inject constructor( private val appStateHandler: AppStateHandler ) : VectorBaseFragment(), KeysBackupBanner.Delegate, - CurrentCallsView.Callback, - ServerBackupStatusViewModel.Factory { + CurrentCallsView.Callback { private val viewModel: HomeDetailViewModel by fragmentViewModel() private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel() @@ -504,7 +502,4 @@ class HomeDetailFragment @Inject constructor( return this } - override fun create(initialState: ServerBackupStatusViewState): ServerBackupStatusViewModel { - return serverBackupStatusViewModelFactory.create(initialState) - } } diff --git a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt index 0c8c9e480c..af6a226198 100644 --- a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt @@ -27,6 +27,8 @@ 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 +74,11 @@ class PromoteRestrictedViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: ActiveSpaceViewState): PromoteRestrictedViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: ActiveSpaceViewState): PromoteRestrictedViewModel } - companion object : MavericksViewModelFactory { - - @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 by hiltMavericksViewModelFactory() override fun handle(action: EmptyAction) {} } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index 76c3816ce6..24d7e13b79 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -48,7 +48,6 @@ class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable, RequireActiveMembershipViewModel.Factory, - RoomWidgetPermissionViewModel.Factory, MatrixToBottomSheet.InteractionListener { override fun getBinding(): ActivityRoomDetailBinding { @@ -85,12 +84,6 @@ class RoomDetailActivity : 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) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt index 81ebd6d3de..356de36294 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt @@ -44,7 +44,6 @@ class ViewReactionsBottomSheet : private val viewModel: ViewReactionsViewModel by fragmentViewModel(ViewReactionsViewModel::class) - @Inject lateinit var viewReactionsViewModelFactory: ViewReactionsViewModel.Factory private lateinit var sharedActionViewModel: MessageSharedActionViewModel @Inject lateinit var epoxyController: ViewReactionsEpoxyController diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt index 5baab683cf..715b0130bf 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt @@ -27,6 +27,8 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.date.DateFormatKind import im.vector.app.core.date.VectorDateFormatter +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 @@ -70,18 +72,11 @@ class ViewReactionsViewModel @AssistedInject constructor(@Assisted ?: throw IllegalStateException("Shouldn't use this ViewModel without a room") @AssistedFactory - interface Factory { - fun create(initialState: DisplayReactionsViewState): ViewReactionsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: DisplayReactionsViewState): ViewReactionsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: DisplayReactionsViewState): ViewReactionsViewModel? { - val fragment: ViewReactionsBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewReactionsViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { observeEventAnnotationSummaries() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt index 2fa210a748..bd4092097a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt @@ -37,8 +37,7 @@ import kotlinx.parcelize.Parcelize import javax.inject.Inject class MigrateRoomBottomSheet : - VectorBaseBottomSheetDialogFragment(), - MigrateRoomViewModel.Factory { + VectorBaseBottomSheetDialogFragment(){ enum class MigrationReason { MANUAL, @@ -53,9 +52,6 @@ class MigrateRoomBottomSheet : val customDescription: CharSequence? = null ) : Parcelable - @Inject - lateinit var viewModelFactory: MigrateRoomViewModel.Factory - override val showExpanded = true @Inject @@ -152,10 +148,6 @@ class MigrateRoomBottomSheet : } } - override fun create(initialState: MigrateRoomViewState): MigrateRoomViewModel { - return viewModelFactory.create(initialState) - } - companion object { const val REQUEST_KEY = "MigrateRoomBottomSheetRequest" diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt index bb28836cd3..94be14fe4d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt @@ -16,15 +16,14 @@ package im.vector.app.features.home.room.detail.upgrade -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.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.session.coroutineScope @@ -51,20 +50,11 @@ class MigrateRoomViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: MigrateRoomViewState): MigrateRoomViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: MigrateRoomViewState): MigrateRoomViewModel } - companion object : MavericksViewModelFactory { - - override fun create(viewModelContext: ViewModelContext, state: MigrateRoomViewState): MigrateRoomViewModel? { - 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 by hiltMavericksViewModelFactory() override fun handle(action: MigrateRoomAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 8c1bdc086f..ac667fb5fe 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -62,7 +62,6 @@ class RoomListQuickActionsBottomSheet : private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel @Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool - @Inject lateinit var roomNotificationSettingsViewModelFactory: RoomNotificationSettingsViewModel.Factory @Inject lateinit var roomListActionsEpoxyController: RoomListQuickActionsEpoxyController @Inject lateinit var navigator: Navigator @Inject lateinit var errorFormatter: ErrorFormatter diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt index dd07319e9f..0aaa5b9834 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt @@ -53,13 +53,11 @@ import javax.inject.Inject @Parcelize data class InviteUsersToRoomArgs(val roomId: String) : Parcelable -class InviteUsersToRoomActivity : SimpleFragmentActivity(), UserListViewModel.Factory, ContactsBookViewModel.Factory, InviteUsersToRoomViewModel.Factory { +class InviteUsersToRoomActivity : SimpleFragmentActivity(), InviteUsersToRoomViewModel.Factory { private val viewModel: InviteUsersToRoomViewModel by viewModel() private lateinit var sharedActionViewModel: UserListSharedActionViewModel - @Inject lateinit var userListViewModelFactory: UserListViewModel.Factory @Inject lateinit var inviteUsersToRoomViewModelFactory: InviteUsersToRoomViewModel.Factory - @Inject lateinit var contactsBookViewModelFactory: ContactsBookViewModel.Factory @Inject lateinit var errorFormatter: ErrorFormatter override fun injectWith(injector: ScreenComponent) { @@ -67,10 +65,6 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity(), UserListViewModel.Fa injector.inject(this) } - override fun create(initialState: UserListViewState) = userListViewModelFactory.create(initialState) - - override fun create(initialState: ContactsBookViewState) = contactsBookViewModelFactory.create(initialState) - override fun create(initialState: InviteUsersToRoomViewState) = inviteUsersToRoomViewModelFactory.create(initialState) override fun onCreate(savedInstanceState: Bundle?) { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt index a32a3a897f..2707b87c1f 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt @@ -39,8 +39,7 @@ import im.vector.app.features.roomdirectory.RoomDirectoryViewModel import timber.log.Timber import javax.inject.Inject -class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerViewModelFactory: RoomDirectoryPickerViewModel.Factory, - private val roomDirectoryPickerController: RoomDirectoryPickerController +class RoomDirectoryPickerFragment @Inject constructor(private val roomDirectoryPickerController: RoomDirectoryPickerController ) : VectorBaseFragment(), OnBackPressed, RoomDirectoryPickerController.Callback { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt index 3f73b80bc6..019afafa20 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.roomdirectory.picker -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Fail import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.Loading @@ -28,6 +27,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -46,18 +47,11 @@ class RoomDirectoryPickerViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomDirectoryPickerViewState): RoomDirectoryPickerViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: RoomDirectoryPickerViewState): RoomDirectoryPickerViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomDirectoryPickerViewState): RoomDirectoryPickerViewModel? { - val fragment: RoomDirectoryPickerFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.roomDirectoryPickerViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { observeAndCompute() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt index f91b482b13..c83a069250 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt @@ -16,16 +16,14 @@ package im.vector.app.features.roomprofile.notifications -import androidx.lifecycle.viewModelScope -import com.airbnb.mvrx.FragmentViewModelContext 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.platform.VectorViewModel -import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.flow.flow @@ -37,24 +35,11 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel { - val fragmentModelContext = (viewModelContext as FragmentViewModelContext) - return if (fragmentModelContext.fragment is RoomNotificationSettingsFragment) { - val fragment: RoomNotificationSettingsFragment = fragmentModelContext.fragment() - fragment.viewModelFactory.create(state) - } else { - val fragment: RoomListQuickActionsBottomSheet = fragmentModelContext.fragment() - fragment.roomNotificationSettingsViewModelFactory.create(state) - } - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val room = session.getRoom(initialState.roomId)!! diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt index 91213809de..abfeab9504 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt @@ -28,6 +28,8 @@ 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 im.vector.app.core.platform.VectorViewModelAction import kotlinx.coroutines.launch @@ -49,18 +51,11 @@ class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: IgnoredUsersViewState): IgnoredUsersViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: IgnoredUsersViewState): IgnoredUsersViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: IgnoredUsersViewState): IgnoredUsersViewModel? { - val ignoredUsersFragment: VectorSettingsIgnoredUsersFragment = (viewModelContext as FragmentViewModelContext).fragment() - return ignoredUsersFragment.ignoredUsersViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { observeIgnoredUsers() diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt index 1526ac0e69..509014492d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -36,7 +36,6 @@ import im.vector.app.databinding.FragmentGenericRecyclerBinding import javax.inject.Inject class VectorSettingsIgnoredUsersFragment @Inject constructor( - val ignoredUsersViewModelFactory: IgnoredUsersViewModel.Factory, private val ignoredUsersController: IgnoredUsersController ) : VectorBaseFragment(), IgnoredUsersController.Callback { diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt index 1844e8e9ca..4c86c4d554 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt @@ -41,9 +41,7 @@ import im.vector.app.features.spaces.create.SpaceTopology import im.vector.app.features.spaces.create.SpaceType import javax.inject.Inject -class SpaceCreationActivity : SimpleFragmentActivity(), CreateSpaceViewModel.Factory { - - @Inject lateinit var viewModelFactory: CreateSpaceViewModel.Factory +class SpaceCreationActivity : SimpleFragmentActivity(){ override fun injectWith(injector: ScreenComponent) { super.injectWith(injector) @@ -188,5 +186,4 @@ class SpaceCreationActivity : SimpleFragmentActivity(), CreateSpaceViewModel.Fac } } - override fun create(initialState: CreateSpaceState): CreateSpaceViewModel = viewModelFactory.create(initialState) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt index 47e4c6420b..675dc08716 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt @@ -37,9 +37,7 @@ import im.vector.app.features.spaces.explore.SpaceDirectoryViewEvents import im.vector.app.features.spaces.explore.SpaceDirectoryViewModel import javax.inject.Inject -class SpaceExploreActivity : VectorBaseActivity(), SpaceDirectoryViewModel.Factory, MatrixToBottomSheet.InteractionListener { - - @Inject lateinit var spaceDirectoryViewModelFactory: SpaceDirectoryViewModel.Factory +class SpaceExploreActivity : VectorBaseActivity(), MatrixToBottomSheet.InteractionListener { override fun injectWith(injector: ScreenComponent) { injector.inject(this) @@ -113,9 +111,6 @@ class SpaceExploreActivity : VectorBaseActivity(), SpaceD } } - override fun create(initialState: SpaceDirectoryState): SpaceDirectoryViewModel = - spaceDirectoryViewModelFactory.create(initialState) - override fun mxToBottomSheetNavigateToRoom(roomId: String) { navigator.openRoom(this, roomId) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt index 34cc72b03f..e9e6f1c0d4 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt @@ -16,10 +16,7 @@ package im.vector.app.features.spaces.create -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 @@ -29,6 +26,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.isEmail @@ -76,8 +75,8 @@ class CreateSpaceViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: CreateSpaceState): CreateSpaceViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: CreateSpaceState): CreateSpaceViewModel } private fun startListenToIdentityManager() { @@ -93,17 +92,9 @@ class CreateSpaceViewModel @AssistedInject constructor( super.onCleared() } - companion object : MavericksViewModelFactory { + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory(){ - override fun create(viewModelContext: ViewModelContext, state: CreateSpaceState): CreateSpaceViewModel? { - 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") - } - - override fun initialState(viewModelContext: ViewModelContext): CreateSpaceState? { + override fun initialState(viewModelContext: ViewModelContext): CreateSpaceState { return CreateSpaceState( defaultRooms = mapOf( 0 to viewModelContext.activity.getString(R.string.create_spaces_default_public_room_name), diff --git a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt index 5e2537f587..b3bfed5cba 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt @@ -16,17 +16,16 @@ package im.vector.app.features.spaces.explore -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.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.VectorViewModel import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import kotlinx.coroutines.Dispatchers @@ -52,19 +51,11 @@ class SpaceDirectoryViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SpaceDirectoryState): SpaceDirectoryViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SpaceDirectoryState): SpaceDirectoryViewModel } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: SpaceDirectoryState): SpaceDirectoryViewModel? { - 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 by hiltMavericksViewModelFactory() init { diff --git a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt index 4f8d0b6c2f..9aec9edeaa 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt @@ -43,7 +43,7 @@ import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject -class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment(), SpaceInviteBottomSheetViewModel.Factory { +class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment() { interface InteractionListener { fun spaceInviteBottomSheetOnAccept(spaceId: String) @@ -65,10 +65,6 @@ class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment { + override fun create(state: SpaceInviteBottomSheetState): SpaceInviteBottomSheetViewModel } - companion object : MavericksViewModelFactory { - - override fun create(viewModelContext: ViewModelContext, state: SpaceInviteBottomSheetState): SpaceInviteBottomSheetViewModel? { - 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 by hiltMavericksViewModelFactory() override fun handle(action: SpaceInviteBottomSheetAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt index 762abf10cb..de3456863c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt @@ -41,18 +41,14 @@ import im.vector.app.features.spaces.SpaceBottomSheetSettingsArgs import javax.inject.Inject class SpaceLeaveAdvancedActivity : VectorBaseActivity(), - SpaceLeaveAdvancedViewModel.Factory, ToolbarConfigurable { override fun getBinding(): ActivitySimpleLoadingBinding = ActivitySimpleLoadingBinding.inflate(layoutInflater) val leaveViewModel: SpaceLeaveAdvancedViewModel by viewModel() - @Inject lateinit var viewModelFactory: SpaceLeaveAdvancedViewModel.Factory @Inject lateinit var errorFormatter: ErrorFormatter - override fun create(initialState: SpaceLeaveAdvanceViewState) = viewModelFactory.create(initialState) - override fun injectWith(injector: ScreenComponent) { super.injectWith(injector) injector.inject(this) diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt index 3d24cf6225..aeca13d1cf 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt @@ -16,18 +16,17 @@ package im.vector.app.features.spaces.leave -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.Uninitialized -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.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 kotlinx.coroutines.flow.launchIn @@ -127,17 +126,9 @@ class SpaceLeaveAdvancedViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: SpaceLeaveAdvanceViewState): SpaceLeaveAdvancedViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SpaceLeaveAdvanceViewState): SpaceLeaveAdvancedViewModel } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: SpaceLeaveAdvanceViewState): SpaceLeaveAdvancedViewModel? { - 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 by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomFragment.kt index 0512a478a1..5dbd35fc20 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomFragment.kt @@ -44,9 +44,8 @@ class SpaceAddRoomFragment @Inject constructor( private val spaceEpoxyController: AddRoomListController, private val roomEpoxyController: AddRoomListController, private val dmEpoxyController: AddRoomListController, - private val viewModelFactory: SpaceAddRoomsViewModel.Factory ) : VectorBaseFragment(), - OnBackPressed, AddRoomListController.Listener, SpaceAddRoomsViewModel.Factory { + OnBackPressed, AddRoomListController.Listener { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) = FragmentSpaceAddRoomsBinding.inflate(layoutInflater, container, false) @@ -55,9 +54,6 @@ class SpaceAddRoomFragment @Inject constructor( private val sharedViewModel: SpaceManageSharedViewModel by activityViewModel() - override fun create(initialState: SpaceAddRoomsState): SpaceAddRoomsViewModel = - viewModelFactory.create(initialState) - override fun getMenuRes(): Int = R.menu.menu_space_add_room private var saveNeeded = false diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt index bf062ce0a8..1ff8a321e5 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt @@ -29,6 +29,8 @@ 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 kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -55,10 +57,12 @@ class SpaceAddRoomsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SpaceAddRoomsState): SpaceAddRoomsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SpaceAddRoomsState): SpaceAddRoomsViewModel } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + val updatableLiveSpacePageResult: UpdatableLivePageResult by lazy { session.getFilteredPagedRoomSummariesLive( roomSummaryQueryParams { @@ -132,16 +136,6 @@ class SpaceAddRoomsViewModel @AssistedInject constructor( } } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: SpaceAddRoomsState): SpaceAddRoomsViewModel? { - 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") - } - } - fun canGoBack(): Boolean { val needToSave = selectionList.values.any { it } if (needToSave) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt index e1629d5dc1..b53845c09a 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt @@ -44,13 +44,11 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject class SpacePeopleFragment @Inject constructor( - private val viewModelFactory: SpacePeopleViewModel.Factory, private val roomMemberModelFactory: RoomMemberListViewModel.Factory, private val drawableProvider: DrawableProvider, private val colorProvider: ColorProvider, private val epoxyController: SpacePeopleListController ) : VectorBaseFragment(), - SpacePeopleViewModel.Factory, RoomMemberListViewModel.Factory, OnBackPressed, SpacePeopleListController.InteractionListener { @@ -66,10 +64,6 @@ class SpacePeopleFragment @Inject constructor( return true } - override fun create(initialState: SpacePeopleViewState): SpacePeopleViewModel { - return viewModelFactory.create(initialState) - } - override fun create(initialState: RoomMemberListViewState): RoomMemberListViewModel { return roomMemberModelFactory.create(initialState) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt index efa7d97e9c..bf77166a5c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt @@ -16,17 +16,15 @@ package im.vector.app.features.spaces.people -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 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.raw.wellknown.getElementWellknown @@ -44,19 +42,11 @@ class SpacePeopleViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SpacePeopleViewState): SpacePeopleViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SpacePeopleViewState): SpacePeopleViewModel } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: SpacePeopleViewState): SpacePeopleViewModel? { - 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 by hiltMavericksViewModelFactory() override fun handle(action: SpacePeopleViewAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewFragment.kt index eb02ed7c2d..7e08d7c924 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewFragment.kt @@ -49,10 +49,9 @@ data class SpacePreviewArgs( ) : Parcelable class SpacePreviewFragment @Inject constructor( - private val viewModelFactory: SpacePreviewViewModel.Factory, private val avatarRenderer: AvatarRenderer, private val epoxyController: SpacePreviewController -) : VectorBaseFragment(), SpacePreviewViewModel.Factory { +) : VectorBaseFragment() { private val viewModel by fragmentViewModel(SpacePreviewViewModel::class) lateinit var sharedActionViewModel: SpacePreviewSharedActionViewModel @@ -66,8 +65,6 @@ class SpacePreviewFragment @Inject constructor( sharedActionViewModel = activityViewModelProvider.get(SpacePreviewSharedActionViewModel::class.java) } - override fun create(initialState: SpacePreviewState) = viewModelFactory.create(initialState) - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt index d71a4bef46..ae69375ad6 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt @@ -28,6 +28,8 @@ 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.error.ErrorFormatter import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.Dispatchers @@ -58,19 +60,11 @@ class SpacePreviewViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: SpacePreviewState): SpacePreviewViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SpacePreviewState): SpacePreviewViewModel } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: SpacePreviewState): SpacePreviewViewModel? { - 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 by hiltMavericksViewModelFactory() override fun handle(action: SpacePreviewViewAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceBottomSheet.kt index bd69de0d95..d32c121258 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceBottomSheet.kt @@ -35,7 +35,7 @@ import im.vector.app.features.invite.InviteUsersToRoomActivity import kotlinx.parcelize.Parcelize import javax.inject.Inject -class ShareSpaceBottomSheet : VectorBaseBottomSheetDialogFragment(), ShareSpaceViewModel.Factory { +class ShareSpaceBottomSheet : VectorBaseBottomSheetDialogFragment(){ @Parcelize data class Args( @@ -47,10 +47,6 @@ class ShareSpaceBottomSheet : VectorBaseBottomSheetDialogFragment(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: ShareSpaceViewState): ShareSpaceViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: ShareSpaceViewState): ShareSpaceViewModel } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: ShareSpaceViewState): ShareSpaceViewModel? { - 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 by hiltMavericksViewModelFactory() init { val roomSummary = session.getRoomSummary(initialState.spaceId) diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt index 02f25563b8..194084fe2d 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt @@ -32,7 +32,6 @@ import javax.inject.Inject class ReviewTermsActivity : SimpleFragmentActivity() { @Inject lateinit var errorFormatter: ErrorFormatter - @Inject lateinit var viewModelFactory: ReviewTermsViewModel.Factory private val reviewTermsViewModel: ReviewTermsViewModel by viewModel() diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt index 6a46061a31..db46c55b7d 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt @@ -15,16 +15,15 @@ */ package im.vector.app.features.terms -import androidx.lifecycle.viewModelScope -import com.airbnb.mvrx.ActivityViewModelContext 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.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch @@ -37,18 +36,11 @@ class ReviewTermsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: ReviewTermsViewState): ReviewTermsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: ReviewTermsViewState): ReviewTermsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: ReviewTermsViewState): ReviewTermsViewModel? { - val activity: ReviewTermsActivity = (viewModelContext as ActivityViewModelContext).activity() - return activity.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() lateinit var termsArgs: ServiceTermsArgs diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt index db1bc3056a..a2c156d722 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt @@ -41,11 +41,8 @@ import javax.inject.Inject import kotlin.reflect.KClass class UserCodeActivity : VectorBaseActivity(), - UserCodeSharedViewModel.Factory, MatrixToBottomSheet.InteractionListener { - @Inject lateinit var viewModelFactory: UserCodeSharedViewModel.Factory - val sharedViewModel: UserCodeSharedViewModel by viewModel() @Parcelize @@ -147,9 +144,6 @@ class UserCodeActivity : VectorBaseActivity(), }.exhaustive } - override fun create(initialState: UserCodeState) = - viewModelFactory.create(initialState) - companion object { fun newIntent(context: Context, userId: String): Intent { return Intent(context, UserCodeActivity::class.java).apply { diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt index 2319eef6c4..7efbfd396e 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt @@ -16,15 +16,13 @@ package im.vector.app.features.usercode -import androidx.lifecycle.viewModelScope -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.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import im.vector.app.features.createdirect.DirectRoomHelper @@ -45,15 +43,7 @@ class UserCodeSharedViewModel @AssistedInject constructor( private val directRoomHelper: DirectRoomHelper, private val rawService: RawService) : VectorViewModel(initialState) { - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: UserCodeState): UserCodeSharedViewModel? { - 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 by hiltMavericksViewModelFactory() init { val user = session.getUser(initialState.userId) @@ -66,8 +56,8 @@ class UserCodeSharedViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: UserCodeState): UserCodeSharedViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: UserCodeState): UserCodeSharedViewModel } override fun handle(action: UserCodeActions) { diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index 457f8cbd9a..a22c7ecf16 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -25,6 +25,8 @@ 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.extensions.isEmail import im.vector.app.core.extensions.toggle @@ -61,20 +63,11 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User private val identityServerUsersSearch = MutableStateFlow("") @AssistedFactory - interface Factory { - fun create(initialState: UserListViewState): UserListViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: UserListViewState): UserListViewModel } - companion object : MavericksViewModelFactory { - - override fun create(viewModelContext: ViewModelContext, state: UserListViewState): UserListViewModel? { - 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 by hiltMavericksViewModelFactory() private val identityServerListener = object : IdentityServiceListener { override fun onIdentityServerChange() { diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt index 23f1cfe119..d2061c71b3 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt @@ -38,9 +38,7 @@ import java.io.Serializable import javax.inject.Inject class WidgetActivity : VectorBaseActivity(), - ToolbarConfigurable, - WidgetViewModel.Factory, - RoomWidgetPermissionViewModel.Factory { + ToolbarConfigurable { companion object { @@ -66,9 +64,6 @@ class WidgetActivity : VectorBaseActivity(), } } - @Inject lateinit var viewModelFactory: WidgetViewModel.Factory - @Inject lateinit var permissionsViewModelFactory: RoomWidgetPermissionViewModel.Factory - private val viewModel: WidgetViewModel by viewModel() private val permissionViewModel: RoomWidgetPermissionViewModel by viewModel() @@ -133,14 +128,6 @@ class WidgetActivity : VectorBaseActivity(), } } - override fun create(initialState: WidgetViewState): WidgetViewModel { - return viewModelFactory.create(initialState) - } - - override fun create(initialState: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel { - return permissionsViewModelFactory.create(initialState) - } - private fun handleClose(event: WidgetViewEvents.Close) { if (event.content != null) { val intent = createResultIntent(event.content) diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt index 1cf3e367ea..26a43ec8d0 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt @@ -27,6 +27,8 @@ 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 im.vector.app.core.resources.StringProvider import im.vector.app.features.widgets.permissions.WidgetPermissionsHelper @@ -57,21 +59,11 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi IntegrationManagerService.Listener { @AssistedFactory - interface Factory { - fun create(initialState: WidgetViewState): WidgetViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: WidgetViewState): WidgetViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: WidgetViewState): WidgetViewModel? { - 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 by hiltMavericksViewModelFactory() private val room = session.getRoom(initialState.roomId) private val widgetService = session.widgetService() diff --git a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt index 71eaebbc91..b1fe18cc3f 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt @@ -18,11 +18,12 @@ package im.vector.app.features.widgets.permissions 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.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map @@ -141,19 +142,9 @@ class RoomWidgetPermissionViewModel @AssistedInject constructor(@Assisted val in } @AssistedFactory - interface Factory { - fun create(initialState: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel? { - 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 by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt index 9b9f3fe490..0663ec83ab 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt @@ -27,6 +27,8 @@ 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 @@ -67,21 +69,11 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS VectorViewModel(initialState), KeysBackupStateListener { @AssistedFactory - interface Factory { - fun create(initialState: ServerBackupStatusViewState): ServerBackupStatusViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: ServerBackupStatusViewState): ServerBackupStatusViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: ServerBackupStatusViewState): ServerBackupStatusViewModel? { - 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 by hiltMavericksViewModelFactory() // Keys exported manually val keysExportedToFile = MutableLiveData() diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt index 7f089082a2..68502bceaf 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt @@ -46,8 +46,7 @@ import javax.inject.Inject // TODO this needs to be refactored to current standard and remove legacy class SignOutBottomSheetDialogFragment : - VectorBaseBottomSheetDialogFragment(), - SignoutCheckViewModel.Factory { + VectorBaseBottomSheetDialogFragment(){ var onSignOut: Runnable? = null @@ -59,13 +58,6 @@ class SignOutBottomSheetDialogFragment : isCancelable = true } - @Inject - lateinit var viewModelFactory: SignoutCheckViewModel.Factory - - override fun create(initialState: SignoutCheckViewState): SignoutCheckViewModel { - return viewModelFactory.create(initialState) - } - private val viewModel: SignoutCheckViewModel by fragmentViewModel(SignoutCheckViewModel::class) override fun injectWith(injector: ScreenComponent) { diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt index 057d9e31f8..3e36106ff2 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt @@ -29,6 +29,8 @@ 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.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -66,21 +68,11 @@ class SignoutCheckViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: SignoutCheckViewState): SignoutCheckViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(state: SignoutCheckViewState): SignoutCheckViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: SignoutCheckViewState): SignoutCheckViewModel? { - 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 by hiltMavericksViewModelFactory() init { session.cryptoService().keysBackupService().addListener(this) From bbc0a84af08038f110d6e3fa1bef07d90eec36ca Mon Sep 17 00:00:00 2001 From: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Date: Fri, 15 Oct 2021 19:45:47 +0000 Subject: [PATCH 006/413] Remove redundant text in feature request template Same deal as PR #4076. --- .github/ISSUE_TEMPLATE/enhancement.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index 5d9cfb3c88..d6c84720bc 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -10,10 +10,10 @@ body: id: usecase attributes: label: Your use case - description: What would you like to be able to do? Please feel welcome to include screenshots or mock ups. + description: Please feel welcome to include screenshots or mock ups. placeholder: Tell us what you would like to do! value: | - #### What would you like to do? + #### What would you like to be able to do? #### Why would you like to do it? From 44ab38aa392b8fffc05b35c4cfa2a662327ec885 Mon Sep 17 00:00:00 2001 From: opusforlife2 <53176348+opusforlife2@users.noreply.github.com> Date: Fri, 15 Oct 2021 19:55:15 +0000 Subject: [PATCH 007/413] Add changelog file for PR #4257 --- changelog.d/4257.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/4257.misc diff --git a/changelog.d/4257.misc b/changelog.d/4257.misc new file mode 100644 index 0000000000..fa0657bfea --- /dev/null +++ b/changelog.d/4257.misc @@ -0,0 +1 @@ +Remove redundant text in feature request issue form From 1d73077184ea6083c3bdd52664a27eaeaf808e02 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 18 Oct 2021 18:21:22 +0200 Subject: [PATCH 008/413] Hilt: continue migration VM --- .../di/MavericksAssistedViewModelFactory.kt | 2 +- .../app/core/di/MavericksViewModelModule.kt | 158 ++++++++++++++++++ .../app/features/auth/ReAuthViewModel.kt | 2 +- .../app/features/call/VectorCallViewModel.kt | 2 +- .../call/conference/JitsiCallViewModel.kt | 2 +- .../call/transfer/CallTransferViewModel.kt | 2 +- .../contactsbook/ContactsBookViewModel.kt | 2 +- .../createdirect/CreateDirectRoomViewModel.kt | 2 +- .../settings/KeysBackupSettingsViewModel.kt | 2 +- .../quads/SharedSecureStorageViewModel.kt | 2 +- .../features/devtools/RoomDevToolViewModel.kt | 2 +- .../home/PromoteRestrictedViewModel.kt | 2 +- .../home/room/detail/RoomDetailActivity.kt | 15 +- .../reactions/ViewReactionsViewModel.kt | 2 +- .../detail/upgrade/MigrateRoomViewModel.kt | 2 +- .../home/room/list/RoomListViewModel.kt | 2 +- .../room/RequireActiveMembershipViewModel.kt | 20 +-- .../room/RequireActiveMembershipViewState.kt | 3 +- .../roomdirectory/RoomDirectoryViewModel.kt | 2 +- .../createroom/CreateRoomFragment.kt | 1 - .../createroom/CreateRoomViewModel.kt | 21 +-- .../picker/RoomDirectoryPickerViewModel.kt | 2 +- .../RoomPreviewNoPreviewFragment.kt | 1 - .../roompreview/RoomPreviewViewModel.kt | 18 +- .../RoomMemberProfileActivity.kt | 9 +- .../RoomMemberProfileFragment.kt | 1 - .../RoomMemberProfileViewModel.kt | 17 +- .../roomprofile/RoomProfileActivity.kt | 10 +- .../roomprofile/RoomProfileFragment.kt | 1 - .../roomprofile/RoomProfileViewModel.kt | 17 +- .../roomprofile/alias/RoomAliasFragment.kt | 1 - .../roomprofile/alias/RoomAliasViewModel.kt | 19 +-- .../alias/detail/RoomAliasBottomSheet.kt | 1 - .../detail/RoomAliasBottomSheetViewModel.kt | 17 +- .../banned/RoomBannedMemberListFragment.kt | 1 - .../banned/RoomBannedMemberListViewModel.kt | 19 +-- .../members/RoomMemberListViewModel.kt | 23 +-- .../RoomNotificationSettingsViewModel.kt | 2 +- .../permissions/RoomPermissionsFragment.kt | 1 - .../permissions/RoomPermissionsViewModel.kt | 17 +- .../settings/RoomSettingsViewModel.kt | 22 +-- .../settings/joinrule/RoomJoinRuleActivity.kt | 8 +- .../RoomJoinRuleChooseRestrictedViewModel.kt | 18 +- .../uploads/RoomUploadsFragment.kt | 4 +- .../uploads/RoomUploadsViewModel.kt | 21 +-- .../deactivation/DeactivateAccountFragment.kt | 4 +- .../DeactivateAccountViewModel.kt | 18 +- .../CrossSigningSettingsFragment.kt | 11 +- .../CrossSigningSettingsViewModel.kt | 41 ++--- .../settings/devices/DevicesViewModel.kt | 17 +- .../devices/VectorSettingsDevicesFragment.kt | 1 - .../settings/devtools/AccountDataFragment.kt | 1 - .../settings/devtools/AccountDataViewModel.kt | 17 +- .../GossipingEventsPaperTrailFragment.kt | 1 - .../GossipingEventsPaperTrailViewModel.kt | 18 +- .../IncomingKeyRequestListFragment.kt | 1 - .../devtools/KeyRequestListViewModel.kt | 23 +-- .../settings/devtools/KeyRequestViewModel.kt | 18 +- .../settings/devtools/KeyRequestsFragment.kt | 3 +- .../OutgoingKeyRequestListFragment.kt | 1 - .../homeserver/HomeserverSettingsFragment.kt | 1 - .../homeserver/HomeserverSettingsViewModel.kt | 18 +- .../settings/ignored/IgnoredUsersViewModel.kt | 2 +- .../settings/locale/LocalePickerFragment.kt | 2 - .../settings/locale/LocalePickerViewModel.kt | 22 +-- .../settings/push/PushGatewaysFragment.kt | 1 - .../settings/push/PushGatewaysViewModel.kt | 19 +-- .../threepids/ThreePidsSettingsFragment.kt | 2 - .../threepids/ThreePidsSettingsViewModel.kt | 21 +-- .../features/share/IncomingShareFragment.kt | 1 - .../features/share/IncomingShareViewModel.kt | 17 +- .../signout/soft/SoftLogoutActivity.kt | 1 - .../signout/soft/SoftLogoutViewModel.kt | 13 +- .../app/features/spaces/SpaceListViewModel.kt | 2 +- .../app/features/spaces/SpaceMenuViewModel.kt | 21 +-- .../spaces/SpaceSettingsMenuBottomSheet.kt | 7 +- .../spaces/create/CreateSpaceViewModel.kt | 2 +- .../spaces/explore/SpaceDirectoryViewModel.kt | 2 +- .../invite/SpaceInviteBottomSheetViewModel.kt | 2 +- .../leave/SpaceLeaveAdvancedViewModel.kt | 2 +- .../spaces/manage/SpaceAddRoomsViewModel.kt | 2 +- .../manage/SpaceManageRoomsViewModel.kt | 2 +- .../manage/SpaceManageSharedViewModel.kt | 2 +- .../spaces/manage/SpaceSettingsFragment.kt | 5 - .../spaces/people/SpacePeopleFragment.kt | 6 - .../spaces/people/SpacePeopleViewModel.kt | 2 +- .../spaces/preview/SpacePreviewViewModel.kt | 2 +- .../spaces/share/ShareSpaceViewModel.kt | 2 +- .../features/terms/ReviewTermsViewModel.kt | 2 +- .../usercode/UserCodeSharedViewModel.kt | 2 +- .../userdirectory/UserListViewModel.kt | 2 +- .../app/features/widgets/WidgetViewModel.kt | 2 +- .../RoomWidgetPermissionViewModel.kt | 2 +- .../signout/ServerBackupStatusViewModel.kt | 2 +- .../workers/signout/SignoutCheckViewModel.kt | 2 +- 95 files changed, 366 insertions(+), 502 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksAssistedViewModelFactory.kt b/vector/src/main/java/im/vector/app/core/di/MavericksAssistedViewModelFactory.kt index 4600ced00e..7cd6245d64 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksAssistedViewModelFactory.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksAssistedViewModelFactory.kt @@ -36,5 +36,5 @@ import com.airbnb.mvrx.MavericksViewModel * If you already have a ViewModelsModule then all you have to do is add the multibinding entry for your new [MavericksViewModel]. */ interface MavericksAssistedViewModelFactory, S : MavericksState> { - fun create(state: S): VM + fun create(initialState: S): VM } diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index 6724954479..6b7f275638 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -33,11 +33,37 @@ import im.vector.app.features.home.PromoteRestrictedViewModel 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.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.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.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 @@ -235,4 +261,136 @@ interface MavericksViewModelModule { @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<*, *> + + + } diff --git a/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt b/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt index a3d32ed13f..42c465e439 100644 --- a/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt @@ -38,7 +38,7 @@ class ReAuthViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: ReAuthState): ReAuthViewModel + override fun create(initialState: ReAuthState): ReAuthViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt index 72b5f557dc..07852b3fea 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt @@ -344,7 +344,7 @@ class VectorCallViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: VectorCallViewState): VectorCallViewModel + override fun create(initialState: VectorCallViewState): VectorCallViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt index 7a9a9099b5..e82a6829c0 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt @@ -49,7 +49,7 @@ class JitsiCallViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: JitsiCallViewState): JitsiCallViewModel + override fun create(initialState: JitsiCallViewState): JitsiCallViewModel } private var currentWidgetObserver: Job? = null diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt index de352149a7..f35e077025 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt @@ -41,7 +41,7 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState: @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: CallTransferViewState): CallTransferViewModel + override fun create(initialState: CallTransferViewState): CallTransferViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt index 05f98dedff..1d8c905c84 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt @@ -48,7 +48,7 @@ class ContactsBookViewModel @AssistedInject constructor(@Assisted @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: ContactsBookViewState): ContactsBookViewModel + override fun create(initialState: ContactsBookViewState): ContactsBookViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt index 0d75bb7ecb..1d284730cd 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt @@ -44,7 +44,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: CreateDirectRoomViewState): CreateDirectRoomViewModel + override fun create(initialState: CreateDirectRoomViewState): CreateDirectRoomViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index 08d118c403..b591d88286 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -42,7 +42,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: KeysBackupSettingViewState): KeysBackupSettingsViewModel + override fun create(initialState: KeysBackupSettingViewState): KeysBackupSettingsViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt index b93dac7c8c..c19fe0c33b 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt @@ -83,7 +83,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SharedSecureStorageViewState): SharedSecureStorageViewModel + override fun create(initialState: SharedSecureStorageViewState): SharedSecureStorageViewModel } init { diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt index b17bb1d2b1..04d90a63e7 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt @@ -50,7 +50,7 @@ class RoomDevToolViewModel @AssistedInject constructor( @AssistedFactory interface Factory : MavericksAssistedViewModelFactory { - override fun create(state: RoomDevToolViewState): RoomDevToolViewModel + override fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt index af6a226198..760de3a320 100644 --- a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt @@ -75,7 +75,7 @@ class PromoteRestrictedViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: ActiveSpaceViewState): PromoteRestrictedViewModel + override fun create(initialState: ActiveSpaceViewState): PromoteRestrictedViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index 24d7e13b79..08141a757e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -24,6 +24,7 @@ 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 im.vector.app.R @@ -39,15 +40,10 @@ 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 class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable, - RequireActiveMembershipViewModel.Factory, MatrixToBottomSheet.InteractionListener { override fun getBinding(): ActivityRoomDetailBinding { @@ -76,14 +72,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 ?: "")) - } - override fun injectWith(injector: ScreenComponent) { injector.inject(this) } @@ -101,6 +89,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()) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt index 715b0130bf..14e06c221a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt @@ -73,7 +73,7 @@ class ViewReactionsViewModel @AssistedInject constructor(@Assisted @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: DisplayReactionsViewState): ViewReactionsViewModel + override fun create(initialState: DisplayReactionsViewState): ViewReactionsViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt index 94be14fe4d..be718682b6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt @@ -51,7 +51,7 @@ class MigrateRoomViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: MigrateRoomViewState): MigrateRoomViewModel + override fun create(initialState: MigrateRoomViewState): MigrateRoomViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 81c887bd0e..c851f95cde 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -64,7 +64,7 @@ class RoomListViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: RoomListViewState): RoomListViewModel + override fun create(initialState: RoomListViewState): RoomListViewModel } private var updatableQuery: UpdatableLivePageResult? = null diff --git a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt index 44a6963a5d..93810b54cf 100644 --- a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt @@ -16,14 +16,14 @@ package im.vector.app.features.room -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.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 @@ -55,21 +55,11 @@ class RequireActiveMembershipViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RequireActiveMembershipViewState): RequireActiveMembershipViewModel? { - 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 by hiltMavericksViewModelFactory() private val roomIdFlow = MutableStateFlow(Optional.from(initialState.roomId)) diff --git a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewState.kt b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewState.kt index dbf399bdf2..7a5363100f 100644 --- a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewState.kt +++ b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewState.kt @@ -17,6 +17,7 @@ package im.vector.app.features.room import com.airbnb.mvrx.MavericksState +import im.vector.app.features.home.room.detail.RoomDetailArgs import im.vector.app.features.roommemberprofile.RoomMemberProfileArgs import im.vector.app.features.roomprofile.RoomProfileArgs @@ -24,7 +25,7 @@ data class RequireActiveMembershipViewState( val roomId: String? = null ) : MavericksState { - // No constructor for RoomDetailArgs because of intent for Shortcut + constructor(args: RoomDetailArgs) : this(roomId = args.roomId) constructor(args: RoomProfileArgs) : this(roomId = args.roomId) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt index 7b002c9631..ebd12e10b3 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt @@ -52,7 +52,7 @@ class RoomDirectoryViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: PublicRoomsViewState): RoomDirectoryViewModel + override fun create(initialState: PublicRoomsViewState): RoomDirectoryViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt index ac4c9db89f..c61da211a4 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt @@ -59,7 +59,6 @@ data class CreateRoomArgs( class CreateRoomFragment @Inject constructor( private val createRoomController: CreateRoomController, private val createSpaceController: CreateSubSpaceController, - val createRoomViewModelFactory: CreateRoomViewModel.Factory, colorProvider: ColorProvider ) : VectorBaseFragment(), CreateRoomController.Listener, diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt index e0a542dd68..e0ffdc7a52 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt @@ -17,17 +17,16 @@ package im.vector.app.features.roomdirectory.createroom import androidx.core.net.toFile -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 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.raw.wellknown.getElementWellknown @@ -60,10 +59,12 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted private val init ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: CreateRoomViewState): CreateRoomViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: CreateRoomViewState): CreateRoomViewModel } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + init { initHomeServerName() initAdminE2eByDefault() @@ -122,16 +123,6 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted private val init } } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: CreateRoomViewState): CreateRoomViewModel? { - val fragment: CreateRoomFragment = (viewModelContext as FragmentViewModelContext).fragment() - - return fragment.createRoomViewModelFactory.create(state) - } - } - override fun handle(action: CreateRoomAction) { when (action) { is CreateRoomAction.SetAvatar -> setAvatar(action) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt index 019afafa20..913bd2916b 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt @@ -48,7 +48,7 @@ class RoomDirectoryPickerViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: RoomDirectoryPickerViewState): RoomDirectoryPickerViewModel + override fun create(initialState: RoomDirectoryPickerViewState): RoomDirectoryPickerViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt index ef70a31a00..52617e2f1d 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt @@ -51,7 +51,6 @@ import javax.inject.Inject * Note: this Fragment is also used for world readable room for the moment */ class RoomPreviewNoPreviewFragment @Inject constructor( - val roomPreviewViewModelFactory: RoomPreviewViewModel.Factory, private val avatarRenderer: AvatarRenderer ) : VectorBaseFragment() { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index 1df070d3d9..30c1094687 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -16,15 +16,14 @@ package im.vector.app.features.roomdirectory.roompreview -import androidx.lifecycle.viewModelScope -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.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -50,18 +49,11 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val ini VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomPreviewViewState): RoomPreviewViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: RoomPreviewViewState): RoomPreviewViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomPreviewViewState): RoomPreviewViewModel? { - val fragment: RoomPreviewNoPreviewFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.roomPreviewViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { // Observe joined room (from the sync) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt index 8c166e7715..f5e0465209 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt @@ -36,8 +36,7 @@ import javax.inject.Inject class RoomMemberProfileActivity : VectorBaseActivity(), - ToolbarConfigurable, - RequireActiveMembershipViewModel.Factory { + ToolbarConfigurable { companion object { fun newIntent(context: Context, args: RoomMemberProfileArgs): Intent { @@ -49,12 +48,6 @@ class RoomMemberProfileActivity : private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel() - @Inject - lateinit var requireActiveMembershipViewModelFactory: RequireActiveMembershipViewModel.Factory - - override fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel { - return requireActiveMembershipViewModelFactory.create(initialState) - } override fun injectWith(injector: ScreenComponent) { injector.inject(this) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index d8e967fd27..48823714f5 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -66,7 +66,6 @@ data class RoomMemberProfileArgs( ) : Parcelable class RoomMemberProfileFragment @Inject constructor( - val viewModelFactory: RoomMemberProfileViewModel.Factory, private val roomMemberProfileController: RoomMemberProfileController, private val avatarRenderer: AvatarRenderer, private val roomDetailPendingActionStore: RoomDetailPendingActionStore diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index e99c8dde64..d68fbb9e0a 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -28,6 +28,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.mvrx.runCatchingToAsync import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider @@ -60,21 +62,14 @@ import org.matrix.android.sdk.flow.unwrap class RoomMemberProfileViewModel @AssistedInject constructor(@Assisted private val initialState: RoomMemberProfileViewState, private val stringProvider: StringProvider, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomMemberProfileViewState): RoomMemberProfileViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomMemberProfileViewState): RoomMemberProfileViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomMemberProfileViewState): RoomMemberProfileViewModel? { - val fragment: RoomMemberProfileFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val room = if (initialState.roomId != null) { session.getRoom(initialState.roomId) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index f9ba2f6810..05bff476cc 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -46,8 +46,7 @@ import javax.inject.Inject class RoomProfileActivity : VectorBaseActivity(), - ToolbarConfigurable, - RequireActiveMembershipViewModel.Factory { + ToolbarConfigurable { companion object { @@ -71,16 +70,9 @@ class RoomProfileActivity : private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel() - @Inject - lateinit var requireActiveMembershipViewModelFactory: RequireActiveMembershipViewModel.Factory - @Inject lateinit var roomDetailPendingActionStore: RoomDetailPendingActionStore - override fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel { - return requireActiveMembershipViewModelFactory.create(initialState) - } - override fun injectWith(injector: ScreenComponent) { injector.inject(this) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index e07746af85..23234f8bbd 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -67,7 +67,6 @@ class RoomProfileFragment @Inject constructor( private val roomProfileController: RoomProfileController, private val avatarRenderer: AvatarRenderer, private val roomDetailPendingActionStore: RoomDetailPendingActionStore, - val roomProfileViewModelFactory: RoomProfileViewModel.Factory ) : VectorBaseFragment(), RoomProfileController.Callback { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt index c4fc2bc7bb..472ddfc6b9 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileViewModel.kt @@ -17,13 +17,13 @@ package im.vector.app.features.roomprofile -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 @@ -53,18 +53,11 @@ class RoomProfileViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomProfileViewState): RoomProfileViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomProfileViewState): RoomProfileViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomProfileViewState): RoomProfileViewModel? { - val fragment: RoomProfileFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.roomProfileViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val room = session.getRoom(initialState.roomId)!! diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt index 0b144bea9f..e281c0f84d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt @@ -44,7 +44,6 @@ import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject class RoomAliasFragment @Inject constructor( - val viewModelFactory: RoomAliasViewModel.Factory, private val controller: RoomAliasController, private val avatarRenderer: AvatarRenderer ) : diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt index 68cbfc6170..19f600e5de 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasViewModel.kt @@ -17,15 +17,15 @@ package im.vector.app.features.roomprofile.alias 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.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.powerlevel.PowerLevelsFlowFactory @@ -45,21 +45,14 @@ import org.matrix.android.sdk.flow.unwrap class RoomAliasViewModel @AssistedInject constructor(@Assisted initialState: RoomAliasViewState, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomAliasViewState): RoomAliasViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomAliasViewState): RoomAliasViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomAliasViewState): RoomAliasViewModel? { - val fragment: RoomAliasFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val room = session.getRoom(initialState.roomId)!! diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt index e65efd4936..4a61a80422 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt @@ -50,7 +50,6 @@ class RoomAliasBottomSheet : private lateinit var sharedActionViewModel: RoomAliasBottomSheetSharedActionViewModel @Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool - @Inject lateinit var roomAliasBottomSheetViewModelFactory: RoomAliasBottomSheetViewModel.Factory @Inject lateinit var controller: RoomAliasBottomSheetController private val viewModel: RoomAliasBottomSheetViewModel by fragmentViewModel(RoomAliasBottomSheetViewModel::class) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetViewModel.kt index bc249fc746..0efef6ad8c 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetViewModel.kt @@ -15,12 +15,12 @@ */ package im.vector.app.features.roomprofile.alias.detail -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 @@ -32,18 +32,11 @@ class RoomAliasBottomSheetViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomAliasBottomSheetState): RoomAliasBottomSheetViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomAliasBottomSheetState): RoomAliasBottomSheetViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomAliasBottomSheetState): RoomAliasBottomSheetViewModel? { - val fragment: RoomAliasBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.roomAliasBottomSheetViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { setState { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt index 72f43639ed..c9fc889242 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt @@ -39,7 +39,6 @@ import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject class RoomBannedMemberListFragment @Inject constructor( - val viewModelFactory: RoomBannedMemberListViewModel.Factory, private val roomMemberListController: RoomBannedMemberListController, private val avatarRenderer: AvatarRenderer ) : VectorBaseFragment(), diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt index e3132c3cc5..d7efc2fb79 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListViewModel.kt @@ -16,13 +16,13 @@ package im.vector.app.features.roomprofile.banned -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 @@ -44,11 +44,11 @@ import org.matrix.android.sdk.flow.unwrap class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initialState: RoomBannedMemberListViewState, private val stringProvider: StringProvider, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomBannedMemberListViewState): RoomBannedMemberListViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomBannedMemberListViewState): RoomBannedMemberListViewModel } private val room = session.getRoom(initialState.roomId)!! @@ -77,14 +77,7 @@ class RoomBannedMemberListViewModel @AssistedInject constructor(@Assisted initia } } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomBannedMemberListViewState): RoomBannedMemberListViewModel? { - val fragment: RoomBannedMemberListFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() override fun handle(action: RoomBannedMemberListAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt index f16353353c..adf5a31f2a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt @@ -17,13 +17,12 @@ package im.vector.app.features.roomprofile.members import androidx.lifecycle.asFlow -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.extensions.exhaustive import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -57,24 +56,14 @@ import timber.log.Timber class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState: RoomMemberListViewState, private val roomMemberSummaryComparator: RoomMemberSummaryComparator, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomMemberListViewState): RoomMemberListViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomMemberListViewState): RoomMemberListViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomMemberListViewState): RoomMemberListViewModel? { - 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 by hiltMavericksViewModelFactory() private val room = session.getRoom(initialState.roomId)!! diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt index c83a069250..ab0333e294 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt @@ -36,7 +36,7 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel + override fun create(initialState: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt index a538c9269b..acf01321c9 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsFragment.kt @@ -39,7 +39,6 @@ import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject class RoomPermissionsFragment @Inject constructor( - val viewModelFactory: RoomPermissionsViewModel.Factory, private val controller: RoomPermissionsController, private val avatarRenderer: AvatarRenderer ) : diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt index bf2f2134d6..c0950f226d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt @@ -16,13 +16,13 @@ package im.vector.app.features.roomprofile.permissions -import com.airbnb.mvrx.FragmentViewModelContext 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.powerlevel.PowerLevelsFlowFactory @@ -42,18 +42,11 @@ class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialStat VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomPermissionsViewState): RoomPermissionsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: RoomPermissionsViewState): RoomPermissionsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomPermissionsViewState): RoomPermissionsViewModel? { - val fragment: RoomPermissionsFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val room = session.getRoom(initialState.roomId)!! diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt index c3c8ca7e2f..28c84f9fe4 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt @@ -24,6 +24,8 @@ 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.powerlevel.PowerLevelsFlowFactory @@ -50,24 +52,14 @@ import org.matrix.android.sdk.flow.unwrap class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: RoomSettingsViewState, private val vectorPreferences: VectorPreferences, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomSettingsViewState): RoomSettingsViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomSettingsViewState): RoomSettingsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomSettingsViewState): RoomSettingsViewModel? { - 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 by hiltMavericksViewModelFactory() private val room = session.getRoom(initialState.roomId)!! @@ -150,7 +142,7 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: canChangeJoinRule = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_JOIN_RULES) && powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, - EventType.STATE_ROOM_GUEST_ACCESS), + EventType.STATE_ROOM_GUEST_ACCESS), canAddChildren = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_SPACE_CHILD) ) diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt index dcce7b2384..c54be807b0 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt @@ -44,23 +44,17 @@ import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRul import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedViewModel import javax.inject.Inject -class RoomJoinRuleActivity : VectorBaseActivity(), - RoomJoinRuleChooseRestrictedViewModel.Factory { +class RoomJoinRuleActivity : VectorBaseActivity() { override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) private lateinit var roomProfileArgs: RoomProfileArgs - @Inject - lateinit var allowListViewModelFactory: RoomJoinRuleChooseRestrictedViewModel.Factory - @Inject lateinit var errorFormatter: ErrorFormatter val viewModel: RoomJoinRuleChooseRestrictedViewModel by viewModel() - override fun create(initialState: RoomJoinRuleChooseRestrictedState) = allowListViewModelFactory.create(initialState) - override fun injectWith(injector: ScreenComponent) { injector.inject(this) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt index 1e7f1d2111..039862bde7 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt @@ -18,7 +18,6 @@ package im.vector.app.features.roomprofile.settings.joinrule.advanced import android.graphics.Typeface import androidx.core.text.toSpannable -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.Fail import com.airbnb.mvrx.FragmentViewModelContext @@ -31,6 +30,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider @@ -175,8 +176,8 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: RoomJoinRuleChooseRestrictedState): RoomJoinRuleChooseRestrictedViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: RoomJoinRuleChooseRestrictedState): RoomJoinRuleChooseRestrictedViewModel } override fun handle(action: RoomJoinRuleChooseRestrictedActions) { @@ -391,14 +392,5 @@ class RoomJoinRuleChooseRestrictedViewModel @AssistedInject constructor( } } - companion object : MavericksViewModelFactory { - - override fun create(viewModelContext: ViewModelContext, state: RoomJoinRuleChooseRestrictedState): RoomJoinRuleChooseRestrictedViewModel? { - 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 by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt index f079daf262..3716d9682c 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt @@ -42,11 +42,9 @@ import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject class RoomUploadsFragment @Inject constructor( - private val viewModelFactory: RoomUploadsViewModel.Factory, private val avatarRenderer: AvatarRenderer, private val notificationUtils: NotificationUtils -) : VectorBaseFragment(), - RoomUploadsViewModel.Factory by viewModelFactory { +) : VectorBaseFragment() { private val roomProfileArgs: RoomProfileArgs by args() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt index 3d3ad375ea..0c08ff6d4d 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt @@ -16,16 +16,15 @@ package im.vector.app.features.roomprofile.uploads -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 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.launch @@ -40,21 +39,11 @@ class RoomUploadsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: RoomUploadsViewState): RoomUploadsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: RoomUploadsViewState): RoomUploadsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomUploadsViewState): RoomUploadsViewModel? { - 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 by hiltMavericksViewModelFactory() private val room = session.getRoom(initialState.roomId)!! diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt index 4e599e81fb..5729e773b7 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt @@ -36,9 +36,7 @@ import im.vector.app.features.settings.VectorSettingsActivity import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import javax.inject.Inject -class DeactivateAccountFragment @Inject constructor( - val viewModelFactory: DeactivateAccountViewModel.Factory -) : VectorBaseFragment() { +class DeactivateAccountFragment @Inject constructor() : VectorBaseFragment() { private val viewModel: DeactivateAccountViewModel by fragmentViewModel() diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt index 5aaa0be13a..a0591f837b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt @@ -15,14 +15,13 @@ */ package im.vector.app.features.settings.account.deactivation -import androidx.lifecycle.viewModelScope -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.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.auth.ReAuthActivity @@ -49,8 +48,8 @@ class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private v VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: DeactivateAccountViewState): DeactivateAccountViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: DeactivateAccountViewState): DeactivateAccountViewModel } var uiaContinuation: Continuation? = null @@ -114,12 +113,5 @@ class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private v } } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: DeactivateAccountViewState): DeactivateAccountViewModel? { - val fragment: DeactivateAccountFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt index d60d9138d7..fa061cdf8d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt @@ -42,7 +42,6 @@ import javax.inject.Inject */ class CrossSigningSettingsFragment @Inject constructor( private val controller: CrossSigningSettingsController, - val viewModelFactory: CrossSigningSettingsViewModel.Factory ) : VectorBaseFragment(), CrossSigningSettingsController.InteractionListener { @@ -55,14 +54,14 @@ class CrossSigningSettingsFragment @Inject constructor( private val reAuthActivityResultLauncher = registerStartForActivityResult { activityResult -> if (activityResult.resultCode == Activity.RESULT_OK) { when (activityResult.data?.extras?.getString(ReAuthActivity.RESULT_FLOW_TYPE)) { - LoginFlowTypes.SSO -> { + LoginFlowTypes.SSO -> { viewModel.handle(CrossSigningSettingsAction.SsoAuthDone) } LoginFlowTypes.PASSWORD -> { val password = activityResult.data?.extras?.getString(ReAuthActivity.RESULT_VALUE) ?: "" viewModel.handle(CrossSigningSettingsAction.PasswordAuthDone(password)) } - else -> { + else -> { viewModel.handle(CrossSigningSettingsAction.ReAuthCancelled) } } @@ -78,7 +77,7 @@ class CrossSigningSettingsFragment @Inject constructor( setupRecyclerView() viewModel.observeViewEvents { event -> when (event) { - is CrossSigningSettingsViewEvents.Failure -> { + is CrossSigningSettingsViewEvents.Failure -> { MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.dialog_title_error) .setMessage(errorFormatter.toHumanReadable(event.throwable)) @@ -86,7 +85,7 @@ class CrossSigningSettingsFragment @Inject constructor( .show() Unit } - is CrossSigningSettingsViewEvents.RequestReAuth -> { + is CrossSigningSettingsViewEvents.RequestReAuth -> { ReAuthActivity.newIntent(requireContext(), event.registrationFlowResponse, event.lastErrorCode, @@ -98,7 +97,7 @@ class CrossSigningSettingsFragment @Inject constructor( views.waitingView.waitingView.isVisible = true views.waitingView.waitingStatusText.setTextOrHide(event.status) } - CrossSigningSettingsViewEvents.HideModalWaitingView -> { + CrossSigningSettingsViewEvents.HideModalWaitingView -> { views.waitingView.waitingView.isVisible = false } }.exhaustive diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt index 033d9cf716..644b7f33dd 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt @@ -15,13 +15,13 @@ */ package im.vector.app.features.settings.crosssigning -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 @@ -61,27 +61,27 @@ class CrossSigningSettingsViewModel @AssistedInject constructor( ) { myDevicesInfo, mxCrossSigningInfo -> myDevicesInfo to mxCrossSigningInfo } - .execute { data -> - val crossSigningKeys = data.invoke()?.second?.getOrNull() - val xSigningIsEnableInAccount = crossSigningKeys != null - val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified() - val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign() + .execute { data -> + val crossSigningKeys = data.invoke()?.second?.getOrNull() + val xSigningIsEnableInAccount = crossSigningKeys != null + val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified() + val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign() - copy( - crossSigningInfo = crossSigningKeys, - xSigningIsEnableInAccount = xSigningIsEnableInAccount, - xSigningKeysAreTrusted = xSigningKeysAreTrusted, - xSigningKeyCanSign = xSigningKeyCanSign - ) - } + copy( + crossSigningInfo = crossSigningKeys, + xSigningIsEnableInAccount = xSigningIsEnableInAccount, + xSigningKeysAreTrusted = xSigningKeysAreTrusted, + xSigningKeyCanSign = xSigningKeyCanSign + ) + } } var uiaContinuation: Continuation? = null var pendingAuth: UIABaseAuth? = null @AssistedFactory - interface Factory { - fun create(initialState: CrossSigningSettingsViewState): CrossSigningSettingsViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: CrossSigningSettingsViewState): CrossSigningSettingsViewModel } override fun handle(action: CrossSigningSettingsAction) { @@ -154,12 +154,5 @@ class CrossSigningSettingsViewModel @AssistedInject constructor( _viewEvents.post(CrossSigningSettingsViewEvents.Failure(Exception(stringProvider.getString(R.string.failed_to_initialize_cross_signing)))) } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: CrossSigningSettingsViewState): CrossSigningSettingsViewModel? { - val fragment: CrossSigningSettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index a8154c3e11..e147491093 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -18,17 +18,17 @@ package im.vector.app.features.settings.devices 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.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import im.vector.app.features.auth.ReAuthActivity @@ -97,18 +97,11 @@ class DevicesViewModel @AssistedInject constructor( var pendingAuth: UIABaseAuth? = null @AssistedFactory - interface Factory { - fun create(initialState: DevicesViewState): DevicesViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: DevicesViewState): DevicesViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: DevicesViewState): DevicesViewModel? { - val fragment: VectorSettingsDevicesFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.devicesViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val refreshPublisher: PublishSubject = PublishSubject.create() diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt index 62923d4f3d..531e9a944b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt @@ -47,7 +47,6 @@ import javax.inject.Inject * Display the list of the user's device */ class VectorSettingsDevicesFragment @Inject constructor( - val devicesViewModelFactory: DevicesViewModel.Factory, private val devicesController: DevicesController ) : VectorBaseFragment(), DevicesController.Callback { diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt index 570da6875a..a586e14d99 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt @@ -37,7 +37,6 @@ import org.matrix.android.sdk.internal.di.MoshiProvider import javax.inject.Inject class AccountDataFragment @Inject constructor( - val viewModelFactory: AccountDataViewModel.Factory, private val epoxyController: AccountDataEpoxyController, private val colorProvider: ColorProvider ) : VectorBaseFragment(), diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt index 104ee71edc..ba03bac0d8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt @@ -17,14 +17,14 @@ package im.vector.app.features.settings.devtools import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory 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.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -61,16 +61,9 @@ class AccountDataViewModel @AssistedInject constructor(@Assisted initialState: A } @AssistedFactory - interface Factory { - fun create(initialState: AccountDataViewState): AccountDataViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: AccountDataViewState): AccountDataViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: AccountDataViewState): AccountDataViewModel? { - val fragment: AccountDataFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt index 7325288c55..83740c5018 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt @@ -34,7 +34,6 @@ import org.matrix.android.sdk.api.session.events.model.Event import javax.inject.Inject class GossipingEventsPaperTrailFragment @Inject constructor( - val viewModelFactory: GossipingEventsPaperTrailViewModel.Factory, private val epoxyController: GossipingTrailPagedEpoxyController, private val colorProvider: ColorProvider ) : VectorBaseFragment(), diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt index fd09b38919..1aaebc5598 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt @@ -19,15 +19,15 @@ package im.vector.app.features.settings.devtools import androidx.lifecycle.asFlow import androidx.paging.PagedList import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory 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.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -60,17 +60,9 @@ class GossipingEventsPaperTrailViewModel @AssistedInject constructor(@Assisted i override fun handle(action: EmptyAction) {} @AssistedFactory - interface Factory { - fun create(initialState: GossipingEventsPaperTrailState): GossipingEventsPaperTrailViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: GossipingEventsPaperTrailState): GossipingEventsPaperTrailViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: GossipingEventsPaperTrailState): GossipingEventsPaperTrailViewModel? { - val fragment: GossipingEventsPaperTrailFragment = (viewModelContext as FragmentViewModelContext).fragment() - - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt index 8bf89d975c..ac4bef9c94 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt @@ -30,7 +30,6 @@ import im.vector.app.databinding.FragmentGenericRecyclerBinding import javax.inject.Inject class IncomingKeyRequestListFragment @Inject constructor( - val viewModelFactory: KeyRequestListViewModel.Factory, private val epoxyController: IncomingKeyRequestPagedController ) : VectorBaseFragment() { diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt index 37decc4a12..197a72cb05 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt @@ -17,17 +17,16 @@ package im.vector.app.features.settings.devtools import androidx.lifecycle.asFlow -import androidx.lifecycle.viewModelScope import androidx.paging.PagedList import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory 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.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -43,7 +42,7 @@ data class KeyRequestListViewState( class KeyRequestListViewModel @AssistedInject constructor(@Assisted initialState: KeyRequestListViewState, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { init { refresh() @@ -67,19 +66,9 @@ class KeyRequestListViewModel @AssistedInject constructor(@Assisted initialState override fun handle(action: EmptyAction) {} @AssistedFactory - interface Factory { - fun create(initialState: KeyRequestListViewState): KeyRequestListViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: KeyRequestListViewState): KeyRequestListViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: KeyRequestListViewState): KeyRequestListViewModel? { - val context = viewModelContext as FragmentViewModelContext - val factory = (context.fragment as? IncomingKeyRequestListFragment)?.viewModelFactory - ?: (context.fragment as? OutgoingKeyRequestListFragment)?.viewModelFactory - - return factory?.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt index 362502d7d8..fe9960b9ab 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt @@ -17,19 +17,18 @@ package im.vector.app.features.settings.devtools import android.net.Uri -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.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewEvents import im.vector.app.core.platform.VectorViewModel @@ -56,18 +55,11 @@ class KeyRequestViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: KeyRequestViewState): KeyRequestViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: KeyRequestViewState): KeyRequestViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: KeyRequestViewState): KeyRequestViewModel? { - val fragment: KeyRequestsFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() override fun handle(action: KeyRequestAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt index 0b3d8812f1..d807fc620a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt @@ -41,8 +41,7 @@ import im.vector.app.databinding.FragmentDevtoolKeyrequestsBinding import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject -class KeyRequestsFragment @Inject constructor( - val viewModelFactory: KeyRequestViewModel.Factory) : VectorBaseFragment() { +class KeyRequestsFragment @Inject constructor() : VectorBaseFragment() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDevtoolKeyrequestsBinding { return FragmentDevtoolKeyrequestsBinding.inflate(inflater, container, false) diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt index 0cbca2f38a..0483d5fb4d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt @@ -29,7 +29,6 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding import javax.inject.Inject class OutgoingKeyRequestListFragment @Inject constructor( - val viewModelFactory: KeyRequestListViewModel.Factory, private val epoxyController: OutgoingKeyRequestPagedController ) : VectorBaseFragment() { diff --git a/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsFragment.kt index 20541a1ebb..28bce90424 100644 --- a/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsFragment.kt @@ -34,7 +34,6 @@ import javax.inject.Inject * Display some information about the homeserver */ class HomeserverSettingsFragment @Inject constructor( - val homeserverSettingsViewModelFactory: HomeserverSettingsViewModel.Factory, private val homeserverSettingsController: HomeserverSettingsController ) : VectorBaseFragment(), HomeserverSettingsController.Callback { diff --git a/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsViewModel.kt index 91ad34f1b6..baf24d28a3 100644 --- a/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsViewModel.kt @@ -16,16 +16,15 @@ package im.vector.app.features.settings.homeserver -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.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch @@ -37,18 +36,11 @@ class HomeserverSettingsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: HomeServerSettingsViewState): HomeserverSettingsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: HomeServerSettingsViewState): HomeserverSettingsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: HomeServerSettingsViewState): HomeserverSettingsViewModel? { - val fragment: HomeserverSettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.homeserverSettingsViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { setState { diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt index abfeab9504..1ae079819c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt @@ -52,7 +52,7 @@ class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: IgnoredUsersViewState): IgnoredUsersViewModel + override fun create(initialState: IgnoredUsersViewState): IgnoredUsersViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt index 7368bec397..601574c908 100644 --- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt @@ -34,10 +34,8 @@ import java.util.Locale import javax.inject.Inject class LocalePickerFragment @Inject constructor( - private val viewModelFactory: LocalePickerViewModel.Factory, private val controller: LocalePickerController ) : VectorBaseFragment(), - LocalePickerViewModel.Factory by viewModelFactory, LocalePickerController.Listener { private val viewModel: LocalePickerViewModel by fragmentViewModel() diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt index 83858dff6a..d6b35fa4fe 100644 --- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerViewModel.kt @@ -16,15 +16,13 @@ package im.vector.app.features.settings.locale -import androidx.lifecycle.viewModelScope -import com.airbnb.mvrx.ActivityViewModelContext -import com.airbnb.mvrx.FragmentViewModelContext 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.configuration.VectorConfiguration @@ -37,8 +35,8 @@ class LocalePickerViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: LocalePickerViewState): LocalePickerViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: LocalePickerViewState): LocalePickerViewModel } init { @@ -53,17 +51,7 @@ class LocalePickerViewModel @AssistedInject constructor( } } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: LocalePickerViewState): LocalePickerViewModel? { - 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 by hiltMavericksViewModelFactory() override fun handle(action: LocalePickerAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt index 0801e78197..65c62542bb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt @@ -36,7 +36,6 @@ import javax.inject.Inject // Referenced in vector_settings_notifications.xml class PushGatewaysFragment @Inject constructor( - val pushGatewaysViewModelFactory: PushGatewaysViewModel.Factory, private val epoxyController: PushGateWayController ) : VectorBaseFragment() { diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt index d8205aada9..1256673364 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysViewModel.kt @@ -17,14 +17,14 @@ package im.vector.app.features.settings.push import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory 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.launch @@ -38,21 +38,14 @@ data class PushGatewayViewState( class PushGatewaysViewModel @AssistedInject constructor(@Assisted initialState: PushGatewayViewState, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: PushGatewayViewState): PushGatewaysViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: PushGatewayViewState): PushGatewaysViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: PushGatewayViewState): PushGatewaysViewModel? { - val fragment: PushGatewaysFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.pushGatewaysViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { observePushers() diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt index 384348b85d..a893f0f508 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt @@ -43,12 +43,10 @@ import org.matrix.android.sdk.api.session.identity.ThreePid import javax.inject.Inject class ThreePidsSettingsFragment @Inject constructor( - private val viewModelFactory: ThreePidsSettingsViewModel.Factory, private val epoxyController: ThreePidsSettingsController ) : VectorBaseFragment(), OnBackPressed, - ThreePidsSettingsViewModel.Factory by viewModelFactory, ThreePidsSettingsController.InteractionListener { private val viewModel: ThreePidsSettingsViewModel by fragmentViewModel() diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt index cd0d74a288..12ff436ccb 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt @@ -16,16 +16,15 @@ package im.vector.app.features.settings.threepids -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.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 @@ -79,21 +78,11 @@ class ThreePidsSettingsViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: ThreePidsSettingsViewState): ThreePidsSettingsViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: ThreePidsSettingsViewState): ThreePidsSettingsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: ThreePidsSettingsViewState): ThreePidsSettingsViewModel? { - 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 by hiltMavericksViewModelFactory() init { observeThreePids() diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt index 2132ba7989..d5fd3050e9 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt @@ -50,7 +50,6 @@ import javax.inject.Inject * The user can select multiple rooms to send the data to */ class IncomingShareFragment @Inject constructor( - val incomingShareViewModelFactory: IncomingShareViewModel.Factory, private val incomingShareController: IncomingShareController, private val sessionHolder: ActiveSessionHolder ) : diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt index b476065035..229eca0596 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt @@ -16,12 +16,12 @@ package im.vector.app.features.share -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.extensions.exhaustive import im.vector.app.core.extensions.toggle import im.vector.app.core.platform.VectorViewModel @@ -46,18 +46,11 @@ class IncomingShareViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: IncomingShareViewState): IncomingShareViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: IncomingShareViewState): IncomingShareViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: IncomingShareViewState): IncomingShareViewModel? { - val fragment: IncomingShareFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.incomingShareViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val filterStream = MutableStateFlow("") diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt index 72b9a278e2..91b775cc57 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt @@ -43,7 +43,6 @@ class SoftLogoutActivity : LoginActivity() { private val softLogoutViewModel: SoftLogoutViewModel by viewModel() - @Inject lateinit var softLogoutViewModelFactory: SoftLogoutViewModel.Factory @Inject lateinit var session: Session @Inject lateinit var errorFormatter: ErrorFormatter diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt index dfc483a813..0e272c0981 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt @@ -27,6 +27,8 @@ 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.hasUnsavedKeys import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.login.LoginMode @@ -47,11 +49,11 @@ class SoftLogoutViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SoftLogoutViewState): SoftLogoutViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: SoftLogoutViewState): SoftLogoutViewModel } - companion object : MavericksViewModelFactory { + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory(){ override fun initialState(viewModelContext: ViewModelContext): SoftLogoutViewState? { val activity: SoftLogoutActivity = (viewModelContext as ActivityViewModelContext).activity() @@ -65,11 +67,6 @@ class SoftLogoutViewModel @AssistedInject constructor( ) } - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: SoftLogoutViewState): SoftLogoutViewModel? { - val activity: SoftLogoutActivity = (viewModelContext as ActivityViewModelContext).activity() - return activity.softLogoutViewModelFactory.create(state) - } } init { diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index ed027702f2..f099896fac 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -68,7 +68,7 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SpaceListViewState): SpaceListViewModel + override fun create(initialState: SpaceListViewState): SpaceListViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt index 887c93afd4..3840ef4447 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt @@ -16,18 +16,17 @@ package im.vector.app.features.spaces -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.Uninitialized -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.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.features.powerlevel.PowerLevelsFlowFactory @@ -52,21 +51,11 @@ class SpaceMenuViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SpaceMenuState): SpaceMenuViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: SpaceMenuState): SpaceMenuViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: SpaceMenuState): SpaceMenuViewModel? { - 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 by hiltMavericksViewModelFactory() init { val roomSummary = session.getRoomSummary(initialState.spaceId) diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceSettingsMenuBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceSettingsMenuBottomSheet.kt index 040f1f9057..4818175d30 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceSettingsMenuBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceSettingsMenuBottomSheet.kt @@ -46,12 +46,11 @@ data class SpaceBottomSheetSettingsArgs( val spaceId: String ) : Parcelable -class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment(), SpaceMenuViewModel.Factory { +class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment(){ @Inject lateinit var navigator: Navigator @Inject lateinit var avatarRenderer: AvatarRenderer @Inject lateinit var bugReporter: BugReporter - @Inject lateinit var viewModelFactory: SpaceMenuViewModel.Factory private val spaceArgs: SpaceBottomSheetSettingsArgs by args() @@ -139,8 +138,4 @@ class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment { - override fun create(state: CreateSpaceState): CreateSpaceViewModel + override fun create(initialState: CreateSpaceState): CreateSpaceViewModel } private fun startListenToIdentityManager() { diff --git a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt index b3bfed5cba..b7b419e60f 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt @@ -52,7 +52,7 @@ class SpaceDirectoryViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SpaceDirectoryState): SpaceDirectoryViewModel + override fun create(initialState: SpaceDirectoryState): SpaceDirectoryViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt index d28b3cc9e9..bb07572ca3 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt @@ -96,7 +96,7 @@ class SpaceInviteBottomSheetViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SpaceInviteBottomSheetState): SpaceInviteBottomSheetViewModel + override fun create(initialState: SpaceInviteBottomSheetState): SpaceInviteBottomSheetViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt index aeca13d1cf..ec7cb8d4c5 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt @@ -127,7 +127,7 @@ class SpaceLeaveAdvancedViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SpaceLeaveAdvanceViewState): SpaceLeaveAdvancedViewModel + override fun create(initialState: SpaceLeaveAdvanceViewState): SpaceLeaveAdvancedViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt index 1ff8a321e5..05707df49e 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt @@ -58,7 +58,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SpaceAddRoomsState): SpaceAddRoomsViewModel + override fun create(initialState: SpaceAddRoomsState): SpaceAddRoomsViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt index a0cc4dea5c..469ece6cb0 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt @@ -55,7 +55,7 @@ class SpaceManageRoomsViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SpaceManageRoomViewState): SpaceManageRoomsViewModel + override fun create(initialState: SpaceManageRoomViewState): SpaceManageRoomsViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt index 925315b65c..c05421a9a8 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt @@ -33,7 +33,7 @@ class SpaceManageSharedViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory{ - override fun create(state: SpaceManageViewState): SpaceManageSharedViewModel + override fun create(initialState: SpaceManageViewState): SpaceManageSharedViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt index 5e5eb50b87..18bb6fa01a 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt @@ -59,11 +59,9 @@ import javax.inject.Inject class SpaceSettingsFragment @Inject constructor( private val epoxyController: SpaceSettingsController, private val colorProvider: ColorProvider, - val viewModelFactory: RoomSettingsViewModel.Factory, private val avatarRenderer: AvatarRenderer, private val drawableProvider: DrawableProvider ) : VectorBaseFragment(), - RoomSettingsViewModel.Factory, SpaceSettingsController.Callback, GalleryOrCameraDialogHelper.Listener, OnBackPressed { @@ -81,9 +79,6 @@ class SpaceSettingsFragment @Inject constructor( override fun getMenuRes() = R.menu.vector_room_settings - override fun create(initialState: RoomSettingsViewState): RoomSettingsViewModel { - return viewModelFactory.create(initialState) - } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt index b53845c09a..89ce154021 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt @@ -44,12 +44,10 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject class SpacePeopleFragment @Inject constructor( - private val roomMemberModelFactory: RoomMemberListViewModel.Factory, private val drawableProvider: DrawableProvider, private val colorProvider: ColorProvider, private val epoxyController: SpacePeopleListController ) : VectorBaseFragment(), - RoomMemberListViewModel.Factory, OnBackPressed, SpacePeopleListController.InteractionListener { private val viewModel by fragmentViewModel(SpacePeopleViewModel::class) @@ -64,10 +62,6 @@ class SpacePeopleFragment @Inject constructor( return true } - override fun create(initialState: RoomMemberListViewState): RoomMemberListViewModel { - return roomMemberModelFactory.create(initialState) - } - override fun invalidate() = withState(membersViewModel) { memberListState -> views.appBarTitle.text = getString(R.string.bottom_action_people) val memberCount = (memberListState.roomSummary.invoke()?.otherMemberIds?.size ?: 0) + 1 diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt index bf77166a5c..126539589d 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt @@ -43,7 +43,7 @@ class SpacePeopleViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SpacePeopleViewState): SpacePeopleViewModel + override fun create(initialState: SpacePeopleViewState): SpacePeopleViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt index ae69375ad6..e63fdc638b 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt @@ -61,7 +61,7 @@ class SpacePreviewViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SpacePreviewState): SpacePreviewViewModel + override fun create(initialState: SpacePreviewState): SpacePreviewViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt index 56de40a50a..174edf309e 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt @@ -38,7 +38,7 @@ class ShareSpaceViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: ShareSpaceViewState): ShareSpaceViewModel + override fun create(initialState: ShareSpaceViewState): ShareSpaceViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt index db46c55b7d..508d0210e5 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt @@ -37,7 +37,7 @@ class ReviewTermsViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: ReviewTermsViewState): ReviewTermsViewModel + override fun create(initialState: ReviewTermsViewState): ReviewTermsViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt index 7efbfd396e..f38fb9f3f9 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt @@ -57,7 +57,7 @@ class UserCodeSharedViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: UserCodeState): UserCodeSharedViewModel + override fun create(initialState: UserCodeState): UserCodeSharedViewModel } override fun handle(action: UserCodeActions) { diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index a22c7ecf16..1b5a6390b0 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -64,7 +64,7 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: UserListViewState): UserListViewModel + override fun create(initialState: UserListViewState): UserListViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt index 26a43ec8d0..e137165c3e 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt @@ -60,7 +60,7 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: WidgetViewState): WidgetViewModel + override fun create(initialState: WidgetViewState): WidgetViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt index b1fe18cc3f..236bfb4032 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt @@ -143,7 +143,7 @@ class RoomWidgetPermissionViewModel @AssistedInject constructor(@Assisted val in @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel + override fun create(initialState: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt index 0663ec83ab..7c8904135c 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt @@ -70,7 +70,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: ServerBackupStatusViewState): ServerBackupStatusViewModel + override fun create(initialState: ServerBackupStatusViewState): ServerBackupStatusViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt index 3e36106ff2..ac3efe56db 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt @@ -69,7 +69,7 @@ class SignoutCheckViewModel @AssistedInject constructor( @AssistedFactory interface Factory: MavericksAssistedViewModelFactory { - override fun create(state: SignoutCheckViewState): SignoutCheckViewModel + override fun create(initialState: SignoutCheckViewState): SignoutCheckViewModel } companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() From bb68e735f74f01b0bbf431bc7d030b4c57f5d6b8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 19 Oct 2021 16:31:22 +0200 Subject: [PATCH 009/413] Hilt: continue migration VM --- .../app/core/di/MavericksViewModelModule.kt | 119 ++++++++++++++++++ .../VerificationChooseMethodFragment.kt | 1 - .../VerificationChooseMethodViewModel.kt | 33 +++-- .../emoji/VerificationEmojiCodeFragment.kt | 1 - .../emoji/VerificationEmojiCodeViewModel.kt | 13 +- .../discovery/DiscoverySettingsFragment.kt | 3 +- .../discovery/DiscoverySettingsViewModel.kt | 17 +-- .../change/SetIdentityServerFragment.kt | 1 - .../change/SetIdentityServerViewModel.kt | 18 +-- .../vector/app/features/home/HomeActivity.kt | 12 -- .../app/features/home/HomeDetailFragment.kt | 1 - .../app/features/home/HomeDetailViewModel.kt | 16 +-- .../UnknownDeviceDetectorSharedViewModel.kt | 21 +--- .../home/UnreadMessagesSharedViewModel.kt | 21 +--- .../room/breadcrumbs/BreadcrumbsFragment.kt | 3 +- .../room/breadcrumbs/BreadcrumbsViewModel.kt | 17 +-- .../home/room/detail/RoomDetailFragment.kt | 1 - .../detail/composer/TextComposerViewModel.kt | 15 +-- .../home/room/detail/search/SearchFragment.kt | 1 - .../room/detail/search/SearchViewModel.kt | 18 +-- .../action/MessageActionsBottomSheet.kt | 1 - .../action/MessageActionsViewModel.kt | 16 +-- .../edithistory/ViewEditHistoryBottomSheet.kt | 1 - .../edithistory/ViewEditHistoryViewModel.kt | 18 +-- .../HomeServerCapabilitiesViewModel.kt | 19 ++- .../invite/InviteUsersToRoomActivity.kt | 5 +- .../invite/InviteUsersToRoomViewModel.kt | 21 +--- .../app/features/login/LoginActivity.kt | 2 - .../app/features/login/LoginViewModel.kt | 20 +-- .../app/features/login2/LoginActivity2.kt | 2 - .../app/features/login2/LoginViewModel2.kt | 20 +-- .../login2/created/AccountCreatedFragment.kt | 1 - .../login2/created/AccountCreatedViewModel.kt | 18 +-- .../features/matrixto/MatrixToBottomSheet.kt | 3 - .../matrixto/MatrixToBottomSheetViewModel.kt | 19 +-- .../features/rageshake/BugReportActivity.kt | 2 - .../features/rageshake/BugReportViewModel.kt | 18 +-- .../reactions/EmojiReactionPickerActivity.kt | 1 - .../reactions/EmojiSearchResultViewModel.kt | 18 +-- .../members/RoomMemberListFragment.kt | 8 +- .../settings/RoomSettingsFragment.kt | 8 +- .../userdirectory/UserListFragment.kt | 1 - 42 files changed, 242 insertions(+), 312 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index 6b7f275638..c98acee64c 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -28,11 +28,32 @@ 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.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.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.RoomDetailViewModel +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 @@ -391,6 +412,104 @@ interface MavericksViewModelModule { @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<*, *> } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt index 92faa7a0e7..31a7956db3 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt @@ -40,7 +40,6 @@ import timber.log.Timber import javax.inject.Inject class VerificationChooseMethodFragment @Inject constructor( - val verificationChooseMethodViewModelFactory: VerificationChooseMethodViewModel.Factory, val controller: VerificationChooseMethodController ) : VectorBaseFragment(), VerificationChooseMethodController.Listener { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt index 990a204bc1..44f41c338c 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt @@ -15,7 +15,6 @@ */ 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 @@ -23,6 +22,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject 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.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -50,6 +51,10 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( private val session: Session ) : VectorViewModel(initialState), VerificationService.Listener { + init { + session.cryptoService().verificationService().addListener(this) + } + override fun transactionCreated(tx: VerificationTransaction) { transactionUpdated(tx) } @@ -81,26 +86,13 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: VerificationChooseMethodViewState): VerificationChooseMethodViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: VerificationChooseMethodViewState): VerificationChooseMethodViewModel } - init { - session.cryptoService().verificationService().addListener(this) - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { - override fun onCleared() { - session.cryptoService().verificationService().removeListener(this) - super.onCleared() - } - - companion object : MavericksViewModelFactory { - 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 verificationService = session.cryptoService().verificationService() @@ -121,5 +113,10 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( } } + override fun onCleared() { + session.cryptoService().verificationService().removeListener(this) + super.onCleared() + } + override fun handle(action: EmptyAction) {} } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt index 566307c05b..3f4eaf8ac9 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt @@ -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(), VerificationEmojiCodeController.Listener { diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt index f1e3d1b805..7d7a876b68 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt @@ -28,6 +28,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject 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.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -151,16 +153,11 @@ class VerificationEmojiCodeViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: VerificationEmojiCodeViewState): VerificationEmojiCodeViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: VerificationEmojiCodeViewState): VerificationEmojiCodeViewModel } - companion object : MavericksViewModelFactory { - - override fun create(viewModelContext: ViewModelContext, state: VerificationEmojiCodeViewState): VerificationEmojiCodeViewModel? { - val factory = (viewModelContext as FragmentViewModelContext).fragment().viewModelFactory - return factory.create(state) - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { override fun initialState(viewModelContext: ViewModelContext): VerificationEmojiCodeViewState? { val args = viewModelContext.args() diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt index 6de7c1fba5..7306146027 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt @@ -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(), DiscoverySettingsController.Listener { diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt index 66f38928a7..b02784dad9 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt @@ -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(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: DiscoverySettingsState): DiscoverySettingsViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: DiscoverySettingsState): DiscoverySettingsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: DiscoverySettingsState): DiscoverySettingsViewModel? { - val fragment: DiscoverySettingsFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() private val identityService = session.identityService() private val termsService: TermsService = session diff --git a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt index dd4db36387..15e4e65d3b 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt @@ -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() { diff --git a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt index 8921f0691d..f24f74f31c 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt @@ -15,8 +15,6 @@ */ 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 @@ -24,6 +22,8 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject 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.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider @@ -42,26 +42,20 @@ class SetIdentityServerViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: SetIdentityServerState): SetIdentityServerViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: SetIdentityServerState): SetIdentityServerViewModel } - companion object : MavericksViewModelFactory { + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { - override fun initialState(viewModelContext: ViewModelContext): SetIdentityServerState? { + override fun initialState(viewModelContext: ViewModelContext): SetIdentityServerState { val session = (viewModelContext.activity as HasScreenInjector).injector().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 diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 9894912884..e1c650cb62 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -94,8 +94,6 @@ data class HomeActivityArgs( class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, - UnknownDeviceDetectorSharedViewModel.Factory, - UnreadMessagesSharedViewModel.Factory, NavigationInterceptor, SpaceInviteBottomSheet.InteractionListener, MatrixToBottomSheet.InteractionListener { @@ -115,8 +113,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,14 +171,6 @@ class HomeActivity : injector.inject(this) } - override fun create(initialState: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel { - return unknownDeviceViewModelFactory.create(initialState) - } - - override fun create(initialState: UnreadMessagesState): UnreadMessagesSharedViewModel { - return unreadMessagesSharedViewModelFactory.create(initialState) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index 5ea4855bbe..187f01cfb3 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -64,7 +64,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import javax.inject.Inject class HomeDetailFragment @Inject constructor( - val homeDetailViewModelFactory: HomeDetailViewModel.Factory, private val avatarRenderer: AvatarRenderer, private val colorProvider: ColorProvider, private val alertManager: PopupAlertManager, diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index d981a29fec..25f94a25c7 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -26,6 +26,8 @@ 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.platform.VectorViewModel import im.vector.app.features.call.dialpad.DialPadLookup import im.vector.app.features.call.lookup.CallProtocolsChecker @@ -69,24 +71,18 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho CallProtocolsChecker.Listener { @AssistedFactory - interface Factory { - fun create(initialState: HomeDetailViewState): HomeDetailViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: HomeDetailViewState): HomeDetailViewModel } - companion object : MavericksViewModelFactory { + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory(){ - override fun initialState(viewModelContext: ViewModelContext): HomeDetailViewState? { + override fun initialState(viewModelContext: ViewModelContext): HomeDetailViewState { val uiStateRepository = (viewModelContext.activity as HasScreenInjector).injector().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 { diff --git a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt index 36e31770a9..4018f15cca 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt @@ -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 { + override fun create(initialState: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel } - companion object : MavericksViewModelFactory { - - @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 by hiltMavericksViewModelFactory() private val ignoredDeviceList = ArrayList() diff --git a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt index cc209cd72c..e20f786b1e 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt @@ -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(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: UnreadMessagesState): UnreadMessagesSharedViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: UnreadMessagesState): UnreadMessagesSharedViewModel } - companion object : MavericksViewModelFactory { - - @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 by hiltMavericksViewModelFactory() override fun handle(action: EmptyAction) {} diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt index 47a8256628..4d44ff775a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt @@ -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(), BreadcrumbsController.Listener { diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt index 8ed44053a1..7c0892aa92 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt @@ -22,6 +22,8 @@ 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 +35,14 @@ import org.matrix.android.sdk.flow.flow class BreadcrumbsViewModel @AssistedInject constructor(@Assisted initialState: BreadcrumbsViewState, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: BreadcrumbsViewState): BreadcrumbsViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: BreadcrumbsViewState): BreadcrumbsViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: BreadcrumbsViewState): BreadcrumbsViewModel? { - val fragment: BreadcrumbsFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.breadcrumbsViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { observeBreadcrumbs() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index e9948e6cf4..7abfaa4007 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -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, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt index 742d2848a1..08b1b84a58 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt @@ -23,6 +23,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider @@ -703,16 +705,9 @@ class TextComposerViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory { - fun create(initialState: TextComposerViewState): TextComposerViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: TextComposerViewState): TextComposerViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: TextComposerViewState): TextComposerViewModel { - val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.textComposerViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt index 9f34cdd679..4a285da5f2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt @@ -47,7 +47,6 @@ data class SearchArgs( ) : Parcelable class SearchFragment @Inject constructor( - val viewModelFactory: SearchViewModel.Factory, private val controller: SearchResultController ) : VectorBaseFragment(), StateView.EventCallback, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt index e4832b3876..8a681ad30a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt @@ -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 { + override fun create(initialState: SearchViewState): SearchViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: SearchViewState): SearchViewModel? { - val fragment: SearchFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() override fun handle(action: SearchAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt index 6de8864f10..d7e212d055 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt @@ -36,7 +36,6 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), MessageActionsEpoxyController.MessageActionsEpoxyControllerListener { - @Inject lateinit var messageActionViewModelFactory: MessageActionsViewModel.Factory @Inject lateinit var messageActionsEpoxyController: MessageActionsEpoxyController private val viewModel: MessageActionsViewModel by fragmentViewModel(MessageActionsViewModel::class) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index b4fff6eb3d..8fb2598e58 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -15,14 +15,14 @@ */ package im.vector.app.features.home.room.detail.timeline.action -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.ViewModelContext import dagger.Lazy 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.canReact import im.vector.app.core.platform.EmptyViewEvents @@ -85,17 +85,11 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted private val eventIdFlow = MutableStateFlow(initialState.eventId) @AssistedFactory - interface Factory { - fun create(initialState: MessageActionState): MessageActionsViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: MessageActionState): MessageActionsViewModel } - companion object : MavericksViewModelFactory { - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: MessageActionState): MessageActionsViewModel? { - val fragment: MessageActionsBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.messageActionViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { observeEvent() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt index da3a7396fd..0a5f4be7ca 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt @@ -40,7 +40,6 @@ class ViewEditHistoryBottomSheet : private val viewModel: ViewEditHistoryViewModel by fragmentViewModel(ViewEditHistoryViewModel::class) - @Inject lateinit var viewEditHistoryViewModelFactory: ViewEditHistoryViewModel.Factory @Inject lateinit var epoxyController: ViewEditHistoryEpoxyController override fun injectWith(injector: ScreenComponent) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt index 699f3cf02d..b0495d7c8f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt @@ -15,16 +15,15 @@ */ package im.vector.app.features.home.room.detail.timeline.edithistory -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.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -47,18 +46,11 @@ class ViewEditHistoryViewModel @AssistedInject constructor( ?: throw IllegalStateException("Shouldn't use this ViewModel without a room") @AssistedFactory - interface Factory { - fun create(initialState: ViewEditHistoryViewState): ViewEditHistoryViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: ViewEditHistoryViewState): ViewEditHistoryViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: ViewEditHistoryViewState): ViewEditHistoryViewModel? { - val fragment: ViewEditHistoryBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.viewEditHistoryViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { loadHistory() diff --git a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt index deee0c4cf5..068e0f762e 100644 --- a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt @@ -16,20 +16,19 @@ package im.vector.app.features.homeserver -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 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.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.raw.wellknown.getElementWellknown import im.vector.app.features.raw.wellknown.isE2EByDefault -import im.vector.app.features.userdirectory.UserListFragment import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull @@ -44,18 +43,13 @@ class HomeServerCapabilitiesViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: HomeServerCapabilitiesViewState): HomeServerCapabilitiesViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: HomeServerCapabilitiesViewState): HomeServerCapabilitiesViewModel } - companion object : MavericksViewModelFactory { - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: HomeServerCapabilitiesViewState): HomeServerCapabilitiesViewModel? { - val fragment: UserListFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.homeServerCapabilitiesViewModelFactory.create(state) - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { - override fun initialState(viewModelContext: ViewModelContext): HomeServerCapabilitiesViewState? { + override fun initialState(viewModelContext: ViewModelContext): HomeServerCapabilitiesViewState { val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getSafeActiveSession() return HomeServerCapabilitiesViewState( capabilities = session?.getHomeServerCapabilities() ?: HomeServerCapabilities() @@ -64,6 +58,7 @@ class HomeServerCapabilitiesViewModel @AssistedInject constructor( } init { + initAdminE2eByDefault() } diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt index 0aaa5b9834..fb3bf5ee8a 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt @@ -53,11 +53,10 @@ import javax.inject.Inject @Parcelize data class InviteUsersToRoomArgs(val roomId: String) : Parcelable -class InviteUsersToRoomActivity : SimpleFragmentActivity(), InviteUsersToRoomViewModel.Factory { +class InviteUsersToRoomActivity : SimpleFragmentActivity() { private val viewModel: InviteUsersToRoomViewModel by viewModel() private lateinit var sharedActionViewModel: UserListSharedActionViewModel - @Inject lateinit var inviteUsersToRoomViewModelFactory: InviteUsersToRoomViewModel.Factory @Inject lateinit var errorFormatter: ErrorFormatter override fun injectWith(injector: ScreenComponent) { @@ -65,8 +64,6 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity(), InviteUsersToRoomVie injector.inject(this) } - override fun create(initialState: InviteUsersToRoomViewState) = inviteUsersToRoomViewModelFactory.create(initialState) - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt index fd06614950..30dbadcb37 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt @@ -16,14 +16,13 @@ package im.vector.app.features.invite -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.R +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import im.vector.app.features.userdirectory.PendingSelection @@ -43,21 +42,11 @@ class InviteUsersToRoomViewModel @AssistedInject constructor(@Assisted private val room = session.getRoom(initialState.roomId)!! @AssistedFactory - interface Factory { - fun create(initialState: InviteUsersToRoomViewState): InviteUsersToRoomViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: InviteUsersToRoomViewState): InviteUsersToRoomViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: InviteUsersToRoomViewState): InviteUsersToRoomViewModel? { - 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 by hiltMavericksViewModelFactory() override fun handle(action: InviteUsersToRoomAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index f0a1b1f937..9c2d37b09c 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -57,8 +57,6 @@ open class LoginActivity : VectorBaseActivity(), ToolbarCo private val loginViewModel: LoginViewModel by viewModel() - @Inject lateinit var loginViewModelFactory: LoginViewModel.Factory - @CallSuper override fun injectWith(injector: ScreenComponent) { injector.inject(this) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt index 28a9fa46d1..9eaea0391f 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt @@ -32,6 +32,8 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.R 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.configureAndStart import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel @@ -72,10 +74,12 @@ class LoginViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: LoginViewState): LoginViewModel + interface Factory:MavericksAssistedViewModelFactory { + override fun create(initialState: LoginViewState): LoginViewModel } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + init { getKnownCustomHomeServersUrls() } @@ -86,18 +90,6 @@ class LoginViewModel @AssistedInject constructor( } } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: LoginViewState): LoginViewModel? { - return when (val activity: FragmentActivity = (viewModelContext as ActivityViewModelContext).activity()) { - is LoginActivity -> activity.loginViewModelFactory.create(state) - is SoftLogoutActivity -> activity.loginViewModelFactory.create(state) - else -> error("Invalid Activity") - } - } - } - // Store the last action, to redo it after user has trusted the untrusted certificate private var lastAction: LoginAction? = null private var currentHomeServerConnectionConfig: HomeServerConnectionConfig? = null diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt index a640f02279..51aeb2d1fd 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt @@ -64,8 +64,6 @@ open class LoginActivity2 : VectorBaseActivity(), ToolbarC private val loginViewModel: LoginViewModel2 by viewModel() - @Inject lateinit var loginViewModelFactory: LoginViewModel2.Factory - @CallSuper override fun injectWith(injector: ScreenComponent) { injector.inject(this) diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt index 09ca979c6c..d98bf99a12 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt @@ -29,6 +29,8 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.R 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.configureAndStart import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.tryAsync @@ -72,10 +74,12 @@ class LoginViewModel2 @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: LoginViewState2): LoginViewModel2 + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: LoginViewState2): LoginViewModel2 } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + init { getKnownCustomHomeServersUrls() } @@ -86,18 +90,6 @@ class LoginViewModel2 @AssistedInject constructor( } } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: LoginViewState2): LoginViewModel2? { - return when (val activity: FragmentActivity = (viewModelContext as ActivityViewModelContext).activity()) { - is LoginActivity2 -> activity.loginViewModelFactory.create(state) - // TODO is SoftLogoutActivity -> activity.loginViewModelFactory.create(state) - else -> error("Invalid Activity") - } - } - } - // Store the last action, to redo it after user has trusted the untrusted certificate private var lastAction: LoginAction2? = null private var currentHomeServerConnectionConfig: HomeServerConnectionConfig? = null diff --git a/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedFragment.kt b/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedFragment.kt index 5668214b50..efa4bd29c6 100644 --- a/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedFragment.kt @@ -49,7 +49,6 @@ import javax.inject.Inject * - the account has been created and we propose the user to set an avatar and a display name */ class AccountCreatedFragment @Inject constructor( - val accountCreatedViewModelFactory: AccountCreatedViewModel.Factory, private val avatarRenderer: AvatarRenderer, private val dateFormatter: VectorDateFormatter, private val matrixItemColorProvider: MatrixItemColorProvider, diff --git a/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedViewModel.kt b/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedViewModel.kt index 34957dd47b..559be4aa66 100644 --- a/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedViewModel.kt @@ -16,13 +16,12 @@ package im.vector.app.features.login2.created -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 im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -40,18 +39,11 @@ class AccountCreatedViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: AccountCreatedViewState): AccountCreatedViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: AccountCreatedViewState): AccountCreatedViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: AccountCreatedViewState): AccountCreatedViewModel? { - val fragment: AccountCreatedFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.accountCreatedViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { setState { diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt index aadabcb1b4..64a08f2bf9 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt @@ -49,9 +49,6 @@ class MatrixToBottomSheet : @Inject lateinit var avatarRenderer: AvatarRenderer - @Inject - lateinit var matrixToBottomSheetViewModelFactory: MatrixToBottomSheetViewModel.Factory - override fun injectWith(injector: ScreenComponent) { injector.inject(this) } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt index 327485a3b0..4d2a15402a 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt @@ -16,18 +16,17 @@ package im.vector.app.features.matrixto -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 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 @@ -54,10 +53,12 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: MatrixToBottomSheetState): MatrixToBottomSheetViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: MatrixToBottomSheetState): MatrixToBottomSheetViewModel } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + init { when (initialState.linkType) { is PermalinkData.RoomLink -> { @@ -245,14 +246,6 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( return session.peekRoom(roomIdOrAlias) } - companion object : MavericksViewModelFactory { - override fun create(viewModelContext: ViewModelContext, state: MatrixToBottomSheetState): MatrixToBottomSheetViewModel? { - val fragment: MatrixToBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - - return fragment.matrixToBottomSheetViewModelFactory.create(state) - } - } - override fun handle(action: MatrixToAction) { when (action) { is MatrixToAction.StartChattingWithUser -> handleStartChatting(action) diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt index 89aa307dc4..ea5953d578 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt @@ -44,8 +44,6 @@ class BugReportActivity : VectorBaseActivity() { override fun getBinding() = ActivityBugReportBinding.inflate(layoutInflater) - @Inject lateinit var bugReportViewModelFactory: BugReportViewModel.Factory - private val viewModel: BugReportViewModel by viewModel() private var reportType: ReportType = ReportType.BUG_REPORT diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportViewModel.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportViewModel.kt index a1ec6b2e76..5342a7dec7 100644 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportViewModel.kt @@ -16,14 +16,13 @@ package im.vector.app.features.rageshake -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.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 @@ -36,18 +35,11 @@ class BugReportViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: BugReportState): BugReportViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: BugReportState): BugReportViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: BugReportState): BugReportViewModel? { - val activity: BugReportActivity = (viewModelContext as ActivityViewModelContext).activity() - return activity.bugReportViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { fetchHomeserverVersion() diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt index e371aae096..c9f51534f0 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt @@ -60,7 +60,6 @@ class EmojiReactionPickerActivity : VectorBaseActivity(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: EmojiSearchResultViewState): EmojiSearchResultViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: EmojiSearchResultViewState): EmojiSearchResultViewModel } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: EmojiSearchResultViewState): EmojiSearchResultViewModel? { - val activity: EmojiReactionPickerActivity = (viewModelContext as ActivityViewModelContext).activity() - return activity.emojiSearchResultViewModelFactory.create(state) - } - } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() override fun handle(action: EmojiSearchAction) { when (action) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt index 4337e8767a..8840f61600 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt @@ -42,20 +42,14 @@ import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject class RoomMemberListFragment @Inject constructor( - val viewModelFactory: RoomMemberListViewModel.Factory, private val roomMemberListController: RoomMemberListController, private val avatarRenderer: AvatarRenderer ) : VectorBaseFragment(), - RoomMemberListController.Callback, - RoomMemberListViewModel.Factory { + RoomMemberListController.Callback { private val viewModel: RoomMemberListViewModel by fragmentViewModel() private val roomProfileArgs: RoomProfileArgs by args() - override fun create(initialState: RoomMemberListViewState): RoomMemberListViewModel { - return viewModelFactory.create(initialState) - } - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomMemberListBinding { return FragmentRoomMemberListBinding.inflate(inflater, container, false) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt index b7821c056c..ce059881b8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt @@ -52,7 +52,6 @@ import java.util.UUID import javax.inject.Inject class RoomSettingsFragment @Inject constructor( - val viewModelFactory: RoomSettingsViewModel.Factory, private val controller: RoomSettingsController, colorProvider: ColorProvider, private val avatarRenderer: AvatarRenderer @@ -60,8 +59,7 @@ class RoomSettingsFragment @Inject constructor( VectorBaseFragment(), RoomSettingsController.Callback, OnBackPressed, - GalleryOrCameraDialogHelper.Listener, - RoomSettingsViewModel.Factory { + GalleryOrCameraDialogHelper.Listener { private val viewModel: RoomSettingsViewModel by fragmentViewModel() private lateinit var roomProfileSharedActionViewModel: RoomProfileSharedActionViewModel @@ -77,10 +75,6 @@ class RoomSettingsFragment @Inject constructor( override fun getMenuRes() = R.menu.vector_room_settings - override fun create(initialState: RoomSettingsViewState): RoomSettingsViewModel { - return viewModelFactory.create(initialState) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) roomProfileSharedActionViewModel = activityViewModelProvider.get(RoomProfileSharedActionViewModel::class.java) diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt index daf5d73e8f..aed134816a 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt @@ -52,7 +52,6 @@ import javax.inject.Inject class UserListFragment @Inject constructor( private val userListController: UserListController, private val dimensionConverter: DimensionConverter, - val homeServerCapabilitiesViewModelFactory: HomeServerCapabilitiesViewModel.Factory ) : VectorBaseFragment(), UserListController.Callback { From 92cd79c5502a5d78021a38cfa68b8655aa41e63b Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 19 Oct 2021 18:53:17 +0200 Subject: [PATCH 010/413] Hilt: migrate activities --- .../app/features/debug/DebugMenuActivity.kt | 6 +-- .../im/vector/app/core/di/ScreenComponent.kt | 44 ------------------- .../im/vector/app/features/MainActivity.kt | 6 +-- .../preview/AttachmentsPreviewActivity.kt | 1 + .../app/features/auth/ReAuthActivity.kt | 7 +-- .../app/features/call/VectorCallActivity.kt | 5 +-- .../call/conference/VectorJitsiActivity.kt | 6 +-- .../call/transfer/CallTransferActivity.kt | 6 +-- .../createdirect/CreateDirectRoomActivity.kt | 7 +-- .../settings/KeysBackupManageActivity.kt | 7 +-- .../setup/KeysBackupSetupActivity.kt | 7 +-- .../quads/SharedSecureStorageActivity.kt | 7 +-- .../features/devtools/RoomDevToolActivity.kt | 7 +-- .../vector/app/features/home/HomeActivity.kt | 6 +-- .../home/room/detail/RoomDetailActivity.kt | 6 +-- .../home/room/detail/search/SearchActivity.kt | 6 +-- .../room/filtered/FilteredRoomsActivity.kt | 6 +-- .../invite/InviteUsersToRoomActivity.kt | 7 +-- .../app/features/link/LinkHandlerActivity.kt | 6 +-- .../app/features/login/LoginActivity.kt | 7 +-- .../app/features/login2/LoginActivity2.kt | 7 +-- .../features/media/BigImageViewerActivity.kt | 6 +-- .../features/qrcode/QrCodeScannerActivity.kt | 6 +-- .../features/rageshake/BugReportActivity.kt | 6 +-- .../reactions/EmojiReactionPickerActivity.kt | 6 +-- .../roomdirectory/RoomDirectoryActivity.kt | 6 +-- .../createroom/CreateRoomActivity.kt | 6 +-- .../RoomMemberProfileActivity.kt | 7 +-- .../roomprofile/RoomProfileActivity.kt | 6 +-- .../settings/joinrule/RoomJoinRuleActivity.kt | 6 +-- .../settings/VectorSettingsActivity.kt | 6 +-- .../features/share/IncomingShareActivity.kt | 2 + .../signout/soft/SoftLogoutActivity.kt | 7 +-- .../signout/soft/SoftLogoutActivity2.kt | 8 +--- .../features/spaces/SpaceCreationActivity.kt | 7 +-- .../features/spaces/SpaceExploreActivity.kt | 6 +-- .../leave/SpaceLeaveAdvancedActivity.kt | 7 +-- .../spaces/manage/SpaceManageActivity.kt | 6 +-- .../app/features/terms/ReviewTermsActivity.kt | 7 +-- .../app/features/usercode/UserCodeActivity.kt | 6 +-- .../app/features/widgets/WidgetActivity.kt | 6 +-- 41 files changed, 78 insertions(+), 212 deletions(-) diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index 303a3a14ba..fb47e6abe8 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -24,6 +24,7 @@ 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 @@ -50,6 +51,7 @@ import org.matrix.android.sdk.internal.crypto.verification.qrcode.toQrCodeData import timber.log.Timber import javax.inject.Inject +@AndroidEntryPoint class DebugMenuActivity : VectorBaseActivity() { override fun getBinding() = ActivityDebugMenuBinding.inflate(layoutInflater) @@ -57,10 +59,6 @@ class DebugMenuActivity : VectorBaseActivity() { @Inject lateinit var activeSessionHolder: ActiveSessionHolder - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - private lateinit var buffer: ByteArray override fun initUiAndData() { diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt index f822644676..b06c6daa09 100644 --- a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt @@ -275,50 +275,6 @@ interface ScreenComponent { 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 * ========================================================================================== */ diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index e124dbdf6e..c16d653327 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -24,6 +24,7 @@ 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 @@ -67,6 +68,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(), UnlockedActivity { companion object { @@ -98,10 +100,6 @@ class MainActivity : VectorBaseActivity(), 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() diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt index 6c25f688bd..1f89444365 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt @@ -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 diff --git a/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt b/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt index 13e788d3a0..c4f394e539 100644 --- a/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt +++ b/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt @@ -29,6 +29,7 @@ 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 @@ -42,6 +43,7 @@ import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import timber.log.Timber import javax.inject.Inject +@AndroidEntryPoint class ReAuthActivity : SimpleFragmentActivity(){ @Parcelize @@ -60,11 +62,6 @@ class ReAuthActivity : SimpleFragmentActivity(){ @Inject lateinit var authenticationService: AuthenticationService - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - private val sharedViewModel: ReAuthViewModel by viewModel() // override fun getTitleRes() = R.string.re_authentication_activity_title diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index e54c04736b..990d1114ac 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -86,6 +86,7 @@ data class CallArgs( private val loggerTag = LoggerTag("VectorCallActivity", LoggerTag.VOIP) +@AndroidEntryPoint class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionListener { override fun getBinding() = ActivityCallBinding.inflate(layoutInflater) @@ -93,10 +94,6 @@ class VectorCallActivity : VectorBaseActivity(), CallContro @Inject lateinit var callManager: WebRtcCallManager @Inject lateinit var avatarRenderer: AvatarRenderer - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - private val callViewModel: VectorCallViewModel by viewModel() diff --git a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt index a116d2ac34..9784940374 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt @@ -33,6 +33,7 @@ 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 @@ -50,6 +51,7 @@ import timber.log.Timber import java.net.URL import javax.inject.Inject +@AndroidEntryPoint class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface { @Parcelize @@ -65,10 +67,6 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMee private val jitsiViewModel: JitsiCallViewModel by viewModel() - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index a2e81e64fa..a44a4f2e4f 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -23,6 +23,7 @@ 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 @@ -40,6 +41,7 @@ data class CallTransferArgs(val callId: String) : Parcelable private const val USER_LIST_FRAGMENT_TAG = "USER_LIST_FRAGMENT_TAG" +@AndroidEntryPoint class CallTransferActivity : VectorBaseActivity() { @Inject lateinit var errorFormatter: ErrorFormatter @@ -52,10 +54,6 @@ class CallTransferActivity : VectorBaseActivity() { override fun getCoordinatorLayout() = views.vectorCoordinatorLayout - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) waitingView = views.waitingView.waitingView diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index e310eb8e70..883b5fbe7b 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -28,6 +28,7 @@ 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 @@ -55,17 +56,13 @@ import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure import java.net.HttpURLConnection import javax.inject.Inject +@AndroidEntryPoint class CreateDirectRoomActivity : SimpleFragmentActivity(){ private val viewModel: CreateDirectRoomViewModel by viewModel() private lateinit var sharedActionViewModel: UserListSharedActionViewModel @Inject lateinit var errorFormatter: ErrorFormatter - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) views.toolbar.visibility = View.GONE diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt index 29d513ced0..41f410a875 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt @@ -21,6 +21,7 @@ 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 @@ -28,6 +29,7 @@ import im.vector.app.core.platform.SimpleFragmentActivity import im.vector.app.core.platform.WaitingViewData import javax.inject.Inject +@AndroidEntryPoint class KeysBackupManageActivity : SimpleFragmentActivity() { companion object { @@ -41,11 +43,6 @@ class KeysBackupManageActivity : SimpleFragmentActivity() { private val viewModel: KeysBackupSettingsViewModel by viewModel() - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - override fun initUiAndData() { super.initUiAndData() if (supportFragmentManager.fragments.isEmpty()) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt index 7cc46ef62c..97a29dd707 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt @@ -23,6 +23,7 @@ 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.dialogs.ExportKeysDialog @@ -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 @@ -44,11 +46,6 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() { @Inject lateinit var keysExporter: KeysExporter - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - override fun initUiAndData() { super.initUiAndData() if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt index ad3e28c715..a09653c329 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt @@ -28,6 +28,7 @@ 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 @@ -39,6 +40,7 @@ import kotlinx.parcelize.Parcelize import javax.inject.Inject import kotlin.reflect.KClass +@AndroidEntryPoint class SharedSecureStorageActivity : SimpleFragmentActivity(), VectorBaseBottomSheetDialogFragment.ResultListener, @@ -54,11 +56,6 @@ class SharedSecureStorageActivity : private val viewModel: SharedSecureStorageViewModel by viewModel() @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) diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt index 31880a66ab..a7de1405f7 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt @@ -33,6 +33,7 @@ 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 @@ -45,6 +46,7 @@ import kotlinx.parcelize.Parcelize import org.billcarsonfr.jsonviewer.JSonViewerFragment import javax.inject.Inject +@AndroidEntryPoint class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStackChangedListener { @Inject lateinit var colorProvider: ColorProvider @@ -63,11 +65,6 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac val roomId: String ) : Parcelable - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - override fun initUiAndData() { super.initUiAndData() viewModel.subscribe(this) { diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index e1c650cb62..53b34e16ab 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -34,6 +34,7 @@ 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 @@ -91,6 +92,7 @@ data class HomeActivityArgs( val inviteNotificationRoomId: String? = null ) : Parcelable +@AndroidEntryPoint class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, @@ -167,10 +169,6 @@ class HomeActivity : override fun getBinding() = ActivityHomeBinding.inflate(layoutInflater) - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index 08141a757e..1241bf40e7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -27,6 +27,7 @@ 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 @@ -41,6 +42,7 @@ import im.vector.app.features.room.RequireActiveMembershipAction import im.vector.app.features.room.RequireActiveMembershipViewEvents import im.vector.app.features.room.RequireActiveMembershipViewModel +@AndroidEntryPoint class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable, @@ -72,10 +74,6 @@ class RoomDetailActivity : private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel() - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - // Simple filter var currentRoomId: String? = null diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt index 88ed101252..a143712b3a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt @@ -21,12 +21,14 @@ 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() { private val searchFragment: SearchFragment? @@ -38,10 +40,6 @@ class SearchActivity : VectorBaseActivity() { override fun getCoordinatorLayout() = views.coordinatorLayout - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) configureToolbar(views.searchToolbar) diff --git a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt index a4f6f5f7c4..dc07526732 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import androidx.appcompat.widget.SearchView +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.replaceFragment @@ -29,6 +30,7 @@ import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.list.RoomListParams +@AndroidEntryPoint class FilteredRoomsActivity : VectorBaseActivity() { private val roomListFragment: RoomListFragment? @@ -40,10 +42,6 @@ class FilteredRoomsActivity : VectorBaseActivity() override fun getCoordinatorLayout() = views.coordinatorLayout - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) configureToolbar(views.filteredRoomsToolbar) diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt index fb3bf5ee8a..7f31a02550 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt @@ -24,6 +24,7 @@ import android.view.View 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 @@ -53,17 +54,13 @@ import javax.inject.Inject @Parcelize data class InviteUsersToRoomArgs(val roomId: String) : Parcelable +@AndroidEntryPoint class InviteUsersToRoomActivity : SimpleFragmentActivity() { private val viewModel: InviteUsersToRoomViewModel by viewModel() private lateinit var sharedActionViewModel: UserListSharedActionViewModel @Inject lateinit var errorFormatter: ErrorFormatter - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt index 39105185b1..cac6ab2aa5 100644 --- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt @@ -20,6 +20,7 @@ import android.content.Intent import android.net.Uri 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.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent @@ -38,6 +39,7 @@ import javax.inject.Inject /** * Dummy activity used to dispatch the vector URL links. */ +@AndroidEntryPoint class LinkHandlerActivity : VectorBaseActivity() { @Inject lateinit var sessionHolder: ActiveSessionHolder @@ -46,10 +48,6 @@ class LinkHandlerActivity : VectorBaseActivity() { override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater) - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun initUiAndData() { handleIntent() } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index 9c2d37b09c..8e3374afb4 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -31,6 +31,7 @@ import com.airbnb.mvrx.viewModel import com.airbnb.mvrx.withState import com.google.android.material.appbar.MaterialToolbar 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.POP_BACK_STACK_EXCLUSIVE @@ -53,15 +54,11 @@ import javax.inject.Inject /** * The LoginActivity manages the fragment navigation and also display the loading View */ +@AndroidEntryPoint open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedActivity { private val loginViewModel: LoginViewModel by viewModel() - @CallSuper - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - private val enterAnim = R.anim.enter_fade_in private val exitAnim = R.anim.exit_fade_out diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt index 51aeb2d1fd..7cbe4ca4e0 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt @@ -30,6 +30,7 @@ import androidx.fragment.app.FragmentTransaction 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.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.POP_BACK_STACK_EXCLUSIVE @@ -60,15 +61,11 @@ import javax.inject.Inject /** * The LoginActivity manages the fragment navigation and also display the loading View */ +@AndroidEntryPoint open class LoginActivity2 : VectorBaseActivity(), ToolbarConfigurable, UnlockedActivity { private val loginViewModel: LoginViewModel2 by viewModel() - @CallSuper - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - private val enterAnim = R.anim.enter_fade_in private val exitAnim = R.anim.exit_fade_out diff --git a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt index 28d16adcbb..5004cdc99c 100644 --- a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import androidx.core.net.toUri +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent import im.vector.app.core.platform.VectorBaseActivity @@ -29,15 +30,12 @@ import javax.inject.Inject /** * Simple Activity to display an avatar in fullscreen */ +@AndroidEntryPoint class BigImageViewerActivity : VectorBaseActivity() { @Inject lateinit var sessionHolder: ActiveSessionHolder override fun getBinding() = ActivityBigImageViewerBinding.inflate(layoutInflater) - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt index 13f989994a..979b429932 100644 --- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt @@ -23,22 +23,20 @@ import androidx.activity.result.ActivityResultLauncher import com.google.zxing.BarcodeFormat import com.google.zxing.Result import com.google.zxing.ResultMetadataType +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.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding +@AndroidEntryPoint class QrCodeScannerActivity : VectorBaseActivity() { override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) override fun getCoordinatorLayout() = views.coordinatorLayout - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt index ea5953d578..f14b067f3e 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt @@ -25,6 +25,7 @@ import androidx.core.view.isVisible import androidx.core.widget.doOnTextChanged 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.platform.VectorBaseActivity @@ -36,12 +37,9 @@ import javax.inject.Inject /** * Form to send a bug report */ +@AndroidEntryPoint class BugReportActivity : VectorBaseActivity() { - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding() = ActivityBugReportBinding.inflate(layoutInflater) private val viewModel: BugReportViewModel by viewModel() diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt index c9f51534f0..d5f7bb9f7c 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt @@ -29,6 +29,7 @@ import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.viewModel import com.google.android.material.tabs.TabLayout import com.jakewharton.rxbinding3.widget.queryTextChanges +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.EmojiCompatFontProvider import im.vector.app.R import im.vector.app.core.di.ScreenComponent @@ -47,6 +48,7 @@ import javax.inject.Inject * TODO: Loading indicator while getting emoji data source? * TODO: Finish Refactor to vector base activity */ +@AndroidEntryPoint class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvider.FontProviderListener { @@ -77,10 +79,6 @@ class EmojiReactionPickerActivity : VectorBaseActivity() { @Inject lateinit var roomDirectoryViewModelFactory: RoomDirectoryViewModel.Factory @@ -43,10 +45,6 @@ class RoomDirectoryActivity : VectorBaseActivity() { override fun getCoordinatorLayout() = views.coordinatorLayout - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) sharedActionViewModel = viewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt index 4afda8a0e9..31fa3192e7 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle 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.addFragment @@ -32,6 +33,7 @@ import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel /** * Simple container for [CreateRoomFragment] */ +@AndroidEntryPoint class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel @@ -44,10 +46,6 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarC configureToolbar(toolbar) } - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun initUiAndData() { if (isFirstCreation()) { addFragment( diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt index f5e0465209..9418e1c504 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt @@ -23,6 +23,7 @@ import android.widget.Toast 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.addFragment @@ -34,6 +35,7 @@ import im.vector.app.features.room.RequireActiveMembershipViewModel import im.vector.app.features.room.RequireActiveMembershipViewState import javax.inject.Inject +@AndroidEntryPoint class RoomMemberProfileActivity : VectorBaseActivity(), ToolbarConfigurable { @@ -48,11 +50,6 @@ class RoomMemberProfileActivity : private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel() - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(): ActivitySimpleBinding { return ActivitySimpleBinding.inflate(layoutInflater) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index 05bff476cc..3872fc0393 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -23,6 +23,7 @@ import android.widget.Toast 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.addFragment @@ -44,6 +45,7 @@ import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import javax.inject.Inject +@AndroidEntryPoint class RoomProfileActivity : VectorBaseActivity(), ToolbarConfigurable { @@ -73,10 +75,6 @@ class RoomProfileActivity : @Inject lateinit var roomDetailPendingActionStore: RoomDetailPendingActionStore - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(): ActivitySimpleBinding { return ActivitySimpleBinding.inflate(layoutInflater) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt index c54be807b0..2e4608311e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt @@ -27,6 +27,7 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized 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.error.ErrorFormatter @@ -44,6 +45,7 @@ import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRul import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRuleChooseRestrictedViewModel import javax.inject.Inject +@AndroidEntryPoint class RoomJoinRuleActivity : VectorBaseActivity() { override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) @@ -55,10 +57,6 @@ class RoomJoinRuleActivity : VectorBaseActivity() { val viewModel: RoomJoinRuleChooseRestrictedViewModel by viewModel() - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun initUiAndData() { roomProfileArgs = intent?.extras?.getParcelable(Mavericks.KEY_ARG) ?: return if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt index 7cd4fc2d3d..3d1ebf224d 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt @@ -25,6 +25,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.replaceFragment @@ -45,6 +46,7 @@ private const val KEY_ACTIVITY_PAYLOAD = "settings-activity-payload" /** * Displays the client settings. */ +@AndroidEntryPoint class VectorSettingsActivity : VectorBaseActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, FragmentManager.OnBackStackChangedListener, @@ -62,10 +64,6 @@ class VectorSettingsActivity : VectorBaseActivity @Inject lateinit var session: Session - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun initUiAndData() { configureToolbar(views.settingsToolbar) diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt index b9d3b1ba14..09321ad27e 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt @@ -17,12 +17,14 @@ package im.vector.app.features.share 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 import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding +@AndroidEntryPoint class IncomingShareActivity : VectorBaseActivity(), ToolbarConfigurable { override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt index 91b775cc57..1948b7fbca 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt @@ -23,6 +23,7 @@ import androidx.fragment.app.FragmentManager 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 @@ -39,6 +40,7 @@ import javax.inject.Inject * In this screen, the user is viewing a message informing that he has been logged out * Extends LoginActivity to get the login with SSO and forget password functionality for (nearly) free */ +@AndroidEntryPoint class SoftLogoutActivity : LoginActivity() { private val softLogoutViewModel: SoftLogoutViewModel by viewModel() @@ -46,11 +48,6 @@ class SoftLogoutActivity : LoginActivity() { @Inject lateinit var session: Session @Inject lateinit var errorFormatter: ErrorFormatter - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - override fun initUiAndData() { super.initUiAndData() diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt index 3689bff0c7..c19821c9ad 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt @@ -23,6 +23,7 @@ import androidx.fragment.app.FragmentManager 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 @@ -41,19 +42,14 @@ import javax.inject.Inject * * This is just a copy of SoftLogoutActivity2, which extends LoginActivity2 */ +@AndroidEntryPoint class SoftLogoutActivity2 : LoginActivity2() { private val softLogoutViewModel: SoftLogoutViewModel by viewModel() - @Inject lateinit var softLogoutViewModelFactory: SoftLogoutViewModel.Factory @Inject lateinit var session: Session @Inject lateinit var errorFormatter: ErrorFormatter - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - override fun initUiAndData() { super.initUiAndData() diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt index 4c86c4d554..aac9bcce51 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt @@ -24,6 +24,7 @@ import com.airbnb.mvrx.Loading 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.toMvRxBundle @@ -41,13 +42,9 @@ import im.vector.app.features.spaces.create.SpaceTopology import im.vector.app.features.spaces.create.SpaceType import javax.inject.Inject +@AndroidEntryPoint class SpaceCreationActivity : SimpleFragmentActivity(){ - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - val viewModel: CreateSpaceViewModel by viewModel() override fun onCreate(savedInstanceState: Bundle?) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt index 675dc08716..c4c45ef9fb 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt @@ -23,6 +23,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.viewModel +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.commitTransaction @@ -37,12 +38,9 @@ import im.vector.app.features.spaces.explore.SpaceDirectoryViewEvents import im.vector.app.features.spaces.explore.SpaceDirectoryViewModel import javax.inject.Inject +@AndroidEntryPoint class SpaceExploreActivity : VectorBaseActivity(), MatrixToBottomSheet.InteractionListener { - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(): ActivitySimpleBinding = ActivitySimpleBinding.inflate(layoutInflater) override fun getTitleRes(): Int = R.string.space_explore_activity_title diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt index de3456863c..3e7f51bee7 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt @@ -28,6 +28,7 @@ import com.airbnb.mvrx.Success 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.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.error.ErrorFormatter @@ -40,6 +41,7 @@ import im.vector.app.databinding.ActivitySimpleLoadingBinding import im.vector.app.features.spaces.SpaceBottomSheetSettingsArgs import javax.inject.Inject +@AndroidEntryPoint class SpaceLeaveAdvancedActivity : VectorBaseActivity(), ToolbarConfigurable { @@ -49,11 +51,6 @@ class SpaceLeaveAdvancedActivity : VectorBaseActivity(), ToolbarConfigurable { private lateinit var sharedDirectoryActionViewModel: RoomDirectorySharedActionViewModel - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(): ActivitySimpleLoadingBinding = ActivitySimpleLoadingBinding.inflate(layoutInflater) override fun getTitleRes(): Int = R.string.space_add_existing_rooms diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt index 194084fe2d..72cf96a37a 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent 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 @@ -29,17 +30,13 @@ import im.vector.app.core.platform.SimpleFragmentActivity import org.matrix.android.sdk.api.session.terms.TermsService import javax.inject.Inject +@AndroidEntryPoint class ReviewTermsActivity : SimpleFragmentActivity() { @Inject lateinit var errorFormatter: ErrorFormatter private val reviewTermsViewModel: ReviewTermsViewModel by viewModel() - override fun injectWith(injector: ScreenComponent) { - super.injectWith(injector) - injector.inject(this) - } - override fun initUiAndData() { super.initUiAndData() diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt index a2c156d722..e4f832018c 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt @@ -28,6 +28,7 @@ import androidx.fragment.app.FragmentManager 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.commitTransaction @@ -40,6 +41,7 @@ import kotlinx.parcelize.Parcelize import javax.inject.Inject import kotlin.reflect.KClass +@AndroidEntryPoint class UserCodeActivity : VectorBaseActivity(), MatrixToBottomSheet.InteractionListener { @@ -54,10 +56,6 @@ class UserCodeActivity : VectorBaseActivity(), override fun getCoordinatorLayout() = views.coordinatorLayout - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - private val fragmentLifecycleCallbacks = object : FragmentManager.FragmentLifecycleCallbacks() { override fun onFragmentResumed(fm: FragmentManager, f: Fragment) { if (f is MatrixToBottomSheet) { diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt index d2061c71b3..f300185cbf 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt @@ -23,6 +23,7 @@ import androidx.core.view.isVisible 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.addFragment @@ -37,6 +38,7 @@ import org.matrix.android.sdk.api.session.events.model.Content import java.io.Serializable import javax.inject.Inject +@AndroidEntryPoint class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable { @@ -73,10 +75,6 @@ class WidgetActivity : VectorBaseActivity(), override fun getTitleRes() = R.string.room_widget_activity_title - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun initUiAndData() { val widgetArgs: WidgetArgs? = intent?.extras?.getParcelable(Mavericks.KEY_ARG) if (widgetArgs == null) { From 188b4887bacb1c6460b1359428481089bdde3497 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 20 Oct 2021 17:23:40 +0200 Subject: [PATCH 011/413] Hilt: continue migrating activities --- .../troubleshoot/TestFirebaseToken.kt | 3 +- .../settings/troubleshoot/TestPlayServices.kt | 3 +- .../troubleshoot/TestPushFromPushGateway.kt | 3 +- .../troubleshoot/TestTokenRegistration.kt | 3 +- .../fcm/VectorFirebaseMessagingService.kt | 31 +- .../java/im/vector/app/VectorApplication.kt | 16 +- .../vector/app/core/di/HasVectorInjector.kt | 2 +- .../vector/app/core/di/HiltActivityModules.kt | 1013 +++++++++++++++++ .../im/vector/app/core/di/ScreenComponent.kt | 193 +--- ...orEntryPoint.kt => SingletonEntryPoint.kt} | 2 +- .../{VectorModule.kt => SingletonModule.kt} | 0 .../im/vector/app/core/extensions/Context.kt | 13 +- .../im/vector/app/core/extensions/Session.kt | 2 +- .../app/core/glide/AvatarPlaceholder.kt | 4 +- .../app/core/glide/VectorGlideModelLoader.kt | 4 +- .../core/platform/SimpleFragmentActivity.kt | 10 - .../app/core/platform/VectorBaseActivity.kt | 50 +- .../VectorBaseBottomSheetDialogFragment.kt | 4 +- .../app/core/platform/VectorBaseFragment.kt | 7 +- .../core/preference/UserAvatarPreference.kt | 4 +- .../vector/app/core/services/CallService.kt | 21 +- .../app/core/services/VectorSyncService.kt | 11 +- .../preview/AttachmentsPreviewActivity.kt | 1 + .../restore/KeysBackupRestoreActivity.kt | 9 +- .../setup/KeysBackupSetupActivity.kt | 6 + .../VerificationChooseMethodViewModel.kt | 5 +- .../emoji/VerificationEmojiCodeViewModel.kt | 6 +- .../change/SetIdentityServerViewModel.kt | 5 +- .../app/features/home/HomeDetailViewModel.kt | 7 +- .../HomeServerCapabilitiesViewModel.kt | 5 +- .../app/features/invite/VectorInviteView.kt | 5 +- .../NotificationBroadcastReceiver.kt | 1 - .../app/features/rageshake/RageShake.kt | 3 +- .../reactions/widget/ReactionButton.kt | 8 +- .../devices/DeviceListBottomSheetViewModel.kt | 5 +- .../settings/VectorSettingsBaseFragment.kt | 4 +- .../settings/push/PushRulesViewModel.kt | 5 +- .../troubleshoot/TestSystemSettings.kt | 3 +- .../features/webview/VectorWebViewActivity.kt | 11 +- .../workers/signout/SignOutUiWorker.kt | 4 +- 40 files changed, 1139 insertions(+), 353 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/di/HiltActivityModules.kt rename vector/src/main/java/im/vector/app/core/di/{AggregatorEntryPoint.kt => SingletonEntryPoint.kt} (99%) rename vector/src/main/java/im/vector/app/core/di/{VectorModule.kt => SingletonModule.kt} (100%) diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt index 1107737888..ce34c7ac3b 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt @@ -18,6 +18,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 +31,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) { diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt index 1f822d6060..995bc4117c 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt @@ -18,6 +18,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 +30,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) { diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt index e13b648dec..37ddf1b763 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt @@ -18,6 +18,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 +37,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, diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt index 94d4ec8a56..c2c9e692b3 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt @@ -18,6 +18,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 +34,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) : diff --git a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt index 2ce51ba4c7..b1f0b43705 100755 --- a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt @@ -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. * diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index 093362991f..d346404950 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -39,13 +39,11 @@ import com.facebook.stetho.Stetho import com.gabrielittner.threetenbp.LazyThreeTen import com.vanniktech.emoji.EmojiManager import com.vanniktech.emoji.google.GoogleEmojiProvider -import dagger.hilt.EntryPoints import dagger.hilt.android.HiltAndroidApp import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.di.AggregatorEntryPoint -import im.vector.app.core.di.HasVectorInjector import im.vector.app.core.extensions.configureAndStart import im.vector.app.core.extensions.startSyncing +import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.rx.RxConfig import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.configuration.VectorConfiguration @@ -79,7 +77,6 @@ import androidx.work.Configuration as WorkConfiguration @HiltAndroidApp class VectorApplication : Application(), - HasVectorInjector, MatrixConfiguration.Provider, WorkConfiguration.Provider { @@ -114,11 +111,6 @@ class VectorApplication : } } - fun component(): AggregatorEntryPoint { - // Use EntryPoints to get an instance of the AggregatorEntryPoint. - return EntryPoints.get(this, AggregatorEntryPoint::class.java) - } - override fun onCreate() { enableStrictModeIfNeeded() super.onCreate() @@ -135,7 +127,7 @@ class VectorApplication : if (BuildConfig.DEBUG) { Timber.plant(Timber.DebugTree()) } - Timber.plant(component().vectorFileLogger()) + Timber.plant(singletonEntryPoint().vectorFileLogger()) if (BuildConfig.DEBUG) { Stetho.initializeWithDefaults(this) @@ -239,10 +231,6 @@ class VectorApplication : .build() } - override fun injector(): AggregatorEntryPoint { - return component() - } - private fun logInfo() { val appVersion = versionProvider.getVersion(longFormat = true, useBuildNumber = true) val sdkVersion = Matrix.getSdkVersion() diff --git a/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt b/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt index fcd489146d..ae76919c45 100644 --- a/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt +++ b/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt @@ -18,5 +18,5 @@ package im.vector.app.core.di interface HasVectorInjector { - fun injector(): AggregatorEntryPoint + fun injector(): SingletonEntryPoint } diff --git a/vector/src/main/java/im/vector/app/core/di/HiltActivityModules.kt b/vector/src/main/java/im/vector/app/core/di/HiltActivityModules.kt new file mode 100644 index 0000000000..d62cf8a3bc --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/di/HiltActivityModules.kt @@ -0,0 +1,1013 @@ +/* + * 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 androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import im.vector.app.core.platform.ConfigurationViewModel +import im.vector.app.features.call.SharedKnownCallsViewModel +import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyViewModel +import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel +import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel +import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel +import im.vector.app.features.discovery.DiscoverySharedViewModel +import im.vector.app.features.home.HomeSharedActionViewModel +import im.vector.app.features.home.room.detail.RoomDetailSharedActionViewModel +import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel +import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel +import im.vector.app.features.reactions.EmojiChooserViewModel +import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel +import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel +import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel +import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistoryVisibilitySharedActionViewModel +import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleSharedActionViewModel +import im.vector.app.features.spaces.SpacePreviewSharedActionViewModel +import im.vector.app.features.spaces.people.SpacePeopleSharedActionViewModel +import im.vector.app.features.userdirectory.UserListSharedActionViewModel +import android.os.Handler +import androidx.fragment.app.FragmentActivity +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 +import im.vector.app.features.home.room.detail.timeline.TimelineEventControllerHandler +import im.vector.app.features.home.room.detail.timeline.helper.TimelineAsyncHelper +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentFactory +import dagger.Binds +import dagger.multibindings.IntoMap +import im.vector.app.features.attachments.preview.AttachmentsPreviewFragment +import im.vector.app.features.contactsbook.ContactsBookFragment +import im.vector.app.features.crypto.keysbackup.settings.KeysBackupSettingsFragment +import im.vector.app.features.crypto.quads.SharedSecuredStorageKeyFragment +import im.vector.app.features.crypto.quads.SharedSecuredStoragePassphraseFragment +import im.vector.app.features.crypto.quads.SharedSecuredStorageResetAllFragment +import im.vector.app.features.crypto.recover.BootstrapConclusionFragment +import im.vector.app.features.crypto.recover.BootstrapConfirmPassphraseFragment +import im.vector.app.features.crypto.recover.BootstrapEnterPassphraseFragment +import im.vector.app.features.crypto.recover.BootstrapMigrateBackupFragment +import im.vector.app.features.crypto.recover.BootstrapReAuthFragment +import im.vector.app.features.crypto.recover.BootstrapSaveRecoveryKeyFragment +import im.vector.app.features.crypto.recover.BootstrapSetupRecoveryKeyFragment +import im.vector.app.features.crypto.recover.BootstrapWaitingFragment +import im.vector.app.features.crypto.verification.QuadSLoadingFragment +import im.vector.app.features.crypto.verification.cancel.VerificationCancelFragment +import im.vector.app.features.crypto.verification.cancel.VerificationNotMeFragment +import im.vector.app.features.crypto.verification.choose.VerificationChooseMethodFragment +import im.vector.app.features.crypto.verification.conclusion.VerificationConclusionFragment +import im.vector.app.features.crypto.verification.emoji.VerificationEmojiCodeFragment +import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQRWaitingFragment +import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQrScannedByOtherFragment +import im.vector.app.features.crypto.verification.request.VerificationRequestFragment +import im.vector.app.features.devtools.RoomDevToolEditFragment +import im.vector.app.features.devtools.RoomDevToolFragment +import im.vector.app.features.devtools.RoomDevToolSendFormFragment +import im.vector.app.features.devtools.RoomDevToolStateEventListFragment +import im.vector.app.features.discovery.DiscoverySettingsFragment +import im.vector.app.features.discovery.change.SetIdentityServerFragment +import im.vector.app.features.home.HomeDetailFragment +import im.vector.app.features.home.HomeDrawerFragment +import im.vector.app.features.home.LoadingFragment +import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment +import im.vector.app.features.home.room.detail.RoomDetailFragment +import im.vector.app.features.home.room.detail.search.SearchFragment +import im.vector.app.features.home.room.list.RoomListFragment +import im.vector.app.features.login.LoginCaptchaFragment +import im.vector.app.features.login.LoginFragment +import im.vector.app.features.login.LoginGenericTextInputFormFragment +import im.vector.app.features.login.LoginResetPasswordFragment +import im.vector.app.features.login.LoginResetPasswordMailConfirmationFragment +import im.vector.app.features.login.LoginResetPasswordSuccessFragment +import im.vector.app.features.login.LoginServerSelectionFragment +import im.vector.app.features.login.LoginServerUrlFormFragment +import im.vector.app.features.login.LoginSignUpSignInSelectionFragment +import im.vector.app.features.login.LoginSplashFragment +import im.vector.app.features.login.LoginWaitForEmailFragment +import im.vector.app.features.login.LoginWebFragment +import im.vector.app.features.login.terms.LoginTermsFragment +import im.vector.app.features.login2.LoginCaptchaFragment2 +import im.vector.app.features.login2.LoginFragmentSigninPassword2 +import im.vector.app.features.login2.LoginFragmentSigninUsername2 +import im.vector.app.features.login2.LoginFragmentSignupPassword2 +import im.vector.app.features.login2.LoginFragmentSignupUsername2 +import im.vector.app.features.login2.LoginFragmentToAny2 +import im.vector.app.features.login2.LoginGenericTextInputFormFragment2 +import im.vector.app.features.login2.LoginResetPasswordFragment2 +import im.vector.app.features.login2.LoginResetPasswordMailConfirmationFragment2 +import im.vector.app.features.login2.LoginResetPasswordSuccessFragment2 +import im.vector.app.features.login2.LoginServerSelectionFragment2 +import im.vector.app.features.login2.LoginServerUrlFormFragment2 +import im.vector.app.features.login2.LoginSplashSignUpSignInSelectionFragment2 +import im.vector.app.features.login2.LoginSsoOnlyFragment2 +import im.vector.app.features.login2.LoginWaitForEmailFragment2 +import im.vector.app.features.login2.LoginWebFragment2 +import im.vector.app.features.login2.created.AccountCreatedFragment +import im.vector.app.features.login2.terms.LoginTermsFragment2 +import im.vector.app.features.matrixto.MatrixToRoomSpaceFragment +import im.vector.app.features.matrixto.MatrixToUserFragment +import im.vector.app.features.pin.PinFragment +import im.vector.app.features.qrcode.QrCodeScannerFragment +import im.vector.app.features.reactions.EmojiChooserFragment +import im.vector.app.features.reactions.EmojiSearchResultFragment +import im.vector.app.features.roomdirectory.PublicRoomsFragment +import im.vector.app.features.roomdirectory.createroom.CreateRoomFragment +import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerFragment +import im.vector.app.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment +import im.vector.app.features.roommemberprofile.RoomMemberProfileFragment +import im.vector.app.features.roommemberprofile.devices.DeviceListFragment +import im.vector.app.features.roommemberprofile.devices.DeviceTrustInfoActionFragment +import im.vector.app.features.roomprofile.RoomProfileFragment +import im.vector.app.features.roomprofile.alias.RoomAliasFragment +import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment +import im.vector.app.features.roomprofile.members.RoomMemberListFragment +import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment +import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment +import im.vector.app.features.roomprofile.settings.RoomSettingsFragment +import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleChooseRestrictedFragment +import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleFragment +import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment +import im.vector.app.features.roomprofile.uploads.files.RoomUploadsFilesFragment +import im.vector.app.features.roomprofile.uploads.media.RoomUploadsMediaFragment +import im.vector.app.features.settings.VectorSettingsGeneralFragment +import im.vector.app.features.settings.VectorSettingsHelpAboutFragment +import im.vector.app.features.settings.VectorSettingsLabsFragment +import im.vector.app.features.settings.VectorSettingsPinFragment +import im.vector.app.features.settings.VectorSettingsPreferencesFragment +import im.vector.app.features.settings.VectorSettingsSecurityPrivacyFragment +import im.vector.app.features.settings.account.deactivation.DeactivateAccountFragment +import im.vector.app.features.settings.crosssigning.CrossSigningSettingsFragment +import im.vector.app.features.settings.devices.VectorSettingsDevicesFragment +import im.vector.app.features.settings.devtools.AccountDataFragment +import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailFragment +import im.vector.app.features.settings.devtools.IncomingKeyRequestListFragment +import im.vector.app.features.settings.devtools.KeyRequestsFragment +import im.vector.app.features.settings.devtools.OutgoingKeyRequestListFragment +import im.vector.app.features.settings.homeserver.HomeserverSettingsFragment +import im.vector.app.features.settings.ignored.VectorSettingsIgnoredUsersFragment +import im.vector.app.features.settings.locale.LocalePickerFragment +import im.vector.app.features.settings.notifications.VectorSettingsAdvancedNotificationPreferenceFragment +import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceFragment +import im.vector.app.features.settings.notifications.VectorSettingsNotificationsTroubleshootFragment +import im.vector.app.features.settings.push.PushGatewaysFragment +import im.vector.app.features.settings.push.PushRulesFragment +import im.vector.app.features.settings.threepids.ThreePidsSettingsFragment +import im.vector.app.features.share.IncomingShareFragment +import im.vector.app.features.signout.soft.SoftLogoutFragment +import im.vector.app.features.spaces.SpaceListFragment +import im.vector.app.features.spaces.create.ChoosePrivateSpaceTypeFragment +import im.vector.app.features.spaces.create.ChooseSpaceTypeFragment +import im.vector.app.features.spaces.create.CreateSpaceAdd3pidInvitesFragment +import im.vector.app.features.spaces.create.CreateSpaceDefaultRoomsFragment +import im.vector.app.features.spaces.create.CreateSpaceDetailsFragment +import im.vector.app.features.spaces.explore.SpaceDirectoryFragment +import im.vector.app.features.spaces.leave.SpaceLeaveAdvancedFragment +import im.vector.app.features.spaces.manage.SpaceAddRoomFragment +import im.vector.app.features.spaces.manage.SpaceManageRoomsFragment +import im.vector.app.features.spaces.manage.SpaceSettingsFragment +import im.vector.app.features.spaces.people.SpacePeopleFragment +import im.vector.app.features.spaces.preview.SpacePreviewFragment +import im.vector.app.features.terms.ReviewTermsFragment +import im.vector.app.features.usercode.ShowUserCodeFragment +import im.vector.app.features.userdirectory.UserListFragment +import im.vector.app.features.widgets.WidgetFragment + +@Module +@InstallIn(ActivityComponent::class) +object HiltHomeModule { + @Provides + @JvmStatic + @TimelineEventControllerHandler + fun providesTimelineBackgroundHandler(): Handler { + return TimelineAsyncHelper.getBackgroundHandler() + } + +} + +@Module +@InstallIn(ActivityComponent::class) +object HiltScreenModule { + + @Provides + @JvmStatic + fun providesGlideRequests(context: FragmentActivity) = GlideApp.with(context) + + @Provides + @JvmStatic + @ActivityScoped + fun providesSharedViewPool() = RecyclerView.RecycledViewPool() +} + +@Module +@InstallIn(ActivityComponent::class) +interface HiltFragmentModule { + /** + * Fragments with @IntoMap will be injected by this factory + */ + @Binds + @ActivityScoped + fun bindFragmentFactory(factory: VectorFragmentFactory): FragmentFactory + + @Binds + @IntoMap + @FragmentKey(RoomListFragment::class) + fun bindRoomListFragment(fragment: RoomListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LocalePickerFragment::class) + fun bindLocalePickerFragment(fragment: LocalePickerFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SpaceListFragment::class) + fun bindSpaceListFragment(fragment: SpaceListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomDetailFragment::class) + fun bindRoomDetailFragment(fragment: RoomDetailFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomDirectoryPickerFragment::class) + fun bindRoomDirectoryPickerFragment(fragment: RoomDirectoryPickerFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CreateRoomFragment::class) + fun bindCreateRoomFragment(fragment: CreateRoomFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomPreviewNoPreviewFragment::class) + fun bindRoomPreviewNoPreviewFragment(fragment: RoomPreviewNoPreviewFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(KeysBackupSettingsFragment::class) + fun bindKeysBackupSettingsFragment(fragment: KeysBackupSettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoadingFragment::class) + fun bindLoadingFragment(fragment: LoadingFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(HomeDrawerFragment::class) + fun bindHomeDrawerFragment(fragment: HomeDrawerFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(HomeDetailFragment::class) + fun bindHomeDetailFragment(fragment: HomeDetailFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(EmojiSearchResultFragment::class) + fun bindEmojiSearchResultFragment(fragment: EmojiSearchResultFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginFragment::class) + fun bindLoginFragment(fragment: LoginFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginCaptchaFragment::class) + fun bindLoginCaptchaFragment(fragment: LoginCaptchaFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginTermsFragment::class) + fun bindLoginTermsFragment(fragment: LoginTermsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginServerUrlFormFragment::class) + fun bindLoginServerUrlFormFragment(fragment: LoginServerUrlFormFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginResetPasswordMailConfirmationFragment::class) + fun bindLoginResetPasswordMailConfirmationFragment(fragment: LoginResetPasswordMailConfirmationFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginResetPasswordFragment::class) + fun bindLoginResetPasswordFragment(fragment: LoginResetPasswordFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginResetPasswordSuccessFragment::class) + fun bindLoginResetPasswordSuccessFragment(fragment: LoginResetPasswordSuccessFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginServerSelectionFragment::class) + fun bindLoginServerSelectionFragment(fragment: LoginServerSelectionFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginSignUpSignInSelectionFragment::class) + fun bindLoginSignUpSignInSelectionFragment(fragment: LoginSignUpSignInSelectionFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginSplashFragment::class) + fun bindLoginSplashFragment(fragment: LoginSplashFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginWebFragment::class) + fun bindLoginWebFragment(fragment: LoginWebFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginGenericTextInputFormFragment::class) + fun bindLoginGenericTextInputFormFragment(fragment: LoginGenericTextInputFormFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginWaitForEmailFragment::class) + fun bindLoginWaitForEmailFragment(fragment: LoginWaitForEmailFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginFragmentSigninUsername2::class) + fun bindLoginFragmentSigninUsername2(fragment: LoginFragmentSigninUsername2): Fragment + + @Binds + @IntoMap + @FragmentKey(AccountCreatedFragment::class) + fun bindAccountCreatedFragment(fragment: AccountCreatedFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginFragmentSignupUsername2::class) + fun bindLoginFragmentSignupUsername2(fragment: LoginFragmentSignupUsername2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginFragmentSigninPassword2::class) + fun bindLoginFragmentSigninPassword2(fragment: LoginFragmentSigninPassword2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginFragmentSignupPassword2::class) + fun bindLoginFragmentSignupPassword2(fragment: LoginFragmentSignupPassword2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginCaptchaFragment2::class) + fun bindLoginCaptchaFragment2(fragment: LoginCaptchaFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginFragmentToAny2::class) + fun bindLoginFragmentToAny2(fragment: LoginFragmentToAny2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginTermsFragment2::class) + fun bindLoginTermsFragment2(fragment: LoginTermsFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginServerUrlFormFragment2::class) + fun bindLoginServerUrlFormFragment2(fragment: LoginServerUrlFormFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginResetPasswordMailConfirmationFragment2::class) + fun bindLoginResetPasswordMailConfirmationFragment2(fragment: LoginResetPasswordMailConfirmationFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginResetPasswordFragment2::class) + fun bindLoginResetPasswordFragment2(fragment: LoginResetPasswordFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginResetPasswordSuccessFragment2::class) + fun bindLoginResetPasswordSuccessFragment2(fragment: LoginResetPasswordSuccessFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginServerSelectionFragment2::class) + fun bindLoginServerSelectionFragment2(fragment: LoginServerSelectionFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginSsoOnlyFragment2::class) + fun bindLoginSsoOnlyFragment2(fragment: LoginSsoOnlyFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginSplashSignUpSignInSelectionFragment2::class) + fun bindLoginSplashSignUpSignInSelectionFragment2(fragment: LoginSplashSignUpSignInSelectionFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginWebFragment2::class) + fun bindLoginWebFragment2(fragment: LoginWebFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginGenericTextInputFormFragment2::class) + fun bindLoginGenericTextInputFormFragment2(fragment: LoginGenericTextInputFormFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(LoginWaitForEmailFragment2::class) + fun bindLoginWaitForEmailFragment2(fragment: LoginWaitForEmailFragment2): Fragment + + @Binds + @IntoMap + @FragmentKey(UserListFragment::class) + fun bindUserListFragment(fragment: UserListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(PushGatewaysFragment::class) + fun bindPushGatewaysFragment(fragment: PushGatewaysFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class) + fun bindVectorSettingsNotificationsTroubleshootFragment(fragment: VectorSettingsNotificationsTroubleshootFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) + fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsNotificationPreferenceFragment::class) + fun bindVectorSettingsNotificationPreferenceFragment(fragment: VectorSettingsNotificationPreferenceFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsLabsFragment::class) + fun bindVectorSettingsLabsFragment(fragment: VectorSettingsLabsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(HomeserverSettingsFragment::class) + fun bindHomeserverSettingsFragment(fragment: HomeserverSettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsPinFragment::class) + fun bindVectorSettingsPinFragment(fragment: VectorSettingsPinFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsGeneralFragment::class) + fun bindVectorSettingsGeneralFragment(fragment: VectorSettingsGeneralFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(PushRulesFragment::class) + fun bindPushRulesFragment(fragment: PushRulesFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsPreferencesFragment::class) + fun bindVectorSettingsPreferencesFragment(fragment: VectorSettingsPreferencesFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsSecurityPrivacyFragment::class) + fun bindVectorSettingsSecurityPrivacyFragment(fragment: VectorSettingsSecurityPrivacyFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsHelpAboutFragment::class) + fun bindVectorSettingsHelpAboutFragment(fragment: VectorSettingsHelpAboutFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsIgnoredUsersFragment::class) + fun bindVectorSettingsIgnoredUsersFragment(fragment: VectorSettingsIgnoredUsersFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VectorSettingsDevicesFragment::class) + fun bindVectorSettingsDevicesFragment(fragment: VectorSettingsDevicesFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(ThreePidsSettingsFragment::class) + fun bindThreePidsSettingsFragment(fragment: ThreePidsSettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(PublicRoomsFragment::class) + fun bindPublicRoomsFragment(fragment: PublicRoomsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomProfileFragment::class) + fun bindRoomProfileFragment(fragment: RoomProfileFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomMemberListFragment::class) + fun bindRoomMemberListFragment(fragment: RoomMemberListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomUploadsFragment::class) + fun bindRoomUploadsFragment(fragment: RoomUploadsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomUploadsMediaFragment::class) + fun bindRoomUploadsMediaFragment(fragment: RoomUploadsMediaFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomUploadsFilesFragment::class) + fun bindRoomUploadsFilesFragment(fragment: RoomUploadsFilesFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomSettingsFragment::class) + fun bindRoomSettingsFragment(fragment: RoomSettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomAliasFragment::class) + fun bindRoomAliasFragment(fragment: RoomAliasFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomPermissionsFragment::class) + fun bindRoomPermissionsFragment(fragment: RoomPermissionsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomMemberProfileFragment::class) + fun bindRoomMemberProfileFragment(fragment: RoomMemberProfileFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BreadcrumbsFragment::class) + fun bindBreadcrumbsFragment(fragment: BreadcrumbsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(EmojiChooserFragment::class) + fun bindEmojiChooserFragment(fragment: EmojiChooserFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SoftLogoutFragment::class) + fun bindSoftLogoutFragment(fragment: SoftLogoutFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VerificationRequestFragment::class) + fun bindVerificationRequestFragment(fragment: VerificationRequestFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VerificationChooseMethodFragment::class) + fun bindVerificationChooseMethodFragment(fragment: VerificationChooseMethodFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VerificationEmojiCodeFragment::class) + fun bindVerificationEmojiCodeFragment(fragment: VerificationEmojiCodeFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VerificationQrScannedByOtherFragment::class) + fun bindVerificationQrScannedByOtherFragment(fragment: VerificationQrScannedByOtherFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VerificationQRWaitingFragment::class) + fun bindVerificationQRWaitingFragment(fragment: VerificationQRWaitingFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VerificationConclusionFragment::class) + fun bindVerificationConclusionFragment(fragment: VerificationConclusionFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VerificationCancelFragment::class) + fun bindVerificationCancelFragment(fragment: VerificationCancelFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(QuadSLoadingFragment::class) + fun bindQuadSLoadingFragment(fragment: QuadSLoadingFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(VerificationNotMeFragment::class) + fun bindVerificationNotMeFragment(fragment: VerificationNotMeFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(QrCodeScannerFragment::class) + fun bindQrCodeScannerFragment(fragment: QrCodeScannerFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(DeviceListFragment::class) + fun bindDeviceListFragment(fragment: DeviceListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(DeviceTrustInfoActionFragment::class) + fun bindDeviceTrustInfoActionFragment(fragment: DeviceTrustInfoActionFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CrossSigningSettingsFragment::class) + fun bindCrossSigningSettingsFragment(fragment: CrossSigningSettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(AttachmentsPreviewFragment::class) + fun bindAttachmentsPreviewFragment(fragment: AttachmentsPreviewFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(IncomingShareFragment::class) + fun bindIncomingShareFragment(fragment: IncomingShareFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(AccountDataFragment::class) + fun bindAccountDataFragment(fragment: AccountDataFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(OutgoingKeyRequestListFragment::class) + fun bindOutgoingKeyRequestListFragment(fragment: OutgoingKeyRequestListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(IncomingKeyRequestListFragment::class) + fun bindIncomingKeyRequestListFragment(fragment: IncomingKeyRequestListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(KeyRequestsFragment::class) + fun bindKeyRequestsFragment(fragment: KeyRequestsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(GossipingEventsPaperTrailFragment::class) + fun bindGossipingEventsPaperTrailFragment(fragment: GossipingEventsPaperTrailFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BootstrapEnterPassphraseFragment::class) + fun bindBootstrapEnterPassphraseFragment(fragment: BootstrapEnterPassphraseFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BootstrapConfirmPassphraseFragment::class) + fun bindBootstrapConfirmPassphraseFragment(fragment: BootstrapConfirmPassphraseFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BootstrapWaitingFragment::class) + fun bindBootstrapWaitingFragment(fragment: BootstrapWaitingFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BootstrapSetupRecoveryKeyFragment::class) + fun bindBootstrapSetupRecoveryKeyFragment(fragment: BootstrapSetupRecoveryKeyFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BootstrapSaveRecoveryKeyFragment::class) + fun bindBootstrapSaveRecoveryKeyFragment(fragment: BootstrapSaveRecoveryKeyFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BootstrapConclusionFragment::class) + fun bindBootstrapConclusionFragment(fragment: BootstrapConclusionFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BootstrapReAuthFragment::class) + fun bindBootstrapReAuthFragment(fragment: BootstrapReAuthFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(BootstrapMigrateBackupFragment::class) + fun bindBootstrapMigrateBackupFragment(fragment: BootstrapMigrateBackupFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(DeactivateAccountFragment::class) + fun bindDeactivateAccountFragment(fragment: DeactivateAccountFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SharedSecuredStoragePassphraseFragment::class) + fun bindSharedSecuredStoragePassphraseFragment(fragment: SharedSecuredStoragePassphraseFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SharedSecuredStorageKeyFragment::class) + fun bindSharedSecuredStorageKeyFragment(fragment: SharedSecuredStorageKeyFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SharedSecuredStorageResetAllFragment::class) + fun bindSharedSecuredStorageResetAllFragment(fragment: SharedSecuredStorageResetAllFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SetIdentityServerFragment::class) + fun bindSetIdentityServerFragment(fragment: SetIdentityServerFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(DiscoverySettingsFragment::class) + fun bindDiscoverySettingsFragment(fragment: DiscoverySettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(ReviewTermsFragment::class) + fun bindReviewTermsFragment(fragment: ReviewTermsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(WidgetFragment::class) + fun bindWidgetFragment(fragment: WidgetFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(ContactsBookFragment::class) + fun bindPhoneBookFragment(fragment: ContactsBookFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(PinFragment::class) + fun bindPinFragment(fragment: PinFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomBannedMemberListFragment::class) + fun bindRoomBannedMemberListFragment(fragment: RoomBannedMemberListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomNotificationSettingsFragment::class) + fun bindRoomNotificationSettingsFragment(fragment: RoomNotificationSettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SearchFragment::class) + fun bindSearchFragment(fragment: SearchFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(ShowUserCodeFragment::class) + fun bindShowUserCodeFragment(fragment: ShowUserCodeFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomDevToolFragment::class) + fun bindRoomDevToolFragment(fragment: RoomDevToolFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomDevToolStateEventListFragment::class) + fun bindRoomDevToolStateEventListFragment(fragment: RoomDevToolStateEventListFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomDevToolEditFragment::class) + fun bindRoomDevToolEditFragment(fragment: RoomDevToolEditFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomDevToolSendFormFragment::class) + fun bindRoomDevToolSendFormFragment(fragment: RoomDevToolSendFormFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SpacePreviewFragment::class) + fun bindSpacePreviewFragment(fragment: SpacePreviewFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(ChooseSpaceTypeFragment::class) + fun bindChooseSpaceTypeFragment(fragment: ChooseSpaceTypeFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CreateSpaceDetailsFragment::class) + fun bindCreateSpaceDetailsFragment(fragment: CreateSpaceDetailsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CreateSpaceDefaultRoomsFragment::class) + fun bindCreateSpaceDefaultRoomsFragment(fragment: CreateSpaceDefaultRoomsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(MatrixToUserFragment::class) + fun bindMatrixToUserFragment(fragment: MatrixToUserFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(MatrixToRoomSpaceFragment::class) + fun bindMatrixToRoomSpaceFragment(fragment: MatrixToRoomSpaceFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SpaceDirectoryFragment::class) + fun bindSpaceDirectoryFragment(fragment: SpaceDirectoryFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(ChoosePrivateSpaceTypeFragment::class) + fun bindChoosePrivateSpaceTypeFragment(fragment: ChoosePrivateSpaceTypeFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CreateSpaceAdd3pidInvitesFragment::class) + fun bindCreateSpaceAdd3pidInvitesFragment(fragment: CreateSpaceAdd3pidInvitesFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SpaceAddRoomFragment::class) + fun bindSpaceAddRoomFragment(fragment: SpaceAddRoomFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SpacePeopleFragment::class) + fun bindSpacePeopleFragment(fragment: SpacePeopleFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SpaceSettingsFragment::class) + fun bindSpaceSettingsFragment(fragment: SpaceSettingsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SpaceManageRoomsFragment::class) + fun bindSpaceManageRoomsFragment(fragment: SpaceManageRoomsFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomJoinRuleFragment::class) + fun bindRoomJoinRuleFragment(fragment: RoomJoinRuleFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(RoomJoinRuleChooseRestrictedFragment::class) + fun bindRoomJoinRuleChooseRestrictedFragment(fragment: RoomJoinRuleChooseRestrictedFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(SpaceLeaveAdvancedFragment::class) + fun bindSpaceLeaveAdvancedFragment(fragment: SpaceLeaveAdvancedFragment): Fragment +} + +@Module +@InstallIn(ActivityComponent::class) +interface HiltViewModelModule { + + /** + * ViewModels with @IntoMap will be injected by this factory + */ + @Binds + @ActivityScoped + fun bindViewModelFactory(factory: VectorViewModelFactory): ViewModelProvider.Factory + + /** + * Below are bindings for the androidx view models (which extend ViewModel). Will be converted to MvRx ViewModel in the future. + */ + + @Binds + @IntoMap + @ViewModelKey(EmojiChooserViewModel::class) + fun bindEmojiChooserViewModel(viewModel: EmojiChooserViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(KeysBackupRestoreFromKeyViewModel::class) + fun bindKeysBackupRestoreFromKeyViewModel(viewModel: KeysBackupRestoreFromKeyViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(KeysBackupRestoreSharedViewModel::class) + fun bindKeysBackupRestoreSharedViewModel(viewModel: KeysBackupRestoreSharedViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(KeysBackupRestoreFromPassphraseViewModel::class) + fun bindKeysBackupRestoreFromPassphraseViewModel(viewModel: KeysBackupRestoreFromPassphraseViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(KeysBackupSetupSharedViewModel::class) + fun bindKeysBackupSetupSharedViewModel(viewModel: KeysBackupSetupSharedViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(ConfigurationViewModel::class) + fun bindConfigurationViewModel(viewModel: ConfigurationViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(SharedKnownCallsViewModel::class) + fun bindSharedActiveCallViewModel(viewModel: SharedKnownCallsViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(UserListSharedActionViewModel::class) + fun bindUserListSharedActionViewModel(viewModel: UserListSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(HomeSharedActionViewModel::class) + fun bindHomeSharedActionViewModel(viewModel: HomeSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(MessageSharedActionViewModel::class) + fun bindMessageSharedActionViewModel(viewModel: MessageSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomListQuickActionsSharedActionViewModel::class) + fun bindRoomListQuickActionsSharedActionViewModel(viewModel: RoomListQuickActionsSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomAliasBottomSheetSharedActionViewModel::class) + fun bindRoomAliasBottomSheetSharedActionViewModel(viewModel: RoomAliasBottomSheetSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomHistoryVisibilitySharedActionViewModel::class) + fun bindRoomHistoryVisibilitySharedActionViewModel(viewModel: RoomHistoryVisibilitySharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomJoinRuleSharedActionViewModel::class) + fun bindRoomJoinRuleSharedActionViewModel(viewModel: RoomJoinRuleSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomDirectorySharedActionViewModel::class) + fun bindRoomDirectorySharedActionViewModel(viewModel: RoomDirectorySharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomDetailSharedActionViewModel::class) + fun bindRoomDetailSharedActionViewModel(viewModel: RoomDetailSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(RoomProfileSharedActionViewModel::class) + fun bindRoomProfileSharedActionViewModel(viewModel: RoomProfileSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(DiscoverySharedViewModel::class) + fun bindDiscoverySharedViewModel(viewModel: DiscoverySharedViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(SpacePreviewSharedActionViewModel::class) + fun bindSpacePreviewSharedActionViewModel(viewModel: SpacePreviewSharedActionViewModel): ViewModel + + @Binds + @IntoMap + @ViewModelKey(SpacePeopleSharedActionViewModel::class) + fun bindSpacePeopleSharedActionViewModel(viewModel: SpacePeopleSharedActionViewModel): ViewModel +} + diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt index b06c6daa09..b936a1d944 100644 --- a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt @@ -16,237 +16,52 @@ package im.vector.app.core.di -import android.content.Context -import android.content.res.Resources -import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentFactory import androidx.lifecycle.ViewModelProvider import dagger.BindsInstance import dagger.Component -import dagger.hilt.EntryPoint -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import im.vector.app.ActiveSessionDataSource -import im.vector.app.AppStateHandler -import im.vector.app.EmojiCompatFontProvider -import im.vector.app.EmojiCompatWrapper 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.preference.UserAvatarPreference -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.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.JitsiActiveConferenceHolder -import im.vector.app.features.call.conference.VectorJitsiActivity -import im.vector.app.features.call.transfer.CallTransferActivity -import im.vector.app.features.call.webrtc.WebRtcCallManager -import im.vector.app.features.configuration.VectorConfiguration -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.keysrequest.KeyRequestHandler -import im.vector.app.features.crypto.quads.SharedSecureStorageActivity import im.vector.app.features.crypto.recover.BootstrapBottomSheet -import im.vector.app.features.crypto.verification.IncomingVerificationRequestHandler 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.AvatarRenderer -import im.vector.app.features.home.CurrentSpaceSuggestedRoomListDataSource -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.RoomDetailPendingActionStore 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.helper.MatrixItemColorProvider 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.actions.RoomListQuickActionsBottomSheet -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.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.login.ReAuthHelper -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.notifications.NotifiableEventResolver -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.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.rageshake.VectorFileLogger -import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler -import im.vector.app.features.reactions.EmojiReactionPickerActivity -import im.vector.app.features.reactions.data.EmojiDataSource 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.session.SessionListener -import im.vector.app.features.settings.VectorDataStore -import im.vector.app.features.settings.VectorPreferences -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 -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 - -@InstallIn(SingletonComponent::class) -@EntryPoint -interface ScreenComponentDependencies { - 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( dependencies = [ - ScreenComponentDependencies::class + SingletonEntryPoint::class ], modules = [ ViewModelModule::class, @@ -318,8 +133,8 @@ interface ScreenComponent { @Component.Factory interface Factory { - fun create(deps: ScreenComponentDependencies, - @BindsInstance context: AppCompatActivity + fun create(deps: SingletonEntryPoint, + @BindsInstance context: FragmentActivity ): ScreenComponent } } diff --git a/vector/src/main/java/im/vector/app/core/di/AggregatorEntryPoint.kt b/vector/src/main/java/im/vector/app/core/di/SingletonEntryPoint.kt similarity index 99% rename from vector/src/main/java/im/vector/app/core/di/AggregatorEntryPoint.kt rename to vector/src/main/java/im/vector/app/core/di/SingletonEntryPoint.kt index 034607f741..4b89e31bc5 100644 --- a/vector/src/main/java/im/vector/app/core/di/AggregatorEntryPoint.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonEntryPoint.kt @@ -70,7 +70,7 @@ import org.matrix.android.sdk.api.session.Session @InstallIn(SingletonComponent::class) @EntryPoint -interface AggregatorEntryPoint { +interface SingletonEntryPoint { fun matrix(): Matrix diff --git a/vector/src/main/java/im/vector/app/core/di/VectorModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt similarity index 100% rename from vector/src/main/java/im/vector/app/core/di/VectorModule.kt rename to vector/src/main/java/im/vector/app/core/di/SingletonModule.kt diff --git a/vector/src/main/java/im/vector/app/core/extensions/Context.kt b/vector/src/main/java/im/vector/app/core/extensions/Context.kt index 3ecae79ced..59847da7c9 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Context.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Context.kt @@ -17,14 +17,9 @@ package im.vector.app.core.extensions import android.content.Context -import im.vector.app.core.di.AggregatorEntryPoint -import im.vector.app.core.di.HasVectorInjector +import dagger.hilt.EntryPoints +import im.vector.app.core.di.SingletonEntryPoint -fun Context.vectorComponent(): AggregatorEntryPoint { - 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) } diff --git a/vector/src/main/java/im/vector/app/core/extensions/Session.kt b/vector/src/main/java/im/vector/app/core/extensions/Session.kt index f066fd6784..90b08ef92b 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Session.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Session.kt @@ -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) { diff --git a/vector/src/main/java/im/vector/app/core/glide/AvatarPlaceholder.kt b/vector/src/main/java/im/vector/app/core/glide/AvatarPlaceholder.kt index 9675e30042..e61f81de55 100644 --- a/vector/src/main/java/im/vector/app/core/glide/AvatarPlaceholder.kt +++ b/vector/src/main/java/im/vector/app/core/glide/AvatarPlaceholder.kt @@ -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 { - private val avatarRenderer = context.vectorComponent().avatarRenderer() + private val avatarRenderer = context.singletonEntryPoint().avatarRenderer() override fun loadData(priority: Priority, callback: DataFetcher.DataCallback) { val avatarPlaceholder = avatarRenderer.getPlaceholderDrawable(data.matrixItem) diff --git a/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt b/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt index 7dfee7d981..6b42e3fff8 100644 --- a/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt +++ b/vector/src/main/java/im/vector/app/core/glide/VectorGlideModelLoader.kt @@ -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 { private val localFilesHelper = LocalFilesHelper(context) - private val activeSessionHolder = context.vectorComponent().activeSessionHolder() + private val activeSessionHolder = context.singletonEntryPoint().activeSessionHolder() private val client = activeSessionHolder.getSafeActiveSession()?.getOkHttpClient() ?: OkHttpClient() diff --git a/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt b/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt index 7573bf2e8e..a70b2d66e6 100644 --- a/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt @@ -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() { 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 diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 22648b3196..ca0fef83d5 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -49,12 +49,9 @@ import dagger.hilt.EntryPoints import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.di.AggregatorEntryPoint +import im.vector.app.core.di.SingletonEntryPoint 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.ScreenComponentDependencies import im.vector.app.core.dialogs.DialogLocker import im.vector.app.core.dialogs.UnrecognizedCertificateDialog import im.vector.app.core.extensions.exhaustive @@ -63,7 +60,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 @@ -89,9 +86,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 : AppCompatActivity(), HasScreenInjector, MavericksView { +abstract class VectorBaseActivity : AppCompatActivity(), MavericksView { /* ========================================================================================== * View * ========================================================================================== */ @@ -138,8 +135,8 @@ abstract class VectorBaseActivity : 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 @@ -158,8 +155,6 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasSc private val uiDisposables = CompositeDisposable() private val restorables = ArrayList() - private lateinit var screenComponent: ScreenComponent - override fun attachBaseContext(base: Context) { val vectorConfiguration = VectorConfiguration(this) super.attachBaseContext(vectorConfiguration.getLocalisedContext(base)) @@ -189,28 +184,19 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasSc @CallSuper override fun onCreate(savedInstanceState: Bundle?) { Timber.i("onCreate Activity ${javaClass.simpleName}") - val vectorComponent = getVectorComponent() - val screenComponentDeps = EntryPoints.get( - applicationContext, - ScreenComponentDependencies::class.java) - screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, this) - val timeForInjection = measureTimeMillis { - injectWith(screenComponent) - } - Timber.v("Injecting dependencies into ${javaClass.simpleName} took $timeForInjection ms") + val screenComponentDeps = singletonEntryPoint() + val screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, this) ThemeUtils.setActivityTheme(this, getOtherThemes()) fragmentFactory = screenComponent.fragmentFactory() supportFragmentManager.fragmentFactory = fragmentFactory 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 = screenComponentDeps.bugReporter() + pinLocker = screenComponentDeps.pinLocker() + navigator = screenComponentDeps.navigator() + activeSessionHolder = screenComponentDeps.activeSessionHolder() + vectorPreferences = screenComponentDeps.vectorPreferences() configurationViewModel.activityRestarter.observe(this) { if (!it.hasBeenHandled) { // Recreate the Activity because configuration has changed @@ -222,7 +208,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasSc navigator.openPinCode(this, pinStartForActivityResult, PinMode.AUTH) } } - sessionListener = vectorComponent.sessionListener() + sessionListener = screenComponentDeps.sessionListener() sessionListener.globalErrorLiveData.observeEvent(this) { handleGlobalError(it) } @@ -278,7 +264,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasSc } private fun handleCertificateError(certificateError: GlobalError.CertificateError) { - vectorComponent() + singletonEntryPoint() .unrecognizedCertificateDialog() .show(this, certificateError.fingerprint, @@ -408,12 +394,6 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasSc bugReporter.inMultiWindowMode = isInMultiWindowMode } - override fun injector(): ScreenComponent { - return screenComponent - } - - protected open fun injectWith(injector: ScreenComponent) = Unit - protected fun createFragment(fragmentClass: Class, args: Bundle?): Fragment { return fragmentFactory.instantiate(classLoader, fragmentClass.name).apply { arguments = args @@ -424,7 +404,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasSc * PRIVATE METHODS * ========================================================================================== */ - internal fun getVectorComponent(): AggregatorEntryPoint { + internal fun getVectorComponent(): SingletonEntryPoint { return (application as HasVectorInjector).injector() } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index 90147604e5..3b7485045e 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -34,9 +34,9 @@ import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.jakewharton.rxbinding3.view.clicks import dagger.hilt.EntryPoints +import im.vector.app.core.di.SingletonEntryPoint import im.vector.app.core.di.DaggerScreenComponent import im.vector.app.core.di.ScreenComponent -import im.vector.app.core.di.ScreenComponentDependencies import im.vector.app.core.utils.DimensionConverter import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -126,7 +126,7 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe override fun onAttach(context: Context) { val screenComponentDeps = EntryPoints.get( vectorBaseActivity.applicationContext, - ScreenComponentDependencies::class.java) + SingletonEntryPoint::class.java) screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, vectorBaseActivity) viewModelFactory = screenComponent.viewModelFactory() super.onAttach(context) diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index de36473507..e8f1b88f44 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -37,12 +37,13 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.jakewharton.rxbinding3.view.clicks import dagger.hilt.EntryPoints import im.vector.app.R +import im.vector.app.core.di.SingletonEntryPoint 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.ScreenComponentDependencies 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 @@ -97,9 +98,7 @@ abstract class VectorBaseFragment : Fragment(), MavericksView, * ========================================================================================== */ override fun onAttach(context: Context) { - val screenComponentDeps = EntryPoints.get( - vectorBaseActivity.applicationContext, - ScreenComponentDependencies::class.java) + val screenComponentDeps = context.singletonEntryPoint() screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, vectorBaseActivity) navigator = screenComponent.navigator() errorFormatter = screenComponent.errorFormatter() diff --git a/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt b/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt index 3bb50c6284..3095f98ea5 100755 --- a/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/UserAvatarPreference.kt @@ -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 diff --git a/vector/src/main/java/im/vector/app/core/services/CallService.kt b/vector/src/main/java/im/vector/app/core/services/CallService.kt index 5e07bb76c6..d194434641 100644 --- a/vector/src/main/java/im/vector/app/core/services/CallService.kt +++ b/vector/src/main/java/im/vector/app/core/services/CallService.kt @@ -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() private val knownCalls = mutableMapOf() private val connectedCallIds = mutableSetOf() - 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, diff --git a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt b/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt index 2a00e94976..1fd86cac4d 100644 --- a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt +++ b/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt @@ -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 diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt index 1f89444365..939dd9f11d 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt @@ -29,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(), ToolbarConfigurable { companion object { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt index e80853b035..b3c0612838 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt @@ -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 @@ -27,8 +29,11 @@ import im.vector.app.core.extensions.replaceFragment 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.Session 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 +53,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()) { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt index 97a29dd707..341a195866 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt @@ -25,6 +25,7 @@ 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.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent import im.vector.app.core.dialogs.ExportKeysDialog import im.vector.app.core.extensions.observeEvent @@ -45,6 +46,11 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() { private lateinit var viewModel: KeysBackupSetupSharedViewModel @Inject lateinit var keysExporter: KeysExporter + @Inject lateinit var activeSessionHolder: ActiveSessionHolder + + private val session by lazy { + activeSessionHolder.getActiveSession() + } override fun initUiAndData() { super.initUiAndData() diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt index 44f41c338c..cb42d12e66 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt @@ -21,7 +21,8 @@ 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.SingletonEntryPoint import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyAction @@ -94,7 +95,7 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( 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) diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt index 7d7a876b68..d6c9e348db 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt @@ -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,8 @@ 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.SingletonEntryPoint import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyAction @@ -161,7 +161,7 @@ class VerificationEmojiCodeViewModel @AssistedInject constructor( override fun initialState(viewModelContext: ViewModelContext): VerificationEmojiCodeViewState? { val args = viewModelContext.args() - 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( diff --git a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt index f24f74f31c..7354cafc9f 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt @@ -20,8 +20,9 @@ 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.SingletonEntryPoint import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive @@ -49,7 +50,7 @@ class SetIdentityServerViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { override fun initialState(viewModelContext: ViewModelContext): SetIdentityServerState { - val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession() + val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() return SetIdentityServerState( homeServerUrl = session.sessionParams.homeServerUrl, defaultIdentityServerUrl = session.identityService().getDefaultIdentityServer() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 25f94a25c7..3ab4fa8b5a 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -17,17 +17,18 @@ 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 import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import dagger.hilt.EntryPoints import im.vector.app.AppStateHandler import im.vector.app.RoomGroupingMethod -import im.vector.app.core.di.HasScreenInjector +import im.vector.app.core.di.SingletonEntryPoint 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 @@ -78,7 +79,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory(){ override fun initialState(viewModelContext: ViewModelContext): HomeDetailViewState { - val uiStateRepository = (viewModelContext.activity as HasScreenInjector).injector().uiStateRepository() + val uiStateRepository = viewModelContext.activity.singletonEntryPoint().uiStateRepository() return HomeDetailViewState( currentTab = HomeTab.RoomList(uiStateRepository.getDisplayMode()) ) diff --git a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt index 068e0f762e..d76af19c87 100644 --- a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt @@ -21,7 +21,8 @@ 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.SingletonEntryPoint import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyAction @@ -50,7 +51,7 @@ class HomeServerCapabilitiesViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { override fun initialState(viewModelContext: ViewModelContext): HomeServerCapabilitiesViewState { - val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getSafeActiveSession() + val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getSafeActiveSession() return HomeServerCapabilitiesViewState( capabilities = session?.getHomeServerCapabilities() ?: HomeServerCapabilities() ) diff --git a/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt b/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt index 22f9e9a18c..29b45d45e0 100644 --- a/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt +++ b/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt @@ -21,6 +21,7 @@ import android.util.AttributeSet import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.updateLayoutParams +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.di.HasScreenInjector import im.vector.app.databinding.VectorInviteViewBinding @@ -30,6 +31,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject +@AndroidEntryPoint class VectorInviteView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : ConstraintLayout(context, attrs, defStyle) { @@ -49,9 +51,6 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib var callback: Callback? = null init { - if (context is HasScreenInjector) { - context.injector().inject(this) - } inflate(context, R.layout.vector_invite_view, this) views = VectorInviteViewBinding.bind(this) views.inviteAcceptView.commonClicked = { callback?.onAcceptInvite() } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt index 5f78ac8286..6583db6f69 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt @@ -23,7 +23,6 @@ import androidx.core.app.RemoteInput import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.extensions.vectorComponent import im.vector.app.features.session.coroutineScope import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull diff --git a/vector/src/main/java/im/vector/app/features/rageshake/RageShake.kt b/vector/src/main/java/im/vector/app/features/rageshake/RageShake.kt index 48a6e8a679..b377b0b1df 100644 --- a/vector/src/main/java/im/vector/app/features/rageshake/RageShake.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/RageShake.kt @@ -21,6 +21,7 @@ import android.hardware.Sensor import android.hardware.SensorManager import androidx.appcompat.app.AppCompatActivity import androidx.core.content.getSystemService +import androidx.fragment.app.FragmentActivity import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.squareup.seismic.ShakeDetector import im.vector.app.R @@ -30,7 +31,7 @@ import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorSettingsActivity import javax.inject.Inject -class RageShake @Inject constructor(private val activity: AppCompatActivity, +class RageShake @Inject constructor(private val activity: FragmentActivity, private val bugReporter: BugReporter, private val navigator: Navigator, private val vectorPreferences: VectorPreferences) : ShakeDetector.Listener { diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt index c342d6519d..5e4b2b7ef1 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt @@ -23,6 +23,7 @@ import android.view.View import android.widget.LinearLayout import androidx.core.content.ContextCompat import androidx.core.content.withStyledAttributes +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.EmojiCompatWrapper import im.vector.app.R import im.vector.app.core.di.HasScreenInjector @@ -35,17 +36,12 @@ import javax.inject.Inject * An animated reaction button. * Displays a String reaction (emoji), with a count, and that can be selected or not (toggle) */ +@AndroidEntryPoint class ReactionButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr), View.OnClickListener, View.OnLongClickListener { - init { - if (context is HasScreenInjector) { - context.injector().inject(this) - } - } - @Inject lateinit var emojiCompatWrapper: EmojiCompatWrapper private val views: ReactionButtonBinding diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt index 063f7b6188..03b20bce40 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt @@ -25,7 +25,8 @@ 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.SingletonEntryPoint import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import org.matrix.android.sdk.api.session.Session @@ -118,7 +119,7 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva override fun initialState(viewModelContext: ViewModelContext): DeviceListViewState? { val userId = viewModelContext.args().userId - val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession() + val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() return session.getUser(userId)?.toMatrixItem()?.let { DeviceListViewState( userItem = it, diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index 36af0f906d..8cf82c70a9 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -24,10 +24,10 @@ import androidx.preference.PreferenceFragmentCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.EntryPoints import im.vector.app.R +import im.vector.app.core.di.SingletonEntryPoint 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.ScreenComponentDependencies import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast @@ -60,7 +60,7 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScree override fun onAttach(context: Context) { val screenComponentDeps = EntryPoints.get( vectorActivity.applicationContext, - ScreenComponentDependencies::class.java) + SingletonEntryPoint::class.java) screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, vectorActivity) super.onAttach(context) session = screenComponent.activeSessionHolder().getActiveSession() diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt index 745d71fd41..3b620f53e5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt @@ -18,7 +18,8 @@ package im.vector.app.features.settings.push import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.ViewModelContext -import im.vector.app.core.di.HasScreenInjector +import dagger.hilt.EntryPoints +import im.vector.app.core.di.SingletonEntryPoint import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -34,7 +35,7 @@ class PushRulesViewModel(initialState: PushRulesViewState) : companion object : MavericksViewModelFactory { override fun initialState(viewModelContext: ViewModelContext): PushRulesViewState? { - val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession() + val session = EntryPoints.get(viewModelContext.app(),SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() val rules = session.getPushRules().getAllRules() return PushRulesViewState(rules) } diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt index d4f089b943..e9b6831dcf 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt @@ -19,6 +19,7 @@ import android.content.Context import android.content.Intent import androidx.activity.result.ActivityResultLauncher import androidx.core.app.NotificationManagerCompat +import androidx.fragment.app.FragmentActivity import im.vector.app.R import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.startNotificationSettingsIntent @@ -27,7 +28,7 @@ import javax.inject.Inject /** * Checks if notifications are enable in the system settings for this app. */ -class TestSystemSettings @Inject constructor(private val context: Context, +class TestSystemSettings @Inject constructor(private val context: FragmentActivity, private val stringProvider: StringProvider) : TroubleshootTest(R.string.settings_troubleshoot_test_system_settings_title) { diff --git a/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt b/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt index ab8af20063..74d4cd500b 100644 --- a/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt @@ -21,6 +21,8 @@ import android.content.Intent import android.webkit.WebChromeClient import android.webkit.WebView import androidx.annotation.CallSuper +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityVectorWebViewBinding @@ -33,15 +35,14 @@ import javax.inject.Inject * It relies on the VectorWebViewClient * This class shouldn't be extended. To add new behaviors, you might create a new WebViewMode and a new WebViewEventListener */ +@AndroidEntryPoint class VectorWebViewActivity : VectorBaseActivity() { override fun getBinding() = ActivityVectorWebViewBinding.inflate(layoutInflater) - @Inject lateinit var session: Session - - @CallSuper - override fun injectWith(injector: ScreenComponent) { - session = injector.activeSessionHolder().getActiveSession() + @Inject lateinit var activeSessionHolder: ActiveSessionHolder + val session: Session by lazy { + activeSessionHolder.getActiveSession() } override fun initUiAndData() { diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutUiWorker.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutUiWorker.kt index c5fa130d9b..59ea37036c 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutUiWorker.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutUiWorker.kt @@ -20,14 +20,14 @@ import androidx.fragment.app.FragmentActivity import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.core.extensions.cannotLogoutSafely -import im.vector.app.core.extensions.vectorComponent +import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs class SignOutUiWorker(private val activity: FragmentActivity) { fun perform() { - val session = activity.vectorComponent().activeSessionHolder().getSafeActiveSession() ?: return + val session = activity.singletonEntryPoint().activeSessionHolder().getSafeActiveSession() ?: return if (session.cannotLogoutSafely()) { // The backup check on logout flow has to be displayed if there are keys in the store, and the keys backup state is not Ready val signOutDialog = SignOutBottomSheetDialogFragment.newInstance() From ac1e4e9e9c5c28bc709f79feecb0bafc968f3a02 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 21 Oct 2021 10:10:59 +0200 Subject: [PATCH 012/413] Hilt: remove usage of ScreenComponent --- .../app/features/debug/DebugMenuActivity.kt | 2 +- .../java/im/vector/app/VectorApplication.kt | 5 +- ...creenInjector.kt => ActivityEntryPoint.kt} | 16 +- .../im/vector/app/core/di/FragmentModule.kt | 4 +- .../vector/app/core/di/HiltActivityModules.kt | 1013 ----------------- .../java/im/vector/app/core/di/HomeModule.kt | 37 + .../im/vector/app/core/di/ScreenComponent.kt | 140 --- .../im/vector/app/core/di/ScreenModule.kt | 12 +- .../java/im/vector/app/core/di/ScreenScope.kt | 24 - .../im/vector/app/core/di/ViewModelModule.kt | 5 +- .../app/core/platform/VectorBaseActivity.kt | 24 +- .../VectorBaseBottomSheetDialogFragment.kt | 18 +- .../app/core/platform/VectorBaseFragment.kt | 30 +- .../im/vector/app/features/MainActivity.kt | 2 +- .../app/features/auth/ReAuthActivity.kt | 2 +- .../features/call/CallControlsBottomSheet.kt | 2 + .../app/features/call/VectorCallActivity.kt | 1 - .../call/conference/VectorJitsiActivity.kt | 2 +- .../call/transfer/CallTransferActivity.kt | 2 +- .../createdirect/CreateDirectRoomActivity.kt | 2 +- .../settings/KeysBackupManageActivity.kt | 2 +- .../setup/KeysBackupSetupActivity.kt | 2 +- .../quads/SharedSecureStorageActivity.kt | 2 +- .../crypto/recover/BootstrapBottomSheet.kt | 8 +- .../verification/VerificationBottomSheet.kt | 8 +- .../features/devtools/RoomDevToolActivity.kt | 1 - .../vector/app/features/home/HomeActivity.kt | 2 +- .../detail/JoinReplacementRoomBottomSheet.kt | 8 +- .../home/room/detail/RoomDetailActivity.kt | 2 +- .../DisplayReadReceiptsBottomSheet.kt | 7 +- .../home/room/detail/search/SearchActivity.kt | 2 +- .../action/MessageActionsBottomSheet.kt | 7 +- .../edithistory/ViewEditHistoryBottomSheet.kt | 7 +- .../ContentDownloadStateTrackerBinder.kt | 4 +- .../helper/ContentUploadStateTrackerBinder.kt | 4 +- .../helper/TimelineMediaSizeProvider.kt | 4 +- .../helper/VoiceMessagePlaybackTracker.kt | 4 +- .../reactions/ViewReactionsBottomSheet.kt | 7 +- .../detail/upgrade/MigrateRoomBottomSheet.kt | 11 +- .../detail/widget/RoomWidgetsBottomSheet.kt | 8 +- .../room/filtered/FilteredRoomsActivity.kt | 2 +- .../RoomListQuickActionsBottomSheet.kt | 7 +- .../invite/InviteUsersToRoomActivity.kt | 2 +- .../app/features/invite/VectorInviteView.kt | 1 - .../app/features/link/LinkHandlerActivity.kt | 2 +- .../app/features/login/LoginActivity.kt | 2 +- .../app/features/login2/LoginActivity2.kt | 2 +- .../features/matrixto/MatrixToBottomSheet.kt | 8 +- .../features/media/BigImageViewerActivity.kt | 2 +- .../features/qrcode/QrCodeScannerActivity.kt | 2 +- .../features/rageshake/BugReportActivity.kt | 2 +- .../reactions/EmojiReactionPickerActivity.kt | 2 +- .../reactions/widget/ReactionButton.kt | 1 - .../roomdirectory/RoomDirectoryActivity.kt | 2 +- .../createroom/CreateRoomActivity.kt | 2 +- .../RoomMemberProfileActivity.kt | 2 +- .../devices/DeviceListBottomSheet.kt | 8 +- .../roomprofile/RoomProfileActivity.kt | 2 +- .../alias/detail/RoomAliasBottomSheet.kt | 8 +- .../RoomHistoryVisibilityBottomSheet.kt | 8 +- .../settings/joinrule/RoomJoinRuleActivity.kt | 2 +- .../joinrule/RoomJoinRuleBottomSheet.kt | 8 +- .../settings/VectorSettingsActivity.kt | 2 +- .../settings/VectorSettingsBaseFragment.kt | 25 +- .../DeviceVerificationInfoBottomSheet.kt | 9 +- .../signout/soft/SoftLogoutActivity.kt | 2 +- .../signout/soft/SoftLogoutActivity2.kt | 2 +- .../InviteRoomSpaceChooserBottomSheet.kt | 8 +- .../features/spaces/LeaveSpaceBottomSheet.kt | 8 +- .../features/spaces/SpaceCreationActivity.kt | 2 +- .../features/spaces/SpaceExploreActivity.kt | 2 +- .../spaces/SpaceSettingsMenuBottomSheet.kt | 8 +- .../spaces/invite/SpaceInviteBottomSheet.kt | 15 +- .../leave/SpaceLeaveAdvancedActivity.kt | 2 +- .../spaces/manage/SpaceManageActivity.kt | 2 +- .../spaces/share/ShareSpaceBottomSheet.kt | 8 +- .../app/features/terms/ReviewTermsActivity.kt | 2 +- .../app/features/usercode/UserCodeActivity.kt | 2 +- .../features/webview/VectorWebViewActivity.kt | 2 +- .../app/features/widgets/WidgetActivity.kt | 2 +- .../RoomWidgetPermissionBottomSheet.kt | 8 +- .../SignOutBottomSheetDialogFragment.kt | 8 +- 82 files changed, 211 insertions(+), 1428 deletions(-) rename vector/src/main/java/im/vector/app/core/di/{HasScreenInjector.kt => ActivityEntryPoint.kt} (54%) delete mode 100644 vector/src/main/java/im/vector/app/core/di/HiltActivityModules.kt create mode 100644 vector/src/main/java/im/vector/app/core/di/HomeModule.kt delete mode 100644 vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt delete mode 100644 vector/src/main/java/im/vector/app/core/di/ScreenScope.kt diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index fb47e6abe8..999392f2b7 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -27,7 +27,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index d346404950..d9027231da 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -43,7 +43,6 @@ import dagger.hilt.android.HiltAndroidApp import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.extensions.configureAndStart import im.vector.app.core.extensions.startSyncing -import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.rx.RxConfig import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.configuration.VectorConfiguration @@ -54,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 @@ -98,6 +98,7 @@ class VectorApplication : @Inject lateinit var pinLocker: PinLocker @Inject lateinit var callManager: WebRtcCallManager @Inject lateinit var invitesAcceptor: InvitesAcceptor + @Inject lateinit var vectorFileLogger: VectorFileLogger // font thread handler private var fontThreadHandler: Handler? = null @@ -127,7 +128,7 @@ class VectorApplication : if (BuildConfig.DEBUG) { Timber.plant(Timber.DebugTree()) } - Timber.plant(singletonEntryPoint().vectorFileLogger()) + Timber.plant(vectorFileLogger) if (BuildConfig.DEBUG) { Stetho.initializeWithDefaults(this) diff --git a/vector/src/main/java/im/vector/app/core/di/HasScreenInjector.kt b/vector/src/main/java/im/vector/app/core/di/ActivityEntryPoint.kt similarity index 54% rename from vector/src/main/java/im/vector/app/core/di/HasScreenInjector.kt rename to vector/src/main/java/im/vector/app/core/di/ActivityEntryPoint.kt index 4618bd04d1..c5f7317ebe 100644 --- a/vector/src/main/java/im/vector/app/core/di/HasScreenInjector.kt +++ b/vector/src/main/java/im/vector/app/core/di/ActivityEntryPoint.kt @@ -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 } diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index d943a3806f..a865fcc074 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -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.hilt.migration.DisableInstallInCheck import dagger.multibindings.IntoMap import im.vector.app.features.attachments.preview.AttachmentsPreviewFragment @@ -158,7 +160,7 @@ import im.vector.app.features.usercode.ShowUserCodeFragment import im.vector.app.features.userdirectory.UserListFragment import im.vector.app.features.widgets.WidgetFragment -@DisableInstallInCheck +@InstallIn(ActivityComponent::class) @Module interface FragmentModule { /** diff --git a/vector/src/main/java/im/vector/app/core/di/HiltActivityModules.kt b/vector/src/main/java/im/vector/app/core/di/HiltActivityModules.kt deleted file mode 100644 index d62cf8a3bc..0000000000 --- a/vector/src/main/java/im/vector/app/core/di/HiltActivityModules.kt +++ /dev/null @@ -1,1013 +0,0 @@ -/* - * 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 androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import im.vector.app.core.platform.ConfigurationViewModel -import im.vector.app.features.call.SharedKnownCallsViewModel -import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyViewModel -import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel -import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel -import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel -import im.vector.app.features.discovery.DiscoverySharedViewModel -import im.vector.app.features.home.HomeSharedActionViewModel -import im.vector.app.features.home.room.detail.RoomDetailSharedActionViewModel -import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel -import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel -import im.vector.app.features.reactions.EmojiChooserViewModel -import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel -import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel -import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel -import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistoryVisibilitySharedActionViewModel -import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleSharedActionViewModel -import im.vector.app.features.spaces.SpacePreviewSharedActionViewModel -import im.vector.app.features.spaces.people.SpacePeopleSharedActionViewModel -import im.vector.app.features.userdirectory.UserListSharedActionViewModel -import android.os.Handler -import androidx.fragment.app.FragmentActivity -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 -import im.vector.app.features.home.room.detail.timeline.TimelineEventControllerHandler -import im.vector.app.features.home.room.detail.timeline.helper.TimelineAsyncHelper -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentFactory -import dagger.Binds -import dagger.multibindings.IntoMap -import im.vector.app.features.attachments.preview.AttachmentsPreviewFragment -import im.vector.app.features.contactsbook.ContactsBookFragment -import im.vector.app.features.crypto.keysbackup.settings.KeysBackupSettingsFragment -import im.vector.app.features.crypto.quads.SharedSecuredStorageKeyFragment -import im.vector.app.features.crypto.quads.SharedSecuredStoragePassphraseFragment -import im.vector.app.features.crypto.quads.SharedSecuredStorageResetAllFragment -import im.vector.app.features.crypto.recover.BootstrapConclusionFragment -import im.vector.app.features.crypto.recover.BootstrapConfirmPassphraseFragment -import im.vector.app.features.crypto.recover.BootstrapEnterPassphraseFragment -import im.vector.app.features.crypto.recover.BootstrapMigrateBackupFragment -import im.vector.app.features.crypto.recover.BootstrapReAuthFragment -import im.vector.app.features.crypto.recover.BootstrapSaveRecoveryKeyFragment -import im.vector.app.features.crypto.recover.BootstrapSetupRecoveryKeyFragment -import im.vector.app.features.crypto.recover.BootstrapWaitingFragment -import im.vector.app.features.crypto.verification.QuadSLoadingFragment -import im.vector.app.features.crypto.verification.cancel.VerificationCancelFragment -import im.vector.app.features.crypto.verification.cancel.VerificationNotMeFragment -import im.vector.app.features.crypto.verification.choose.VerificationChooseMethodFragment -import im.vector.app.features.crypto.verification.conclusion.VerificationConclusionFragment -import im.vector.app.features.crypto.verification.emoji.VerificationEmojiCodeFragment -import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQRWaitingFragment -import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQrScannedByOtherFragment -import im.vector.app.features.crypto.verification.request.VerificationRequestFragment -import im.vector.app.features.devtools.RoomDevToolEditFragment -import im.vector.app.features.devtools.RoomDevToolFragment -import im.vector.app.features.devtools.RoomDevToolSendFormFragment -import im.vector.app.features.devtools.RoomDevToolStateEventListFragment -import im.vector.app.features.discovery.DiscoverySettingsFragment -import im.vector.app.features.discovery.change.SetIdentityServerFragment -import im.vector.app.features.home.HomeDetailFragment -import im.vector.app.features.home.HomeDrawerFragment -import im.vector.app.features.home.LoadingFragment -import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment -import im.vector.app.features.home.room.detail.RoomDetailFragment -import im.vector.app.features.home.room.detail.search.SearchFragment -import im.vector.app.features.home.room.list.RoomListFragment -import im.vector.app.features.login.LoginCaptchaFragment -import im.vector.app.features.login.LoginFragment -import im.vector.app.features.login.LoginGenericTextInputFormFragment -import im.vector.app.features.login.LoginResetPasswordFragment -import im.vector.app.features.login.LoginResetPasswordMailConfirmationFragment -import im.vector.app.features.login.LoginResetPasswordSuccessFragment -import im.vector.app.features.login.LoginServerSelectionFragment -import im.vector.app.features.login.LoginServerUrlFormFragment -import im.vector.app.features.login.LoginSignUpSignInSelectionFragment -import im.vector.app.features.login.LoginSplashFragment -import im.vector.app.features.login.LoginWaitForEmailFragment -import im.vector.app.features.login.LoginWebFragment -import im.vector.app.features.login.terms.LoginTermsFragment -import im.vector.app.features.login2.LoginCaptchaFragment2 -import im.vector.app.features.login2.LoginFragmentSigninPassword2 -import im.vector.app.features.login2.LoginFragmentSigninUsername2 -import im.vector.app.features.login2.LoginFragmentSignupPassword2 -import im.vector.app.features.login2.LoginFragmentSignupUsername2 -import im.vector.app.features.login2.LoginFragmentToAny2 -import im.vector.app.features.login2.LoginGenericTextInputFormFragment2 -import im.vector.app.features.login2.LoginResetPasswordFragment2 -import im.vector.app.features.login2.LoginResetPasswordMailConfirmationFragment2 -import im.vector.app.features.login2.LoginResetPasswordSuccessFragment2 -import im.vector.app.features.login2.LoginServerSelectionFragment2 -import im.vector.app.features.login2.LoginServerUrlFormFragment2 -import im.vector.app.features.login2.LoginSplashSignUpSignInSelectionFragment2 -import im.vector.app.features.login2.LoginSsoOnlyFragment2 -import im.vector.app.features.login2.LoginWaitForEmailFragment2 -import im.vector.app.features.login2.LoginWebFragment2 -import im.vector.app.features.login2.created.AccountCreatedFragment -import im.vector.app.features.login2.terms.LoginTermsFragment2 -import im.vector.app.features.matrixto.MatrixToRoomSpaceFragment -import im.vector.app.features.matrixto.MatrixToUserFragment -import im.vector.app.features.pin.PinFragment -import im.vector.app.features.qrcode.QrCodeScannerFragment -import im.vector.app.features.reactions.EmojiChooserFragment -import im.vector.app.features.reactions.EmojiSearchResultFragment -import im.vector.app.features.roomdirectory.PublicRoomsFragment -import im.vector.app.features.roomdirectory.createroom.CreateRoomFragment -import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerFragment -import im.vector.app.features.roomdirectory.roompreview.RoomPreviewNoPreviewFragment -import im.vector.app.features.roommemberprofile.RoomMemberProfileFragment -import im.vector.app.features.roommemberprofile.devices.DeviceListFragment -import im.vector.app.features.roommemberprofile.devices.DeviceTrustInfoActionFragment -import im.vector.app.features.roomprofile.RoomProfileFragment -import im.vector.app.features.roomprofile.alias.RoomAliasFragment -import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment -import im.vector.app.features.roomprofile.members.RoomMemberListFragment -import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment -import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment -import im.vector.app.features.roomprofile.settings.RoomSettingsFragment -import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleChooseRestrictedFragment -import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleFragment -import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment -import im.vector.app.features.roomprofile.uploads.files.RoomUploadsFilesFragment -import im.vector.app.features.roomprofile.uploads.media.RoomUploadsMediaFragment -import im.vector.app.features.settings.VectorSettingsGeneralFragment -import im.vector.app.features.settings.VectorSettingsHelpAboutFragment -import im.vector.app.features.settings.VectorSettingsLabsFragment -import im.vector.app.features.settings.VectorSettingsPinFragment -import im.vector.app.features.settings.VectorSettingsPreferencesFragment -import im.vector.app.features.settings.VectorSettingsSecurityPrivacyFragment -import im.vector.app.features.settings.account.deactivation.DeactivateAccountFragment -import im.vector.app.features.settings.crosssigning.CrossSigningSettingsFragment -import im.vector.app.features.settings.devices.VectorSettingsDevicesFragment -import im.vector.app.features.settings.devtools.AccountDataFragment -import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailFragment -import im.vector.app.features.settings.devtools.IncomingKeyRequestListFragment -import im.vector.app.features.settings.devtools.KeyRequestsFragment -import im.vector.app.features.settings.devtools.OutgoingKeyRequestListFragment -import im.vector.app.features.settings.homeserver.HomeserverSettingsFragment -import im.vector.app.features.settings.ignored.VectorSettingsIgnoredUsersFragment -import im.vector.app.features.settings.locale.LocalePickerFragment -import im.vector.app.features.settings.notifications.VectorSettingsAdvancedNotificationPreferenceFragment -import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceFragment -import im.vector.app.features.settings.notifications.VectorSettingsNotificationsTroubleshootFragment -import im.vector.app.features.settings.push.PushGatewaysFragment -import im.vector.app.features.settings.push.PushRulesFragment -import im.vector.app.features.settings.threepids.ThreePidsSettingsFragment -import im.vector.app.features.share.IncomingShareFragment -import im.vector.app.features.signout.soft.SoftLogoutFragment -import im.vector.app.features.spaces.SpaceListFragment -import im.vector.app.features.spaces.create.ChoosePrivateSpaceTypeFragment -import im.vector.app.features.spaces.create.ChooseSpaceTypeFragment -import im.vector.app.features.spaces.create.CreateSpaceAdd3pidInvitesFragment -import im.vector.app.features.spaces.create.CreateSpaceDefaultRoomsFragment -import im.vector.app.features.spaces.create.CreateSpaceDetailsFragment -import im.vector.app.features.spaces.explore.SpaceDirectoryFragment -import im.vector.app.features.spaces.leave.SpaceLeaveAdvancedFragment -import im.vector.app.features.spaces.manage.SpaceAddRoomFragment -import im.vector.app.features.spaces.manage.SpaceManageRoomsFragment -import im.vector.app.features.spaces.manage.SpaceSettingsFragment -import im.vector.app.features.spaces.people.SpacePeopleFragment -import im.vector.app.features.spaces.preview.SpacePreviewFragment -import im.vector.app.features.terms.ReviewTermsFragment -import im.vector.app.features.usercode.ShowUserCodeFragment -import im.vector.app.features.userdirectory.UserListFragment -import im.vector.app.features.widgets.WidgetFragment - -@Module -@InstallIn(ActivityComponent::class) -object HiltHomeModule { - @Provides - @JvmStatic - @TimelineEventControllerHandler - fun providesTimelineBackgroundHandler(): Handler { - return TimelineAsyncHelper.getBackgroundHandler() - } - -} - -@Module -@InstallIn(ActivityComponent::class) -object HiltScreenModule { - - @Provides - @JvmStatic - fun providesGlideRequests(context: FragmentActivity) = GlideApp.with(context) - - @Provides - @JvmStatic - @ActivityScoped - fun providesSharedViewPool() = RecyclerView.RecycledViewPool() -} - -@Module -@InstallIn(ActivityComponent::class) -interface HiltFragmentModule { - /** - * Fragments with @IntoMap will be injected by this factory - */ - @Binds - @ActivityScoped - fun bindFragmentFactory(factory: VectorFragmentFactory): FragmentFactory - - @Binds - @IntoMap - @FragmentKey(RoomListFragment::class) - fun bindRoomListFragment(fragment: RoomListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LocalePickerFragment::class) - fun bindLocalePickerFragment(fragment: LocalePickerFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SpaceListFragment::class) - fun bindSpaceListFragment(fragment: SpaceListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomDetailFragment::class) - fun bindRoomDetailFragment(fragment: RoomDetailFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomDirectoryPickerFragment::class) - fun bindRoomDirectoryPickerFragment(fragment: RoomDirectoryPickerFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(CreateRoomFragment::class) - fun bindCreateRoomFragment(fragment: CreateRoomFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomPreviewNoPreviewFragment::class) - fun bindRoomPreviewNoPreviewFragment(fragment: RoomPreviewNoPreviewFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(KeysBackupSettingsFragment::class) - fun bindKeysBackupSettingsFragment(fragment: KeysBackupSettingsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoadingFragment::class) - fun bindLoadingFragment(fragment: LoadingFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(HomeDrawerFragment::class) - fun bindHomeDrawerFragment(fragment: HomeDrawerFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(HomeDetailFragment::class) - fun bindHomeDetailFragment(fragment: HomeDetailFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(EmojiSearchResultFragment::class) - fun bindEmojiSearchResultFragment(fragment: EmojiSearchResultFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginFragment::class) - fun bindLoginFragment(fragment: LoginFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginCaptchaFragment::class) - fun bindLoginCaptchaFragment(fragment: LoginCaptchaFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginTermsFragment::class) - fun bindLoginTermsFragment(fragment: LoginTermsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginServerUrlFormFragment::class) - fun bindLoginServerUrlFormFragment(fragment: LoginServerUrlFormFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginResetPasswordMailConfirmationFragment::class) - fun bindLoginResetPasswordMailConfirmationFragment(fragment: LoginResetPasswordMailConfirmationFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginResetPasswordFragment::class) - fun bindLoginResetPasswordFragment(fragment: LoginResetPasswordFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginResetPasswordSuccessFragment::class) - fun bindLoginResetPasswordSuccessFragment(fragment: LoginResetPasswordSuccessFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginServerSelectionFragment::class) - fun bindLoginServerSelectionFragment(fragment: LoginServerSelectionFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginSignUpSignInSelectionFragment::class) - fun bindLoginSignUpSignInSelectionFragment(fragment: LoginSignUpSignInSelectionFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginSplashFragment::class) - fun bindLoginSplashFragment(fragment: LoginSplashFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginWebFragment::class) - fun bindLoginWebFragment(fragment: LoginWebFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginGenericTextInputFormFragment::class) - fun bindLoginGenericTextInputFormFragment(fragment: LoginGenericTextInputFormFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginWaitForEmailFragment::class) - fun bindLoginWaitForEmailFragment(fragment: LoginWaitForEmailFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginFragmentSigninUsername2::class) - fun bindLoginFragmentSigninUsername2(fragment: LoginFragmentSigninUsername2): Fragment - - @Binds - @IntoMap - @FragmentKey(AccountCreatedFragment::class) - fun bindAccountCreatedFragment(fragment: AccountCreatedFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginFragmentSignupUsername2::class) - fun bindLoginFragmentSignupUsername2(fragment: LoginFragmentSignupUsername2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginFragmentSigninPassword2::class) - fun bindLoginFragmentSigninPassword2(fragment: LoginFragmentSigninPassword2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginFragmentSignupPassword2::class) - fun bindLoginFragmentSignupPassword2(fragment: LoginFragmentSignupPassword2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginCaptchaFragment2::class) - fun bindLoginCaptchaFragment2(fragment: LoginCaptchaFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginFragmentToAny2::class) - fun bindLoginFragmentToAny2(fragment: LoginFragmentToAny2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginTermsFragment2::class) - fun bindLoginTermsFragment2(fragment: LoginTermsFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginServerUrlFormFragment2::class) - fun bindLoginServerUrlFormFragment2(fragment: LoginServerUrlFormFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginResetPasswordMailConfirmationFragment2::class) - fun bindLoginResetPasswordMailConfirmationFragment2(fragment: LoginResetPasswordMailConfirmationFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginResetPasswordFragment2::class) - fun bindLoginResetPasswordFragment2(fragment: LoginResetPasswordFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginResetPasswordSuccessFragment2::class) - fun bindLoginResetPasswordSuccessFragment2(fragment: LoginResetPasswordSuccessFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginServerSelectionFragment2::class) - fun bindLoginServerSelectionFragment2(fragment: LoginServerSelectionFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginSsoOnlyFragment2::class) - fun bindLoginSsoOnlyFragment2(fragment: LoginSsoOnlyFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginSplashSignUpSignInSelectionFragment2::class) - fun bindLoginSplashSignUpSignInSelectionFragment2(fragment: LoginSplashSignUpSignInSelectionFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginWebFragment2::class) - fun bindLoginWebFragment2(fragment: LoginWebFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginGenericTextInputFormFragment2::class) - fun bindLoginGenericTextInputFormFragment2(fragment: LoginGenericTextInputFormFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(LoginWaitForEmailFragment2::class) - fun bindLoginWaitForEmailFragment2(fragment: LoginWaitForEmailFragment2): Fragment - - @Binds - @IntoMap - @FragmentKey(UserListFragment::class) - fun bindUserListFragment(fragment: UserListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(PushGatewaysFragment::class) - fun bindPushGatewaysFragment(fragment: PushGatewaysFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsNotificationsTroubleshootFragment::class) - fun bindVectorSettingsNotificationsTroubleshootFragment(fragment: VectorSettingsNotificationsTroubleshootFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsAdvancedNotificationPreferenceFragment::class) - fun bindVectorSettingsAdvancedNotificationPreferenceFragment(fragment: VectorSettingsAdvancedNotificationPreferenceFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsNotificationPreferenceFragment::class) - fun bindVectorSettingsNotificationPreferenceFragment(fragment: VectorSettingsNotificationPreferenceFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsLabsFragment::class) - fun bindVectorSettingsLabsFragment(fragment: VectorSettingsLabsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(HomeserverSettingsFragment::class) - fun bindHomeserverSettingsFragment(fragment: HomeserverSettingsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsPinFragment::class) - fun bindVectorSettingsPinFragment(fragment: VectorSettingsPinFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsGeneralFragment::class) - fun bindVectorSettingsGeneralFragment(fragment: VectorSettingsGeneralFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(PushRulesFragment::class) - fun bindPushRulesFragment(fragment: PushRulesFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsPreferencesFragment::class) - fun bindVectorSettingsPreferencesFragment(fragment: VectorSettingsPreferencesFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsSecurityPrivacyFragment::class) - fun bindVectorSettingsSecurityPrivacyFragment(fragment: VectorSettingsSecurityPrivacyFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsHelpAboutFragment::class) - fun bindVectorSettingsHelpAboutFragment(fragment: VectorSettingsHelpAboutFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsIgnoredUsersFragment::class) - fun bindVectorSettingsIgnoredUsersFragment(fragment: VectorSettingsIgnoredUsersFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VectorSettingsDevicesFragment::class) - fun bindVectorSettingsDevicesFragment(fragment: VectorSettingsDevicesFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(ThreePidsSettingsFragment::class) - fun bindThreePidsSettingsFragment(fragment: ThreePidsSettingsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(PublicRoomsFragment::class) - fun bindPublicRoomsFragment(fragment: PublicRoomsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomProfileFragment::class) - fun bindRoomProfileFragment(fragment: RoomProfileFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomMemberListFragment::class) - fun bindRoomMemberListFragment(fragment: RoomMemberListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomUploadsFragment::class) - fun bindRoomUploadsFragment(fragment: RoomUploadsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomUploadsMediaFragment::class) - fun bindRoomUploadsMediaFragment(fragment: RoomUploadsMediaFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomUploadsFilesFragment::class) - fun bindRoomUploadsFilesFragment(fragment: RoomUploadsFilesFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomSettingsFragment::class) - fun bindRoomSettingsFragment(fragment: RoomSettingsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomAliasFragment::class) - fun bindRoomAliasFragment(fragment: RoomAliasFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomPermissionsFragment::class) - fun bindRoomPermissionsFragment(fragment: RoomPermissionsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomMemberProfileFragment::class) - fun bindRoomMemberProfileFragment(fragment: RoomMemberProfileFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BreadcrumbsFragment::class) - fun bindBreadcrumbsFragment(fragment: BreadcrumbsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(EmojiChooserFragment::class) - fun bindEmojiChooserFragment(fragment: EmojiChooserFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SoftLogoutFragment::class) - fun bindSoftLogoutFragment(fragment: SoftLogoutFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VerificationRequestFragment::class) - fun bindVerificationRequestFragment(fragment: VerificationRequestFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VerificationChooseMethodFragment::class) - fun bindVerificationChooseMethodFragment(fragment: VerificationChooseMethodFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VerificationEmojiCodeFragment::class) - fun bindVerificationEmojiCodeFragment(fragment: VerificationEmojiCodeFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VerificationQrScannedByOtherFragment::class) - fun bindVerificationQrScannedByOtherFragment(fragment: VerificationQrScannedByOtherFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VerificationQRWaitingFragment::class) - fun bindVerificationQRWaitingFragment(fragment: VerificationQRWaitingFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VerificationConclusionFragment::class) - fun bindVerificationConclusionFragment(fragment: VerificationConclusionFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VerificationCancelFragment::class) - fun bindVerificationCancelFragment(fragment: VerificationCancelFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(QuadSLoadingFragment::class) - fun bindQuadSLoadingFragment(fragment: QuadSLoadingFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(VerificationNotMeFragment::class) - fun bindVerificationNotMeFragment(fragment: VerificationNotMeFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(QrCodeScannerFragment::class) - fun bindQrCodeScannerFragment(fragment: QrCodeScannerFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(DeviceListFragment::class) - fun bindDeviceListFragment(fragment: DeviceListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(DeviceTrustInfoActionFragment::class) - fun bindDeviceTrustInfoActionFragment(fragment: DeviceTrustInfoActionFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(CrossSigningSettingsFragment::class) - fun bindCrossSigningSettingsFragment(fragment: CrossSigningSettingsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(AttachmentsPreviewFragment::class) - fun bindAttachmentsPreviewFragment(fragment: AttachmentsPreviewFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(IncomingShareFragment::class) - fun bindIncomingShareFragment(fragment: IncomingShareFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(AccountDataFragment::class) - fun bindAccountDataFragment(fragment: AccountDataFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(OutgoingKeyRequestListFragment::class) - fun bindOutgoingKeyRequestListFragment(fragment: OutgoingKeyRequestListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(IncomingKeyRequestListFragment::class) - fun bindIncomingKeyRequestListFragment(fragment: IncomingKeyRequestListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(KeyRequestsFragment::class) - fun bindKeyRequestsFragment(fragment: KeyRequestsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(GossipingEventsPaperTrailFragment::class) - fun bindGossipingEventsPaperTrailFragment(fragment: GossipingEventsPaperTrailFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapEnterPassphraseFragment::class) - fun bindBootstrapEnterPassphraseFragment(fragment: BootstrapEnterPassphraseFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapConfirmPassphraseFragment::class) - fun bindBootstrapConfirmPassphraseFragment(fragment: BootstrapConfirmPassphraseFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapWaitingFragment::class) - fun bindBootstrapWaitingFragment(fragment: BootstrapWaitingFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapSetupRecoveryKeyFragment::class) - fun bindBootstrapSetupRecoveryKeyFragment(fragment: BootstrapSetupRecoveryKeyFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapSaveRecoveryKeyFragment::class) - fun bindBootstrapSaveRecoveryKeyFragment(fragment: BootstrapSaveRecoveryKeyFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapConclusionFragment::class) - fun bindBootstrapConclusionFragment(fragment: BootstrapConclusionFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapReAuthFragment::class) - fun bindBootstrapReAuthFragment(fragment: BootstrapReAuthFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapMigrateBackupFragment::class) - fun bindBootstrapMigrateBackupFragment(fragment: BootstrapMigrateBackupFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(DeactivateAccountFragment::class) - fun bindDeactivateAccountFragment(fragment: DeactivateAccountFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SharedSecuredStoragePassphraseFragment::class) - fun bindSharedSecuredStoragePassphraseFragment(fragment: SharedSecuredStoragePassphraseFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SharedSecuredStorageKeyFragment::class) - fun bindSharedSecuredStorageKeyFragment(fragment: SharedSecuredStorageKeyFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SharedSecuredStorageResetAllFragment::class) - fun bindSharedSecuredStorageResetAllFragment(fragment: SharedSecuredStorageResetAllFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SetIdentityServerFragment::class) - fun bindSetIdentityServerFragment(fragment: SetIdentityServerFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(DiscoverySettingsFragment::class) - fun bindDiscoverySettingsFragment(fragment: DiscoverySettingsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(ReviewTermsFragment::class) - fun bindReviewTermsFragment(fragment: ReviewTermsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(WidgetFragment::class) - fun bindWidgetFragment(fragment: WidgetFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(ContactsBookFragment::class) - fun bindPhoneBookFragment(fragment: ContactsBookFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(PinFragment::class) - fun bindPinFragment(fragment: PinFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomBannedMemberListFragment::class) - fun bindRoomBannedMemberListFragment(fragment: RoomBannedMemberListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomNotificationSettingsFragment::class) - fun bindRoomNotificationSettingsFragment(fragment: RoomNotificationSettingsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SearchFragment::class) - fun bindSearchFragment(fragment: SearchFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(ShowUserCodeFragment::class) - fun bindShowUserCodeFragment(fragment: ShowUserCodeFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomDevToolFragment::class) - fun bindRoomDevToolFragment(fragment: RoomDevToolFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomDevToolStateEventListFragment::class) - fun bindRoomDevToolStateEventListFragment(fragment: RoomDevToolStateEventListFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomDevToolEditFragment::class) - fun bindRoomDevToolEditFragment(fragment: RoomDevToolEditFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomDevToolSendFormFragment::class) - fun bindRoomDevToolSendFormFragment(fragment: RoomDevToolSendFormFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SpacePreviewFragment::class) - fun bindSpacePreviewFragment(fragment: SpacePreviewFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(ChooseSpaceTypeFragment::class) - fun bindChooseSpaceTypeFragment(fragment: ChooseSpaceTypeFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(CreateSpaceDetailsFragment::class) - fun bindCreateSpaceDetailsFragment(fragment: CreateSpaceDetailsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(CreateSpaceDefaultRoomsFragment::class) - fun bindCreateSpaceDefaultRoomsFragment(fragment: CreateSpaceDefaultRoomsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(MatrixToUserFragment::class) - fun bindMatrixToUserFragment(fragment: MatrixToUserFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(MatrixToRoomSpaceFragment::class) - fun bindMatrixToRoomSpaceFragment(fragment: MatrixToRoomSpaceFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SpaceDirectoryFragment::class) - fun bindSpaceDirectoryFragment(fragment: SpaceDirectoryFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(ChoosePrivateSpaceTypeFragment::class) - fun bindChoosePrivateSpaceTypeFragment(fragment: ChoosePrivateSpaceTypeFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(CreateSpaceAdd3pidInvitesFragment::class) - fun bindCreateSpaceAdd3pidInvitesFragment(fragment: CreateSpaceAdd3pidInvitesFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SpaceAddRoomFragment::class) - fun bindSpaceAddRoomFragment(fragment: SpaceAddRoomFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SpacePeopleFragment::class) - fun bindSpacePeopleFragment(fragment: SpacePeopleFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SpaceSettingsFragment::class) - fun bindSpaceSettingsFragment(fragment: SpaceSettingsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SpaceManageRoomsFragment::class) - fun bindSpaceManageRoomsFragment(fragment: SpaceManageRoomsFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomJoinRuleFragment::class) - fun bindRoomJoinRuleFragment(fragment: RoomJoinRuleFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(RoomJoinRuleChooseRestrictedFragment::class) - fun bindRoomJoinRuleChooseRestrictedFragment(fragment: RoomJoinRuleChooseRestrictedFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(SpaceLeaveAdvancedFragment::class) - fun bindSpaceLeaveAdvancedFragment(fragment: SpaceLeaveAdvancedFragment): Fragment -} - -@Module -@InstallIn(ActivityComponent::class) -interface HiltViewModelModule { - - /** - * ViewModels with @IntoMap will be injected by this factory - */ - @Binds - @ActivityScoped - fun bindViewModelFactory(factory: VectorViewModelFactory): ViewModelProvider.Factory - - /** - * Below are bindings for the androidx view models (which extend ViewModel). Will be converted to MvRx ViewModel in the future. - */ - - @Binds - @IntoMap - @ViewModelKey(EmojiChooserViewModel::class) - fun bindEmojiChooserViewModel(viewModel: EmojiChooserViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(KeysBackupRestoreFromKeyViewModel::class) - fun bindKeysBackupRestoreFromKeyViewModel(viewModel: KeysBackupRestoreFromKeyViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(KeysBackupRestoreSharedViewModel::class) - fun bindKeysBackupRestoreSharedViewModel(viewModel: KeysBackupRestoreSharedViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(KeysBackupRestoreFromPassphraseViewModel::class) - fun bindKeysBackupRestoreFromPassphraseViewModel(viewModel: KeysBackupRestoreFromPassphraseViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(KeysBackupSetupSharedViewModel::class) - fun bindKeysBackupSetupSharedViewModel(viewModel: KeysBackupSetupSharedViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(ConfigurationViewModel::class) - fun bindConfigurationViewModel(viewModel: ConfigurationViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(SharedKnownCallsViewModel::class) - fun bindSharedActiveCallViewModel(viewModel: SharedKnownCallsViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(UserListSharedActionViewModel::class) - fun bindUserListSharedActionViewModel(viewModel: UserListSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(HomeSharedActionViewModel::class) - fun bindHomeSharedActionViewModel(viewModel: HomeSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(MessageSharedActionViewModel::class) - fun bindMessageSharedActionViewModel(viewModel: MessageSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(RoomListQuickActionsSharedActionViewModel::class) - fun bindRoomListQuickActionsSharedActionViewModel(viewModel: RoomListQuickActionsSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(RoomAliasBottomSheetSharedActionViewModel::class) - fun bindRoomAliasBottomSheetSharedActionViewModel(viewModel: RoomAliasBottomSheetSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(RoomHistoryVisibilitySharedActionViewModel::class) - fun bindRoomHistoryVisibilitySharedActionViewModel(viewModel: RoomHistoryVisibilitySharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(RoomJoinRuleSharedActionViewModel::class) - fun bindRoomJoinRuleSharedActionViewModel(viewModel: RoomJoinRuleSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(RoomDirectorySharedActionViewModel::class) - fun bindRoomDirectorySharedActionViewModel(viewModel: RoomDirectorySharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(RoomDetailSharedActionViewModel::class) - fun bindRoomDetailSharedActionViewModel(viewModel: RoomDetailSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(RoomProfileSharedActionViewModel::class) - fun bindRoomProfileSharedActionViewModel(viewModel: RoomProfileSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(DiscoverySharedViewModel::class) - fun bindDiscoverySharedViewModel(viewModel: DiscoverySharedViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(SpacePreviewSharedActionViewModel::class) - fun bindSpacePreviewSharedActionViewModel(viewModel: SpacePreviewSharedActionViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(SpacePeopleSharedActionViewModel::class) - fun bindSpacePeopleSharedActionViewModel(viewModel: SpacePeopleSharedActionViewModel): ViewModel -} - diff --git a/vector/src/main/java/im/vector/app/core/di/HomeModule.kt b/vector/src/main/java/im/vector/app/core/di/HomeModule.kt new file mode 100644 index 0000000000..7d63f2ffc8 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/di/HomeModule.kt @@ -0,0 +1,37 @@ +/* + * 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() + } + +} diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt deleted file mode 100644 index b936a1d944..0000000000 --- a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt +++ /dev/null @@ -1,140 +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.fragment.app.FragmentActivity -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.call.CallControlsBottomSheet -import im.vector.app.features.crypto.recover.BootstrapBottomSheet -import im.vector.app.features.crypto.verification.VerificationBottomSheet -import im.vector.app.features.home.HomeModule -import im.vector.app.features.home.room.detail.JoinReplacementRoomBottomSheet -import im.vector.app.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet -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.list.actions.RoomListQuickActionsBottomSheet -import im.vector.app.features.invite.AutoAcceptInvites -import im.vector.app.features.invite.VectorInviteView -import im.vector.app.features.matrixto.MatrixToBottomSheet -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.rageshake.RageShake -import im.vector.app.features.reactions.widget.ReactionButton -import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet -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.RoomJoinRuleBottomSheet -import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheet -import im.vector.app.features.spaces.InviteRoomSpaceChooserBottomSheet -import im.vector.app.features.spaces.LeaveSpaceBottomSheet -import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet -import im.vector.app.features.spaces.invite.SpaceInviteBottomSheet -import im.vector.app.features.spaces.share.ShareSpaceBottomSheet -import im.vector.app.features.ui.UiStateRepository -import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet -import im.vector.app.features.workers.signout.SignOutBottomSheetDialogFragment -import kotlinx.coroutines.CoroutineScope - -@Component( - dependencies = [ - SingletonEntryPoint::class - ], - modules = [ - ViewModelModule::class, - FragmentModule::class, - HomeModule::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 - - /* ========================================================================================== - * 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(deps: SingletonEntryPoint, - @BindsInstance context: FragmentActivity - ): ScreenComponent - } -} diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenModule.kt b/vector/src/main/java/im/vector/app/core/di/ScreenModule.kt index a7b5f2cd5c..2dab05378c 100644 --- a/vector/src/main/java/im/vector/app/core/di/ScreenModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/ScreenModule.kt @@ -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,11 +20,13 @@ import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.RecyclerView import dagger.Module import dagger.Provides -import dagger.hilt.migration.DisableInstallInCheck +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ActivityComponent +import dagger.hilt.android.scopes.ActivityScoped import im.vector.app.core.glide.GlideApp @Module -@DisableInstallInCheck +@InstallIn(ActivityComponent::class) object ScreenModule { @Provides @@ -33,6 +35,6 @@ object ScreenModule { @Provides @JvmStatic - @ScreenScope + @ActivityScoped fun providesSharedViewPool() = RecyclerView.RecycledViewPool() } diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenScope.kt b/vector/src/main/java/im/vector/app/core/di/ScreenScope.kt deleted file mode 100644 index c39d6a947e..0000000000 --- a/vector/src/main/java/im/vector/app/core/di/ScreenScope.kt +++ /dev/null @@ -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 diff --git a/vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt index 783c8432a3..4f8329c026 100644 --- a/vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt @@ -20,7 +20,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import dagger.Binds import dagger.Module -import dagger.hilt.migration.DisableInstallInCheck +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 @@ -43,7 +44,7 @@ import im.vector.app.features.spaces.SpacePreviewSharedActionViewModel import im.vector.app.features.spaces.people.SpacePeopleSharedActionViewModel import im.vector.app.features.userdirectory.UserListSharedActionViewModel -@DisableInstallInCheck +@InstallIn(ActivityComponent::class) @Module interface ViewModelModule { diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index ca0fef83d5..1b035676cc 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -45,12 +45,12 @@ 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.EntryPoints +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.ActivityEntryPoint import im.vector.app.core.di.SingletonEntryPoint -import im.vector.app.core.di.DaggerScreenComponent import im.vector.app.core.di.HasVectorInjector import im.vector.app.core.dialogs.DialogLocker import im.vector.app.core.dialogs.UnrecognizedCertificateDialog @@ -184,19 +184,19 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver @CallSuper override fun onCreate(savedInstanceState: Bundle?) { Timber.i("onCreate Activity ${javaClass.simpleName}") - val screenComponentDeps = singletonEntryPoint() - val screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, this) + 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 = screenComponentDeps.bugReporter() - pinLocker = screenComponentDeps.pinLocker() - navigator = screenComponentDeps.navigator() - activeSessionHolder = screenComponentDeps.activeSessionHolder() - vectorPreferences = screenComponentDeps.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 @@ -208,7 +208,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver navigator.openPinCode(this, pinStartForActivityResult, PinMode.AUTH) } } - sessionListener = screenComponentDeps.sessionListener() + sessionListener = singletonEntryPoint.sessionListener() sessionListener.globalErrorLiveData.observeEvent(this) { handleGlobalError(it) } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index 3b7485045e..711b2b144b 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -33,10 +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 dagger.hilt.EntryPoints -import im.vector.app.core.di.SingletonEntryPoint -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 @@ -49,8 +47,6 @@ import java.util.concurrent.TimeUnit */ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment(), MavericksView { - private lateinit var screenComponent: ScreenComponent - /* ========================================================================================== * View * ========================================================================================== */ @@ -124,17 +120,11 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe } override fun onAttach(context: Context) { - val screenComponentDeps = EntryPoints.get( - vectorBaseActivity.applicationContext, - SingletonEntryPoint::class.java) - screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, 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}") diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index e8f1b88f44..6c10fba3c1 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -35,12 +35,10 @@ 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.EntryPoints +import dagger.hilt.android.EntryPointAccessors import im.vector.app.R -import im.vector.app.core.di.SingletonEntryPoint -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 @@ -53,7 +51,7 @@ import io.reactivex.disposables.Disposable import timber.log.Timber import java.util.concurrent.TimeUnit -abstract class VectorBaseFragment : Fragment(), MavericksView, HasScreenInjector { +abstract class VectorBaseFragment : Fragment(), MavericksView { protected val vectorBaseActivity: VectorBaseActivity<*> by lazy { activity as VectorBaseActivity<*> @@ -63,8 +61,6 @@ abstract class VectorBaseFragment : 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 @@ -98,13 +94,13 @@ abstract class VectorBaseFragment : Fragment(), MavericksView, * ========================================================================================== */ override fun onAttach(context: Context) { - val screenComponentDeps = context.singletonEntryPoint() - screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, 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) } @@ -165,10 +161,6 @@ abstract class VectorBaseFragment : Fragment(), MavericksView, super.onDestroy() } - override fun injector(): ScreenComponent { - return screenComponent - } - /* ========================================================================================== * Restorable * ========================================================================================== */ diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index c16d653327..37b1fb1aad 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -27,7 +27,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt b/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt index c4f394e539..80a12fcd00 100644 --- a/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt +++ b/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt @@ -31,7 +31,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt index f9e2338077..b4f49db781 100644 --- a/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt @@ -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() { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetCallControlsBinding { return BottomSheetCallControlsBinding.inflate(inflater, container, false) diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index 990d1114ac..c4f2520685 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -43,7 +43,6 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt index 9784940374..b33eecee61 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt @@ -35,7 +35,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index a44a4f2e4f..87e40ac591 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -25,7 +25,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index 883b5fbe7b..fc6afc583c 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -30,7 +30,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt index 41f410a875..b6220b24b7 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt @@ -23,7 +23,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt index 341a195866..262768f9f2 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt @@ -26,7 +26,7 @@ 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.dialogs.ExportKeysDialog import im.vector.app.core.extensions.observeEvent import im.vector.app.core.extensions.queryExportKeys diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt index a09653c329..21d03fead0 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt @@ -30,7 +30,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt index a42c3d2dda..d3e086f973 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt @@ -33,8 +33,9 @@ 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 @@ -46,6 +47,7 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import javax.inject.Inject import kotlin.reflect.KClass +@AndroidEntryPoint class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() { @Parcelize @@ -60,10 +62,6 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() { @Parcelize @@ -83,10 +85,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() { @@ -43,10 +45,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 diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index 1241bf40e7..efaadb7170 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -29,7 +29,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt index 9f98d655cc..6c315a4e76 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt @@ -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(), 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) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt index a143712b3a..d8a4e01bc6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt @@ -23,7 +23,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt index d7e212d055..5e0db19d9e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt @@ -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,6 +32,7 @@ import javax.inject.Inject /** * Bottom sheet fragment that shows a message preview with list of contextual actions */ +@AndroidEntryPoint class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), MessageActionsEpoxyController.MessageActionsEpoxyControllerListener { @@ -44,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) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt index 0a5f4be7ca..63140edd8b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt @@ -22,8 +22,8 @@ import android.view.ViewGroup import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment @@ -35,6 +35,7 @@ import javax.inject.Inject /** * Bottom sheet displaying list of edits for a given event ordered by timestamp */ +@AndroidEntryPoint class ViewEditHistoryBottomSheet : VectorBaseBottomSheetDialogFragment() { @@ -42,10 +43,6 @@ class ViewEditHistoryBottomSheet : @Inject lateinit var epoxyController: ViewEditHistoryEpoxyController - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentDownloadStateTrackerBinder.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentDownloadStateTrackerBinder.kt index abaaaf2152..caf0131144 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentDownloadStateTrackerBinder.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentDownloadStateTrackerBinder.kt @@ -19,16 +19,16 @@ package im.vector.app.features.home.room.detail.timeline.helper import android.graphics.drawable.Drawable import androidx.vectordrawable.graphics.drawable.Animatable2Compat import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat +import dagger.hilt.android.scopes.ActivityScoped import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.di.ScreenScope import im.vector.app.core.error.ErrorFormatter import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.item.MessageFileItem import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker import javax.inject.Inject -@ScreenScope +@ActivityScoped class ContentDownloadStateTrackerBinder @Inject constructor(private val activeSessionHolder: ActiveSessionHolder, private val messageColorProvider: MessageColorProvider, private val errorFormatter: ErrorFormatter) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt index 75570a67a0..0909cbe8de 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt @@ -22,9 +22,9 @@ import android.view.ViewGroup import android.widget.ProgressBar import android.widget.TextView import androidx.core.view.isVisible +import dagger.hilt.android.scopes.ActivityScoped import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.di.ScreenScope import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.exhaustive import im.vector.app.core.utils.TextUtils @@ -33,7 +33,7 @@ import org.matrix.android.sdk.api.session.content.ContentUploadStateTracker import org.matrix.android.sdk.api.session.room.send.SendState import javax.inject.Inject -@ScreenScope +@ActivityScoped class ContentUploadStateTrackerBinder @Inject constructor(private val activeSessionHolder: ActiveSessionHolder, private val messageColorProvider: MessageColorProvider, private val errorFormatter: ErrorFormatter) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineMediaSizeProvider.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineMediaSizeProvider.kt index 52229151a0..9ec61e6054 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineMediaSizeProvider.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineMediaSizeProvider.kt @@ -17,11 +17,11 @@ package im.vector.app.features.home.room.detail.timeline.helper import androidx.recyclerview.widget.RecyclerView -import im.vector.app.core.di.ScreenScope +import dagger.hilt.android.scopes.ActivityScoped import javax.inject.Inject import kotlin.math.roundToInt -@ScreenScope +@ActivityScoped class TimelineMediaSizeProvider @Inject constructor() { var recyclerView: RecyclerView? = null diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt index 446d4161e3..2e8f6d9336 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt @@ -18,10 +18,10 @@ package im.vector.app.features.home.room.detail.timeline.helper import android.os.Handler import android.os.Looper -import im.vector.app.core.di.ScreenScope +import dagger.hilt.android.scopes.ActivityScoped import javax.inject.Inject -@ScreenScope +@ActivityScoped class VoiceMessagePlaybackTracker @Inject constructor() { private val mainHandler = Handler(Looper.getMainLooper()) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt index 356de36294..8071ed8809 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt @@ -23,8 +23,8 @@ import android.view.ViewGroup import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment @@ -38,6 +38,7 @@ import javax.inject.Inject /** * Bottom sheet displaying list of reactions for a given event ordered by timestamp */ +@AndroidEntryPoint class ViewReactionsBottomSheet : VectorBaseBottomSheetDialogFragment(), ViewReactionsEpoxyController.Listener { @@ -48,10 +49,6 @@ class ViewReactionsBottomSheet : @Inject lateinit var epoxyController: ViewReactionsEpoxyController - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt index bd4092097a..f7994319c2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt @@ -27,8 +27,9 @@ import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.core.di.ScreenComponent + import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment @@ -36,6 +37,7 @@ import im.vector.app.databinding.BottomSheetRoomUpgradeBinding import kotlinx.parcelize.Parcelize import javax.inject.Inject +@AndroidEntryPoint class MigrateRoomBottomSheet : VectorBaseBottomSheetDialogFragment(){ @@ -54,15 +56,10 @@ class MigrateRoomBottomSheet : override val showExpanded = true - @Inject - lateinit var errorFormatter: ErrorFormatter + @Inject lateinit var errorFormatter: ErrorFormatter val viewModel: MigrateRoomViewModel by fragmentViewModel() - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun invalidate() = withState(viewModel) { state -> views.headerText.setText(if (state.isPublic) R.string.upgrade_public_room else R.string.upgrade_private_room) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt index 42f613d60f..211a001fc3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt @@ -22,8 +22,9 @@ import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel 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.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment @@ -39,6 +40,7 @@ import javax.inject.Inject /** * Bottom sheet displaying active widgets in a room */ +@AndroidEntryPoint class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidgetsController.Listener { @@ -49,10 +51,6 @@ class RoomWidgetsBottomSheet : private val roomDetailViewModel: RoomDetailViewModel by parentFragmentViewModel() - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt index dc07526732..5e2b75acb1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt @@ -22,7 +22,7 @@ import android.os.Bundle import androidx.appcompat.widget.SearchView 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.VectorBaseActivity import im.vector.app.databinding.ActivityFilteredRoomsBinding diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index ac667fb5fe..014ce14c95 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -26,8 +26,8 @@ import com.airbnb.mvrx.args 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.error.ErrorFormatter import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith @@ -56,6 +56,7 @@ data class RoomListActionsArgs( /** * Bottom sheet fragment that shows room information with list of contextual actions */ +@AndroidEntryPoint class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener { @@ -71,10 +72,6 @@ class RoomListQuickActionsBottomSheet : override val showExpanded = true - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding { return BottomSheetGenericListBinding.inflate(inflater, container, false) } diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt index 7f31a02550..51c0b0762c 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt @@ -26,7 +26,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt b/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt index 29b45d45e0..d9f1ad343b 100644 --- a/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt +++ b/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt @@ -23,7 +23,6 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.updateLayoutParams import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.core.di.HasScreenInjector import im.vector.app.databinding.VectorInviteViewBinding import im.vector.app.features.home.AvatarRenderer import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt index cac6ab2aa5..ffee04df42 100644 --- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt @@ -23,7 +23,7 @@ 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.platform.VectorBaseActivity import im.vector.app.core.utils.toast diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index 8e3374afb4..5b91a5ed7c 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -33,7 +33,7 @@ import com.google.android.material.appbar.MaterialToolbar 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.POP_BACK_STACK_EXCLUSIVE import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt index 7cbe4ca4e0..2b2c7e69be 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt @@ -32,7 +32,7 @@ import com.google.android.material.appbar.MaterialToolbar 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.POP_BACK_STACK_EXCLUSIVE import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt index 64a08f2bf9..2cae10d01f 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt @@ -28,8 +28,9 @@ 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.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetMatrixToCardBinding @@ -39,6 +40,7 @@ import org.matrix.android.sdk.api.session.permalinks.PermalinkData import javax.inject.Inject import kotlin.reflect.KClass +@AndroidEntryPoint class MatrixToBottomSheet : VectorBaseBottomSheetDialogFragment() { @@ -49,10 +51,6 @@ class MatrixToBottomSheet : @Inject lateinit var avatarRenderer: AvatarRenderer - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - var interactionListener: InteractionListener? = null override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetMatrixToCardBinding { diff --git a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt index 5004cdc99c..2d897fcc51 100644 --- a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt @@ -22,7 +22,7 @@ import android.os.Bundle import androidx.core.net.toUri import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.di.ActiveSessionHolder -import im.vector.app.core.di.ScreenComponent + import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityBigImageViewerBinding import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt index 979b429932..f6cabf1932 100644 --- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt @@ -25,7 +25,7 @@ import com.google.zxing.Result import com.google.zxing.ResultMetadataType 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.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt index f14b067f3e..dbf9ceded8 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt @@ -27,7 +27,7 @@ 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.platform.VectorBaseActivity import im.vector.app.databinding.ActivityBugReportBinding import org.matrix.android.sdk.api.extensions.tryOrNull diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt index d5f7bb9f7c..d5b27213e1 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt @@ -32,7 +32,7 @@ import com.jakewharton.rxbinding3.widget.queryTextChanges import dagger.hilt.android.AndroidEntryPoint import im.vector.app.EmojiCompatFontProvider import im.vector.app.R -import im.vector.app.core.di.ScreenComponent + import im.vector.app.core.extensions.observeEvent import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityEmojiReactionPickerBinding diff --git a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt index 5e4b2b7ef1..2b4e9ee5ab 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/widget/ReactionButton.kt @@ -26,7 +26,6 @@ import androidx.core.content.withStyledAttributes import dagger.hilt.android.AndroidEntryPoint import im.vector.app.EmojiCompatWrapper import im.vector.app.R -import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.TextUtils import im.vector.app.databinding.ReactionButtonBinding diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt index 2a97b04fe0..03b10ef983 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt @@ -23,7 +23,7 @@ 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.extensions.addFragmentToBackstack import im.vector.app.core.extensions.popBackstack diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt index 31fa3192e7..c55225ae80 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt @@ -22,7 +22,7 @@ import android.os.Bundle 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.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt index 9418e1c504..c07dfd5a3b 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt @@ -25,7 +25,7 @@ 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.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt index 05ccc57b10..d156521690 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt @@ -27,8 +27,9 @@ import androidx.fragment.app.Fragment import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R -import im.vector.app.core.di.ScreenComponent + import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment @@ -38,6 +39,7 @@ import kotlinx.parcelize.Parcelize import javax.inject.Inject import kotlin.reflect.KClass +@AndroidEntryPoint class DeviceListBottomSheet : VectorBaseBottomSheetDialogFragment() { @@ -49,10 +51,6 @@ class DeviceListBottomSheet : @Inject lateinit var viewModelFactory: DeviceListBottomSheetViewModel.Factory - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.observeViewEvents { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index 3872fc0393..d19c953d8e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -25,7 +25,7 @@ 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.addFragment import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.exhaustive diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt index 4a61a80422..9b1521e2f4 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt @@ -24,7 +24,8 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView 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 @@ -44,6 +45,7 @@ data class RoomAliasBottomSheetArgs( /** * Bottom sheet fragment that shows room alias information with list of contextual actions */ +@AndroidEntryPoint class RoomAliasBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomAliasBottomSheetController.Listener { @@ -56,10 +58,6 @@ class RoomAliasBottomSheet : override val showExpanded = true - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding { return BottomSheetGenericListBinding.inflate(inflater, container, false) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt index 4089139b78..c5c375ba70 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt @@ -21,7 +21,8 @@ import android.os.Parcelable import android.view.View 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.ui.bottomsheet.BottomSheetGeneric import im.vector.app.core.ui.bottomsheet.BottomSheetGenericController import kotlinx.parcelize.Parcelize @@ -33,16 +34,13 @@ data class RoomHistoryVisibilityBottomSheetArgs( val currentRoomHistoryVisibility: RoomHistoryVisibility ) : Parcelable +@AndroidEntryPoint class RoomHistoryVisibilityBottomSheet : BottomSheetGeneric() { private lateinit var roomHistoryVisibilitySharedActionViewModel: RoomHistoryVisibilitySharedActionViewModel @Inject lateinit var controller: RoomHistoryVisibilityController private val viewModel: RoomHistoryVisibilityViewModel by fragmentViewModel(RoomHistoryVisibilityViewModel::class) - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getController(): BottomSheetGenericController = controller override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt index 2e4608311e..beabd2b878 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt @@ -29,7 +29,7 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.commitTransaction diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt index f0f8193cc5..9684f1fe30 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt @@ -21,7 +21,8 @@ import android.os.Parcelable import android.view.View 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.ui.bottomsheet.BottomSheetGeneric import im.vector.app.core.ui.bottomsheet.BottomSheetGenericController import kotlinx.parcelize.Parcelize @@ -44,16 +45,13 @@ data class RoomJoinRuleBottomSheetArgs( val parentSpaceName: String? ) : Parcelable +@AndroidEntryPoint class RoomJoinRuleBottomSheet : BottomSheetGeneric() { private lateinit var roomJoinRuleSharedActionViewModel: RoomJoinRuleSharedActionViewModel @Inject lateinit var controller: RoomJoinRuleController private val viewModel: RoomJoinRuleViewModel by fragmentViewModel(RoomJoinRuleViewModel::class) - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun getController(): BottomSheetGenericController = controller override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt index 3d1ebf224d..d9db00b50f 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt @@ -27,7 +27,7 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat 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.VectorBaseActivity import im.vector.app.databinding.ActivityVectorSettingsBinding diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index 8cf82c70a9..bffabf2e93 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -22,13 +22,9 @@ import android.view.View import androidx.annotation.CallSuper import androidx.preference.PreferenceFragmentCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.EntryPoints import im.vector.app.R -import im.vector.app.core.di.SingletonEntryPoint -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.error.ErrorFormatter +import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast import io.reactivex.disposables.CompositeDisposable @@ -36,7 +32,7 @@ import io.reactivex.disposables.Disposable import org.matrix.android.sdk.api.session.Session import timber.log.Timber -abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScreenInjector { +abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat() { val vectorActivity: VectorBaseActivity<*> by lazy { activity as VectorBaseActivity<*> @@ -47,7 +43,6 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScree // members protected lateinit var session: Session protected lateinit var errorFormatter: ErrorFormatter - private lateinit var screenComponent: ScreenComponent abstract val preferenceXmlRes: Int @@ -58,20 +53,10 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScree } override fun onAttach(context: Context) { - val screenComponentDeps = EntryPoints.get( - vectorActivity.applicationContext, - SingletonEntryPoint::class.java) - screenComponent = DaggerScreenComponent.factory().create(screenComponentDeps, vectorActivity) + val singletonEntryPoint = context.singletonEntryPoint() super.onAttach(context) - session = screenComponent.activeSessionHolder().getActiveSession() - errorFormatter = screenComponent.errorFormatter() - injectWith(injector()) - } - - protected open fun injectWith(injector: ScreenComponent) = Unit - - override fun injector(): ScreenComponent { - return screenComponent + session = singletonEntryPoint.activeSessionHolder().getActiveSession() + errorFormatter = singletonEntryPoint.errorFormatter() } override fun onResume() { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt index 7ba6042027..66a9ca4943 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt @@ -25,7 +25,8 @@ import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.parentFragmentViewModel 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 @@ -39,6 +40,7 @@ data class DeviceVerificationInfoArgs( val deviceId: String ) : Parcelable +@AndroidEntryPoint class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(), DeviceVerificationInfoBottomSheetController.Callback { @@ -48,11 +50,6 @@ class DeviceVerificationInfoBottomSheet : private val sharedViewModel: DevicesViewModel by parentFragmentViewModel(DevicesViewModel::class) @Inject lateinit var deviceVerificationInfoViewModelFactory: DeviceVerificationInfoBottomSheetViewModel.Factory - - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - @Inject lateinit var controller: DeviceVerificationInfoBottomSheetController override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt index 1948b7fbca..651526faa2 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt @@ -25,7 +25,7 @@ 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.replaceFragment import im.vector.app.features.MainActivity diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt index c19821c9ad..e16162222a 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt @@ -25,7 +25,7 @@ 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.replaceFragment import im.vector.app.features.MainActivity diff --git a/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt index cf7871bc99..3b2bd3d0a1 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt @@ -23,14 +23,16 @@ import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible import com.airbnb.mvrx.args +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.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetSpaceInviteChooserBinding import kotlinx.parcelize.Parcelize import javax.inject.Inject +@AndroidEntryPoint class InviteRoomSpaceChooserBottomSheet : VectorBaseBottomSheetDialogFragment() { @Parcelize @@ -53,10 +55,6 @@ class InviteRoomSpaceChooserBottomSheet : VectorBaseBottomSheetDialogFragment() { val settingsViewModel: SpaceMenuViewModel by parentFragmentViewModel() @@ -60,10 +62,6 @@ class LeaveSpaceBottomSheet : VectorBaseBottomSheetDialogFragment(){ @Inject lateinit var navigator: Navigator @@ -64,10 +66,6 @@ class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment() { interface InteractionListener { @@ -57,18 +59,11 @@ class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment(){ @Parcelize @@ -47,10 +49,6 @@ class ShareSpaceBottomSheet : VectorBaseBottomSheetDialogFragment() { @@ -49,10 +51,6 @@ class RoomWidgetPermissionBottomSheet : override val showExpanded = true - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - // Use this if you don't need the full activity view model var directListener: ((Boolean) -> Unit)? = null diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt index 68502bceaf..f6e30b8693 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt @@ -31,8 +31,9 @@ import com.airbnb.mvrx.withState import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog 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.dialogs.ExportKeysDialog import im.vector.app.core.extensions.queryExportKeys import im.vector.app.core.extensions.registerStartForActivityResult @@ -45,6 +46,7 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import javax.inject.Inject // TODO this needs to be refactored to current standard and remove legacy +@AndroidEntryPoint class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(){ @@ -60,10 +62,6 @@ class SignOutBottomSheetDialogFragment : private val viewModel: SignoutCheckViewModel by fragmentViewModel(SignoutCheckViewModel::class) - override fun injectWith(injector: ScreenComponent) { - injector.inject(this) - } - override fun onResume() { super.onResume() viewModel.refreshRemoteStateIfNeeded() From d724504662aac3a6320e27d9efa5bbbff70721c4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 21 Oct 2021 20:17:49 +0200 Subject: [PATCH 013/413] Hilt: finish migration of latest view models --- .../app/core/di/MavericksViewModelModule.kt | 31 ++++++++ .../crypto/recover/BootstrapBottomSheet.kt | 3 - .../recover/BootstrapSharedViewModel.kt | 31 +++----- .../crypto/recover/BootstrapViewState.kt | 7 +- .../verification/VerificationBottomSheet.kt | 3 - .../VerificationBottomSheetViewModel.kt | 75 +++++++++---------- .../vector/app/features/home/HomeActivity.kt | 1 - .../features/home/HomeActivityViewModel.kt | 20 ++--- .../home/room/detail/RoomDetailViewModel.kt | 6 +- .../devices/DeviceListBottomSheet.kt | 4 - .../devices/DeviceListBottomSheetViewModel.kt | 62 +++++++-------- .../DeviceVerificationInfoBottomSheet.kt | 1 - ...iceVerificationInfoBottomSheetViewModel.kt | 26 ++----- ...iceVerificationInfoBottomSheetViewState.kt | 6 +- 14 files changed, 133 insertions(+), 143 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index c98acee64c..17c29eb706 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -28,11 +28,14 @@ import im.vector.app.features.contactsbook.ContactsBookViewModel import im.vector.app.features.createdirect.CreateDirectRoomViewModel import im.vector.app.features.crypto.keysbackup.settings.KeysBackupSettingsViewModel import im.vector.app.features.crypto.quads.SharedSecureStorageViewModel +import im.vector.app.features.crypto.recover.BootstrapSharedViewModel +import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel import im.vector.app.features.crypto.verification.choose.VerificationChooseMethodViewModel import im.vector.app.features.crypto.verification.emoji.VerificationEmojiCodeViewModel import im.vector.app.features.devtools.RoomDevToolViewModel import im.vector.app.features.discovery.DiscoverySettingsViewModel import im.vector.app.features.discovery.change.SetIdentityServerViewModel +import im.vector.app.features.home.HomeActivityViewModel import im.vector.app.features.home.HomeDetailViewModel import im.vector.app.features.home.PromoteRestrictedViewModel import im.vector.app.features.home.UnknownDeviceDetectorSharedViewModel @@ -60,6 +63,7 @@ import im.vector.app.features.roomdirectory.createroom.CreateRoomViewModel import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerViewModel import im.vector.app.features.roomdirectory.roompreview.RoomPreviewViewModel import im.vector.app.features.roommemberprofile.RoomMemberProfileViewModel +import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheetViewModel import im.vector.app.features.roomprofile.RoomProfileViewModel import im.vector.app.features.roomprofile.alias.RoomAliasViewModel import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetViewModel @@ -72,6 +76,7 @@ import im.vector.app.features.roomprofile.settings.joinrule.advanced.RoomJoinRul import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel import im.vector.app.features.settings.account.deactivation.DeactivateAccountViewModel import im.vector.app.features.settings.crosssigning.CrossSigningSettingsViewModel +import im.vector.app.features.settings.devices.DeviceVerificationInfoBottomSheetViewModel import im.vector.app.features.settings.devices.DevicesViewModel import im.vector.app.features.settings.devtools.AccountDataViewModel import im.vector.app.features.settings.devtools.GossipingEventsPaperTrailViewModel @@ -512,4 +517,30 @@ interface MavericksViewModelModule { @MavericksViewModelKey(HomeDetailViewModel::class) fun homeDetailViewModelFactory(factory: HomeDetailViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + @Binds + @IntoMap + @MavericksViewModelKey(DeviceVerificationInfoBottomSheetViewModel::class) + fun deviceVerificationInfoBottomSheetViewModelFactory(factory: DeviceVerificationInfoBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(DeviceListBottomSheetViewModel::class) + fun deviceListBottomSheetViewModelFactory(factory: DeviceListBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(HomeActivityViewModel::class) + fun homeActivityViewModelFactory(factory: HomeActivityViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(BootstrapSharedViewModel::class) + fun bootstrapSharedViewModelFactory(factory: BootstrapSharedViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(VerificationBottomSheetViewModel::class) + fun verificationBottomSheetViewModelFactory(factory: VerificationBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt index d3e086f973..264f51f379 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt @@ -57,9 +57,6 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment(initialState) { private var doesKeyBackupExist: Boolean = false @@ -73,10 +72,12 @@ class BootstrapSharedViewModel @AssistedInject constructor( private val zxcvbn = Zxcvbn() @AssistedFactory - interface Factory { - fun create(initialState: BootstrapViewState, args: BootstrapBottomSheet.Args): BootstrapSharedViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: BootstrapViewState): BootstrapSharedViewModel } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + // private var _pendingSession: String? = null var uiaContinuation: Continuation? = null @@ -84,7 +85,7 @@ class BootstrapSharedViewModel @AssistedInject constructor( init { - when (args.setUpMode) { + when (initialState.setupMode) { SetupMode.PASSPHRASE_RESET, SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET, SetupMode.HARD_RESET -> { @@ -410,7 +411,7 @@ class BootstrapSharedViewModel @AssistedInject constructor( progressListener = progressListener, passphrase = state.passphrase, keySpec = state.migrationRecoveryKey?.let { extractCurveKeyFromRecoveryKey(it)?.let { RawBytesKeySpec(it) } }, - setupMode = args.setUpMode + setupMode = state.setupMode ) ) { bootstrapResult -> when (bootstrapResult) { @@ -516,7 +517,7 @@ class BootstrapSharedViewModel @AssistedInject constructor( BootstrapStep.CheckingMigration -> Unit is BootstrapStep.FirstForm -> { _viewEvents.post( - when (args.setUpMode) { + when (state.setupMode) { SetupMode.CROSS_SIGNING_ONLY, SetupMode.NORMAL -> BootstrapViewEvents.SkipBootstrap() else -> BootstrapViewEvents.Dismiss(success = false) @@ -547,18 +548,4 @@ class BootstrapSharedViewModel @AssistedInject constructor( else -> stringProvider.getString(R.string.unexpected_error) } } - - // ====================================== - // Companion, view model assisted creation - // ====================================== - - companion object : MavericksViewModelFactory { - - override fun create(viewModelContext: ViewModelContext, state: BootstrapViewState): BootstrapSharedViewModel? { - val fragment: BootstrapBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - val args: BootstrapBottomSheet.Args = fragment.arguments?.getParcelable(BootstrapBottomSheet.EXTRA_ARGS) - ?: BootstrapBottomSheet.Args(SetupMode.CROSS_SIGNING_ONLY) - return fragment.bootstrapViewModelFactory.create(state, args) - } - } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt index b8c9f10b49..380a2b5fb4 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt @@ -24,6 +24,7 @@ import im.vector.app.core.platform.WaitingViewData import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo data class BootstrapViewState( + val setupMode: SetupMode, val step: BootstrapStep = BootstrapStep.CheckingMigration, val passphrase: String? = null, val migrationRecoveryKey: String? = null, @@ -34,4 +35,8 @@ data class BootstrapViewState( val recoveryKeyCreationInfo: SsssKeyCreationInfo? = null, val initializationWaitingViewData: WaitingViewData? = null, val recoverySaveFileProcess: Async = Uninitialized -) : MavericksState +) : MavericksState { + + constructor(args: BootstrapBottomSheet.Args): this(setupMode = args.setUpMode) + +} diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt index fa86c76691..5a4a985e2d 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt @@ -77,9 +77,6 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment = 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(initialState), + VectorViewModel(initialState), VerificationService.Listener { + @AssistedFactory + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: VerificationBottomSheetViewState): VerificationBottomSheetViewModel + } + + companion object : MavericksViewModelFactory 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 { - - override fun create(viewModelContext: ViewModelContext, state: VerificationBottomSheetViewState): VerificationBottomSheetViewModel? { - val fragment: VerificationBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - val args: VerificationBottomSheet.VerificationArgs = viewModelContext.args() - - return fragment.verificationViewModelFactory.create(state, args) - } - } - override fun handle(action: VerificationAction) = withState { state -> val otherUserId = state.otherUserMxItem?.id ?: return@withState val roomId = state.roomId @@ -542,7 +537,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( state.pendingRequest.invoke()?.transactionId == pr.transactionId) { setState { copy( - transactionId = args.verificationId ?: pr.transactionId, + transactionId = state.verificationId ?: pr.transactionId, pendingRequest = Success(pr) ) } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index e4b759284c..6e4b26cb9d 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -103,7 +103,6 @@ class HomeActivity : private lateinit var sharedActionViewModel: HomeSharedActionViewModel private val homeActivityViewModel: HomeActivityViewModel by viewModel() - @Inject lateinit var viewModelFactory: HomeActivityViewModel.Factory private val serverBackupStatusViewModel: ServerBackupStatusViewModel by viewModel() private val promoteRestrictedViewModel: PromoteRestrictedViewModel by viewModel() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 627ff4be12..59b9cafd6e 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -17,14 +17,13 @@ package im.vector.app.features.home import androidx.lifecycle.asFlow -import androidx.lifecycle.viewModelScope -import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.login.ReAuthHelper @@ -58,26 +57,17 @@ import kotlin.coroutines.resumeWithException class HomeActivityViewModel @AssistedInject constructor( @Assisted initialState: HomeActivityViewState, - @Assisted private val args: HomeActivityArgs, private val activeSessionHolder: ActiveSessionHolder, private val reAuthHelper: ReAuthHelper, private val vectorPreferences: VectorPreferences ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: HomeActivityViewState, args: HomeActivityArgs): HomeActivityViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: HomeActivityViewState): HomeActivityViewModel } - companion object : MavericksViewModelFactory { - - @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 by hiltMavericksViewModelFactory() private var checkBootstrap = false private var onceTrusted = false diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index 0c0e5ee6cd..3873a2eb77 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -147,14 +147,16 @@ class RoomDetailViewModel @AssistedInject constructor( fun create(initialState: RoomDetailViewState): RoomDetailViewModel } + /** + * Can't use the hiltMaverick here because some dependencies are injected here and in fragment but they don't share the graph. + */ companion object : MavericksViewModelFactory { const val PAGINATION_COUNT = 50 @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? { + override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel { val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment() - return fragment.roomDetailViewModelFactory.create(state) } } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt index d156521690..f83ac8f19d 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt @@ -29,14 +29,12 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetWithFragmentsBinding import im.vector.app.features.crypto.verification.VerificationBottomSheet import kotlinx.parcelize.Parcelize -import javax.inject.Inject import kotlin.reflect.KClass @AndroidEntryPoint @@ -49,8 +47,6 @@ class DeviceListBottomSheet : private val viewModel: DeviceListBottomSheetViewModel by fragmentViewModel(DeviceListBottomSheetViewModel::class) - @Inject lateinit var viewModelFactory: DeviceListBottomSheetViewModel.Factory - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.observeViewEvents { diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt index 03b20bce40..d2491237ca 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt @@ -17,7 +17,6 @@ package im.vector.app.features.roommemberprofile.devices import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory @@ -26,7 +25,9 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import dagger.hilt.EntryPoints +import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.SingletonEntryPoint +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorViewModel import org.matrix.android.sdk.api.session.Session @@ -38,6 +39,8 @@ import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo data class DeviceListViewState( + val userId: String, + val allowDeviceAction: Boolean, val userItem: MatrixItem? = null, val isMine: Boolean = false, val memberCrossSigningKey: MXCrossSigningInfo? = null, @@ -46,24 +49,41 @@ data class DeviceListViewState( ) : MavericksState class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted private val initialState: DeviceListViewState, - @Assisted private val args: DeviceListBottomSheet.Args, private val session: Session) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: DeviceListViewState, args: DeviceListBottomSheet.Args): DeviceListBottomSheetViewModel + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: DeviceListViewState): DeviceListBottomSheetViewModel + } + + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { + + override fun initialState(viewModelContext: ViewModelContext): DeviceListViewState? { + val args = viewModelContext.args() + val userId = args.userId + val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() + return session.getUser(userId)?.toMatrixItem()?.let { + DeviceListViewState( + userId = userId, + allowDeviceAction = args.allowDeviceAction, + userItem = it, + isMine = userId == session.myUserId + ) + } ?: return super.initialState(viewModelContext) + } } init { - session.flow().liveUserCryptoDevices(args.userId) + + session.flow().liveUserCryptoDevices(initialState.userId) .execute { copy(cryptoDevices = it).also { refreshSelectedId() } } - session.flow().liveCrossSigningInfo(args.userId) + session.flow().liveCrossSigningInfo(initialState.userId) .execute { copy(memberCrossSigningKey = it.invoke()?.getOrNull()) } @@ -90,7 +110,7 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva } private fun selectDevice(action: DeviceListAction.SelectDevice) { - if (!args.allowDeviceAction) return + if (!initialState.allowDeviceAction) return setState { copy(selectedDevice = action.device) } @@ -103,29 +123,9 @@ class DeviceListBottomSheetViewModel @AssistedInject constructor(@Assisted priva } private fun manuallyVerify(action: DeviceListAction.ManuallyVerify) { - if (!args.allowDeviceAction) return - session.cryptoService().verificationService().beginKeyVerification(VerificationMethod.SAS, args.userId, action.deviceId, null)?.let { txID -> - _viewEvents.post(DeviceListBottomSheetViewEvents.Verify(args.userId, txID)) - } - } - - companion object : MavericksViewModelFactory { - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: DeviceListViewState): DeviceListBottomSheetViewModel? { - val fragment: DeviceListBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - val args = viewModelContext.args() - return fragment.viewModelFactory.create(state, args) - } - - override fun initialState(viewModelContext: ViewModelContext): DeviceListViewState? { - val userId = viewModelContext.args().userId - val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() - return session.getUser(userId)?.toMatrixItem()?.let { - DeviceListViewState( - userItem = it, - isMine = userId == session.myUserId - ) - } ?: return super.initialState(viewModelContext) + if (!initialState.allowDeviceAction) return + session.cryptoService().verificationService().beginKeyVerification(VerificationMethod.SAS, initialState.userId, action.deviceId, null)?.let { txID -> + _viewEvents.post(DeviceListBottomSheetViewEvents.Verify(initialState.userId, txID)) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt index 66a9ca4943..31a6bbd295 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt @@ -49,7 +49,6 @@ class DeviceVerificationInfoBottomSheet : private val sharedViewModel: DevicesViewModel by parentFragmentViewModel(DevicesViewModel::class) - @Inject lateinit var deviceVerificationInfoViewModelFactory: DeviceVerificationInfoBottomSheetViewModel.Factory @Inject lateinit var controller: DeviceVerificationInfoBottomSheetController override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index e6cde74440..cb70ed4041 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -15,13 +15,13 @@ */ package im.vector.app.features.settings.devices -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyAction import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel @@ -31,15 +31,16 @@ import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: DeviceVerificationInfoBottomSheetViewState, - @Assisted val deviceId: String, val session: Session ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory { - fun create(initialState: DeviceVerificationInfoBottomSheetViewState, deviceId: String): DeviceVerificationInfoBottomSheetViewModel + interface Factory: MavericksAssistedViewModelFactory { + override fun create(initialState: DeviceVerificationInfoBottomSheetViewState): DeviceVerificationInfoBottomSheetViewModel } + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + init { setState { @@ -59,7 +60,7 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As session.flow().liveUserCryptoDevices(session.myUserId) .map { list -> - list.firstOrNull { it.deviceId == deviceId } + list.firstOrNull { it.deviceId == initialState.deviceId } } .execute { copy( @@ -82,24 +83,13 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As session.flow().liveMyDevicesInfo() .map { devices -> - devices.firstOrNull { it.deviceId == deviceId } ?: DeviceInfo(deviceId = deviceId) + devices.firstOrNull { it.deviceId == initialState.deviceId } ?: DeviceInfo(deviceId = initialState.deviceId) } .execute { copy(deviceInfo = it) } } - companion object : MavericksViewModelFactory { - - @JvmStatic - override fun create(viewModelContext: ViewModelContext, state: DeviceVerificationInfoBottomSheetViewState): - DeviceVerificationInfoBottomSheetViewModel? { - val fragment: DeviceVerificationInfoBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() - val args = viewModelContext.args() - return fragment.deviceVerificationInfoViewModelFactory.create(state, args.deviceId) - } - } - override fun handle(action: EmptyAction) { } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt index e320642ed0..32927ca068 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt @@ -23,6 +23,7 @@ import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo data class DeviceVerificationInfoBottomSheetViewState( + val deviceId: String, val cryptoDeviceInfo: Async = Uninitialized, val deviceInfo: Async = Uninitialized, val hasAccountCrossSigning: Boolean = false, @@ -32,6 +33,7 @@ data class DeviceVerificationInfoBottomSheetViewState( val isRecoverySetup: Boolean = false ) : MavericksState { - val canVerifySession: Boolean - get() = hasOtherSessions || isRecoverySetup + constructor(args: DeviceVerificationInfoArgs) : this(deviceId = args.deviceId) + + val canVerifySession = hasOtherSessions || isRecoverySetup } From b6501ce7b2d032d8039bb4ae0a98728b7739ec57 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Oct 2021 11:30:09 +0200 Subject: [PATCH 014/413] Hilt: continue cleaning up --- .../vector/app/core/di/HasVectorInjector.kt | 22 ---- .../im/vector/app/core/di/ImageManager.kt | 1 + .../vector/app/core/di/SingletonEntryPoint.kt | 111 ------------------ .../app/core/platform/VectorBaseActivity.kt | 6 - .../call/service/CallHeadsUpActionReceiver.kt | 8 +- .../VectorSettingsSecurityPrivacyFragment.kt | 5 +- 6 files changed, 6 insertions(+), 147 deletions(-) delete mode 100644 vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt diff --git a/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt b/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt deleted file mode 100644 index ae76919c45..0000000000 --- a/vector/src/main/java/im/vector/app/core/di/HasVectorInjector.kt +++ /dev/null @@ -1,22 +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 - -interface HasVectorInjector { - - fun injector(): SingletonEntryPoint -} diff --git a/vector/src/main/java/im/vector/app/core/di/ImageManager.kt b/vector/src/main/java/im/vector/app/core/di/ImageManager.kt index 60ce70a0b3..154db33fe9 100644 --- a/vector/src/main/java/im/vector/app/core/di/ImageManager.kt +++ b/vector/src/main/java/im/vector/app/core/di/ImageManager.kt @@ -21,6 +21,7 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.model.GlideUrl import com.github.piasy.biv.BigImageViewer import com.github.piasy.biv.loader.glide.GlideImageLoader +import dagger.hilt.android.qualifiers.ApplicationContext import im.vector.app.ActiveSessionDataSource import im.vector.app.core.glide.FactoryUrl import org.matrix.android.sdk.api.session.Session diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonEntryPoint.kt b/vector/src/main/java/im/vector/app/core/di/SingletonEntryPoint.kt index 4b89e31bc5..52316751e6 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonEntryPoint.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonEntryPoint.kt @@ -16,157 +16,46 @@ package im.vector.app.core.di -import android.content.Context -import android.content.res.Resources import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import im.vector.app.ActiveSessionDataSource -import im.vector.app.AppStateHandler -import im.vector.app.EmojiCompatFontProvider -import im.vector.app.EmojiCompatWrapper 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.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 @InstallIn(SingletonComponent::class) @EntryPoint interface SingletonEntryPoint { - 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 } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 1b035676cc..4d06dbe6a2 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -50,8 +50,6 @@ import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ActivityEntryPoint -import im.vector.app.core.di.SingletonEntryPoint -import im.vector.app.core.di.HasVectorInjector import im.vector.app.core.dialogs.DialogLocker import im.vector.app.core.dialogs.UnrecognizedCertificateDialog import im.vector.app.core.extensions.exhaustive @@ -404,10 +402,6 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver * PRIVATE METHODS * ========================================================================================== */ - internal fun getVectorComponent(): SingletonEntryPoint { - return (application as HasVectorInjector).injector() - } - /** * Force to render the activity in fullscreen */ diff --git a/vector/src/main/java/im/vector/app/features/call/service/CallHeadsUpActionReceiver.kt b/vector/src/main/java/im/vector/app/features/call/service/CallHeadsUpActionReceiver.kt index 5a1d8cd396..161aa33d1d 100644 --- a/vector/src/main/java/im/vector/app/features/call/service/CallHeadsUpActionReceiver.kt +++ b/vector/src/main/java/im/vector/app/features/call/service/CallHeadsUpActionReceiver.kt @@ -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 diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 7e60e69379..b622d8aab4 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -67,6 +67,7 @@ import kotlinx.coroutines.launch import me.gujun.android.span.span import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.extensions.getFingerprintHumanReadable +import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse @@ -79,6 +80,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( private val pinCodeStore: PinCodeStore, private val keysExporter: KeysExporter, private val keysImporter: KeysImporter, + private val rawService: RawService, private val navigator: Navigator ) : VectorSettingsBaseFragment() { @@ -155,8 +157,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( lifecycleScope.launchWhenResumed { findPreference(VectorPreferences.SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT)?.isVisible = - vectorActivity.getVectorComponent() - .rawService() + rawService .getElementWellknown(session.sessionParams) ?.isE2EByDefault() == false } From d89264ff7708503b0d82b7b530e6d5a414e0d690 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Oct 2021 11:30:21 +0200 Subject: [PATCH 015/413] Hilt: add small migration guide --- docs/hilt_migration.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs/hilt_migration.md diff --git a/docs/hilt_migration.md b/docs/hilt_migration.md new file mode 100644 index 0000000000..50021e9792 --- /dev/null +++ b/docs/hilt_migration.md @@ -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 { + override fun create(initialState: MyViewState): MyViewModel + } + + companion object : MavericksViewModelFactory 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. + From e6e8c7f7d10be86555607873f78483fe47efeba1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Oct 2021 12:41:06 +0200 Subject: [PATCH 016/413] Hilt: clean code and add changelog --- changelog.d/3888.misc | 1 + .../im/vector/app/features/debug/DebugMenuActivity.kt | 1 - .../settings/troubleshoot/TestFirebaseToken.kt | 1 - .../features/settings/troubleshoot/TestPlayServices.kt | 1 - .../settings/troubleshoot/TestPushFromPushGateway.kt | 1 - .../settings/troubleshoot/TestTokenRegistration.kt | 1 - .../main/java/im/vector/app/core/di/FragmentModule.kt | 1 - .../app/core/di/HiltMavericksViewModelFactory.kt | 1 - .../src/main/java/im/vector/app/core/di/HomeModule.kt | 1 - .../main/java/im/vector/app/core/di/ImageManager.kt | 1 - .../im/vector/app/core/di/MavericksViewModelModule.kt | 3 --- .../im/vector/app/core/platform/VectorBaseFragment.kt | 3 +-- .../main/java/im/vector/app/features/MainActivity.kt | 1 - .../java/im/vector/app/features/auth/ReAuthActivity.kt | 3 +-- .../im/vector/app/features/auth/ReAuthViewModel.kt | 5 +---- .../im/vector/app/features/call/VectorCallActivity.kt | 1 - .../im/vector/app/features/call/VectorCallViewModel.kt | 3 +-- .../app/features/call/conference/JitsiCallViewModel.kt | 5 +---- .../app/features/call/conference/JitsiCallViewState.kt | 3 +-- .../features/call/conference/VectorJitsiActivity.kt | 2 -- .../app/features/call/transfer/CallTransferActivity.kt | 5 ----- .../features/call/transfer/CallTransferViewModel.kt | 2 +- .../app/features/contactsbook/ContactsBookViewModel.kt | 5 +---- .../features/createdirect/CreateDirectRoomActivity.kt | 7 +------ .../features/createdirect/CreateDirectRoomViewModel.kt | 2 +- .../keysbackup/restore/KeysBackupRestoreActivity.kt | 1 - .../keysbackup/settings/KeysBackupManageActivity.kt | 2 -- .../keysbackup/settings/KeysBackupSettingsViewModel.kt | 2 +- .../crypto/keysbackup/setup/KeysBackupSetupActivity.kt | 1 - .../crypto/quads/SharedSecureStorageActivity.kt | 1 - .../crypto/quads/SharedSecureStorageViewModel.kt | 10 ++++------ .../features/crypto/recover/BootstrapBottomSheet.kt | 2 -- .../crypto/recover/BootstrapSharedViewModel.kt | 3 --- .../app/features/crypto/recover/BootstrapViewState.kt | 3 +-- .../crypto/verification/VerificationBottomSheet.kt | 1 - .../choose/VerificationChooseMethodViewModel.kt | 2 +- .../emoji/VerificationEmojiCodeViewModel.kt | 4 ++-- .../discovery/change/SetIdentityServerViewModel.kt | 5 ++--- .../java/im/vector/app/features/home/HomeActivity.kt | 2 -- .../im/vector/app/features/home/HomeDetailFragment.kt | 2 -- .../im/vector/app/features/home/HomeDetailViewModel.kt | 6 ++---- .../app/features/home/PromoteRestrictedViewModel.kt | 5 +---- .../home/UnknownDeviceDetectorSharedViewModel.kt | 2 +- .../app/features/home/UnreadMessagesSharedViewModel.kt | 2 +- .../home/room/breadcrumbs/BreadcrumbsViewModel.kt | 2 -- .../home/room/detail/JoinReplacementRoomBottomSheet.kt | 1 - .../features/home/room/detail/RoomDetailActivity.kt | 1 - .../home/room/detail/composer/TextComposerViewModel.kt | 5 +---- .../features/home/room/detail/search/SearchActivity.kt | 1 - .../home/room/detail/search/SearchViewModel.kt | 2 +- .../detail/timeline/action/MessageActionsViewModel.kt | 2 +- .../timeline/edithistory/ViewEditHistoryViewModel.kt | 2 +- .../timeline/reactions/ViewReactionsViewModel.kt | 4 +--- .../home/room/detail/upgrade/MigrateRoomBottomSheet.kt | 3 +-- .../home/room/detail/upgrade/MigrateRoomViewModel.kt | 2 +- .../home/room/detail/widget/RoomWidgetsBottomSheet.kt | 1 - .../home/room/filtered/FilteredRoomsActivity.kt | 1 - .../app/features/home/room/list/RoomListViewModel.kt | 5 +---- .../homeserver/HomeServerCapabilitiesViewModel.kt | 4 ++-- .../app/features/invite/InviteUsersToRoomActivity.kt | 5 ----- .../app/features/invite/InviteUsersToRoomViewModel.kt | 2 +- .../im/vector/app/features/link/LinkHandlerActivity.kt | 1 - .../java/im/vector/app/features/login/LoginActivity.kt | 3 --- .../im/vector/app/features/login/LoginViewModel.kt | 6 +----- .../im/vector/app/features/login2/LoginActivity2.kt | 3 --- .../im/vector/app/features/login2/LoginViewModel2.kt | 5 +---- .../features/login2/created/AccountCreatedViewModel.kt | 2 +- .../app/features/matrixto/MatrixToBottomSheet.kt | 1 - .../features/matrixto/MatrixToBottomSheetViewModel.kt | 2 +- .../app/features/media/BigImageViewerActivity.kt | 1 - .../features/media/VectorAttachmentViewerActivity.kt | 1 - .../app/features/qrcode/QrCodeScannerActivity.kt | 1 - .../vector/app/features/rageshake/BugReportActivity.kt | 2 -- .../app/features/rageshake/BugReportViewModel.kt | 2 +- .../java/im/vector/app/features/rageshake/RageShake.kt | 1 - .../features/reactions/EmojiReactionPickerActivity.kt | 1 - .../features/reactions/EmojiSearchResultViewModel.kt | 2 +- .../features/room/RequireActiveMembershipViewModel.kt | 3 +-- .../features/roomdirectory/RoomDirectoryActivity.kt | 1 - .../features/roomdirectory/RoomDirectoryViewModel.kt | 4 +--- .../roomdirectory/createroom/CreateRoomActivity.kt | 1 - .../picker/RoomDirectoryPickerViewModel.kt | 4 +--- .../roomdirectory/roompreview/RoomPreviewViewModel.kt | 2 +- .../roommemberprofile/RoomMemberProfileActivity.kt | 3 --- .../roommemberprofile/RoomMemberProfileViewModel.kt | 2 -- .../app/features/roomprofile/RoomProfileActivity.kt | 2 -- .../roomprofile/alias/detail/RoomAliasBottomSheet.kt | 1 - .../notifications/RoomNotificationSettingsViewModel.kt | 2 +- .../permissions/RoomPermissionsViewModel.kt | 2 +- .../roomprofile/settings/RoomSettingsViewModel.kt | 3 --- .../RoomHistoryVisibilityBottomSheet.kt | 1 - .../settings/joinrule/RoomJoinRuleActivity.kt | 1 - .../settings/joinrule/RoomJoinRuleBottomSheet.kt | 1 - .../advanced/RoomJoinRuleChooseRestrictedViewModel.kt | 3 --- .../roomprofile/uploads/RoomUploadsViewModel.kt | 2 +- .../app/features/settings/VectorSettingsActivity.kt | 1 - .../account/deactivation/DeactivateAccountViewModel.kt | 2 +- .../devices/DeviceVerificationInfoBottomSheet.kt | 1 - .../DeviceVerificationInfoBottomSheetViewModel.kt | 5 +++-- .../app/features/settings/devices/DevicesViewModel.kt | 2 +- .../features/settings/devtools/AccountDataViewModel.kt | 2 +- .../devtools/GossipingEventsPaperTrailViewModel.kt | 2 +- .../features/settings/devtools/KeyRequestViewModel.kt | 2 +- .../settings/homeserver/HomeserverSettingsViewModel.kt | 2 +- .../features/settings/ignored/IgnoredUsersViewModel.kt | 4 +--- .../app/features/settings/push/PushRulesViewModel.kt | 2 +- .../settings/troubleshoot/TestSystemSettings.kt | 1 - .../app/features/share/IncomingShareViewModel.kt | 2 +- .../app/features/signout/soft/SoftLogoutActivity.kt | 1 - .../app/features/signout/soft/SoftLogoutActivity2.kt | 1 - .../app/features/signout/soft/SoftLogoutViewModel.kt | 5 ++--- .../spaces/InviteRoomSpaceChooserBottomSheet.kt | 1 - .../app/features/spaces/LeaveSpaceBottomSheet.kt | 1 - .../app/features/spaces/SpaceCreationActivity.kt | 5 +---- .../vector/app/features/spaces/SpaceExploreActivity.kt | 3 --- .../vector/app/features/spaces/SpaceListViewModel.kt | 2 +- .../vector/app/features/spaces/SpaceMenuViewModel.kt | 2 +- .../features/spaces/SpaceSettingsMenuBottomSheet.kt | 3 +-- .../app/features/spaces/create/CreateSpaceViewModel.kt | 4 ++-- .../features/spaces/explore/SpaceDirectoryViewModel.kt | 2 +- .../features/spaces/invite/SpaceInviteBottomSheet.kt | 1 - .../spaces/invite/SpaceInviteBottomSheetViewModel.kt | 5 +---- .../spaces/leave/SpaceLeaveAdvancedActivity.kt | 1 - .../spaces/leave/SpaceLeaveAdvancedViewModel.kt | 2 +- .../features/spaces/manage/SpaceAddRoomsViewModel.kt | 5 +---- .../app/features/spaces/manage/SpaceManageActivity.kt | 2 -- .../spaces/manage/SpaceManageRoomsViewModel.kt | 2 +- .../spaces/manage/SpaceManageSharedViewModel.kt | 2 +- .../features/spaces/manage/SpaceSettingsFragment.kt | 1 - .../app/features/spaces/people/SpacePeopleFragment.kt | 1 - .../app/features/spaces/people/SpacePeopleViewModel.kt | 2 +- .../features/spaces/preview/SpacePreviewViewModel.kt | 5 +---- .../app/features/spaces/share/ShareSpaceBottomSheet.kt | 4 +--- .../app/features/spaces/share/ShareSpaceViewModel.kt | 2 +- .../vector/app/features/terms/ReviewTermsActivity.kt | 1 - .../vector/app/features/terms/ReviewTermsViewModel.kt | 2 +- .../vector/app/features/usercode/UserCodeActivity.kt | 2 -- .../app/features/usercode/UserCodeSharedViewModel.kt | 2 +- .../app/features/userdirectory/UserListViewModel.kt | 5 +---- .../app/features/webview/VectorWebViewActivity.kt | 2 -- .../im/vector/app/features/widgets/WidgetActivity.kt | 3 --- .../im/vector/app/features/widgets/WidgetViewModel.kt | 5 +---- .../permissions/RoomWidgetPermissionBottomSheet.kt | 1 - .../permissions/RoomWidgetPermissionViewModel.kt | 4 +--- .../workers/signout/ServerBackupStatusViewModel.kt | 5 +---- .../signout/SignOutBottomSheetDialogFragment.kt | 4 +--- .../features/workers/signout/SignoutCheckViewModel.kt | 5 +---- 147 files changed, 89 insertions(+), 276 deletions(-) create mode 100644 changelog.d/3888.misc diff --git a/changelog.d/3888.misc b/changelog.d/3888.misc new file mode 100644 index 0000000000..314e515631 --- /dev/null +++ b/changelog.d/3888.misc @@ -0,0 +1 @@ +Migrate app DI framework to Hilt \ No newline at end of file diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index 999392f2b7..960994b169 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -27,7 +27,6 @@ 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.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt index ce34c7ac3b..89270cce55 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestFirebaseToken.kt @@ -17,7 +17,6 @@ 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 diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt index 995bc4117c..cc682e7a5f 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPlayServices.kt @@ -17,7 +17,6 @@ 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 diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt index 37ddf1b763..7ae68b201b 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromPushGateway.kt @@ -17,7 +17,6 @@ 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 diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt index c2c9e692b3..913b5491ea 100644 --- a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestTokenRegistration.kt @@ -17,7 +17,6 @@ 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 diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index a865fcc074..bf72dcb076 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -23,7 +23,6 @@ import dagger.Binds import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityComponent -import dagger.hilt.migration.DisableInstallInCheck import dagger.multibindings.IntoMap import im.vector.app.features.attachments.preview.AttachmentsPreviewFragment import im.vector.app.features.contactsbook.ContactsBookFragment diff --git a/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt b/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt index 10485b8189..13702053e8 100644 --- a/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt +++ b/vector/src/main/java/im/vector/app/core/di/HiltMavericksViewModelFactory.kt @@ -63,7 +63,6 @@ class HiltMavericksViewModelFactory, S : MavericksSta override fun initialState(viewModelContext: ViewModelContext): S? { return super.initialState(viewModelContext) } - } /** diff --git a/vector/src/main/java/im/vector/app/core/di/HomeModule.kt b/vector/src/main/java/im/vector/app/core/di/HomeModule.kt index 7d63f2ffc8..1af67cdc83 100644 --- a/vector/src/main/java/im/vector/app/core/di/HomeModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/HomeModule.kt @@ -33,5 +33,4 @@ object HomeModule { fun providesTimelineBackgroundHandler(): Handler { return TimelineAsyncHelper.getBackgroundHandler() } - } diff --git a/vector/src/main/java/im/vector/app/core/di/ImageManager.kt b/vector/src/main/java/im/vector/app/core/di/ImageManager.kt index 154db33fe9..60ce70a0b3 100644 --- a/vector/src/main/java/im/vector/app/core/di/ImageManager.kt +++ b/vector/src/main/java/im/vector/app/core/di/ImageManager.kt @@ -21,7 +21,6 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.model.GlideUrl import com.github.piasy.biv.BigImageViewer import com.github.piasy.biv.loader.glide.GlideImageLoader -import dagger.hilt.android.qualifiers.ApplicationContext import im.vector.app.ActiveSessionDataSource import im.vector.app.core.glide.FactoryUrl import org.matrix.android.sdk.api.session.Session diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index 17c29eb706..5637c97b51 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -41,7 +41,6 @@ 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.RoomDetailViewModel 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 @@ -541,6 +540,4 @@ interface MavericksViewModelModule { @IntoMap @MavericksViewModelKey(VerificationBottomSheetViewModel::class) fun verificationBottomSheetViewModelFactory(factory: VerificationBottomSheetViewModel.Factory): MavericksAssistedViewModelFactory<*, *> - - } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index 6c10fba3c1..d3c66ec61d 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -38,7 +38,6 @@ import com.jakewharton.rxbinding3.view.clicks import dagger.hilt.android.EntryPointAccessors import im.vector.app.R 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 @@ -95,7 +94,7 @@ abstract class VectorBaseFragment : Fragment(), MavericksView override fun onAttach(context: Context) { val singletonEntryPoint = context.singletonEntryPoint() - val activityEntryPoint = EntryPointAccessors.fromActivity(vectorBaseActivity,ActivityEntryPoint::class.java) + val activityEntryPoint = EntryPointAccessors.fromActivity(vectorBaseActivity, ActivityEntryPoint::class.java) navigator = singletonEntryPoint.navigator() errorFormatter = singletonEntryPoint.errorFormatter() unrecognizedCertificateDialog = singletonEntryPoint.unrecognizedCertificateDialog() diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index 37b1fb1aad..8e0995b426 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -27,7 +27,6 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.startSyncing import im.vector.app.core.platform.VectorBaseActivity diff --git a/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt b/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt index 80a12fcd00..e3c9795b13 100644 --- a/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt +++ b/vector/src/main/java/im/vector/app/features/auth/ReAuthActivity.kt @@ -31,7 +31,6 @@ 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.extensions.addFragment import im.vector.app.core.platform.SimpleFragmentActivity import im.vector.app.core.utils.openUrlInChromeCustomTab @@ -44,7 +43,7 @@ import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint -class ReAuthActivity : SimpleFragmentActivity(){ +class ReAuthActivity : SimpleFragmentActivity() { @Parcelize data class Args( diff --git a/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt b/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt index 42c465e439..830fd4e79d 100644 --- a/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt @@ -16,10 +16,7 @@ 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 @@ -37,7 +34,7 @@ class ReAuthViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: ReAuthState): ReAuthViewModel } diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index c4f2520685..879a357dfb 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -95,7 +95,6 @@ class VectorCallActivity : VectorBaseActivity(), CallContro private val callViewModel: VectorCallViewModel by viewModel() - private val dialPadCallback = object : DialPadFragment.Callback { override fun onDigitAppended(digit: String) { callViewModel.handle(VectorCallViewActions.SendDtmfDigit(digit)) diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt index 07852b3fea..5af2b826af 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt @@ -21,7 +21,6 @@ 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 @@ -343,7 +342,7 @@ class VectorCallViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: VectorCallViewState): VectorCallViewModel } diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt index e82a6829c0..d04bebfd1b 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt @@ -22,7 +22,6 @@ 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 @@ -48,7 +47,7 @@ class JitsiCallViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: JitsiCallViewState): JitsiCallViewModel } @@ -148,6 +147,4 @@ class JitsiCallViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { const val ENABLE_VIDEO_OPTION = "ENABLE_VIDEO_OPTION" } - - } diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewState.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewState.kt index 462e143fca..7ecd44b9b0 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewState.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewState.kt @@ -28,10 +28,9 @@ data class JitsiCallViewState( val widget: Async = Uninitialized ) : MavericksState { - constructor(args: VectorJitsiActivity.Args): this( + constructor(args: VectorJitsiActivity.Args) : this( roomId = args.roomId, widgetId = args.widgetId, enableVideo = args.enableVideo ) - } diff --git a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt index b33eecee61..3fcefc9c8e 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt @@ -35,7 +35,6 @@ 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.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityJitsiBinding @@ -49,7 +48,6 @@ 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(), JitsiMeetActivityInterface { diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index 87e40ac591..c03b526f8c 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -25,14 +25,9 @@ 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.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 diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt index f35e077025..ffc6ff9bc3 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferViewModel.kt @@ -40,7 +40,7 @@ class CallTransferViewModel @AssistedInject constructor(@Assisted initialState: VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: CallTransferViewState): CallTransferViewModel } diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt index 1d8c905c84..7f0dbcb7b2 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewModel.kt @@ -17,12 +17,9 @@ 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 @@ -47,7 +44,7 @@ class ContactsBookViewModel @AssistedInject constructor(@Assisted VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: ContactsBookViewState): ContactsBookViewModel } diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index fc6afc583c..28da72714a 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -30,7 +30,6 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack @@ -43,21 +42,17 @@ 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 @AndroidEntryPoint -class CreateDirectRoomActivity : SimpleFragmentActivity(){ +class CreateDirectRoomActivity : SimpleFragmentActivity() { private val viewModel: CreateDirectRoomViewModel by viewModel() private lateinit var sharedActionViewModel: UserListSharedActionViewModel diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt index 1d284730cd..41360eab93 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomViewModel.kt @@ -43,7 +43,7 @@ class CreateDirectRoomViewModel @AssistedInject constructor(@Assisted VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: CreateDirectRoomViewState): CreateDirectRoomViewModel } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt index b3c0612838..bdae975846 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreActivity.kt @@ -29,7 +29,6 @@ import im.vector.app.core.extensions.replaceFragment 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.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt index b6220b24b7..2b666e9cf8 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupManageActivity.kt @@ -23,11 +23,9 @@ 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.extensions.replaceFragment import im.vector.app.core.platform.SimpleFragmentActivity import im.vector.app.core.platform.WaitingViewData -import javax.inject.Inject @AndroidEntryPoint class KeysBackupManageActivity : SimpleFragmentActivity() { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index b591d88286..d6d9e10669 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -41,7 +41,7 @@ class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialS KeysBackupStateListener { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: KeysBackupSettingViewState): KeysBackupSettingsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt index 262768f9f2..0f7c09ca16 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupActivity.kt @@ -26,7 +26,6 @@ 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.dialogs.ExportKeysDialog import im.vector.app.core.extensions.observeEvent import im.vector.app.core.extensions.queryExportKeys diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt index 21d03fead0..61c8ab8f0a 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt @@ -30,7 +30,6 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.platform.SimpleFragmentActivity diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt index c19fe0c33b..8994ad901b 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt @@ -19,12 +19,10 @@ 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 @@ -62,7 +60,7 @@ data class SharedSecureStorageViewState( val resultKeyStoreAlias: String ) : MavericksState { - constructor(args: SharedSecureStorageActivity.Args): this( + constructor(args: SharedSecureStorageActivity.Args) : this( keyId = args.keyId, requestedSecrets = args.requestedSecrets, resultKeyStoreAlias = args.resultKeyStoreAlias @@ -82,7 +80,7 @@ class SharedSecureStorageViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SharedSecureStorageViewState): SharedSecureStorageViewModel } @@ -90,8 +88,8 @@ class SharedSecureStorageViewModel @AssistedInject constructor( setState { copy(userId = session.myUserId) } - val isValid = session.sharedSecretStorageService.checkShouldBeAbleToAccessSecrets(initialState.requestedSecrets, initialState.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), diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt index 264f51f379..50f9526da5 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt @@ -35,7 +35,6 @@ 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.extensions.commitTransaction import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.registerStartForActivityResult @@ -44,7 +43,6 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt index 69309a9ae4..f75ab634b8 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt @@ -17,12 +17,10 @@ package im.vector.app.features.crypto.recover 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 @@ -36,7 +34,6 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt index 380a2b5fb4..9d5760cbf9 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapViewState.kt @@ -37,6 +37,5 @@ data class BootstrapViewState( val recoverySaveFileProcess: Async = Uninitialized ) : MavericksState { - constructor(args: BootstrapBottomSheet.Args): this(setupMode = args.setUpMode) - + constructor(args: BootstrapBottomSheet.Args) : this(setupMode = args.setUpMode) } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt index 5a4a985e2d..4ef0109227 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt @@ -30,7 +30,6 @@ 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.extensions.commitTransaction import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.registerStartForActivityResult diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt index cb42d12e66..7696bb8f5b 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt @@ -22,8 +22,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import dagger.hilt.EntryPoints -import im.vector.app.core.di.SingletonEntryPoint 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 diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt index d6c9e348db..6f213adb7e 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt @@ -27,8 +27,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import dagger.hilt.EntryPoints -import im.vector.app.core.di.SingletonEntryPoint 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 @@ -153,7 +153,7 @@ class VerificationEmojiCodeViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: VerificationEmojiCodeViewState): VerificationEmojiCodeViewModel } diff --git a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt index 7354cafc9f..c258652b49 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerViewModel.kt @@ -22,8 +22,8 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import dagger.hilt.EntryPoints import im.vector.app.R -import im.vector.app.core.di.SingletonEntryPoint 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 @@ -43,7 +43,7 @@ class SetIdentityServerViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SetIdentityServerState): SetIdentityServerViewModel } @@ -56,7 +56,6 @@ class SetIdentityServerViewModel @AssistedInject constructor( defaultIdentityServerUrl = session.identityService().getDefaultIdentityServer() ) } - } var currentWantedUrl: String? = null diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 6e4b26cb9d..e8af044bbd 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -38,7 +38,6 @@ 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.extensions.exhaustive import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.registerStartForActivityResult @@ -73,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 diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index 6b33c103c7..80351a437e 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -57,7 +57,6 @@ 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 @@ -500,5 +499,4 @@ class HomeDetailFragment @Inject constructor( } return this } - } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 3ab4fa8b5a..73e50ad5f1 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -22,10 +22,8 @@ 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.AppStateHandler import im.vector.app.RoomGroupingMethod -import im.vector.app.core.di.SingletonEntryPoint import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.extensions.singletonEntryPoint @@ -72,11 +70,11 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho CallProtocolsChecker.Listener { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: HomeDetailViewState): HomeDetailViewModel } - companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory(){ + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { override fun initialState(viewModelContext: ViewModelContext): HomeDetailViewState { val uiStateRepository = viewModelContext.activity.singletonEntryPoint().uiStateRepository() diff --git a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt index 760de3a320..218574c03e 100644 --- a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt @@ -16,11 +16,8 @@ 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 @@ -74,7 +71,7 @@ class PromoteRestrictedViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: ActiveSpaceViewState): PromoteRestrictedViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt index 4018f15cca..8a36a4c19e 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt @@ -65,7 +65,7 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt index e20f786b1e..5bdbc95b48 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt @@ -60,7 +60,7 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: UnreadMessagesState): UnreadMessagesSharedViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt index 7c0892aa92..112b7e8574 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsViewModel.kt @@ -16,9 +16,7 @@ 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 diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt index ebd7ff0367..ba559677c9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/JoinReplacementRoomBottomSheet.kt @@ -27,7 +27,6 @@ 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.epoxy.ClickListener import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.ButtonStateView diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index efaadb7170..ba53f75eca 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -29,7 +29,6 @@ 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.extensions.hideKeyboard import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.ToolbarConfigurable diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt index 88d600abc7..e80f25de2f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt @@ -16,9 +16,7 @@ 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 @@ -31,7 +29,6 @@ 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 @@ -712,7 +709,7 @@ class TextComposerViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: TextComposerViewState): TextComposerViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt index d8a4e01bc6..eea62b0907 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt @@ -23,7 +23,6 @@ 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.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySearchBinding diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt index 8a681ad30a..a360b91085 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchViewModel.kt @@ -45,7 +45,7 @@ class SearchViewModel @AssistedInject constructor( private var nextBatch: String? = null @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SearchViewState): SearchViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index 8fb2598e58..30c231131e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -85,7 +85,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted private val eventIdFlow = MutableStateFlow(initialState.eventId) @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: MessageActionState): MessageActionsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt index b0495d7c8f..9abc67e41f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt @@ -46,7 +46,7 @@ class ViewEditHistoryViewModel @AssistedInject constructor( ?: throw IllegalStateException("Shouldn't use this ViewModel without a room") @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: ViewEditHistoryViewState): ViewEditHistoryViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt index 14e06c221a..1f4d67db03 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt @@ -17,11 +17,9 @@ package im.vector.app.features.home.room.detail.timeline.reactions import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Uninitialized -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -72,7 +70,7 @@ class ViewReactionsViewModel @AssistedInject constructor(@Assisted ?: throw IllegalStateException("Shouldn't use this ViewModel without a room") @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: DisplayReactionsViewState): ViewReactionsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt index f7994319c2..03a0e64d9b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomBottomSheet.kt @@ -29,7 +29,6 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment @@ -39,7 +38,7 @@ import javax.inject.Inject @AndroidEntryPoint class MigrateRoomBottomSheet : - VectorBaseBottomSheetDialogFragment(){ + VectorBaseBottomSheetDialogFragment() { enum class MigrationReason { MANUAL, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt index be718682b6..98be65c167 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/upgrade/MigrateRoomViewModel.kt @@ -50,7 +50,7 @@ class MigrateRoomViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: MigrateRoomViewState): MigrateRoomViewModel } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt index 211a001fc3..aa6966254f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt @@ -24,7 +24,6 @@ import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment diff --git a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt index 5e2b75acb1..18618099bd 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt @@ -22,7 +22,6 @@ import android.os.Bundle import androidx.appcompat.widget.SearchView import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityFilteredRoomsBinding diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index c851f95cde..89f5aec8fb 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -19,11 +19,9 @@ package im.vector.app.features.home.room.list import androidx.lifecycle.MutableLiveData 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.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -51,7 +49,6 @@ import org.matrix.android.sdk.api.session.room.state.isPublic import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow import timber.log.Timber -import javax.inject.Inject class RoomListViewModel @AssistedInject constructor( @Assisted initialState: RoomListViewState, @@ -63,7 +60,7 @@ class RoomListViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: RoomListViewState): RoomListViewModel } diff --git a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt index d76af19c87..9223485eff 100644 --- a/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/homeserver/HomeServerCapabilitiesViewModel.kt @@ -22,8 +22,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import dagger.hilt.EntryPoints -import im.vector.app.core.di.SingletonEntryPoint 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 @@ -44,7 +44,7 @@ class HomeServerCapabilitiesViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: HomeServerCapabilitiesViewState): HomeServerCapabilitiesViewModel } diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt index 51c0b0762c..6f4aff0041 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt @@ -26,7 +26,6 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack @@ -38,14 +37,10 @@ import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.core.utils.toast 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 kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.failure.Failure import java.net.HttpURLConnection diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt index 30dbadcb37..891194040e 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomViewModel.kt @@ -42,7 +42,7 @@ class InviteUsersToRoomViewModel @AssistedInject constructor(@Assisted private val room = session.getRoom(initialState.roomId)!! @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: InviteUsersToRoomViewState): InviteUsersToRoomViewModel } diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt index ffee04df42..c22f8eb779 100644 --- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt @@ -23,7 +23,6 @@ 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.error.ErrorFormatter import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index 5b91a5ed7c..b3606a68ca 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -20,7 +20,6 @@ import android.content.Context import android.content.Intent import android.view.View import android.view.ViewGroup -import androidx.annotation.CallSuper import androidx.core.view.ViewCompat import androidx.core.view.children import androidx.core.view.isVisible @@ -33,7 +32,6 @@ import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.POP_BACK_STACK_EXCLUSIVE import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack @@ -49,7 +47,6 @@ import im.vector.app.features.pin.UnlockedActivity import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.extensions.tryOrNull -import javax.inject.Inject /** * The LoginActivity manages the fragment navigation and also display the loading View diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt index 9eaea0391f..c08c36d552 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt @@ -18,15 +18,12 @@ package im.vector.app.features.login import android.content.Context import android.net.Uri -import androidx.fragment.app.FragmentActivity import androidx.lifecycle.viewModelScope -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 @@ -39,7 +36,6 @@ 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.core.utils.ensureTrailingSlash -import im.vector.app.features.signout.soft.SoftLogoutActivity import kotlinx.coroutines.Job import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixPatterns.getDomain @@ -74,7 +70,7 @@ class LoginViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory:MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: LoginViewState): LoginViewModel } diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt index 2b2c7e69be..40dd1d2872 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt @@ -20,7 +20,6 @@ import android.content.Context import android.content.Intent import android.view.View import android.view.ViewGroup -import androidx.annotation.CallSuper import androidx.core.view.ViewCompat import androidx.core.view.children import androidx.core.view.isVisible @@ -32,7 +31,6 @@ import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.POP_BACK_STACK_EXCLUSIVE import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack @@ -56,7 +54,6 @@ import im.vector.app.features.pin.UnlockedActivity import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.extensions.tryOrNull -import javax.inject.Inject /** * The LoginActivity manages the fragment navigation and also display the loading View diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt index d98bf99a12..ee33b8c222 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt @@ -18,12 +18,9 @@ package im.vector.app.features.login2 import android.content.Context import android.net.Uri -import androidx.fragment.app.FragmentActivity import androidx.lifecycle.viewModelScope -import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -74,7 +71,7 @@ class LoginViewModel2 @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: LoginViewState2): LoginViewModel2 } diff --git a/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedViewModel.kt b/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedViewModel.kt index 559be4aa66..568cdab119 100644 --- a/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login2/created/AccountCreatedViewModel.kt @@ -39,7 +39,7 @@ class AccountCreatedViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: AccountCreatedViewState): AccountCreatedViewModel } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt index 2cae10d01f..029234a66d 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt @@ -30,7 +30,6 @@ 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.extensions.commitTransaction import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetMatrixToCardBinding diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt index 4d2a15402a..e741f6fb39 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt @@ -53,7 +53,7 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: MatrixToBottomSheetState): MatrixToBottomSheetViewModel } diff --git a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt index 2d897fcc51..84454ee509 100644 --- a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt @@ -22,7 +22,6 @@ import android.os.Bundle import androidx.core.net.toUri import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.di.ActiveSessionHolder - import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityBigImageViewerBinding import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt index c2d7cac507..103511bad5 100644 --- a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt @@ -63,7 +63,6 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), BaseAttachmen @Inject lateinit var imageContentRenderer: ImageContentRenderer - private var initialIndex = 0 private var isAnimatingOut = false diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt index f6cabf1932..7fb2f1f254 100644 --- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt @@ -25,7 +25,6 @@ import com.google.zxing.Result import com.google.zxing.ResultMetadataType import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt index dbf9ceded8..b27c2e9818 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt @@ -27,12 +27,10 @@ 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.platform.VectorBaseActivity import im.vector.app.databinding.ActivityBugReportBinding import org.matrix.android.sdk.api.extensions.tryOrNull import timber.log.Timber -import javax.inject.Inject /** * Form to send a bug report diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportViewModel.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportViewModel.kt index 5342a7dec7..d0a1280868 100644 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportViewModel.kt @@ -35,7 +35,7 @@ class BugReportViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: BugReportState): BugReportViewModel } diff --git a/vector/src/main/java/im/vector/app/features/rageshake/RageShake.kt b/vector/src/main/java/im/vector/app/features/rageshake/RageShake.kt index b377b0b1df..93c72ea69e 100644 --- a/vector/src/main/java/im/vector/app/features/rageshake/RageShake.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/RageShake.kt @@ -19,7 +19,6 @@ package im.vector.app.features.rageshake import android.content.Context import android.hardware.Sensor import android.hardware.SensorManager -import androidx.appcompat.app.AppCompatActivity import androidx.core.content.getSystemService import androidx.fragment.app.FragmentActivity import com.google.android.material.dialog.MaterialAlertDialogBuilder diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt index d5b27213e1..5675af6960 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt @@ -32,7 +32,6 @@ import com.jakewharton.rxbinding3.widget.queryTextChanges import dagger.hilt.android.AndroidEntryPoint import im.vector.app.EmojiCompatFontProvider import im.vector.app.R - import im.vector.app.core.extensions.observeEvent import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityEmojiReactionPickerBinding diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultViewModel.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultViewModel.kt index 48ac871b99..e1e52fdca1 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultViewModel.kt @@ -39,7 +39,7 @@ class EmojiSearchResultViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: EmojiSearchResultViewState): EmojiSearchResultViewModel } diff --git a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt index 93810b54cf..6ad93abe0c 100644 --- a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt @@ -17,7 +17,6 @@ package im.vector.app.features.room import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -55,7 +54,7 @@ class RequireActiveMembershipViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt index 03b10ef983..dd4011a865 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt @@ -23,7 +23,6 @@ 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.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.popBackstack diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt index ebd12e10b3..844266e668 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt @@ -16,12 +16,10 @@ package im.vector.app.features.roomdirectory -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.ViewModelContext import com.airbnb.mvrx.appendAt import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -51,7 +49,7 @@ class RoomDirectoryViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: PublicRoomsViewState): RoomDirectoryViewModel } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt index c55225ae80..eeb7d217c0 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt @@ -22,7 +22,6 @@ import android.os.Bundle 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 import im.vector.app.core.platform.VectorBaseActivity diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt index 913bd2916b..a5673e78a2 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerViewModel.kt @@ -17,12 +17,10 @@ package im.vector.app.features.roomdirectory.picker 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 @@ -47,7 +45,7 @@ class RoomDirectoryPickerViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: RoomDirectoryPickerViewState): RoomDirectoryPickerViewModel } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index 30c1094687..7b012f4fac 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -49,7 +49,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted private val ini VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: RoomPreviewViewState): RoomPreviewViewModel } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt index c07dfd5a3b..c563f6b855 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileActivity.kt @@ -25,15 +25,12 @@ 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.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.room.RequireActiveMembershipViewEvents import im.vector.app.features.room.RequireActiveMembershipViewModel -import im.vector.app.features.room.RequireActiveMembershipViewState -import javax.inject.Inject @AndroidEntryPoint class RoomMemberProfileActivity : diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index d68fbb9e0a..5b07b101e7 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -18,12 +18,10 @@ package im.vector.app.features.roommemberprofile 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 diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index d19c953d8e..fdb639e7d6 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -25,7 +25,6 @@ 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.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.exhaustive @@ -35,7 +34,6 @@ import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore 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.roomprofile.alias.RoomAliasFragment import im.vector.app.features.roomprofile.banned.RoomBannedMemberListFragment import im.vector.app.features.roomprofile.members.RoomMemberListFragment diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt index 9b1521e2f4..56dbcbfba4 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt @@ -25,7 +25,6 @@ import androidx.recyclerview.widget.RecyclerView import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState 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 diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt index ab0333e294..26db6b001e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/notifications/RoomNotificationSettingsViewModel.kt @@ -35,7 +35,7 @@ class RoomNotificationSettingsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: RoomNotificationSettingsViewState): RoomNotificationSettingsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt index c0950f226d..011c4ea8ae 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsViewModel.kt @@ -42,7 +42,7 @@ class RoomPermissionsViewModel @AssistedInject constructor(@Assisted initialStat VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: RoomPermissionsViewState): RoomPermissionsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt index 28c84f9fe4..1e3cd053b1 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsViewModel.kt @@ -17,10 +17,7 @@ package im.vector.app.features.roomprofile.settings import androidx.core.net.toFile -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 diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt index c5c375ba70..c63cf918c8 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt @@ -22,7 +22,6 @@ import android.view.View import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint - import im.vector.app.core.ui.bottomsheet.BottomSheetGeneric import im.vector.app.core.ui.bottomsheet.BottomSheetGenericController import kotlinx.parcelize.Parcelize diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt index beabd2b878..bb8db019c3 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleActivity.kt @@ -29,7 +29,6 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.commitTransaction diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt index 9684f1fe30..4185c2031b 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt @@ -22,7 +22,6 @@ import android.view.View import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint - import im.vector.app.core.ui.bottomsheet.BottomSheetGeneric import im.vector.app.core.ui.bottomsheet.BottomSheetGenericController import kotlinx.parcelize.Parcelize diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt index 039862bde7..4bd7568ccd 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/advanced/RoomJoinRuleChooseRestrictedViewModel.kt @@ -18,14 +18,11 @@ package im.vector.app.features.roomprofile.settings.joinrule.advanced import android.graphics.Typeface import androidx.core.text.toSpannable -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.Uninitialized -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt index 0c08ff6d4d..92ff33395e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsViewModel.kt @@ -39,7 +39,7 @@ class RoomUploadsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: RoomUploadsViewState): RoomUploadsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt index d9db00b50f..27fbacc362 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt @@ -27,7 +27,6 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityVectorSettingsBinding diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt index a0591f837b..922435047f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt @@ -48,7 +48,7 @@ class DeactivateAccountViewModel @AssistedInject constructor(@Assisted private v VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: DeactivateAccountViewState): DeactivateAccountViewModel } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt index 31a6bbd295..441a344660 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt @@ -26,7 +26,6 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState 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 diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index cb70ed4041..3a944b5a71 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -35,11 +35,12 @@ class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@As ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: DeviceVerificationInfoBottomSheetViewState): DeviceVerificationInfoBottomSheetViewModel } - companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + companion object : MavericksViewModelFactory + by hiltMavericksViewModelFactory() init { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index e147491093..e8300a1097 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -97,7 +97,7 @@ class DevicesViewModel @AssistedInject constructor( var pendingAuth: UIABaseAuth? = null @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: DevicesViewState): DevicesViewModel } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt index ba03bac0d8..6289699687 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataViewModel.kt @@ -61,7 +61,7 @@ class AccountDataViewModel @AssistedInject constructor(@Assisted initialState: A } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: AccountDataViewState): AccountDataViewModel } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt index 1aaebc5598..dde032d303 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailViewModel.kt @@ -60,7 +60,7 @@ class GossipingEventsPaperTrailViewModel @AssistedInject constructor(@Assisted i override fun handle(action: EmptyAction) {} @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: GossipingEventsPaperTrailState): GossipingEventsPaperTrailViewModel } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt index fe9960b9ab..f480eb2db8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestViewModel.kt @@ -55,7 +55,7 @@ class KeyRequestViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: KeyRequestViewState): KeyRequestViewModel } diff --git a/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsViewModel.kt index baf24d28a3..fab563b49e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsViewModel.kt @@ -36,7 +36,7 @@ class HomeserverSettingsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: HomeServerSettingsViewState): HomeserverSettingsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt index 1ae079819c..b2a7b2cbd1 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt @@ -18,13 +18,11 @@ package im.vector.app.features.settings.ignored 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 @@ -51,7 +49,7 @@ class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: IgnoredUsersViewState): IgnoredUsersViewModel } diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt index 3b620f53e5..0b6b72bb10 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesViewModel.kt @@ -35,7 +35,7 @@ class PushRulesViewModel(initialState: PushRulesViewState) : companion object : MavericksViewModelFactory { override fun initialState(viewModelContext: ViewModelContext): PushRulesViewState? { - val session = EntryPoints.get(viewModelContext.app(),SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() + val session = EntryPoints.get(viewModelContext.app(), SingletonEntryPoint::class.java).activeSessionHolder().getActiveSession() val rules = session.getPushRules().getAllRules() return PushRulesViewState(rules) } diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt index e9b6831dcf..42f506d4a6 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/TestSystemSettings.kt @@ -15,7 +15,6 @@ */ package im.vector.app.features.settings.troubleshoot -import android.content.Context import android.content.Intent import androidx.activity.result.ActivityResultLauncher import androidx.core.app.NotificationManagerCompat diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt index 229eca0596..4a413ad8ba 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareViewModel.kt @@ -46,7 +46,7 @@ class IncomingShareViewModel @AssistedInject constructor( VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: IncomingShareViewState): IncomingShareViewModel } diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt index 651526faa2..6e70b34002 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt @@ -25,7 +25,6 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.replaceFragment import im.vector.app.features.MainActivity diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt index e16162222a..ed45069e92 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt @@ -25,7 +25,6 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.replaceFragment import im.vector.app.features.MainActivity diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt index 0e272c0981..52986a1f3b 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutViewModel.kt @@ -49,11 +49,11 @@ class SoftLogoutViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SoftLogoutViewState): SoftLogoutViewModel } - companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory(){ + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { override fun initialState(viewModelContext: ViewModelContext): SoftLogoutViewState? { val activity: SoftLogoutActivity = (viewModelContext as ActivityViewModelContext).activity() @@ -66,7 +66,6 @@ class SoftLogoutViewModel @AssistedInject constructor( hasUnsavedKeys = activity.session.hasUnsavedKeys() ) } - } init { diff --git a/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt index 3b2bd3d0a1..b4c1e67cfb 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/InviteRoomSpaceChooserBottomSheet.kt @@ -26,7 +26,6 @@ import com.airbnb.mvrx.args import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder - import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetSpaceInviteChooserBinding import kotlinx.parcelize.Parcelize diff --git a/vector/src/main/java/im/vector/app/features/spaces/LeaveSpaceBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/LeaveSpaceBottomSheet.kt index 9bb36e9d8a..fb3fceaa02 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/LeaveSpaceBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/LeaveSpaceBottomSheet.kt @@ -34,7 +34,6 @@ import com.airbnb.mvrx.withState import com.jakewharton.rxbinding3.widget.checkedChanges import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.extensions.setTextOrHide diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt index 3210c27668..75373775f9 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt @@ -26,7 +26,6 @@ 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.extensions.toMvRxBundle import im.vector.app.core.platform.SimpleFragmentActivity import im.vector.app.features.spaces.create.ChoosePrivateSpaceTypeFragment @@ -40,10 +39,9 @@ import im.vector.app.features.spaces.create.CreateSpaceState import im.vector.app.features.spaces.create.CreateSpaceViewModel import im.vector.app.features.spaces.create.SpaceTopology import im.vector.app.features.spaces.create.SpaceType -import javax.inject.Inject @AndroidEntryPoint -class SpaceCreationActivity : SimpleFragmentActivity(){ +class SpaceCreationActivity : SimpleFragmentActivity() { val viewModel: CreateSpaceViewModel by viewModel() @@ -182,5 +180,4 @@ class SpaceCreationActivity : SimpleFragmentActivity(){ return data?.extras?.getBoolean(RESULT_DATA_CREATED_SPACE_IS_JUST_ME, false) == true } } - } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt index 21128b40af..780183d866 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt @@ -25,7 +25,6 @@ import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.viewModel import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding @@ -33,10 +32,8 @@ import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.navigation.Navigator import im.vector.app.features.spaces.explore.SpaceDirectoryArgs import im.vector.app.features.spaces.explore.SpaceDirectoryFragment -import im.vector.app.features.spaces.explore.SpaceDirectoryState import im.vector.app.features.spaces.explore.SpaceDirectoryViewEvents import im.vector.app.features.spaces.explore.SpaceDirectoryViewModel -import javax.inject.Inject @AndroidEntryPoint class SpaceExploreActivity : VectorBaseActivity(), MatrixToBottomSheet.InteractionListener { diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index f099896fac..4487833773 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -67,7 +67,7 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpaceListViewState): SpaceListViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt index 3840ef4447..2e9af2eacb 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceMenuViewModel.kt @@ -51,7 +51,7 @@ class SpaceMenuViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpaceMenuState): SpaceMenuViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceSettingsMenuBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceSettingsMenuBottomSheet.kt index 28e6d8797a..7449868292 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceSettingsMenuBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceSettingsMenuBottomSheet.kt @@ -27,7 +27,6 @@ import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint - import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetSpaceSettingsBinding @@ -48,7 +47,7 @@ data class SpaceBottomSheetSettingsArgs( ) : Parcelable @AndroidEntryPoint -class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment(){ +class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment() { @Inject lateinit var navigator: Navigator @Inject lateinit var avatarRenderer: AvatarRenderer diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt index 9c7ecfda14..8ddeab3223 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceViewModel.kt @@ -75,7 +75,7 @@ class CreateSpaceViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: CreateSpaceState): CreateSpaceViewModel } @@ -92,7 +92,7 @@ class CreateSpaceViewModel @AssistedInject constructor( super.onCleared() } - companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory(){ + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() { override fun initialState(viewModelContext: ViewModelContext): CreateSpaceState { return CreateSpaceState( diff --git a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt index b7b419e60f..d7bdf4f511 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt @@ -51,7 +51,7 @@ class SpaceDirectoryViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpaceDirectoryState): SpaceDirectoryViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt index 34c2f84c9f..bd6dec7c4b 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheet.kt @@ -32,7 +32,6 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.platform.ButtonStateView import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.utils.toast diff --git a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt index bb07572ca3..79ad043813 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt @@ -17,14 +17,11 @@ package im.vector.app.features.spaces.invite 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.Uninitialized -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -95,7 +92,7 @@ class SpaceInviteBottomSheetViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpaceInviteBottomSheetState): SpaceInviteBottomSheetViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt index 8b423455cd..541d883405 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt @@ -30,7 +30,6 @@ import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.hideKeyboard diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt index ec7cb8d4c5..e9b75836e9 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedViewModel.kt @@ -126,7 +126,7 @@ class SpaceLeaveAdvancedViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpaceLeaveAdvanceViewState): SpaceLeaveAdvancedViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt index 05707df49e..8fa269d439 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt @@ -19,13 +19,10 @@ package im.vector.app.features.spaces.manage import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import androidx.paging.PagedList -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 dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -57,7 +54,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpaceAddRoomsState): SpaceAddRoomsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt index 9f41fea2ce..2dae088c2e 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt @@ -28,7 +28,6 @@ import com.airbnb.mvrx.withState import com.google.android.material.appbar.MaterialToolbar import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.hideKeyboard @@ -43,7 +42,6 @@ import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.alias.RoomAliasFragment import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment import kotlinx.parcelize.Parcelize -import javax.inject.Inject @Parcelize data class SpaceManageArgs( diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt index 469ece6cb0..a1dd26a936 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsViewModel.kt @@ -54,7 +54,7 @@ class SpaceManageRoomsViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpaceManageRoomViewState): SpaceManageRoomsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt index c05421a9a8..bedd1873e8 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageSharedViewModel.kt @@ -32,7 +32,7 @@ class SpaceManageSharedViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory{ + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpaceManageViewState): SpaceManageSharedViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt index 18bb6fa01a..c2ab015858 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt @@ -79,7 +79,6 @@ class SpaceSettingsFragment @Inject constructor( override fun getMenuRes() = R.menu.vector_room_settings - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupToolbar(views.roomSettingsToolbar) diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt index 89ce154021..6e14893f77 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt @@ -37,7 +37,6 @@ import im.vector.app.core.resources.DrawableProvider import im.vector.app.databinding.FragmentRecyclerviewWithSearchBinding import im.vector.app.features.roomprofile.members.RoomMemberListAction import im.vector.app.features.roomprofile.members.RoomMemberListViewModel -import im.vector.app.features.roomprofile.members.RoomMemberListViewState import io.reactivex.rxkotlin.subscribeBy import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import java.util.concurrent.TimeUnit diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt index 126539589d..55d1dbe61e 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleViewModel.kt @@ -42,7 +42,7 @@ class SpacePeopleViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpacePeopleViewState): SpacePeopleViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt index e63fdc638b..8d34ad94d8 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt @@ -17,14 +17,11 @@ package im.vector.app.features.spaces.preview 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.Uninitialized -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -60,7 +57,7 @@ class SpacePreviewViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SpacePreviewState): SpacePreviewViewModel } diff --git a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceBottomSheet.kt b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceBottomSheet.kt index a4386441d9..6a98aa3cf8 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceBottomSheet.kt @@ -27,17 +27,15 @@ import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.databinding.BottomSheetSpaceInviteBinding import im.vector.app.features.invite.InviteUsersToRoomActivity import kotlinx.parcelize.Parcelize -import javax.inject.Inject @AndroidEntryPoint -class ShareSpaceBottomSheet : VectorBaseBottomSheetDialogFragment(){ +class ShareSpaceBottomSheet : VectorBaseBottomSheetDialogFragment() { @Parcelize data class Args( diff --git a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt index 174edf309e..c624f1ed46 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/share/ShareSpaceViewModel.kt @@ -37,7 +37,7 @@ class ShareSpaceViewModel @AssistedInject constructor( private val session: Session) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: ShareSpaceViewState): ShareSpaceViewModel } diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt index 2a4ae5e46b..0efb6119af 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsActivity.kt @@ -22,7 +22,6 @@ 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.error.ErrorFormatter import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.replaceFragment diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt index 508d0210e5..9932efb11a 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsViewModel.kt @@ -36,7 +36,7 @@ class ReviewTermsViewModel @AssistedInject constructor( ) : VectorViewModel(initialState) { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: ReviewTermsViewState): ReviewTermsViewModel } diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt index 11128b7cf9..7fa7a45131 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt @@ -30,7 +30,6 @@ 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.extensions.commitTransaction import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity @@ -38,7 +37,6 @@ import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.matrixto.MatrixToBottomSheet import kotlinx.parcelize.Parcelize -import javax.inject.Inject import kotlin.reflect.KClass @AndroidEntryPoint diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt index f38fb9f3f9..64bcf9cead 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeSharedViewModel.kt @@ -56,7 +56,7 @@ class UserCodeSharedViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: UserCodeState): UserCodeSharedViewModel } diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index 1b5a6390b0..fde69ce9ba 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -17,11 +17,8 @@ package im.vector.app.features.userdirectory import androidx.lifecycle.asFlow -import com.airbnb.mvrx.ActivityViewModelContext -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Uninitialized -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -63,7 +60,7 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User private val identityServerUsersSearch = MutableStateFlow("") @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: UserListViewState): UserListViewModel } diff --git a/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt b/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt index 77e56716a5..ab7913a99c 100644 --- a/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt @@ -20,10 +20,8 @@ import android.content.Context import android.content.Intent import android.webkit.WebChromeClient import android.webkit.WebView -import androidx.annotation.CallSuper import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.di.ActiveSessionHolder - import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityVectorWebViewBinding import org.matrix.android.sdk.api.session.Session diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt index 914bc62d65..a31edfcb02 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt @@ -25,7 +25,6 @@ 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.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity @@ -33,10 +32,8 @@ import im.vector.app.databinding.ActivityWidgetBinding import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewEvents import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewModel -import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewState import org.matrix.android.sdk.api.session.events.model.Content import java.io.Serializable -import javax.inject.Inject @AndroidEntryPoint class WidgetActivity : VectorBaseActivity(), diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt index e137165c3e..20fae6e31a 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetViewModel.kt @@ -17,13 +17,10 @@ package im.vector.app.features.widgets import android.net.Uri -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 dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -59,7 +56,7 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi IntegrationManagerService.Listener { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: WidgetViewState): WidgetViewModel } diff --git a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt index 9744bb6d20..ae3028925a 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt @@ -28,7 +28,6 @@ import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.extensions.withArgs import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetRoomWidgetPermissionBinding diff --git a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt index 236bfb4032..f29e6d1928 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionViewModel.kt @@ -15,8 +15,6 @@ */ package im.vector.app.features.widgets.permissions -import com.airbnb.mvrx.ActivityViewModelContext -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MavericksViewModelFactory import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -142,7 +140,7 @@ class RoomWidgetPermissionViewModel @AssistedInject constructor(@Assisted val in } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel } diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt index 7c8904135c..eeadd45d13 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/ServerBackupStatusViewModel.kt @@ -17,13 +17,10 @@ package im.vector.app.features.workers.signout import androidx.lifecycle.MutableLiveData -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.Uninitialized -import com.airbnb.mvrx.ViewModelContext import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -69,7 +66,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS VectorViewModel(initialState), KeysBackupStateListener { @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: ServerBackupStatusViewState): ServerBackupStatusViewModel } diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt index f6e30b8693..5d38dac15f 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt @@ -33,7 +33,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R - import im.vector.app.core.dialogs.ExportKeysDialog import im.vector.app.core.extensions.queryExportKeys import im.vector.app.core.extensions.registerStartForActivityResult @@ -43,12 +42,11 @@ import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity import im.vector.app.features.crypto.recover.BootstrapBottomSheet import im.vector.app.features.crypto.recover.SetupMode import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState -import javax.inject.Inject // TODO this needs to be refactored to current standard and remove legacy @AndroidEntryPoint class SignOutBottomSheetDialogFragment : - VectorBaseBottomSheetDialogFragment(){ + VectorBaseBottomSheetDialogFragment() { var onSignOut: Runnable? = null diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt index ac3efe56db..4daaef6fe1 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignoutCheckViewModel.kt @@ -17,15 +17,12 @@ package im.vector.app.features.workers.signout import android.net.Uri -import com.airbnb.mvrx.ActivityViewModelContext import com.airbnb.mvrx.Async -import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory 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 @@ -68,7 +65,7 @@ class SignoutCheckViewModel @AssistedInject constructor( } @AssistedFactory - interface Factory: MavericksAssistedViewModelFactory { + interface Factory : MavericksAssistedViewModelFactory { override fun create(initialState: SignoutCheckViewState): SignoutCheckViewModel } From c87d276f8ac0d5392333bf9f4b0d46ec1be73297 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Oct 2021 18:09:14 +0200 Subject: [PATCH 017/413] Hilt: fix fdroid --- .../troubleshoot/TestBackgroundRestrictions.kt | 4 ++-- .../settings/troubleshoot/TestBatteryOptimization.kt | 4 ++-- .../app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt | 7 +++---- .../receiver/OnApplicationUpgradeOrRebootReceiver.kt | 11 ++++------- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt b/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt index 3725fc828d..b5635e186c 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt +++ b/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBackgroundRestrictions.kt @@ -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) { diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBatteryOptimization.kt b/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBatteryOptimization.kt index b1eeae6681..a5154c7483 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBatteryOptimization.kt +++ b/vector/src/fdroid/java/im/vector/app/fdroid/features/settings/troubleshoot/TestBatteryOptimization.kt @@ -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) { diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt b/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt index b94e99208b..0f375561b2 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt +++ b/vector/src/fdroid/java/im/vector/app/fdroid/receiver/AlarmSyncBroadcastReceiver.kt @@ -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.") } diff --git a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/OnApplicationUpgradeOrRebootReceiver.kt b/vector/src/fdroid/java/im/vector/app/fdroid/receiver/OnApplicationUpgradeOrRebootReceiver.kt index 797b5734a2..935d7e6e13 100644 --- a/vector/src/fdroid/java/im/vector/app/fdroid/receiver/OnApplicationUpgradeOrRebootReceiver.kt +++ b/vector/src/fdroid/java/im/vector/app/fdroid/receiver/OnApplicationUpgradeOrRebootReceiver.kt @@ -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() ) - } } } From e1f4e4f934ee7ab88f73f5bc8fdf9f223d4d2275 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Oct 2021 18:38:48 +0200 Subject: [PATCH 018/413] Hilt: fix test --- .../quads/SharedSecureStorageViewModelTest.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/vector/src/test/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModelTest.kt b/vector/src/test/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModelTest.kt index 0fff663972..506ac9c7d0 100644 --- a/vector/src/test/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModelTest.kt @@ -46,6 +46,7 @@ class SharedSecureStorageViewModelTest { private val stringProvider = FakeStringProvider() private val session = FakeSession() + val args = SharedSecureStorageActivity.Args(keyId = null, emptyList(), "alias") @Test fun `given a key info with passphrase when initialising then step is EnterPassphrase`() { @@ -123,14 +124,15 @@ class SharedSecureStorageViewModelTest { test.assertEvents(SharedSecureStorageViewEvent.Dismiss) } - private fun createViewModel() = SharedSecureStorageViewModel( - SharedSecureStorageViewState(), - SharedSecureStorageActivity.Args(keyId = null, emptyList(), "alias"), - stringProvider.instance, - session - ) + private fun createViewModel(): SharedSecureStorageViewModel { + return SharedSecureStorageViewModel( + SharedSecureStorageViewState(args), + stringProvider.instance, + session + ) + } - private fun aViewState(hasPassphrase: Boolean, step: SharedSecureStorageViewState.Step) = SharedSecureStorageViewState( + private fun aViewState(hasPassphrase: Boolean, step: SharedSecureStorageViewState.Step) = SharedSecureStorageViewState(args).copy( ready = true, hasPassphrase = hasPassphrase, checkingSSSSAction = Uninitialized, From 9ed8d5b22ed91db8aae6403d21dd98275ff6935b Mon Sep 17 00:00:00 2001 From: Szimszon Date: Fri, 22 Oct 2021 13:59:01 +0000 Subject: [PATCH 019/413] Translated using Weblate (Hungarian) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/hu/ --- fastlane/metadata/android/hu-HU/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40103040.txt diff --git a/fastlane/metadata/android/hu-HU/changelogs/40103040.txt b/fastlane/metadata/android/hu-HU/changelogs/40103040.txt new file mode 100644 index 0000000000..de2e859028 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: Állapot állítási lehetőség közvetlen beszélgetéseknél (megj.: a matrix.org-on az állapot jelzés ki van kapcsolva). Újra elérhető az Android Auto. +Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From cc96c0398dae697a1e4fd96f7b1d0dae3a3d405e Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Fri, 22 Oct 2021 09:31:50 +0000 Subject: [PATCH 020/413] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/pt_BR/ --- fastlane/metadata/android/pt-BR/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40103040.txt diff --git a/fastlane/metadata/android/pt-BR/changelogs/40103040.txt b/fastlane/metadata/android/pt-BR/changelogs/40103040.txt new file mode 100644 index 0000000000..b713e0418f --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Adicionar suporte a Presença, para sala de Mensagem Direta (nota: presença está desabilitada em matrix.org). Adicionar de novo suporte a Android Auto. +Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From 7e4a115bfbc133622cbfe829271f30565f46a8ac Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Fri, 22 Oct 2021 21:22:49 +0000 Subject: [PATCH 021/413] Translated using Weblate (Swedish) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/ --- fastlane/metadata/android/sv-SE/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sv-SE/changelogs/40103040.txt diff --git a/fastlane/metadata/android/sv-SE/changelogs/40103040.txt b/fastlane/metadata/android/sv-SE/changelogs/40103040.txt new file mode 100644 index 0000000000..faec3bef4d --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Lägg till närvarostöd för direktmeddelanden (obs: närvaro är inaktiverat på matrix.org). Lägg till stöd för Android Auto igen. +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From 028d3182461133aa2e6d7a52b744f494f9937bc5 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 22 Oct 2021 22:28:02 +0000 Subject: [PATCH 022/413] Translated using Weblate (Ukrainian) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40103040.txt diff --git a/fastlane/metadata/android/uk/changelogs/40103040.txt b/fastlane/metadata/android/uk/changelogs/40103040.txt new file mode 100644 index 0000000000..3e65e0bc07 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Додано підтримку присутності для кімнати особистих повідомлень (примітка: присутність вимкнено на matrix.org. Знову додано підтримку Android Auto. +Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From 63ca323d9234a0ffd141678395535f6f6c652cea Mon Sep 17 00:00:00 2001 From: sr093906 Date: Sat, 23 Oct 2021 04:42:33 +0000 Subject: [PATCH 023/413] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hans/ --- fastlane/metadata/android/zh-CN/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/zh-CN/changelogs/40103040.txt diff --git a/fastlane/metadata/android/zh-CN/changelogs/40103040.txt b/fastlane/metadata/android/zh-CN/changelogs/40103040.txt new file mode 100644 index 0000000000..0c3d4d57c3 --- /dev/null +++ b/fastlane/metadata/android/zh-CN/changelogs/40103040.txt @@ -0,0 +1,2 @@ +此版本主要变化:为 Direct Message 聊天室添加 Presence 支持 (注意:Presence 在matrix.org 上是禁用的。再次添加 Android Auto 支持。 +完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.3.4 From 359b8e215867dac0debde4f2af6a7fb1e60a8d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sat, 23 Oct 2021 21:33:37 +0000 Subject: [PATCH 024/413] Translated using Weblate (Estonian) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40103040.txt diff --git a/fastlane/metadata/android/et/changelogs/40103040.txt b/fastlane/metadata/android/et/changelogs/40103040.txt new file mode 100644 index 0000000000..2ede9de81e --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: Lisasime otsevestlustele kasutaja võrguolekute toe (matrix.org puhul on välja lülitatud) ja uuesti lisasime Android Auto toe. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From 91500dc7cbc99d636c9055ead42a5d90fbb77bdc Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Fri, 22 Oct 2021 09:28:30 +0000 Subject: [PATCH 025/413] Translated using Weblate (Czech) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/cs/ --- fastlane/metadata/android/cs-CZ/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40103040.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40103040.txt b/fastlane/metadata/android/cs-CZ/changelogs/40103040.txt new file mode 100644 index 0000000000..ac909485d7 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Přidání podpory přítomnosti pro místnost s přímými zprávami (poznámka: přítomnost je na matrix.org zakázána). Opět přidána podpora Android Auto. +Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From ff04337e0482b2a4a000c8e3dbb18fe075eb0f7c Mon Sep 17 00:00:00 2001 From: Linerly Date: Sat, 23 Oct 2021 05:55:05 +0000 Subject: [PATCH 026/413] Translated using Weblate (Indonesian) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/id/changelogs/40103040.txt diff --git a/fastlane/metadata/android/id/changelogs/40103040.txt b/fastlane/metadata/android/id/changelogs/40103040.txt new file mode 100644 index 0000000000..60e2e3a4de --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Perubahan utama di versi ini: Menambahkan dukungan presensi, untuk ruangan Pesan Langsung (diingat bahwa presensi dinonaktifkan di matrix.org). Menambahkan lagi dukungan Android Auto. +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From d4b010bad772de71c9399d2aefbacf37bd975089 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Fri, 22 Oct 2021 11:48:22 +0000 Subject: [PATCH 027/413] Translated using Weblate (Albanian) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/ --- fastlane/metadata/android/sq/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sq/changelogs/40103040.txt diff --git a/fastlane/metadata/android/sq/changelogs/40103040.txt b/fastlane/metadata/android/sq/changelogs/40103040.txt new file mode 100644 index 0000000000..7f37e82801 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Shtim mbulimi për Prani, për dhomë Mesazh i Drejtpërdrejtë (shënim: në matrix.org prania është e çaktivizuar. Shtim sërish i mbulimit për Android Auto. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From 79d56319b74325f499450f4799973de6eeda906a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 12:40:24 +0200 Subject: [PATCH 028/413] Version++ --- matrix-sdk-android/build.gradle | 2 +- vector/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index c92d735fac..e3d0f273b8 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -31,7 +31,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.3.5\"" + buildConfigField "String", "SDK_VERSION", "\"1.3.6\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" resValue "string", "git_sdk_revision", "\"${gitRevision()}\"" diff --git a/vector/build.gradle b/vector/build.gradle index 254bf3873c..eed3e7909e 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -14,7 +14,7 @@ kapt { // Note: 2 digits max for each value ext.versionMajor = 1 ext.versionMinor = 3 -ext.versionPatch = 5 +ext.versionPatch = 6 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From 3e03db200c306ac1e0ef01af5c92453caa0deb8f Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 25 Oct 2021 14:47:57 +0300 Subject: [PATCH 029/413] Add poll icon to attachment type selector. --- .../attachments/AttachmentTypeSelectorView.kt | 5 +++- .../ic_attachment_poll_white_24dp.xml | 10 +++++++ .../layout/view_attachment_type_selector.xml | 30 +++++++++++++++++++ vector/src/main/res/values/strings.xml | 1 + 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 vector/src/main/res/drawable/ic_attachment_poll_white_24dp.xml diff --git a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt index 35644e1843..6c349d18dc 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt @@ -75,6 +75,7 @@ class AttachmentTypeSelectorView(context: Context, views.attachmentStickersButton.configure(Type.STICKER) views.attachmentAudioButton.configure(Type.AUDIO) views.attachmentContactButton.configure(Type.CONTACT) + views.attachmentPollButton.configure(Type.POLL) width = LinearLayout.LayoutParams.MATCH_PARENT height = LinearLayout.LayoutParams.WRAP_CONTENT animationStyle = 0 @@ -108,6 +109,7 @@ class AttachmentTypeSelectorView(context: Context, animateButtonIn(views.attachmentAudioButton, 0) animateButtonIn(views.attachmentContactButton, ANIMATION_DURATION / 4) animateButtonIn(views.attachmentStickersButton, ANIMATION_DURATION / 2) + animateButtonIn(views.attachmentPollButton, ANIMATION_DURATION / 4) } override fun dismiss() { @@ -212,6 +214,7 @@ class AttachmentTypeSelectorView(context: Context, FILE(PERMISSIONS_EMPTY), STICKER(PERMISSIONS_EMPTY), AUDIO(PERMISSIONS_EMPTY), - CONTACT(PERMISSIONS_FOR_PICKING_CONTACT) + CONTACT(PERMISSIONS_FOR_PICKING_CONTACT), + POLL(PERMISSIONS_EMPTY) } } diff --git a/vector/src/main/res/drawable/ic_attachment_poll_white_24dp.xml b/vector/src/main/res/drawable/ic_attachment_poll_white_24dp.xml new file mode 100644 index 0000000000..8cbcc6e47c --- /dev/null +++ b/vector/src/main/res/drawable/ic_attachment_poll_white_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/vector/src/main/res/layout/view_attachment_type_selector.xml b/vector/src/main/res/layout/view_attachment_type_selector.xml index 648ca91820..22ed6ec0e9 100644 --- a/vector/src/main/res/layout/view_attachment_type_selector.xml +++ b/vector/src/main/res/layout/view_attachment_type_selector.xml @@ -163,5 +163,35 @@ + + + + + + + + + + + diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 274753ee3f..02b27b1a94 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2429,6 +2429,7 @@ "Audio" "Gallery" "Sticker" + Poll Rotate and crop Couldn\'t handle share data From 363ae79378b2999c6710f86cd2e4f2286c2f5189 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 15:32:27 +0200 Subject: [PATCH 030/413] DI: Use interfaces instead of implementation --- .../android/sdk/internal/crypto/tasks/SendEventTask.kt | 2 +- .../internal/crypto/tasks/SendVerificationMessageTask.kt | 2 +- .../sdk/internal/database/mapper/RoomSummaryMapper.kt | 4 ++-- .../matrix/android/sdk/internal/session/DefaultSession.kt | 6 +++--- .../android/sdk/internal/session/content/FileUploader.kt | 4 ++-- .../sdk/internal/session/identity/DefaultIdentityService.kt | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt index e1e297767b..e40db6af67 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendEventTask.kt @@ -34,7 +34,7 @@ internal interface SendEventTask : Task { internal class DefaultSendEventTask @Inject constructor( private val localEchoRepository: LocalEchoRepository, - private val encryptEventTask: DefaultEncryptEventTask, + private val encryptEventTask: EncryptEventTask, private val loadRoomMembersTask: LoadRoomMembersTask, private val roomAPI: RoomAPI, private val globalErrorReceiver: GlobalErrorReceiver) : SendEventTask { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt index 7fa48c3da1..c4a6ba27d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendVerificationMessageTask.kt @@ -34,7 +34,7 @@ internal interface SendVerificationMessageTask : Task, private val accountService: Lazy, private val eventService: Lazy, - private val defaultIdentityService: DefaultIdentityService, + private val identityService: IdentityService, private val integrationManagerService: IntegrationManagerService, private val thirdPartyService: Lazy, private val callSignalingService: Lazy, @@ -275,7 +275,7 @@ internal class DefaultSession @Inject constructor( override fun cryptoService(): CryptoService = cryptoService.get() - override fun identityService() = defaultIdentityService + override fun identityService() = identityService override fun fileService(): FileService = defaultFileService.get() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt index bdebb0addf..1b0ccbb489 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/FileUploader.kt @@ -35,12 +35,12 @@ import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities +import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.internal.di.Authenticated import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.ProgressRequestBody import org.matrix.android.sdk.internal.network.awaitResponse import org.matrix.android.sdk.internal.network.toFailure -import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapabilitiesService import org.matrix.android.sdk.internal.util.TemporaryFileCreator import java.io.File import java.io.FileNotFoundException @@ -50,7 +50,7 @@ import javax.inject.Inject internal class FileUploader @Inject constructor( @Authenticated private val okHttpClient: OkHttpClient, private val globalErrorReceiver: GlobalErrorReceiver, - private val homeServerCapabilitiesService: DefaultHomeServerCapabilitiesService, + private val homeServerCapabilitiesService: HomeServerCapabilitiesService, private val context: Context, private val temporaryFileCreator: TemporaryFileCreator, contentUrlResolver: ContentUrlResolver, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt index 37d9a4e74f..c8a9c0f09a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt @@ -80,7 +80,7 @@ internal class DefaultIdentityService @Inject constructor( private val identityApiProvider: IdentityApiProvider, private val accountDataDataSource: UserAccountDataDataSource, private val homeServerCapabilitiesService: HomeServerCapabilitiesService, - private val sign3pidInvitationTask: DefaultSign3pidInvitationTask, + private val sign3pidInvitationTask: Sign3pidInvitationTask, private val sessionParams: SessionParams ) : IdentityService, SessionLifecycleObserver { From 4af42902a08246c229993e90f2942b497978cb83 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 25 Oct 2021 16:41:37 +0300 Subject: [PATCH 031/413] Create poll screen components implemented. --- vector/src/main/AndroidManifest.xml | 1 + .../im/vector/app/core/di/ScreenComponent.kt | 2 + .../features/createpoll/CreatePollAction.kt | 22 ++++++++ .../features/createpoll/CreatePollActivity.kt | 51 +++++++++++++++++++ .../createpoll/CreatePollViewEvents.kt | 21 ++++++++ .../createpoll/CreatePollViewModel.kt | 51 +++++++++++++++++++ .../createpoll/CreatePollViewState.kt | 23 +++++++++ .../home/room/detail/RoomDetailFragment.kt | 1 + .../features/navigation/DefaultNavigator.kt | 6 +++ .../app/features/navigation/Navigator.kt | 2 + 10 files changed, 180 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/createpoll/CreatePollAction.kt create mode 100644 vector/src/main/java/im/vector/app/features/createpoll/CreatePollActivity.kt create mode 100644 vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewEvents.kt create mode 100644 vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewModel.kt create mode 100644 vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewState.kt diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 376e0e869a..cf8e1b92da 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -339,6 +339,7 @@ + diff --git a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt index 76b511d2bd..07b3ae02b7 100644 --- a/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt +++ b/vector/src/main/java/im/vector/app/core/di/ScreenComponent.kt @@ -31,6 +31,7 @@ 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.createpoll.CreatePollActivity 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 @@ -174,6 +175,7 @@ interface ScreenComponent { fun inject(activity: SpaceManageActivity) fun inject(activity: RoomJoinRuleActivity) fun inject(activity: SpaceLeaveAdvancedActivity) + fun inject(activity: CreatePollActivity) /* ========================================================================================== * BottomSheets diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollAction.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollAction.kt new file mode 100644 index 0000000000..ad8da6e208 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollAction.kt @@ -0,0 +1,22 @@ +/* + * 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.features.createpoll + +import im.vector.app.core.platform.VectorViewModelAction + +sealed class CreatePollAction : VectorViewModelAction { +} diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollActivity.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollActivity.kt new file mode 100644 index 0000000000..2aefdb51d7 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollActivity.kt @@ -0,0 +1,51 @@ +/* + * 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.features.createpoll + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.view.View +import com.airbnb.mvrx.viewModel +import im.vector.app.core.di.ScreenComponent +import im.vector.app.core.platform.SimpleFragmentActivity +import javax.inject.Inject + +class CreatePollActivity : SimpleFragmentActivity(), CreatePollViewModel.Factory { + + private val viewModel: CreatePollViewModel by viewModel() + @Inject lateinit var viewModelFactory: CreatePollViewModel.Factory + + override fun injectWith(injector: ScreenComponent) { + super.injectWith(injector) + injector.inject(this) + } + + override fun create(initialState: CreatePollViewState) = viewModelFactory.create(initialState) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + views.toolbar.visibility = View.GONE + } + + companion object { + + fun getIntent(context: Context): Intent { + return Intent(context, CreatePollActivity::class.java) + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewEvents.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewEvents.kt new file mode 100644 index 0000000000..8541a1d482 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewEvents.kt @@ -0,0 +1,21 @@ +/* + * 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.features.createpoll + +import im.vector.app.core.platform.VectorViewEvents + +sealed class CreatePollViewEvents : VectorViewEvents diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewModel.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewModel.kt new file mode 100644 index 0000000000..a93285dfc2 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewModel.kt @@ -0,0 +1,51 @@ +/* + * 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.features.createpoll + +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.platform.VectorViewModel + +class CreatePollViewModel @AssistedInject constructor(@Assisted + initialState: CreatePollViewState) : + VectorViewModel(initialState) { + + @AssistedFactory + interface Factory { + fun create(initialState: CreatePollViewState): CreatePollViewModel + } + + companion object : MavericksViewModelFactory { + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: CreatePollViewState): CreatePollViewModel { + 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") + } + } + + override fun handle(action: CreatePollAction) { + } +} diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewState.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewState.kt new file mode 100644 index 0000000000..f53e7b2843 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewState.kt @@ -0,0 +1,23 @@ +/* + * 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.features.createpoll + +import com.airbnb.mvrx.MavericksState + +data class CreatePollViewState( + val question: String = "" +) : MavericksState diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index fa0ca24289..d275dccf39 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -2145,6 +2145,7 @@ class RoomDetailFragment @Inject constructor( AttachmentTypeSelectorView.Type.AUDIO -> attachmentsHelper.selectAudio(attachmentAudioActivityResultLauncher) AttachmentTypeSelectorView.Type.CONTACT -> attachmentsHelper.selectContact(attachmentContactActivityResultLauncher) AttachmentTypeSelectorView.Type.STICKER -> roomDetailViewModel.handle(RoomDetailAction.SelectStickerAttachment) + AttachmentTypeSelectorView.Type.POLL -> navigator.openCreatePoll(requireContext()) }.exhaustive } diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index debdf3739c..d727f24ade 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -40,6 +40,7 @@ import im.vector.app.features.call.conference.JitsiCallViewModel 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.createpoll.CreatePollActivity import im.vector.app.features.crypto.keysbackup.settings.KeysBackupManageActivity import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity import im.vector.app.features.crypto.recover.BootstrapBottomSheet @@ -498,6 +499,11 @@ class DefaultNavigator @Inject constructor( context.startActivity(intent) } + override fun openCreatePoll(context: Context) { + val intent = CreatePollActivity.getIntent(context) + context.startActivity(intent) + } + private fun startActivity(context: Context, intent: Intent, buildTask: Boolean) { if (buildTask) { val stackBuilder = TaskStackBuilder.create(context) diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index 612643c804..0ff17887f9 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -140,4 +140,6 @@ interface Navigator { fun openDevTools(context: Context, roomId: String) fun openCallTransfer(context: Context, callId: String) + + fun openCreatePoll(context: Context) } From d0f226dcd1d90ca462253cd05fbf0de4d97322dc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 15:47:17 +0200 Subject: [PATCH 032/413] Bind identity service --- .../android/sdk/internal/session/identity/IdentityModule.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt index 19e602d7a7..65794e6b14 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityModule.kt @@ -21,6 +21,7 @@ import dagger.Module import dagger.Provides import io.realm.RealmConfiguration import okhttp3.OkHttpClient +import org.matrix.android.sdk.api.session.identity.IdentityService import org.matrix.android.sdk.internal.database.RealmKeysUtils import org.matrix.android.sdk.internal.di.AuthenticatedIdentity import org.matrix.android.sdk.internal.di.IdentityDatabase @@ -75,6 +76,9 @@ internal abstract class IdentityModule { } } + @Binds + abstract fun bindIdentityService(service: DefaultIdentityService): IdentityService + @Binds @AuthenticatedIdentity abstract fun bindAccessTokenProvider(provider: IdentityAccessTokenProvider): AccessTokenProvider From cb1d5e888d27a1309a5f36c6ddbffdcf5701601f Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 25 Oct 2021 20:14:10 +0300 Subject: [PATCH 033/413] Create poll fragment with a title. --- .../im/vector/app/core/di/FragmentModule.kt | 6 ++ .../features/createpoll/CreatePollActivity.kt | 9 +++ .../features/createpoll/CreatePollFragment.kt | 41 ++++++++++++ .../main/res/layout/fragment_create_poll.xml | 63 +++++++++++++++++++ vector/src/main/res/values/strings.xml | 3 + 5 files changed, 122 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/createpoll/CreatePollFragment.kt create mode 100644 vector/src/main/res/layout/fragment_create_poll.xml diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 3bc8e30851..45f29aa43d 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -24,6 +24,7 @@ import dagger.Module import dagger.multibindings.IntoMap import im.vector.app.features.attachments.preview.AttachmentsPreviewFragment import im.vector.app.features.contactsbook.ContactsBookFragment +import im.vector.app.features.createpoll.CreatePollFragment import im.vector.app.features.crypto.keysbackup.settings.KeysBackupSettingsFragment import im.vector.app.features.crypto.quads.SharedSecuredStorageKeyFragment import im.vector.app.features.crypto.quads.SharedSecuredStoragePassphraseFragment @@ -834,4 +835,9 @@ interface FragmentModule { @IntoMap @FragmentKey(SpaceLeaveAdvancedFragment::class) fun bindSpaceLeaveAdvancedFragment(fragment: SpaceLeaveAdvancedFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(CreatePollFragment::class) + fun bindCreatePollFragment(fragment: CreatePollFragment): Fragment } diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollActivity.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollActivity.kt index 2aefdb51d7..c325cd0609 100644 --- a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollActivity.kt @@ -21,7 +21,9 @@ import android.content.Intent import android.os.Bundle import android.view.View import com.airbnb.mvrx.viewModel +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 javax.inject.Inject @@ -40,6 +42,13 @@ class CreatePollActivity : SimpleFragmentActivity(), CreatePollViewModel.Factory override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) views.toolbar.visibility = View.GONE + + if (isFirstCreation()) { + addFragment( + R.id.container, + CreatePollFragment::class.java + ) + } } companion object { diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollFragment.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollFragment.kt new file mode 100644 index 0000000000..706d58e489 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollFragment.kt @@ -0,0 +1,41 @@ +/* + * 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.features.createpoll + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentCreatePollBinding +import javax.inject.Inject + +class CreatePollFragment @Inject constructor() : VectorBaseFragment() { + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentCreatePollBinding { + return FragmentCreatePollBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + vectorBaseActivity.setSupportActionBar(views.createPollToolbar) + + views.createPollClose.debouncedClicks { + requireActivity().finish() + } + } +} diff --git a/vector/src/main/res/layout/fragment_create_poll.xml b/vector/src/main/res/layout/fragment_create_poll.xml new file mode 100644 index 0000000000..76c744c6c5 --- /dev/null +++ b/vector/src/main/res/layout/fragment_create_poll.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 02b27b1a94..86dc7153a5 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3625,4 +3625,7 @@ Link this email with your account %s in Settings to receive invites directly in Element. + + + Create Poll From c90dbf2f38c7fdc3f58cda79d50c23004013db03 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Oct 2021 11:55:52 +0100 Subject: [PATCH 034/413] allowing null users in the email search, fixes missing indentity server helpers when inviting by email --- .../vector/app/features/userdirectory/UserListViewModel.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index fde69ce9ba..8b32bddca2 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -177,11 +177,9 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User private suspend fun executeSearchEmail(search: String) { suspend { val params = listOf(ThreePid.Email(search)) - val foundThreePid = tryOrNull { - session.identityService().lookUp(params).firstOrNull() - } + val foundThreePid = session.identityService().lookUp(params).firstOrNull() if (foundThreePid == null) { - null + ThreePidUser(email = search, user = null) } else { try { val json = session.getProfile(foundThreePid.matrixId) From 10df75bd57ab2effbccbb03f1f10fa4180fd00a3 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Oct 2021 12:25:17 +0100 Subject: [PATCH 035/413] allowing the re-emission of identical search terms, fixes the finish setup/give consent steps from not properly updating the UI - also captures the fragmet resumed event in order to handle returning from the settings page and applying a identity server --- .../features/userdirectory/UserListAction.kt | 1 + .../userdirectory/UserListFragment.kt | 5 +++ .../userdirectory/UserListViewModel.kt | 36 +++++++++++++++---- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListAction.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListAction.kt index 83829c1119..86de26ac23 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListAction.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListAction.kt @@ -25,4 +25,5 @@ sealed class UserListAction : VectorViewModelAction { data class RemovePendingSelection(val pendingSelection: PendingSelection) : UserListAction() object ComputeMatrixToLinkForSharing : UserListAction() data class UpdateUserConsent(val consent: Boolean) : UserListAction() + object Resumed : UserListAction() } diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt index aed134816a..8935f93671 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt @@ -222,6 +222,11 @@ class UserListFragment @Inject constructor( ) } + override fun onResume() { + super.onResume() + viewModel.handle(UserListAction.Resumed) + } + override fun giveIdentityServerConsent() { withState(viewModel) { state -> requireContext().showIdentityServerConsentDialog( diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index 8b32bddca2..5798fb86f1 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -17,6 +17,7 @@ package im.vector.app.features.userdirectory import androidx.lifecycle.asFlow +import com.airbnb.mvrx.Fail import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Uninitialized import dagger.assisted.Assisted @@ -40,6 +41,7 @@ import kotlinx.coroutines.flow.sample import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.IdentityServiceListener import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.profile.ProfileService @@ -57,7 +59,7 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User private val knownUsersSearch = MutableStateFlow("") private val directoryUsersSearch = MutableStateFlow("") - private val identityServerUsersSearch = MutableStateFlow("") + private val identityServerUsersSearch = MutableStateFlow(UserSearch(searchTerm = "")) @AssistedFactory interface Factory : MavericksAssistedViewModelFactory { @@ -69,7 +71,7 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User private val identityServerListener = object : IdentityServiceListener { override fun onIdentityServerChange() { withState { - identityServerUsersSearch.tryEmit(it.searchTerm) + identityServerUsersSearch.tryEmit(UserSearch(it.searchTerm)) val identityServerURL = cleanISURL(session.identityService().getCurrentIdentityServerUrl()) setState { copy(configuredIdentityServer = identityServerURL) @@ -105,16 +107,29 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User is UserListAction.RemovePendingSelection -> handleRemoveSelectedUser(action) UserListAction.ComputeMatrixToLinkForSharing -> handleShareMyMatrixToLink() is UserListAction.UpdateUserConsent -> handleISUpdateConsent(action) + UserListAction.Resumed -> handleResumed() }.exhaustive } private fun handleISUpdateConsent(action: UserListAction.UpdateUserConsent) { session.identityService().setUserConsent(action.consent) withState { - identityServerUsersSearch.tryEmit(it.searchTerm) + retryUserSearch(it) } } + private fun handleResumed() { + withState { + if (it.hasNoIdentityServerConfigured()) { + retryUserSearch(it) + } + } + } + + private fun retryUserSearch(state: UserListViewState) { + identityServerUsersSearch.tryEmit(UserSearch(state.searchTerm, cacheBuster = System.currentTimeMillis())) + } + private fun handleSearchUsers(searchTerm: String) { setState { copy( @@ -130,7 +145,7 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User ) } } - identityServerUsersSearch.tryEmit(searchTerm) + identityServerUsersSearch.tryEmit(UserSearch(searchTerm)) knownUsersSearch.tryEmit(searchTerm) directoryUsersSearch.tryEmit(searchTerm) } @@ -144,7 +159,7 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User private fun handleClearSearchUsers() { knownUsersSearch.tryEmit("") directoryUsersSearch.tryEmit("") - identityServerUsersSearch.tryEmit("") + identityServerUsersSearch.tryEmit(UserSearch("")) setState { copy(searchTerm = "") } @@ -152,10 +167,10 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User private fun observeUsers() = withState { state -> identityServerUsersSearch - .filter { it.isEmail() } + .filter { it.searchTerm.isEmail() } .sample(300) .onEach { search -> - executeSearchEmail(search) + executeSearchEmail(search.searchTerm) }.launchIn(viewModelScope) knownUsersSearch @@ -239,3 +254,10 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User setState { copy(pendingSelections = selections) } } } + +private fun UserListViewState.hasNoIdentityServerConfigured() = matchingEmail is Fail && matchingEmail.error == IdentityServiceError.NoIdentityServerConfigured + +/** + * Wrapper class to allow identical search terms to be re-emitted + */ +private data class UserSearch(val searchTerm: String, val cacheBuster: Long = 0) From c936954119b920eb14fc6a9734599f0ed54f2700 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 26 Oct 2021 14:24:23 +0200 Subject: [PATCH 036/413] Flow migration: start replacing Rx by Flow --- vector/build.gradle | 3 - .../java/im/vector/app/AppStateHandler.kt | 20 +- .../app/core/platform/VectorBaseActivity.kt | 12 +- .../VectorBaseBottomSheetDialogFragment.kt | 12 +- .../app/core/platform/VectorBaseFragment.kt | 14 +- .../app/core/platform/VectorViewModel.kt | 40 +--- .../im/vector/app/core/utils/DataSource.kt | 26 +-- .../features/call/CallControlsBottomSheet.kt | 2 +- .../app/features/call/VectorCallActivity.kt | 14 +- .../call/conference/VectorJitsiActivity.kt | 2 +- .../createdirect/CreateDirectRoomActivity.kt | 9 +- .../quads/SharedSecureStorageActivity.kt | 2 +- .../SharedSecuredStorageResetAllFragment.kt | 2 +- .../features/devtools/RoomDevToolActivity.kt | 2 +- .../vector/app/features/home/HomeActivity.kt | 12 +- .../app/features/home/HomeDetailFragment.kt | 2 +- .../app/features/home/HomeDetailViewModel.kt | 30 +-- .../home/PromoteRestrictedViewModel.kt | 1 + .../home/UnreadMessagesSharedViewModel.kt | 172 +++++++++--------- .../home/room/detail/RoomDetailActivity.kt | 9 +- .../home/room/detail/RoomDetailFragment.kt | 8 +- .../home/room/detail/RoomDetailViewModel.kt | 19 +- .../detail/composer/TextComposerViewModel.kt | 2 +- .../reactions/ViewReactionsViewModel.kt | 52 +++--- .../home/room/list/RoomListFragment.kt | 9 +- .../home/room/list/RoomListSectionBuilder.kt | 2 - .../room/list/RoomListSectionBuilderGroup.kt | 32 ++-- .../room/list/RoomListSectionBuilderSpace.kt | 54 +++--- .../home/room/list/RoomListViewModel.kt | 5 +- .../invite/InviteUsersToRoomActivity.kt | 9 +- .../app/features/invite/InvitesAcceptor.kt | 12 +- .../app/features/login/LoginActivity.kt | 7 +- .../app/features/login2/LoginActivity2.kt | 13 +- .../powerlevel/PowerLevelsFlowFactory.kt | 2 +- .../room/RequireActiveMembershipViewModel.kt | 2 +- .../roomdirectory/RoomDirectoryActivity.kt | 9 +- .../createroom/CreateRoomActivity.kt | 9 +- .../createroom/CreateRoomFragment.kt | 9 +- .../roomprofile/RoomProfileActivity.kt | 9 +- .../roomprofile/RoomProfileFragment.kt | 9 +- .../roomprofile/alias/RoomAliasFragment.kt | 9 +- .../members/RoomMemberListViewModel.kt | 1 - .../settings/RoomSettingsFragment.kt | 15 +- .../VectorSettingsSecurityPrivacyFragment.kt | 4 +- .../settings/devices/DevicesViewModel.kt | 12 +- .../signout/soft/SoftLogoutActivity.kt | 2 +- .../signout/soft/SoftLogoutActivity2.kt | 2 +- .../signout/soft/SoftLogoutFragment.kt | 2 +- .../features/spaces/SpaceCreationActivity.kt | 2 +- .../app/features/spaces/SpaceListViewModel.kt | 17 +- .../features/spaces/SpacePreviewActivity.kt | 9 +- .../CreateSpaceAdd3pidInvitesFragment.kt | 2 +- .../create/CreateSpaceDefaultRoomsFragment.kt | 2 +- .../create/CreateSpaceDetailsFragment.kt | 2 +- .../leave/SpaceLeaveAdvancedActivity.kt | 2 +- .../spaces/manage/SpaceManageActivity.kt | 9 +- .../spaces/manage/SpaceSettingsFragment.kt | 9 +- .../spaces/people/SpacePeopleActivity.kt | 9 +- .../spaces/people/SpacePeopleFragment.kt | 2 +- .../userdirectory/UserListViewModel.kt | 4 +- .../java/im/vector/app/test/Extensions.kt | 8 +- 61 files changed, 408 insertions(+), 375 deletions(-) diff --git a/vector/build.gradle b/vector/build.gradle index 5f032e55c2..35d1acfe8b 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -388,9 +388,6 @@ dependencies { kapt libs.airbnb.epoxyProcessor implementation libs.airbnb.epoxyPaging implementation libs.airbnb.mavericks - //TODO: remove when entirely migrated to Flow - implementation libs.airbnb.mavericksRx - // Work implementation libs.androidx.work diff --git a/vector/src/main/java/im/vector/app/AppStateHandler.kt b/vector/src/main/java/im/vector/app/AppStateHandler.kt index 30078963f4..650047787e 100644 --- a/vector/src/main/java/im/vector/app/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/app/AppStateHandler.kt @@ -25,12 +25,19 @@ import im.vector.app.core.utils.BehaviorDataSource import im.vector.app.features.session.coroutineScope import im.vector.app.features.ui.UiStateRepository import io.reactivex.disposables.CompositeDisposable +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session 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.api.util.CancelableBag import javax.inject.Inject import javax.inject.Singleton @@ -54,10 +61,10 @@ class AppStateHandler @Inject constructor( private val activeSessionHolder: ActiveSessionHolder ) : LifecycleObserver { - private val compositeDisposable = CompositeDisposable() + private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) private val selectedSpaceDataSource = BehaviorDataSource>(Option.empty()) - val selectedRoomGroupingObservable = selectedSpaceDataSource.observe() + val selectedRoomGroupingObservable = selectedSpaceDataSource.stream() fun getCurrentRoomGroupingMethod(): RoomGroupingMethod? { // XXX we should somehow make it live :/ just a work around @@ -105,9 +112,9 @@ class AppStateHandler @Inject constructor( } private fun observeActiveSession() { - sessionDataSource.observe() + sessionDataSource.stream() .distinctUntilChanged() - .subscribe { + .onEach { // sessionDataSource could already return a session while activeSession holder still returns null it.orNull()?.let { session -> if (uiStateRepository.isGroupingMethodSpace(session.sessionId)) { @@ -116,9 +123,8 @@ class AppStateHandler @Inject constructor( setCurrentGroup(uiStateRepository.getSelectedGroup(session.sessionId), session) } } - }.also { - compositeDisposable.add(it) } + .launchIn(coroutineScope) } fun safeActiveSpaceId(): String? { @@ -136,7 +142,7 @@ class AppStateHandler @Inject constructor( @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun entersBackground() { - compositeDisposable.clear() + coroutineScope.coroutineContext.cancelChildren() val session = activeSessionHolder.getSafeActiveSession() ?: return when (val currentMethod = selectedSpaceDataSource.currentValue?.orNull() ?: RoomGroupingMethod.BySpace(null)) { is RoomGroupingMethod.BySpace -> { diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 4d06dbe6a2..a28d9fa355 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -39,6 +39,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentFactory import androidx.fragment.app.FragmentManager import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.MavericksView import com.bumptech.glide.util.Util @@ -80,6 +81,10 @@ import im.vector.app.receivers.DebugReceiver import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.GlobalError import timber.log.Timber @@ -104,13 +109,12 @@ abstract class VectorBaseActivity : AppCompatActivity(), Maver protected fun VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) { viewEvents - .observe() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { + .stream() + .onEach { hideWaitingView() observer(it) } - .disposeOnDestroy() + .launchIn(lifecycleScope) } /* ========================================================================================== diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index 711b2b144b..04a34a8876 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -26,6 +26,7 @@ import android.view.ViewGroup import android.widget.FrameLayout import androidx.annotation.CallSuper import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.MavericksView @@ -39,6 +40,10 @@ import im.vector.app.core.utils.DimensionConverter import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import java.util.concurrent.TimeUnit @@ -193,11 +198,10 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomShe protected fun VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) { viewEvents - .observe() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { + .stream() + .onEach { observer(it) } - .disposeOnDestroyView() + .launchIn(viewLifecycleOwner.lifecycleScope) } } diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index d3c66ec61d..7dce2bc954 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -29,6 +29,7 @@ import androidx.annotation.MainThread import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.MavericksView import com.bumptech.glide.util.Util.assertMainThread @@ -47,6 +48,12 @@ import im.vector.lib.ui.styles.dialogs.MaterialProgressDialog import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach import timber.log.Timber import java.util.concurrent.TimeUnit @@ -237,13 +244,12 @@ abstract class VectorBaseFragment : Fragment(), MavericksView protected fun VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) { viewEvents - .observe() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { + .stream() + .onEach { dismissLoadingDialog() observer(it) } - .disposeOnDestroyView() + .launchIn(viewLifecycleOwner.lifecycleScope) } /* ========================================================================================== diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt b/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt index 6e7c24d4e9..c9d58f9545 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorViewModel.kt @@ -16,53 +16,17 @@ package im.vector.app.core.platform -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.BaseMvRxViewModel -import com.airbnb.mvrx.Fail -import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksState -import com.airbnb.mvrx.Success +import com.airbnb.mvrx.MavericksViewModel import im.vector.app.core.utils.DataSource import im.vector.app.core.utils.PublishDataSource -import io.reactivex.Observable -import io.reactivex.Single abstract class VectorViewModel(initialState: S) : - BaseMvRxViewModel(initialState) { - - interface Factory { - fun create(state: S): BaseMvRxViewModel - } + MavericksViewModel(initialState) { // Used to post transient events to the View protected val _viewEvents = PublishDataSource() val viewEvents: DataSource = _viewEvents - /** - * This method does the same thing as the execute function, but it doesn't subscribe to the stream - * so you can use this in a switchMap or a flatMap - */ - // False positive - @Suppress("USELESS_CAST", "NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER") - fun Single.toAsync(stateReducer: S.(Async) -> S): Single> { - setState { stateReducer(Loading()) } - return map { Success(it) as Async } - .onErrorReturn { Fail(it) } - .doOnSuccess { setState { stateReducer(it) } } - } - - /** - * This method does the same thing as the execute function, but it doesn't subscribe to the stream - * so you can use this in a switchMap or a flatMap - */ - // False positive - @Suppress("USELESS_CAST", "NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER") - fun Observable.toAsync(stateReducer: S.(Async) -> S): Observable> { - setState { stateReducer(Loading()) } - return map { Success(it) as Async } - .onErrorReturn { Fail(it) } - .doOnNext { setState { stateReducer(it) } } - } - abstract fun handle(action: VA) } diff --git a/vector/src/main/java/im/vector/app/core/utils/DataSource.kt b/vector/src/main/java/im/vector/app/core/utils/DataSource.kt index fc4ee330bb..6338768723 100644 --- a/vector/src/main/java/im/vector/app/core/utils/DataSource.kt +++ b/vector/src/main/java/im/vector/app/core/utils/DataSource.kt @@ -17,12 +17,12 @@ package im.vector.app.core.utils import com.jakewharton.rxrelay2.BehaviorRelay -import com.jakewharton.rxrelay2.PublishRelay -import io.reactivex.Observable -import io.reactivex.android.schedulers.AndroidSchedulers +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow interface DataSource { - fun observe(): Observable + fun stream(): Flow } interface MutableDataSource : DataSource { @@ -34,17 +34,17 @@ interface MutableDataSource : DataSource { */ open class BehaviorDataSource(private val defaultValue: T? = null) : MutableDataSource { - private val behaviorRelay = createRelay() + private val mutableFlow = MutableSharedFlow(replay = 1) val currentValue: T? - get() = behaviorRelay.value + get() = mutableFlow.replayCache.firstOrNull() - override fun observe(): Observable { - return behaviorRelay.hide().observeOn(AndroidSchedulers.mainThread()) + override fun stream(): Flow { + return mutableFlow } override fun post(value: T) { - behaviorRelay.accept(value!!) + mutableFlow.tryEmit(value) } private fun createRelay(): BehaviorRelay { @@ -61,13 +61,13 @@ open class BehaviorDataSource(private val defaultValue: T? = null) : MutableD */ open class PublishDataSource : MutableDataSource { - private val publishRelay = PublishRelay.create() + private val mutableFlow = MutableSharedFlow(replay = 0, extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - override fun observe(): Observable { - return publishRelay.hide().observeOn(AndroidSchedulers.mainThread()) + override fun stream(): Flow { + return mutableFlow } override fun post(value: T) { - publishRelay.accept(value!!) + mutableFlow.tryEmit(value) } } diff --git a/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt index b4f49db781..e38b53c858 100644 --- a/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt @@ -39,7 +39,7 @@ class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment(), CallContro setSupportActionBar(views.callToolbar) configureCallViews() - callViewModel.subscribe(this) { + callViewModel.onEach { renderState(it) } @@ -141,12 +146,11 @@ class VectorCallActivity : VectorBaseActivity(), CallContro } callViewModel.viewEvents - .observe() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { + .stream() + .onEach { handleViewEvents(it) } - .disposeOnDestroy() + .launchIn(lifecycleScope) callViewModel.onEach(VectorCallViewState::callId, VectorCallViewState::isVideoCall) { _, isVideoCall -> if (isVideoCall) { diff --git a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt index 3fcefc9c8e..0fdfea8bff 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt @@ -68,7 +68,7 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMee override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - jitsiViewModel.subscribe(this) { + jitsiViewModel.onEach { renderState(it) } diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index 28da72714a..3ff989da5a 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -22,6 +22,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.view.View +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Async import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading @@ -46,6 +47,8 @@ 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 kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure import java.net.HttpURLConnection @@ -64,8 +67,8 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { sharedActionViewModel = viewModelProvider.get(UserListSharedActionViewModel::class.java) sharedActionViewModel - .observe() - .subscribe { action -> + .stream() + .onEach { action -> when (action) { UserListSharedAction.Close -> finish() UserListSharedAction.GoBack -> onBackPressed() @@ -74,7 +77,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { UserListSharedAction.AddByQrCode -> openAddByQrCode() }.exhaustive } - .disposeOnDestroy() + .launchIn(lifecycleScope) if (isFirstCreation()) { addFragment( R.id.container, diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt index 61c8ab8f0a..bb854aca26 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt @@ -63,7 +63,7 @@ class SharedSecureStorageActivity : viewModel.observeViewEvents { observeViewEvents(it) } - viewModel.subscribe(this) { renderState(it) } + viewModel.onEach { renderState(it) } } override fun onDestroy() { diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt index 670e5c610a..200b2b73c2 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt @@ -55,7 +55,7 @@ class SharedSecuredStorageResetAllFragment @Inject constructor() : } } - sharedViewModel.subscribe(this) { state -> + sharedViewModel.onEach { state -> views.ssssResetOtherDevices.setTextOrHide( state.activeDeviceCount .takeIf { it > 0 } diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt index 772ef99931..2c7a15e6ad 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt @@ -66,7 +66,7 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac override fun initUiAndData() { super.initUiAndData() - viewModel.subscribe(this) { + viewModel.onEach { renderState(it) } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index e8af044bbd..04ca25332f 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -73,6 +73,8 @@ 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.push.fcm.FcmHelper +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.initsync.SyncStatusService @@ -178,8 +180,8 @@ class HomeActivity : } sharedActionViewModel - .observe() - .subscribe { sharedAction -> + .stream() + .onEach { sharedAction -> when (sharedAction) { is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START) is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START) @@ -222,7 +224,7 @@ class HomeActivity : } }.exhaustive } - .disposeOnDestroy() + .launchIn(lifecycleScope) val args = intent.getParcelableExtra(Mavericks.KEY_ARG) @@ -243,13 +245,13 @@ class HomeActivity : is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it) }.exhaustive } - homeActivityViewModel.subscribe(this) { renderState(it) } + homeActivityViewModel.onEach { renderState(it) } shortcutsHandler.observeRoomsAndBuildShortcuts() .disposeOnDestroy() if (!vectorPreferences.didPromoteNewRestrictedFeature()) { - promoteRestrictedViewModel.subscribe(this) { + promoteRestrictedViewModel.onEach { if (it.activeSpaceSummary != null && !it.activeSpaceSummary.isPublic && it.activeSpaceSummary.otherMemberIds.isNotEmpty()) { // It's a private space with some members show this once diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index 80351a437e..55d8e2e09a 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -299,7 +299,7 @@ class HomeDetailFragment @Inject constructor( private fun setupKeysBackupBanner() { serverBackupStatusViewModel - .subscribe(this) { + .onEach { when (val banState = it.bannerState.invoke()) { is BannerState.Setup -> views.homeKeysBackupBanner.render(KeysBackupBanner.State.Setup(banState.numberOfKeys), false) BannerState.BackingUp -> views.homeKeysBackupBanner.render(KeysBackupBanner.State.BackingUp, false) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 73e50ad5f1..8bfc1a8db4 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -39,7 +39,13 @@ import im.vector.app.features.ui.UiStateRepository import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.sample +import kotlinx.coroutines.flow.switchMap import kotlinx.coroutines.launch import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.RoomCategoryFilter @@ -66,7 +72,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho private val directRoomHelper: DirectRoomHelper, private val appStateHandler: AppStateHandler, private val autoAcceptInvites: AutoAcceptInvites) : - VectorViewModel(initialState), + VectorViewModel(initialState), CallProtocolsChecker.Listener { @AssistedFactory @@ -194,18 +200,15 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho private fun observeRoomGroupingMethod() { appStateHandler.selectedRoomGroupingObservable - .subscribe { - setState { - copy( - roomGroupingMethod = it.orNull() ?: RoomGroupingMethod.BySpace(null) - ) - } + .setOnEach { + copy( + roomGroupingMethod = it.orNull() ?: RoomGroupingMethod.BySpace(null) + ) } - .disposeOnClear() } private fun observeRoomSummaries() { - appStateHandler.selectedRoomGroupingObservable.distinctUntilChanged().switchMap { + appStateHandler.selectedRoomGroupingObservable.distinctUntilChanged().flatMapLatest { // we use it as a trigger to all changes in room, but do not really load // the actual models session.getPagedRoomSummariesLive( @@ -213,11 +216,10 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho memberships = Membership.activeMemberships() }, sortOrder = RoomSortOrder.NONE - ).asObservable() + ).asFlow() } - .observeOn(Schedulers.computation()) - .throttleFirst(300, TimeUnit.MILLISECONDS) - .subscribe { + .sample(300) + .onEach { when (val groupingMethod = appStateHandler.getCurrentRoomGroupingMethod()) { is RoomGroupingMethod.ByLegacyGroup -> { // TODO!! @@ -274,6 +276,6 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho } } } - .disposeOnClear() + .launchIn(viewModelScope) } } diff --git a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt index 218574c03e..77ee23f732 100644 --- a/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/PromoteRestrictedViewModel.kt @@ -29,6 +29,7 @@ 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 +import kotlinx.coroutines.flow.distinctUntilChanged import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel diff --git a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt index 5bdbc95b48..3434f9dfb0 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt @@ -16,6 +16,7 @@ package im.vector.app.features.home +import androidx.lifecycle.asFlow import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory import dagger.assisted.Assisted @@ -30,8 +31,12 @@ import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.settings.VectorPreferences -import io.reactivex.Observable -import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.sample import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.RoomSortOrder @@ -57,7 +62,7 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia private val vectorPreferences: VectorPreferences, appStateHandler: AppStateHandler, private val autoAcceptInvites: AutoAcceptInvites) : - VectorViewModel(initialState) { + VectorViewModel(initialState) { @AssistedFactory interface Factory : MavericksAssistedViewModelFactory { @@ -75,8 +80,8 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia this.memberships = listOf(Membership.JOIN) this.activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(null) }, sortOrder = RoomSortOrder.NONE - ).asObservable() - .throttleFirst(300, TimeUnit.MILLISECONDS) + ).asFlow() + .sample(300) .execute { val counts = session.getNotificationCountForRooms( roomSummaryQueryParams { @@ -103,91 +108,92 @@ class UnreadMessagesSharedViewModel @AssistedInject constructor(@Assisted initia ) } - Observable.combineLatest( + combine( appStateHandler.selectedRoomGroupingObservable.distinctUntilChanged(), - appStateHandler.selectedRoomGroupingObservable.switchMap { + appStateHandler.selectedRoomGroupingObservable.flatMapLatest { session.getPagedRoomSummariesLive( roomSummaryQueryParams { this.memberships = Membership.activeMemberships() }, sortOrder = RoomSortOrder.NONE - ).asObservable() - .throttleFirst(300, TimeUnit.MILLISECONDS) - .observeOn(Schedulers.computation()) - }, - { groupingMethod, _ -> - when (groupingMethod.orNull()) { - is RoomGroupingMethod.ByLegacyGroup -> { - // currently not supported - CountInfo( - RoomAggregateNotificationCount(0, 0), - RoomAggregateNotificationCount(0, 0) - ) - } - is RoomGroupingMethod.BySpace -> { - val selectedSpace = appStateHandler.safeActiveSpaceId() + ).asFlow() + .sample(300) - val inviteCount = if (autoAcceptInvites.hideInvites) { - 0 - } else { - session.getRoomSummaries( - roomSummaryQueryParams { this.memberships = listOf(Membership.INVITE) } - ).size - } - - val spaceInviteCount = if (autoAcceptInvites.hideInvites) { - 0 - } else { - session.getRoomSummaries( - spaceSummaryQueryParams { - this.memberships = listOf(Membership.INVITE) - } - ).size - } - - val totalCount = session.getNotificationCountForRooms( - roomSummaryQueryParams { - this.memberships = listOf(Membership.JOIN) - this.activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(null).takeIf { - !vectorPreferences.prefSpacesShowAllRoomInHome() - } ?: ActiveSpaceFilter.None - } - ) - - val counts = RoomAggregateNotificationCount( - totalCount.notificationCount + inviteCount, - totalCount.highlightCount + inviteCount - ) - val rootCounts = session.spaceService().getRootSpaceSummaries() - .filter { - // filter out current selection - it.roomId != selectedSpace - } - - CountInfo( - homeCount = counts, - otherCount = RoomAggregateNotificationCount( - notificationCount = rootCounts.fold(0, { acc, rs -> acc + rs.notificationCount }) + - (counts.notificationCount.takeIf { selectedSpace != null } ?: 0) + - spaceInviteCount, - highlightCount = rootCounts.fold(0, { acc, rs -> acc + rs.highlightCount }) + - (counts.highlightCount.takeIf { selectedSpace != null } ?: 0) + - spaceInviteCount - ) - ) - } - null -> { - CountInfo( - RoomAggregateNotificationCount(0, 0), - RoomAggregateNotificationCount(0, 0) - ) - } - } } - ).execute { - copy( - homeSpaceUnread = it.invoke()?.homeCount ?: RoomAggregateNotificationCount(0, 0), - otherSpacesUnread = it.invoke()?.otherCount ?: RoomAggregateNotificationCount(0, 0) - ) + ) { groupingMethod, _ -> + when (groupingMethod.orNull()) { + is RoomGroupingMethod.ByLegacyGroup -> { + // currently not supported + CountInfo( + RoomAggregateNotificationCount(0, 0), + RoomAggregateNotificationCount(0, 0) + ) + } + is RoomGroupingMethod.BySpace -> { + val selectedSpace = appStateHandler.safeActiveSpaceId() + + val inviteCount = if (autoAcceptInvites.hideInvites) { + 0 + } else { + session.getRoomSummaries( + roomSummaryQueryParams { this.memberships = listOf(Membership.INVITE) } + ).size + } + + val spaceInviteCount = if (autoAcceptInvites.hideInvites) { + 0 + } else { + session.getRoomSummaries( + spaceSummaryQueryParams { + this.memberships = listOf(Membership.INVITE) + } + ).size + } + + val totalCount = session.getNotificationCountForRooms( + roomSummaryQueryParams { + this.memberships = listOf(Membership.JOIN) + this.activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(null).takeIf { + !vectorPreferences.prefSpacesShowAllRoomInHome() + } ?: ActiveSpaceFilter.None + } + ) + + val counts = RoomAggregateNotificationCount( + totalCount.notificationCount + inviteCount, + totalCount.highlightCount + inviteCount + ) + val rootCounts = session.spaceService().getRootSpaceSummaries() + .filter { + // filter out current selection + it.roomId != selectedSpace + } + + CountInfo( + homeCount = counts, + otherCount = RoomAggregateNotificationCount( + notificationCount = rootCounts.fold(0, { acc, rs -> acc + rs.notificationCount }) + + (counts.notificationCount.takeIf { selectedSpace != null } ?: 0) + + spaceInviteCount, + highlightCount = rootCounts.fold(0, { acc, rs -> acc + rs.highlightCount }) + + (counts.highlightCount.takeIf { selectedSpace != null } ?: 0) + + spaceInviteCount + ) + ) + } + null -> { + CountInfo( + RoomAggregateNotificationCount(0, 0), + RoomAggregateNotificationCount(0, 0) + ) + } + } } + .flowOn(Dispatchers.Default) + .execute { + copy( + homeSpaceUnread = it.invoke()?.homeCount ?: RoomAggregateNotificationCount(0, 0), + otherSpacesUnread = it.invoke()?.otherCount ?: RoomAggregateNotificationCount(0, 0) + ) + } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index ba53f75eca..415ca7bc04 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -24,6 +24,7 @@ import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.viewModel import com.google.android.material.appbar.MaterialToolbar @@ -40,6 +41,8 @@ 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 kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach @AndroidEntryPoint class RoomDetailActivity : @@ -97,13 +100,13 @@ class RoomDetailActivity : sharedActionViewModel = viewModelProvider.get(RoomDetailSharedActionViewModel::class.java) sharedActionViewModel - .observe() - .subscribe { sharedAction -> + .stream() + .onEach { sharedAction -> when (sharedAction) { is RoomDetailSharedAction.SwitchToRoom -> switchToRoom(sharedAction) } } - .disposeOnDestroy() + .launchIn(lifecycleScope) requireActiveMembershipViewModel.observeViewEvents { when (it) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index d20c9796d2..9b103cebb5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -184,6 +184,8 @@ import im.vector.app.features.widgets.WidgetActivity import im.vector.app.features.widgets.WidgetArgs import im.vector.app.features.widgets.WidgetKind import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import nl.dionsegijn.konfetti.models.Shape @@ -365,11 +367,11 @@ class RoomDetailFragment @Inject constructor( } sharedActionViewModel - .observe() - .subscribe { + .stream() + .onEach { handleActions(it) } - .disposeOnDestroyView() + .launchIn(viewLifecycleOwner.lifecycleScope) knownCallsViewModel .liveKnownCalls diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index 03bde7d4cc..ee929243b5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -27,7 +27,6 @@ import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext -import com.jakewharton.rxrelay2.BehaviorRelay import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -37,6 +36,7 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.mvrx.runCatchingToAsync import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider +import im.vector.app.core.utils.BehaviorDataSource import im.vector.app.features.attachments.toContentAttachmentData import im.vector.app.features.call.conference.ConferenceEvent import im.vector.app.features.call.conference.JitsiActiveConferenceHolder @@ -56,7 +56,6 @@ import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorDataStore import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.voice.VoicePlayerHelper -import io.reactivex.rxkotlin.subscribeBy import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.collect @@ -123,8 +122,8 @@ class RoomDetailViewModel @AssistedInject constructor( private val room = session.getRoom(initialState.roomId)!! private val eventId = initialState.eventId - private val invisibleEventsObservable = BehaviorRelay.create() - private val visibleEventsObservable = BehaviorRelay.create() + private val invisibleEventsSource = BehaviorDataSource() + private val visibleEventsSource = BehaviorDataSource() private var timelineEvents = MutableSharedFlow>(0) val timeline = timelineFactory.createTimeline(viewModelScope, room, eventId) @@ -562,7 +561,7 @@ class RoomDetailViewModel @AssistedInject constructor( } private fun handleEventInvisible(action: RoomDetailAction.TimelineEventTurnsInvisible) { - invisibleEventsObservable.accept(action) + invisibleEventsSource.post(action) } fun getMember(userId: String): RoomMemberSummary? { @@ -711,12 +710,12 @@ class RoomDetailViewModel @AssistedInject constructor( private fun handleEventVisible(action: RoomDetailAction.TimelineEventTurnsVisible) { viewModelScope.launch(Dispatchers.Default) { if (action.event.root.sendState.isSent()) { // ignore pending/local events - visibleEventsObservable.accept(action) + visibleEventsSource.post(action) } // We need to update this with the related m.replace also (to move read receipt) action.event.annotations?.editSummary?.sourceEvents?.forEach { room.getTimeLineEvent(it)?.let { event -> - visibleEventsObservable.accept(RoomDetailAction.TimelineEventTurnsVisible(event)) + visibleEventsSource.post(RoomDetailAction.TimelineEventTurnsVisible(event)) } } @@ -864,7 +863,9 @@ class RoomDetailViewModel @AssistedInject constructor( private fun observeEventDisplayedActions() { // We are buffering scroll events for one second // and keep the most recent one to set the read receipt on. - visibleEventsObservable + /* + visibleEventsSource + .stream() .buffer(1, TimeUnit.SECONDS) .filter { it.isNotEmpty() } .subscribeBy(onNext = { actions -> @@ -884,6 +885,8 @@ class RoomDetailViewModel @AssistedInject constructor( } }) .disposeOnClear() + + */ } private fun handleMarkAllAsRead() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt index e80f25de2f..3d7c4c71f9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewModel.kt @@ -104,7 +104,7 @@ class TextComposerViewModel @AssistedInject constructor( } private fun subscribeToStateInternal() { - selectSubscribe(TextComposerViewState::sendMode, TextComposerViewState::canSendMessage, TextComposerViewState::isVoiceRecording) { _, _, _ -> + onEach(TextComposerViewState::sendMode, TextComposerViewState::canSendMessage, TextComposerViewState::isVoiceRecording) { _, _, _ -> updateIsSendButtonVisibility(false) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt index 1f4d67db03..324164bf58 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsViewModel.kt @@ -32,17 +32,17 @@ import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs import io.reactivex.Observable -import io.reactivex.Single +import kotlinx.coroutines.flow.map import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.room.model.ReactionAggregatedSummary -import org.matrix.android.sdk.rx.RxRoom -import org.matrix.android.sdk.rx.unwrap +import org.matrix.android.sdk.flow.FlowRoom +import org.matrix.android.sdk.flow.flow +import org.matrix.android.sdk.flow.unwrap data class DisplayReactionsViewState( val eventId: String, val roomId: String, val mapReactionKeyToMemberList: Async> = Uninitialized) : - MavericksState { + MavericksState { constructor(args: TimelineEventFragmentArgs) : this(roomId = args.roomId, eventId = args.eventId) } @@ -81,39 +81,31 @@ class ViewReactionsViewModel @AssistedInject constructor(@Assisted } private fun observeEventAnnotationSummaries() { - RxRoom(room) + room.flow() .liveAnnotationSummary(eventId) .unwrap() - .flatMapSingle { summaries -> - Observable - .fromIterable(summaries.reactionsSummary) - // .filter { reactionAggregatedSummary -> isSingleEmoji(reactionAggregatedSummary.key) } - .toReactionInfoList() + .map { annotationsSummary -> + annotationsSummary.reactionsSummary + .flatMap { reactionsSummary -> + reactionsSummary.sourceEvents.map { + val event = room.getTimeLineEvent(it) + ?: throw RuntimeException("Your eventId is not valid") + ReactionInfo( + event.root.eventId!!, + reactionsSummary.key, + event.root.senderId ?: "", + event.senderInfo.disambiguatedDisplayName, + dateFormatter.format(event.root.originServerTs, DateFormatKind.DEFAULT_DATE_AND_TIME) + + ) + } + } } .execute { copy(mapReactionKeyToMemberList = it) } } - private fun Observable.toReactionInfoList(): Single> { - return flatMap { summary -> - Observable - .fromIterable(summary.sourceEvents) - .map { - val event = room.getTimeLineEvent(it) - ?: throw RuntimeException("Your eventId is not valid") - ReactionInfo( - event.root.eventId!!, - summary.key, - event.root.senderId ?: "", - event.senderInfo.disambiguatedDisplayName, - dateFormatter.format(event.root.originServerTs, DateFormatKind.DEFAULT_DATE_AND_TIME) - - ) - } - }.toList() - } - override fun handle(action: EmptyAction) { // No op } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index 1c173e12e8..0e049e22b1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -23,6 +23,7 @@ import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -49,6 +50,8 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.app.features.home.room.list.widget.NotifsFabMenuView import im.vector.app.features.notifications.NotificationDrawerManager +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.extensions.orTrue import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -118,9 +121,9 @@ class RoomListFragment @Inject constructor( views.createChatFabMenu.listener = this sharedActionViewModel - .observe() - .subscribe { handleQuickActions(it) } - .disposeOnDestroyView() + .stream() + .onEach { handleQuickActions(it) } + .launchIn(viewLifecycleOwner.lifecycleScope) roomListViewModel.onEach(RoomListViewState::roomMembershipChanges) { ms -> // it's for invites local echo diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt index 2b3152f8cf..c98f613c40 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilder.kt @@ -20,6 +20,4 @@ import im.vector.app.features.home.RoomListDisplayMode interface RoomListSectionBuilder { fun buildSections(mode: RoomListDisplayMode): List - - fun dispose() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt index f101669af3..58db2a4030 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt @@ -17,6 +17,7 @@ package im.vector.app.features.home.room.list import androidx.annotation.StringRes +import androidx.lifecycle.asFlow import im.vector.app.AppStateHandler import im.vector.app.R import im.vector.app.RoomGroupingMethod @@ -24,17 +25,21 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.invite.showInvites -import io.reactivex.disposables.CompositeDisposable -import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.query.RoomTagQueryFilter import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.rx.asObservable class RoomListSectionBuilderGroup( + private val coroutineScope: CoroutineScope, private val session: Session, private val stringProvider: StringProvider, private val appStateHandler: AppStateHandler, @@ -42,8 +47,6 @@ class RoomListSectionBuilderGroup( private val onUpdatable: (UpdatableLivePageResult) -> Unit ) : RoomListSectionBuilder { - private val disposables = CompositeDisposable() - override fun buildSections(mode: RoomListDisplayMode): List { val activeGroupAwareQueries = mutableListOf() val sections = mutableListOf() @@ -103,16 +106,14 @@ class RoomListSectionBuilderGroup( appStateHandler.selectedRoomGroupingObservable .distinctUntilChanged() - .subscribe { groupingMethod -> + .onEach { groupingMethod -> val selectedGroupId = (groupingMethod.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId activeGroupAwareQueries.onEach { updater -> updater.updateQuery { query -> query.copy(activeGroupId = selectedGroupId) } } - }.also { - disposables.add(it) - } + }.launchIn(coroutineScope) return sections } @@ -251,15 +252,14 @@ class RoomListSectionBuilderGroup( }.livePagedList .let { livePagedList -> // use it also as a source to update count - livePagedList.asObservable() - .observeOn(Schedulers.computation()) - .subscribe { + livePagedList.asFlow() + .onEach { sections.find { it.sectionName == name } ?.notificationCount ?.postValue(session.getNotificationCountForRooms(roomQueryParams)) - }.also { - disposables.add(it) } + .flowOn(Dispatchers.Default) + .launchIn(coroutineScope) sections.add( RoomsSection( @@ -280,8 +280,4 @@ class RoomListSectionBuilderGroup( .build() .let { block(it) } } - - override fun dispose() { - disposables.dispose() - } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt index 7063281853..0bf7087618 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt @@ -19,6 +19,7 @@ package im.vector.app.features.home.room.list import androidx.annotation.StringRes import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.asFlow import androidx.lifecycle.liveData import androidx.paging.PagedList import com.airbnb.mvrx.Async @@ -31,10 +32,17 @@ import im.vector.app.features.invite.showInvites import im.vector.app.space import io.reactivex.Observable import io.reactivex.disposables.CompositeDisposable -import io.reactivex.rxkotlin.Observables import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.RoomCategoryFilter @@ -45,6 +53,7 @@ import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount import org.matrix.android.sdk.rx.asObservable +import timber.log.Timber class RoomListSectionBuilderSpace( private val session: Session, @@ -57,8 +66,6 @@ class RoomListSectionBuilderSpace( private val onlyOrphansInHome: Boolean = false ) : RoomListSectionBuilder { - private val disposables = CompositeDisposable() - private val pagedListConfig = PagedList.Config.Builder() .setPageSize(10) .setInitialLoadSizeHint(20) @@ -132,14 +139,12 @@ class RoomListSectionBuilderSpace( appStateHandler.selectedRoomGroupingObservable .distinctUntilChanged() - .subscribe { groupingMethod -> + .onEach { groupingMethod -> val selectedSpace = groupingMethod.orNull()?.space() activeSpaceAwareQueries.onEach { updater -> updater.updateForSpaceId(selectedSpace?.roomId) } - }.also { - disposables.add(it) - } + }.launchIn(viewModelScope) return sections } @@ -221,13 +226,13 @@ class RoomListSectionBuilderSpace( } // add suggested rooms - val suggestedRoomsObservable = // MutableLiveData>() + val suggestedRoomsFlow = // MutableLiveData>() appStateHandler.selectedRoomGroupingObservable .distinctUntilChanged() - .switchMap { groupingMethod -> + .flatMapLatest { groupingMethod -> val selectedSpace = groupingMethod.orNull()?.space() if (selectedSpace == null) { - Observable.just(emptyList()) + flowOf(emptyList()) } else { liveData(context = viewModelScope.coroutineContext + Dispatchers.IO) { val spaceSum = tryOrNull { @@ -240,24 +245,23 @@ class RoomListSectionBuilderSpace( session.getRoomSummary(it.childRoomId)?.membership?.isActive() != true } emit(filtered) - }.asObservable() + }.asFlow() } } val liveSuggestedRooms = MutableLiveData() - Observables.combineLatest( - suggestedRoomsObservable, - suggestedRoomJoiningState.asObservable() + combine( + suggestedRoomsFlow, + suggestedRoomJoiningState.asFlow() ) { rooms, joinStates -> SuggestedRoomInfo( rooms, joinStates ) - }.subscribe { + }.onEach { liveSuggestedRooms.postValue(it) - }.also { - disposables.add(it) - } + }.launchIn(viewModelScope) + sections.add( RoomsSection( sectionName = stringProvider.getString(R.string.suggested_header), @@ -373,9 +377,9 @@ class RoomListSectionBuilderSpace( }.livePagedList .let { livePagedList -> // use it also as a source to update count - livePagedList.asObservable() - .observeOn(Schedulers.computation()) - .subscribe { + livePagedList.asFlow() + .onEach { + Timber.v("Thread space list: ${Thread.currentThread()}") sections.find { it.sectionName == name } ?.notificationCount ?.postValue( @@ -387,9 +391,9 @@ class RoomListSectionBuilderSpace( ) } ) - }.also { - disposables.add(it) } + .flowOn(Dispatchers.Default) + .launchIn(viewModelScope) sections.add( RoomsSection( @@ -432,8 +436,4 @@ class RoomListSectionBuilderSpace( RoomListViewModel.SpaceFilterStrategy.NONE -> this } } - - override fun dispose() { - disposables.dispose() - } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 89f5aec8fb..2fd55eb7e5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -135,6 +135,7 @@ class RoomListViewModel @AssistedInject constructor( ) } else { RoomListSectionBuilderGroup( + viewModelScope, session, stringProvider, appStateHandler, @@ -336,8 +337,4 @@ class RoomListViewModel @AssistedInject constructor( } } - override fun onCleared() { - super.onCleared() - roomListSectionBuilder.dispose() - } } diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt index 6f4aff0041..1bf1c12a48 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt @@ -21,6 +21,7 @@ import android.content.Intent import android.os.Bundle import android.os.Parcelable import android.view.View +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.viewModel import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -41,6 +42,8 @@ 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 kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.failure.Failure import java.net.HttpURLConnection @@ -63,8 +66,8 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() { sharedActionViewModel = viewModelProvider.get(UserListSharedActionViewModel::class.java) sharedActionViewModel - .observe() - .subscribe { sharedAction -> + .stream() + .onEach { sharedAction -> when (sharedAction) { UserListSharedAction.Close -> finish() UserListSharedAction.GoBack -> onBackPressed() @@ -75,7 +78,7 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() { } } } - .disposeOnDestroy() + .launchIn(lifecycleScope) if (isFirstCreation()) { addFragment( R.id.container, diff --git a/vector/src/main/java/im/vector/app/features/invite/InvitesAcceptor.kt b/vector/src/main/java/im/vector/app/features/invite/InvitesAcceptor.kt index 09eff756d5..a1cc6d6d5e 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InvitesAcceptor.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InvitesAcceptor.kt @@ -19,10 +19,14 @@ package im.vector.app.features.invite import im.vector.app.ActiveSessionDataSource import im.vector.app.features.session.coroutineScope import io.reactivex.disposables.Disposable +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -51,7 +55,8 @@ class InvitesAcceptor @Inject constructor( private val autoAcceptInvites: AutoAcceptInvites ) : Session.Listener { - private lateinit var activeSessionDisposable: Disposable + private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + private val shouldRejectRoomIds = mutableSetOf() private val activeSessionIds = mutableSetOf() private val semaphore = Semaphore(1) @@ -61,13 +66,14 @@ class InvitesAcceptor @Inject constructor( } private fun observeActiveSession() { - activeSessionDisposable = sessionDataSource.observe() + sessionDataSource.stream() .distinctUntilChanged() - .subscribe { + .onEach { it.orNull()?.let { session -> onSessionActive(session) } } + .launchIn(coroutineScope) } private fun onSessionActive(session: Session) { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index b3606a68ca..bcde8fd37e 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -85,10 +85,9 @@ open class LoginActivity : VectorBaseActivity(), ToolbarCo addFirstFragment() } - loginViewModel - .subscribe(this) { - updateWithState(it) - } + loginViewModel.onEach { + updateWithState(it) + } loginViewModel.observeViewEvents { handleLoginViewEvents(it) } diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt index 40dd1d2872..8f1b20aa7f 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginActivity2.kt @@ -92,10 +92,9 @@ open class LoginActivity2 : VectorBaseActivity(), ToolbarC addFirstFragment() } - loginViewModel - .subscribe(this) { - updateWithState(it) - } + loginViewModel.onEach { + updateWithState(it) + } loginViewModel.observeViewEvents { handleLoginViewEvents(it) } @@ -201,19 +200,19 @@ open class LoginActivity2 : VectorBaseActivity(), ToolbarC // Go back to the login fragment supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE) } - is LoginViewEvents2.OnSendEmailSuccess -> + is LoginViewEvents2.OnSendEmailSuccess -> addFragmentToBackstack(R.id.loginFragmentContainer, LoginWaitForEmailFragment2::class.java, LoginWaitForEmailFragmentArgument(event.email), tag = FRAGMENT_REGISTRATION_STAGE_TAG, option = commonOption) - is LoginViewEvents2.OpenSigninPasswordScreen -> { + is LoginViewEvents2.OpenSigninPasswordScreen -> { addFragmentToBackstack(R.id.loginFragmentContainer, LoginFragmentSigninPassword2::class.java, tag = FRAGMENT_LOGIN_TAG, option = commonOption) } - is LoginViewEvents2.OpenSignupPasswordScreen -> { + is LoginViewEvents2.OpenSignupPasswordScreen -> { addFragmentToBackstack(R.id.loginFragmentContainer, LoginFragmentSignupPassword2::class.java, tag = FRAGMENT_REGISTRATION_STAGE_TAG, diff --git a/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt b/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt index 767d6f1ba7..d8857b3be3 100644 --- a/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt +++ b/vector/src/main/java/im/vector/app/features/powerlevel/PowerLevelsFlowFactory.kt @@ -33,8 +33,8 @@ class PowerLevelsFlowFactory(private val room: Room) { fun createFlow(): Flow { return room.flow() .liveStateEvent(EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) - .flowOn(Dispatchers.Default) .mapOptional { it.content.toModel() } + .flowOn(Dispatchers.Default) .unwrap() } } diff --git a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt index 6ad93abe0c..d2ee3a56ec 100644 --- a/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/room/RequireActiveMembershipViewModel.kt @@ -77,8 +77,8 @@ class RequireActiveMembershipViewModel @AssistedInject constructor( room.flow() .liveRoomSummary() .unwrap() - .flowOn(Dispatchers.Default) .map { mapToLeftViewEvent(room, it) } + .flowOn(Dispatchers.Default) } .unwrap() .onEach { event -> diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt index dd4011a865..e59cfafa42 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt @@ -19,6 +19,7 @@ package im.vector.app.features.roomdirectory import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.viewModel import com.airbnb.mvrx.withState import dagger.hilt.android.AndroidEntryPoint @@ -31,6 +32,8 @@ import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.roomdirectory.createroom.CreateRoomArgs import im.vector.app.features.roomdirectory.createroom.CreateRoomFragment import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerFragment +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import javax.inject.Inject @AndroidEntryPoint @@ -53,8 +56,8 @@ class RoomDirectoryActivity : VectorBaseActivity() { } sharedActionViewModel - .observe() - .subscribe { sharedAction -> + .stream() + .onEach { sharedAction -> when (sharedAction) { is RoomDirectorySharedAction.Back -> popBackstack() is RoomDirectorySharedAction.CreateRoom -> { @@ -72,7 +75,7 @@ class RoomDirectoryActivity : VectorBaseActivity() { is RoomDirectorySharedAction.Close -> finish() } } - .disposeOnDestroy() + .launchIn(lifecycleScope) } override fun initUiAndData() { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt index eeb7d217c0..b3a21dadb9 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt @@ -19,6 +19,7 @@ package im.vector.app.features.roomdirectory.createroom import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.lifecycle.lifecycleScope import com.google.android.material.appbar.MaterialToolbar import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R @@ -28,6 +29,8 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.roomdirectory.RoomDirectorySharedAction import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach /** * Simple container for [CreateRoomFragment] @@ -62,14 +65,14 @@ class CreateRoomActivity : VectorBaseActivity(), ToolbarC super.onCreate(savedInstanceState) sharedActionViewModel = viewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) sharedActionViewModel - .observe() - .subscribe { sharedAction -> + .stream() + .onEach { sharedAction -> when (sharedAction) { is RoomDirectorySharedAction.Back, is RoomDirectorySharedAction.Close -> finish() } } - .disposeOnDestroy() + .launchIn(lifecycleScope) } companion object { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt index c61da211a4..1244a0f64e 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt @@ -23,6 +23,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success import com.airbnb.mvrx.args @@ -44,6 +45,8 @@ import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleBottomSheet import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleSharedActionViewModel import im.vector.app.features.roomprofile.settings.joinrule.toOption +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure import org.matrix.android.sdk.api.session.room.model.RoomJoinRules @@ -103,11 +106,11 @@ class CreateRoomFragment @Inject constructor( private fun setupRoomJoinRuleSharedActionViewModel() { roomJoinRuleSharedActionViewModel = activityViewModelProvider.get(RoomJoinRuleSharedActionViewModel::class.java) roomJoinRuleSharedActionViewModel - .observe() - .subscribe { action -> + .stream() + .onEach { action -> viewModel.handle(CreateRoomAction.SetVisibility(action.roomJoinRule)) } - .disposeOnDestroyView() + .launchIn(viewLifecycleOwner.lifecycleScope) } override fun showFailure(throwable: Throwable) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt index fdb639e7d6..c06a2927c5 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileActivity.kt @@ -20,6 +20,7 @@ package im.vector.app.features.roomprofile import android.content.Context import android.content.Intent import android.widget.Toast +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.viewModel import com.google.android.material.appbar.MaterialToolbar @@ -41,6 +42,8 @@ import im.vector.app.features.roomprofile.notifications.RoomNotificationSettings import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import javax.inject.Inject @AndroidEntryPoint @@ -93,8 +96,8 @@ class RoomProfileActivity : } } sharedActionViewModel - .observe() - .subscribe { sharedAction -> + .stream() + .onEach { sharedAction -> when (sharedAction) { RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers() RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings() @@ -105,7 +108,7 @@ class RoomProfileActivity : RoomProfileSharedAction.OpenRoomNotificationSettings -> openRoomNotificationSettings() }.exhaustive } - .disposeOnDestroy() + .launchIn(lifecycleScope) requireActiveMembershipViewModel.observeViewEvents { when (it) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 23234f8bbd..e1a5cae907 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -26,6 +26,7 @@ import android.view.ViewGroup import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.view.isVisible import androidx.fragment.app.setFragmentResultListener +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -52,6 +53,8 @@ import im.vector.app.features.home.room.list.actions.RoomListActionsArgs import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import org.matrix.android.sdk.api.util.toMatrixItem @@ -124,9 +127,9 @@ class RoomProfileFragment @Inject constructor( }.exhaustive } roomListQuickActionsSharedActionViewModel - .observe() - .subscribe { handleQuickActions(it) } - .disposeOnDestroyView() + .stream() + .onEach { handleQuickActions(it) } + .launchIn(viewLifecycleOwner.lifecycleScope) setupClicks() setupLongClicks() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt index e281c0f84d..15686a6848 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt @@ -21,6 +21,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -38,6 +39,8 @@ import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheet import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedAction import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.session.room.alias.RoomAliasError import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility import org.matrix.android.sdk.api.util.toMatrixItem @@ -77,9 +80,9 @@ class RoomAliasFragment @Inject constructor( } sharedActionViewModel - .observe() - .subscribe { handleAliasAction(it) } - .disposeOnDestroyView() + .stream() + .onEach { handleAliasAction(it) } + .launchIn(viewLifecycleOwner.lifecycleScope) } private fun handleAliasAction(action: RoomAliasBottomSheetSharedAction?) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt index adf5a31f2a..1ea9d59229 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt @@ -95,7 +95,6 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState if (room.isEncrypted()) { room.flow().liveRoomMembers(roomMemberQueryParams) - .flowOn(Dispatchers.Main) .flatMapLatest { membersSummary -> session.cryptoService().getLiveCryptoDeviceInfo(membersSummary.map { it.userId }) .asFlow() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt index ce059881b8..0a5f8f4d9a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt @@ -24,6 +24,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -46,6 +47,8 @@ import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistory import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistoryVisibilitySharedActionViewModel import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleActivity import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleSharedActionViewModel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.util.toMatrixItem import java.util.UUID @@ -101,21 +104,21 @@ class RoomSettingsFragment @Inject constructor( private fun setupRoomJoinRuleSharedActionViewModel() { roomJoinRuleSharedActionViewModel = activityViewModelProvider.get(RoomJoinRuleSharedActionViewModel::class.java) roomJoinRuleSharedActionViewModel - .observe() - .subscribe { action -> + .stream() + .onEach { action -> viewModel.handle(RoomSettingsAction.SetRoomJoinRule(action.roomJoinRule)) } - .disposeOnDestroyView() + .launchIn(viewLifecycleOwner.lifecycleScope) } private fun setupRoomHistoryVisibilitySharedActionViewModel() { roomHistoryVisibilitySharedActionViewModel = activityViewModelProvider.get(RoomHistoryVisibilitySharedActionViewModel::class.java) roomHistoryVisibilitySharedActionViewModel - .observe() - .subscribe { action -> + .stream() + .onEach { action -> viewModel.handle(RoomSettingsAction.SetRoomHistoryVisibility(action.roomHistoryVisibility)) } - .disposeOnDestroyView() + .launchIn(viewLifecycleOwner.lifecycleScope) } private fun showSuccess() { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index b622d8aab4..2c32070c76 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -149,11 +149,11 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( refreshMyDevice() refreshXSigningStatus() session.liveSecretSynchronisationInfo() - .flowOn(Dispatchers.Main) .onEach { refresh4SSection(it) refreshXSigningStatus() - }.launchIn(viewLifecycleOwner.lifecycleScope) + } + .launchIn(viewLifecycleOwner.lifecycleScope) lifecycleScope.launchWhenResumed { findPreference(VectorPreferences.SETTINGS_CRYPTOGRAPHY_HS_ADMIN_DISABLED_E2E_DEFAULT)?.isVisible = diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index e8300a1097..154518778d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -31,6 +31,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider +import im.vector.app.core.utils.PublishDataSource import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.login.ReAuthHelper import io.reactivex.subjects.PublishSubject @@ -66,6 +67,7 @@ import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import java.util.concurrent.TimeUnit import javax.net.ssl.HttpsURLConnection +import javax.sql.DataSource import kotlin.coroutines.Continuation import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException @@ -103,7 +105,7 @@ class DevicesViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() - private val refreshPublisher: PublishSubject = PublishSubject.create() + private val refreshSource= PublishDataSource() init { @@ -166,12 +168,12 @@ class DevicesViewModel @AssistedInject constructor( // ) // } - refreshPublisher.throttleFirst(4_000, TimeUnit.MILLISECONDS) - .subscribe { + refreshSource.stream().sample(4_000) + .onEach { session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) session.cryptoService().downloadKeys(listOf(session.myUserId), true, NoOpMatrixCallback()) } - .disposeOnClear() + .launchIn(viewModelScope) // then force download queryRefreshDevicesList() } @@ -193,7 +195,7 @@ class DevicesViewModel @AssistedInject constructor( * It can be any mobile devices, and any browsers. */ private fun queryRefreshDevicesList() { - refreshPublisher.onNext(Unit) + refreshSource.post(Unit) } override fun handle(action: DevicesAction) { diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt index 6e70b34002..4fba8fc3de 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt @@ -50,7 +50,7 @@ class SoftLogoutActivity : LoginActivity() { override fun initUiAndData() { super.initUiAndData() - softLogoutViewModel.subscribe(this) { + softLogoutViewModel.onEach { updateWithState(it) } diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt index ed45069e92..26500b60f0 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity2.kt @@ -52,7 +52,7 @@ class SoftLogoutActivity2 : LoginActivity2() { override fun initUiAndData() { super.initUiAndData() - softLogoutViewModel.subscribe(this) { + softLogoutViewModel.onEach { updateWithState(it) } diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt index 2aa7f15172..016d340f80 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt @@ -55,7 +55,7 @@ class SoftLogoutFragment @Inject constructor( setupRecyclerView() - softLogoutViewModel.subscribe(this) { softLogoutViewState -> + softLogoutViewModel.onEach { softLogoutViewState -> softLogoutController.update(softLogoutViewState) when (val mode = softLogoutViewState.asyncHomeServerLoginFlowRequest.invoke()) { is LoginMode.SsoAndPassword -> { diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt index 75373775f9..44acfa8ee3 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceCreationActivity.kt @@ -71,7 +71,7 @@ class SpaceCreationActivity : SimpleFragmentActivity() { override fun initUiAndData() { super.initUiAndData() - viewModel.subscribe(this) { + viewModel.onEach { renderState(it) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index 4487833773..a762e13cba 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -35,6 +35,7 @@ import im.vector.app.group import im.vector.app.space import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map @@ -89,14 +90,11 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa // observeSelectionState() appStateHandler.selectedRoomGroupingObservable .distinctUntilChanged() - .subscribe { - setState { - copy( - selectedGroupingMethod = it.orNull() ?: RoomGroupingMethod.BySpace(null) - ) - } + .setOnEach { + copy( + selectedGroupingMethod = it.orNull() ?: RoomGroupingMethod.BySpace(null) + ) } - .disposeOnClear() session.getGroupSummariesLive(groupSummaryQueryParams {}) .asFlow() @@ -114,7 +112,6 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa }, sortOrder = RoomSortOrder.NONE ).asFlow() .sample(300) - .flowOn(Dispatchers.Default) .onEach { val inviteCount = if (autoAcceptInvites.hideInvites) { 0 @@ -140,7 +137,9 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa homeAggregateCount = counts ) } - }.launchIn(viewModelScope) + } + .flowOn(Dispatchers.Default) + .launchIn(viewModelScope) } override fun handle(action: SpaceListAction) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt index 59166529b9..fcbbf6a752 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt @@ -19,6 +19,7 @@ package im.vector.app.features.spaces import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Mavericks import im.vector.app.R import im.vector.app.core.extensions.commitTransaction @@ -26,6 +27,8 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.spaces.preview.SpacePreviewArgs import im.vector.app.features.spaces.preview.SpacePreviewFragment +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach class SpacePreviewActivity : VectorBaseActivity() { @@ -37,8 +40,8 @@ class SpacePreviewActivity : VectorBaseActivity() { super.onCreate(savedInstanceState) sharedActionViewModel = viewModelProvider.get(SpacePreviewSharedActionViewModel::class.java) sharedActionViewModel - .observe() - .subscribe { action -> + .stream() + .onEach { action -> when (action) { SpacePreviewSharedAction.DismissAction -> finish() SpacePreviewSharedAction.ShowModalLoading -> showWaitingView() @@ -46,7 +49,7 @@ class SpacePreviewActivity : VectorBaseActivity() { is SpacePreviewSharedAction.ShowErrorMessage -> action.error?.let { showSnackbar(it) } } } - .disposeOnDestroy() + .launchIn(lifecycleScope) if (isFirstCreation()) { val simpleName = SpacePreviewFragment::class.java.simpleName diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceAdd3pidInvitesFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceAdd3pidInvitesFragment.kt index 6dc3ad8c21..4328c46188 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceAdd3pidInvitesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceAdd3pidInvitesFragment.kt @@ -50,7 +50,7 @@ class CreateSpaceAdd3pidInvitesFragment @Inject constructor( views.recyclerView.configureWith(epoxyController) epoxyController.listener = this - sharedViewModel.subscribe(this) { + sharedViewModel.onEach { invalidateState(it) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceDefaultRoomsFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceDefaultRoomsFragment.kt index 53a4ee689b..4ed7e91417 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceDefaultRoomsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceDefaultRoomsFragment.kt @@ -46,7 +46,7 @@ class CreateSpaceDefaultRoomsFragment @Inject constructor( views.recyclerView.configureWith(epoxyController) epoxyController.listener = this - sharedViewModel.subscribe(this) { + sharedViewModel.onEach { epoxyController.setData(it) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceDetailsFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceDetailsFragment.kt index 544c33948b..920ceed33c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceDetailsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/create/CreateSpaceDetailsFragment.kt @@ -50,7 +50,7 @@ class CreateSpaceDetailsFragment @Inject constructor( views.recyclerView.configureWith(epoxyController) epoxyController.listener = this - sharedViewModel.subscribe(this) { + sharedViewModel.onEach { epoxyController.setData(it) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt index 541d883405..69de39e436 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/leave/SpaceLeaveAdvancedActivity.kt @@ -86,7 +86,7 @@ class SpaceLeaveAdvancedActivity : VectorBaseActivity + leaveViewModel.onEach { state -> when (state.leaveState) { is Loading -> { showWaitingView() diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt index 2dae088c2e..932110d0e3 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageActivity.kt @@ -22,6 +22,7 @@ import android.os.Bundle import android.os.Parcelable import androidx.core.view.isGone import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.viewModel import com.airbnb.mvrx.withState @@ -41,6 +42,8 @@ import im.vector.app.features.roomdirectory.createroom.CreateRoomFragment import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.alias.RoomAliasFragment import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.parcelize.Parcelize @Parcelize @@ -80,14 +83,14 @@ class SpaceManageActivity : VectorBaseActivity(), sharedDirectoryActionViewModel = viewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) sharedDirectoryActionViewModel - .observe() - .subscribe { sharedAction -> + .stream() + .onEach { sharedAction -> when (sharedAction) { is RoomDirectorySharedAction.Back, is RoomDirectorySharedAction.Close -> finish() } } - .disposeOnDestroy() + .launchIn(lifecycleScope) val args = intent?.getParcelableExtra(Mavericks.KEY_ARG) if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt index c2ab015858..a0ab055311 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsFragment.kt @@ -24,6 +24,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel @@ -49,6 +50,8 @@ import im.vector.app.features.roomprofile.settings.RoomSettingsViewModel import im.vector.app.features.roomprofile.settings.RoomSettingsViewState import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleActivity import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleSharedActionViewModel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomJoinRules @@ -142,11 +145,11 @@ class SpaceSettingsFragment @Inject constructor( private fun setupRoomJoinRuleSharedActionViewModel() { roomJoinRuleSharedActionViewModel = activityViewModelProvider.get(RoomJoinRuleSharedActionViewModel::class.java) roomJoinRuleSharedActionViewModel - .observe() - .subscribe { action -> + .stream() + .onEach { action -> viewModel.handle(RoomSettingsAction.SetRoomJoinRule(action.roomJoinRule)) } - .disposeOnDestroyView() + .launchIn(viewLifecycleOwner.lifecycleScope) } private var ignoreChanges = false diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt index 3b84a12bc1..bc778a1b34 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt @@ -21,6 +21,7 @@ import android.content.Intent import android.os.Bundle import androidx.core.view.isGone import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Mavericks import im.vector.app.R import im.vector.app.core.extensions.commitTransaction @@ -29,6 +30,8 @@ import im.vector.app.core.platform.GenericIdArgs import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleLoadingBinding import im.vector.app.features.spaces.share.ShareSpaceBottomSheet +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach class SpacePeopleActivity : VectorBaseActivity() { @@ -73,8 +76,8 @@ class SpacePeopleActivity : VectorBaseActivity() { sharedActionViewModel = viewModelProvider.get(SpacePeopleSharedActionViewModel::class.java) sharedActionViewModel - .observe() - .subscribe { sharedAction -> + .stream() + .onEach { sharedAction -> when (sharedAction) { SpacePeopleSharedAction.Dismiss -> finish() is SpacePeopleSharedAction.NavigateToRoom -> navigateToRooms(sharedAction) @@ -86,7 +89,7 @@ class SpacePeopleActivity : VectorBaseActivity() { ShareSpaceBottomSheet.show(supportFragmentManager, sharedAction.spaceId) } } - }.disposeOnDestroy() + }.launchIn(lifecycleScope) } private fun navigateToRooms(action: SpacePeopleSharedAction.NavigateToRoom) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt index 6e14893f77..dad8ecfcca 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleFragment.kt @@ -91,7 +91,7 @@ class SpacePeopleFragment @Inject constructor( handleViewEvents(it) } - viewModel.subscribe(this) { + viewModel.onEach { when (it.createAndInviteState) { is Loading -> sharedActionViewModel.post(SpacePeopleSharedAction.ShowModalLoading) Uninitialized, diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index fde69ce9ba..c7ffc43727 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -160,10 +160,10 @@ class UserListViewModel @AssistedInject constructor(@Assisted initialState: User knownUsersSearch .sample(300) - .flowOn(Dispatchers.Main) .flatMapLatest { search -> session.getPagedUsersLive(search, state.excludedUserIds).asFlow() - }.execute { + } + .execute { copy(knownUsers = it) } diff --git a/vector/src/test/java/im/vector/app/test/Extensions.kt b/vector/src/test/java/im/vector/app/test/Extensions.kt index f2a087fd52..5c0cfd265b 100644 --- a/vector/src/test/java/im/vector/app/test/Extensions.kt +++ b/vector/src/test/java/im/vector/app/test/Extensions.kt @@ -27,17 +27,17 @@ fun String.trimIndentOneLine() = trimIndent().replace("\n", "") fun VectorViewModel.test(): ViewModelTest { val state = { com.airbnb.mvrx.withState(this) { it } } - val viewEvents = viewEvents.observe().test() - return ViewModelTest(state, viewEvents) + //val viewEvents = viewEvents.stream().test() + return ViewModelTest(state) } class ViewModelTest( val state: () -> S, - val viewEvents: TestObserver + //val viewEvents: TestObserver ) { fun assertEvents(vararg expected: VE) { - viewEvents.assertValues(*expected) + //viewEvents.assertValues(*expected) } fun assertState(expected: S) { From 0236396c593160d5f6176ea41d29e9064948d94a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 26 Oct 2021 11:15:33 +0200 Subject: [PATCH 037/413] Add optional deviceId to the login API --- changelog.d/4334.removal | 1 + .../sdk/api/auth/AuthenticationService.kt | 8 +++- .../android/sdk/api/auth/login/LoginWizard.kt | 6 ++- .../auth/DefaultAuthenticationService.kt | 11 ++++- .../internal/auth/data/PasswordLoginParams.kt | 45 ++++++++++--------- .../internal/auth/login/DefaultLoginWizard.kt | 18 ++++++-- .../internal/auth/login/DirectLoginTask.kt | 10 ++++- .../session/signout/SignInAgainTask.kt | 5 ++- .../app/features/login2/LoginViewModel2.kt | 2 +- 9 files changed, 72 insertions(+), 34 deletions(-) create mode 100644 changelog.d/4334.removal diff --git a/changelog.d/4334.removal b/changelog.d/4334.removal new file mode 100644 index 0000000000..1ed04d3cdf --- /dev/null +++ b/changelog.d/4334.removal @@ -0,0 +1 @@ +Add optional deviceId to the login API \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt index 5e35917243..9cb784c9c0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/AuthenticationService.kt @@ -105,9 +105,15 @@ interface AuthenticationService { /** * Authenticate with a matrixId and a password * Usually call this after a successful call to getWellKnownData() + * @param homeServerConnectionConfig the information about the homeserver and other configuration + * @param matrixId the matrixId of the user + * @param password the password of the account + * @param initialDeviceName the initial device name + * @param deviceId the device id, optional. If not provided or null, the server will generate one. */ suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig, matrixId: String, password: String, - initialDeviceName: String): Session + initialDeviceName: String, + deviceId: String? = null): Session } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt index a2a9373837..3f25a1b416 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt @@ -34,12 +34,14 @@ interface LoginWizard { * * @param login the login field. Can be a user name, or a msisdn (email or phone number) associated to the account * @param password the password of the account - * @param deviceName the initial device name + * @param initialDeviceName the initial device name + * @param deviceId the device id, optional. If not provided or null, the server will generate one. * @return a [Session] if the login is successful */ suspend fun login(login: String, password: String, - deviceName: String): Session + initialDeviceName: String, + deviceId: String? = null): Session /** * Exchange a login token to an access token. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt index 641a8f1bb6..8784d85c10 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt @@ -388,8 +388,15 @@ internal class DefaultAuthenticationService @Inject constructor( override suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig, matrixId: String, password: String, - initialDeviceName: String): Session { - return directLoginTask.execute(DirectLoginTask.Params(homeServerConnectionConfig, matrixId, password, initialDeviceName)) + initialDeviceName: String, + deviceId: String?): Session { + return directLoginTask.execute(DirectLoginTask.Params( + homeServerConnectionConfig = homeServerConnectionConfig, + userId = matrixId, + password = password, + deviceName = initialDeviceName, + deviceId = deviceId + )) } private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/PasswordLoginParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/PasswordLoginParams.kt index d4b14f1ca9..5be480f633 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/PasswordLoginParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/PasswordLoginParams.kt @@ -49,51 +49,54 @@ internal data class PasswordLoginParams( fun userIdentifier(user: String, password: String, - deviceDisplayName: String? = null, - deviceId: String? = null): PasswordLoginParams { + deviceDisplayName: String?, + deviceId: String?): PasswordLoginParams { return PasswordLoginParams( - mapOf( + identifier = mapOf( IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_USER, IDENTIFIER_KEY_USER to user ), - password, - LoginFlowTypes.PASSWORD, - deviceDisplayName, - deviceId) + password = password, + type = LoginFlowTypes.PASSWORD, + deviceDisplayName = deviceDisplayName, + deviceId = deviceId + ) } fun thirdPartyIdentifier(medium: String, address: String, password: String, - deviceDisplayName: String? = null, - deviceId: String? = null): PasswordLoginParams { + deviceDisplayName: String?, + deviceId: String?): PasswordLoginParams { return PasswordLoginParams( - mapOf( + identifier = mapOf( IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_THIRD_PARTY, IDENTIFIER_KEY_MEDIUM to medium, IDENTIFIER_KEY_ADDRESS to address ), - password, - LoginFlowTypes.PASSWORD, - deviceDisplayName, - deviceId) + password = password, + type = LoginFlowTypes.PASSWORD, + deviceDisplayName = deviceDisplayName, + deviceId = deviceId + ) } fun phoneIdentifier(country: String, phone: String, password: String, - deviceDisplayName: String? = null, - deviceId: String? = null): PasswordLoginParams { + deviceDisplayName: String?, + deviceId: String?): PasswordLoginParams { return PasswordLoginParams( - mapOf( + identifier = mapOf( IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_PHONE, IDENTIFIER_KEY_COUNTRY to country, IDENTIFIER_KEY_PHONE to phone ), - password, - LoginFlowTypes.PASSWORD, - deviceDisplayName, - deviceId) + password = password, + type = LoginFlowTypes.PASSWORD, + deviceDisplayName = deviceDisplayName, + deviceId = deviceId + ) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt index 854caf8a62..79b83decc6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt @@ -52,11 +52,23 @@ internal class DefaultLoginWizard( override suspend fun login(login: String, password: String, - deviceName: String): Session { + initialDeviceName: String, + deviceId: String?): Session { val loginParams = if (Patterns.EMAIL_ADDRESS.matcher(login).matches()) { - PasswordLoginParams.thirdPartyIdentifier(ThreePidMedium.EMAIL, login, password, deviceName) + PasswordLoginParams.thirdPartyIdentifier( + medium = ThreePidMedium.EMAIL, + address = login, + password = password, + deviceDisplayName = initialDeviceName, + deviceId = deviceId + ) } else { - PasswordLoginParams.userIdentifier(login, password, deviceName) + PasswordLoginParams.userIdentifier( + user = login, + password = password, + deviceDisplayName = initialDeviceName, + deviceId = deviceId + ) } val credentials = executeRequest(null) { authAPI.login(loginParams) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt index 8f61afe374..28706c7e80 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DirectLoginTask.kt @@ -37,7 +37,8 @@ internal interface DirectLoginTask : Task { val homeServerConnectionConfig: HomeServerConnectionConfig, val userId: String, val password: String, - val deviceName: String + val deviceName: String, + val deviceId: String? ) } @@ -55,7 +56,12 @@ internal class DefaultDirectLoginTask @Inject constructor( val authAPI = retrofitFactory.create(client, homeServerUrl) .create(AuthAPI::class.java) - val loginParams = PasswordLoginParams.userIdentifier(params.userId, params.password, params.deviceName) + val loginParams = PasswordLoginParams.userIdentifier( + user = params.userId, + password = params.password, + deviceDisplayName = params.deviceName, + deviceId = params.deviceId + ) val credentials = try { executeRequest(null) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignInAgainTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignInAgainTask.kt index 563e85aefc..42fdf30501 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignInAgainTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/signout/SignInAgainTask.kt @@ -42,11 +42,12 @@ internal class DefaultSignInAgainTask @Inject constructor( signOutAPI.loginAgain( PasswordLoginParams.userIdentifier( // Reuse the same userId - sessionParams.userId, - params.password, + user = sessionParams.userId, + password = params.password, // The spec says the initial device name will be ignored // https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-login // but https://github.com/matrix-org/synapse/issues/6525 + deviceDisplayName = null, // Reuse the same deviceId deviceId = sessionParams.deviceId ) diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt index ee33b8c222..b73988126b 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginViewModel2.kt @@ -547,7 +547,7 @@ class LoginViewModel2 @AssistedInject constructor( safeLoginWizard.login( login = login, password = password, - deviceName = stringProvider.getString(R.string.login_default_session_public_name) + initialDeviceName = stringProvider.getString(R.string.login_default_session_public_name) ) } catch (failure: Throwable) { _viewEvents.post(LoginViewEvents2.Failure(failure)) From 9479342a643aee1803ffeadb4bed27790c4ca397 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 26 Oct 2021 15:16:10 +0200 Subject: [PATCH 038/413] Flow: remove more rx --- dependencies.gradle | 1 - vector/build.gradle | 1 - .../vector/app/features/home/HomeActivity.kt | 3 +-- .../app/features/home/HomeDetailViewModel.kt | 2 -- .../app/features/home/ShortcutsHandler.kt | 20 ++++++++++--------- .../home/UnreadMessagesSharedViewModel.kt | 2 -- .../room/list/RoomListSectionBuilderSpace.kt | 1 - .../settings/SecretsSynchronisationInfo.kt | 1 - .../VectorSettingsSecurityPrivacyFragment.kt | 1 - 9 files changed, 12 insertions(+), 20 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 1e77b6354b..776e89f9b3 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -102,7 +102,6 @@ ext.libs = [ 'epoxyProcessor' : "com.airbnb.android:epoxy-processor:$epoxy", 'epoxyPaging' : "com.airbnb.android:epoxy-paging:$epoxy", 'mavericks' : "com.airbnb.android:mavericks:$mavericks", - 'mavericksRx' : "com.airbnb.android:mavericks-rxjava2:$mavericks", 'mavericksTesting' : "com.airbnb.android:mavericks-testing:$mavericks" ], mockk : [ diff --git a/vector/build.gradle b/vector/build.gradle index 35d1acfe8b..a5d10e222b 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -333,7 +333,6 @@ configurations { dependencies { implementation project(":matrix-sdk-android") - implementation project(":matrix-sdk-android-rx") implementation project(":matrix-sdk-android-flow") implementation project(":diff-match-patch") implementation project(":multipicker") diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 04ca25332f..039b7c3e7b 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -247,8 +247,7 @@ class HomeActivity : } homeActivityViewModel.onEach { renderState(it) } - shortcutsHandler.observeRoomsAndBuildShortcuts() - .disposeOnDestroy() + shortcutsHandler.observeRoomsAndBuildShortcuts(lifecycleScope) if (!vectorPreferences.didPromoteNewRestrictedFeature()) { promoteRestrictedViewModel.onEach { diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 8bfc1a8db4..a7d361c757 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -56,9 +56,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.rx.asObservable import timber.log.Timber -import java.util.concurrent.TimeUnit /** * View model used to update the home bottom bar notification counts, observe the sync state and diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index 7514d455aa..ff553577a0 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -21,13 +21,15 @@ import android.content.pm.ShortcutManager import android.os.Build import androidx.core.content.getSystemService import androidx.core.content.pm.ShortcutManagerCompat +import androidx.lifecycle.asFlow import im.vector.app.core.di.ActiveSessionHolder -import io.reactivex.disposables.Disposable -import io.reactivex.disposables.Disposables +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams -import org.matrix.android.sdk.rx.asObservable import javax.inject.Inject class ShortcutsHandler @Inject constructor( @@ -36,12 +38,11 @@ class ShortcutsHandler @Inject constructor( private val activeSessionHolder: ActiveSessionHolder ) { - fun observeRoomsAndBuildShortcuts(): Disposable { + fun observeRoomsAndBuildShortcuts(coroutineScope: CoroutineScope): Job { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) { // No op - return Disposables.empty() + return Job() } - return activeSessionHolder.getSafeActiveSession() ?.getPagedRoomSummariesLive( roomSummaryQueryParams { @@ -49,8 +50,8 @@ class ShortcutsHandler @Inject constructor( }, sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY ) - ?.asObservable() - ?.subscribe { rooms -> + ?.asFlow() + ?.onEach { rooms -> // Remove dead shortcuts (i.e. deleted rooms) val roomIds = rooms.map { it.roomId } val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC) @@ -66,7 +67,8 @@ class ShortcutsHandler @Inject constructor( ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) } } - ?: Disposables.empty() + ?.launchIn(coroutineScope) + ?: Job() } fun clearShortcuts() { diff --git a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt index 3434f9dfb0..4cfe0f7546 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnreadMessagesSharedViewModel.kt @@ -44,8 +44,6 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount -import org.matrix.android.sdk.rx.asObservable -import java.util.concurrent.TimeUnit data class UnreadMessagesState( val homeSpaceUnread: RoomAggregateNotificationCount = RoomAggregateNotificationCount(0, 0), diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt index 0bf7087618..1e806bb2d8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt @@ -52,7 +52,6 @@ import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount -import org.matrix.android.sdk.rx.asObservable import timber.log.Timber class RoomListSectionBuilderSpace( diff --git a/vector/src/main/java/im/vector/app/features/settings/SecretsSynchronisationInfo.kt b/vector/src/main/java/im/vector/app/features/settings/SecretsSynchronisationInfo.kt index 5afcb77587..e21366db02 100644 --- a/vector/src/main/java/im/vector/app/features/settings/SecretsSynchronisationInfo.kt +++ b/vector/src/main/java/im/vector/app/features/settings/SecretsSynchronisationInfo.kt @@ -26,7 +26,6 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NA import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.rx.SecretsSynchronisationInfo data class SecretsSynchronisationInfo( val isBackupSetup: Boolean, diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 2c32070c76..ca96d6a6bc 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -71,7 +71,6 @@ import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse -import org.matrix.android.sdk.rx.SecretsSynchronisationInfo import javax.inject.Inject class VectorSettingsSecurityPrivacyFragment @Inject constructor( From 8cf5b727e1eba92386bcf813f18a7e42f14779e4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 26 Oct 2021 15:57:18 +0200 Subject: [PATCH 039/413] Flow: restore read receipts --- .../im/vector/app/core/flow/ChunkOperator.kt | 79 +++++++++++++++++++ .../home/room/detail/RoomDetailViewModel.kt | 20 +++-- 2 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/flow/ChunkOperator.kt diff --git a/vector/src/main/java/im/vector/app/core/flow/ChunkOperator.kt b/vector/src/main/java/im/vector/app/core/flow/ChunkOperator.kt new file mode 100644 index 0000000000..533a060883 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/flow/ChunkOperator.kt @@ -0,0 +1,79 @@ +/* + * 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.flow + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.ClosedReceiveChannelException +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.produce +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.isActive +import kotlinx.coroutines.selects.select + +@ExperimentalCoroutinesApi +fun Flow.chunk(durationInMillis: Long): Flow> { + require(durationInMillis> 0) { "Duration should be greater than 0" } + return flow { + coroutineScope { + val events = ArrayList() + val ticker = fixedPeriodTicker(durationInMillis) + try { + val upstreamValues = produce(capacity = Channel.CONFLATED) { + collect { value -> send(value) } + } + while (isActive) { + var hasTimedOut = false + select { + upstreamValues.onReceive { + events.add(it) + } + ticker.onReceive { + hasTimedOut = true + } + } + if (hasTimedOut && events.isNotEmpty()) { + emit(events.toList()) + events.clear() + } + } + } catch (e: ClosedReceiveChannelException) { + // drain remaining events + if (events.isNotEmpty()) emit(events.toList()) + } finally { + ticker.cancel() + } + } + } +} + +private fun CoroutineScope.fixedPeriodTicker(delayMillis: Long, initialDelayMillis: Long = delayMillis): ReceiveChannel { + require(delayMillis >= 0) { "Expected non-negative delay, but has $delayMillis ms" } + require(initialDelayMillis >= 0) { "Expected non-negative initial delay, but has $initialDelayMillis ms" } + return produce(capacity = 0) { + delay(initialDelayMillis) + while (true) { + channel.send(Unit) + delay(delayMillis) + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index ee929243b5..1b765f81b9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -33,6 +33,7 @@ import dagger.assisted.AssistedInject import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.extensions.exhaustive +import im.vector.app.core.flow.chunk import im.vector.app.core.mvrx.runCatchingToAsync import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider @@ -58,13 +59,17 @@ import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.voice.VoicePlayerHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.buffer import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.sample import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixPatterns @@ -863,13 +868,13 @@ class RoomDetailViewModel @AssistedInject constructor( private fun observeEventDisplayedActions() { // We are buffering scroll events for one second // and keep the most recent one to set the read receipt on. - /* + visibleEventsSource .stream() - .buffer(1, TimeUnit.SECONDS) + .chunk(1000) .filter { it.isNotEmpty() } - .subscribeBy(onNext = { actions -> - val bufferedMostRecentDisplayedEvent = actions.maxByOrNull { it.event.displayIndex }?.event ?: return@subscribeBy + .onEach { actions -> + val bufferedMostRecentDisplayedEvent = actions.maxByOrNull { it.event.displayIndex }?.event ?: return@onEach val globalMostRecentDisplayedEvent = mostRecentDisplayedEvent if (trackUnreadMessages.get()) { if (globalMostRecentDisplayedEvent == null) { @@ -883,10 +888,9 @@ class RoomDetailViewModel @AssistedInject constructor( tryOrNull { room.setReadReceipt(eventId) } } } - }) - .disposeOnClear() - - */ + } + .flowOn(Dispatchers.Default) + .launchIn(viewModelScope) } private fun handleMarkAllAsRead() { From 792444d1aca7ea731adfc2d9d01431b581e007b5 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Oct 2021 16:23:32 +0100 Subject: [PATCH 040/413] adding missing hilt annotation for injectable activity --- .../features/roomdirectory/roompreview/RoomPreviewActivity.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt index 0121d5d795..86bfdb79cd 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.os.Parcelable 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 @@ -51,6 +52,7 @@ data class RoomPreviewData( get() = MatrixItem.RoomItem(roomId, roomName ?: roomAlias, avatarUrl) } +@AndroidEntryPoint class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { companion object { From 6c485d5f6e91003f1a5c86fbd8d781cb23c1de77 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 26 Oct 2021 17:23:33 +0200 Subject: [PATCH 041/413] Merge hotfix 1.3.6 --- CHANGES.md | 9 +++++ .../android/en-US/changelogs/40103060.txt | 2 ++ .../vector/app/features/login/LoginAction.kt | 2 ++ .../app/features/login/LoginActivity.kt | 1 - .../login/LoginServerSelectionFragment.kt | 5 --- .../login/LoginServerUrlFormFragment.kt | 5 --- .../app/features/login/LoginSplashFragment.kt | 26 ++++++++++++-- .../app/features/login/LoginViewModel.kt | 34 ++++++++++++++++--- .../app/features/login/LoginViewState.kt | 2 +- vector/src/main/res/values/strings.xml | 2 ++ 10 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/40103060.txt diff --git a/CHANGES.md b/CHANGES.md index d3bc0cc414..3824fead36 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,12 @@ +Changes in Element v1.3.6 (2021-10-26) +====================================== + +Bugfixes 🐛 +---------- + - Correctly handle url of type https://mobile.element.io/?hs_url=…&is_url=… + Skip the choose server screen when such URL are open when Element ([#2684](https://github.com/vector-im/element-android/issues/2684)) + + Changes in Element v1.3.5 (2021-10-25) ====================================== diff --git a/fastlane/metadata/android/en-US/changelogs/40103060.txt b/fastlane/metadata/android/en-US/changelogs/40103060.txt new file mode 100644 index 0000000000..7afd03a5c8 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40103060.txt @@ -0,0 +1,2 @@ +Main changes in this version: Add Presence support, for Direct Message room (note: presence is disabled on matrix.org). Add again Android Auto support. +Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.3.6 \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/login/LoginAction.kt b/vector/src/main/java/im/vector/app/features/login/LoginAction.kt index f6e1ccc9bc..70ca49a10e 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginAction.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginAction.kt @@ -23,6 +23,8 @@ import org.matrix.android.sdk.api.auth.registration.RegisterThreePid import org.matrix.android.sdk.internal.network.ssl.Fingerprint sealed class LoginAction : VectorViewModelAction { + data class OnGetStarted(val resetLoginConfig: Boolean) : LoginAction() + data class UpdateServerType(val serverType: ServerType) : LoginAction() data class UpdateHomeServer(val homeServerUrl: String) : LoginAction() data class UpdateSignMode(val signMode: SignMode) : LoginAction() diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index b3606a68ca..0ca076ccd7 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -95,7 +95,6 @@ open class LoginActivity : VectorBaseActivity(), ToolbarCo // Get config extra val loginConfig = intent.getParcelableExtra(EXTRA_CONFIG) if (isFirstCreation()) { - // TODO Check this loginViewModel.handle(LoginAction.InitWith(loginConfig)) } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt index 2d40ea818a..89d8985a81 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt @@ -87,10 +87,5 @@ class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment override fun updateWithState(state: LoginViewState) { updateSelectedChoice(state) - - if (state.loginMode != LoginMode.Unknown) { - // LoginFlow for matrix.org has been retrieved - loginViewModel.handle(LoginAction.PostViewEvent(LoginViewEvents.OnLoginFlowRetrieved)) - } } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt index d0b4d65b19..ebe82b1163 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt @@ -156,10 +156,5 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment + loginViewModel.handle(LoginAction.OnGetStarted(resetLoginConfig = true)) + } + .setNegativeButton(R.string.cancel, null) + .show() + } else { + super.onError(throwable) + } + } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt index c08c36d552..bfa924c155 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewModel.kt @@ -18,7 +18,6 @@ package im.vector.app.features.login import android.content.Context import android.net.Uri -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory @@ -116,6 +115,7 @@ class LoginViewModel @AssistedInject constructor( override fun handle(action: LoginAction) { when (action) { + is LoginAction.OnGetStarted -> handleOnGetStarted(action) is LoginAction.UpdateServerType -> handleUpdateServerType(action) is LoginAction.UpdateSignMode -> handleUpdateSignMode(action) is LoginAction.InitWith -> handleInitWith(action) @@ -134,6 +134,27 @@ class LoginViewModel @AssistedInject constructor( }.exhaustive } + private fun handleOnGetStarted(action: LoginAction.OnGetStarted) { + if (action.resetLoginConfig) { + loginConfig = null + } + + val configUrl = loginConfig?.homeServerUrl?.takeIf { it.isNotEmpty() } + if (configUrl != null) { + // Use config from uri + val homeServerConnectionConfig = homeServerConnectionConfigFactory.create(configUrl) + if (homeServerConnectionConfig == null) { + // Url is invalid, in this case, just use the regular flow + Timber.w("Url from config url was invalid: $configUrl") + _viewEvents.post(LoginViewEvents.OpenServerSelection) + } else { + getLoginFlow(homeServerConnectionConfig, ServerType.Other) + } + } else { + _viewEvents.post(LoginViewEvents.OpenServerSelection) + } + } + private fun handleUserAcceptCertificate(action: LoginAction.UserAcceptCertificate) { // It happens when we get the login flow, or during direct authentication. // So alter the homeserver config and retrieve again the login flow @@ -732,7 +753,8 @@ class LoginViewModel @AssistedInject constructor( } } - private fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig) { + private fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, + serverTypeOverride: ServerType? = null) { currentHomeServerConnectionConfig = homeServerConnectionConfig currentJob = viewModelScope.launch { @@ -743,7 +765,11 @@ class LoginViewModel @AssistedInject constructor( asyncHomeServerLoginFlowRequest = Loading(), // If user has entered https://matrix.org, ensure that server type is ServerType.MatrixOrg // It is also useful to set the value again in the case of a certificate error on matrix.org - serverType = if (homeServerConnectionConfig.homeServerUri.toString() == matrixOrgUrl) ServerType.MatrixOrg else serverType + serverType = if (homeServerConnectionConfig.homeServerUri.toString() == matrixOrgUrl) { + ServerType.MatrixOrg + } else { + serverTypeOverride ?: serverType + } ) } @@ -776,7 +802,6 @@ class LoginViewModel @AssistedInject constructor( else -> LoginMode.Unsupported } - // FIXME We should post a view event here normally? setState { copy( asyncHomeServerLoginFlowRequest = Uninitialized, @@ -791,6 +816,7 @@ class LoginViewModel @AssistedInject constructor( // Notify the UI _viewEvents.post(LoginViewEvents.OutdatedHomeserver) } + _viewEvents.post(LoginViewEvents.OnLoginFlowRetrieved) } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt b/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt index 46b5052a38..23689225b5 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginViewState.kt @@ -53,7 +53,7 @@ data class LoginViewState( val loginMode: LoginMode = LoginMode.Unknown, // Supported types for the login. We cannot use a sealed class for LoginType because it is not serializable @PersistState -val loginModeSupportedTypes: List = emptyList(), + val loginModeSupportedTypes: List = emptyList(), val knownCustomHomeServersUrls: List = emptyList() ) : MavericksState { diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 274753ee3f..0e8197dbae 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -657,6 +657,8 @@ This URL is not reachable, please check it This is not a valid Matrix server address Cannot reach a homeserver at this URL, please check it + Cannot reach a homeserver at the URL %s. Please check your link or choose a homeserver manually. + Choose homeserver "SSL Error: the peer's identity has not been verified." "SSL Error." Your device is using an outdated TLS security protocol, vulnerable to attack, for your security you will not be able to connect From 01a29f67d0c9dc7ebd784d005af173ec2ea8f781 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 26 Oct 2021 17:33:23 +0200 Subject: [PATCH 042/413] Version++ --- matrix-sdk-android/build.gradle | 2 +- vector/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index e3d0f273b8..2405e2ee4e 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -31,7 +31,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.3.6\"" + buildConfigField "String", "SDK_VERSION", "\"1.3.7\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" resValue "string", "git_sdk_revision", "\"${gitRevision()}\"" diff --git a/vector/build.gradle b/vector/build.gradle index 5f032e55c2..7e2f5d72d6 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -15,7 +15,7 @@ kapt { // Note: 2 digits max for each value ext.versionMajor = 1 ext.versionMinor = 3 -ext.versionPatch = 6 +ext.versionPatch = 7 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From a9d192fa399c6bddcc6d3bdede485f64f7765a7e Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 26 Oct 2021 18:09:07 +0200 Subject: [PATCH 043/413] Flow migration: add back some test --- dependencies.gradle | 3 +- vector/build.gradle | 2 + .../quads/SharedSecureStorageViewModelTest.kt | 110 +++++++++++------- .../java/im/vector/app/test/Extensions.kt | 22 ++-- .../im/vector/app/test/FlowTestObserver.kt | 53 +++++++++ 5 files changed, 138 insertions(+), 52 deletions(-) create mode 100644 vector/src/test/java/im/vector/app/test/FlowTestObserver.kt diff --git a/dependencies.gradle b/dependencies.gradle index 776e89f9b3..15660f17f2 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -41,7 +41,8 @@ ext.libs = [ jetbrains : [ 'coroutinesCore' : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines", 'coroutinesAndroid' : "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutines", - 'coroutinesRx2' : "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$kotlinCoroutines" + 'coroutinesRx2' : "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$kotlinCoroutines", + 'coroutinesTest' : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutines" ], androidx : [ 'appCompat' : "androidx.appcompat:appcompat:1.3.1", diff --git a/vector/build.gradle b/vector/build.gradle index a5d10e222b..493a26dcc6 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -508,6 +508,7 @@ dependencies { // Plant Timber tree for test testImplementation libs.tests.timberJunitRule testImplementation libs.airbnb.mavericksTesting + testImplementation libs.jetbrains.coroutinesTest // Activate when you want to check for leaks, from time to time. //debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3' @@ -521,6 +522,7 @@ dependencies { androidTestImplementation libs.androidx.espressoIntents androidTestImplementation libs.tests.kluent androidTestImplementation libs.androidx.coreTesting + androidTestImplementation libs.jetbrains.coroutinesTest // Plant Timber tree for test androidTestImplementation libs.tests.timberJunitRule // "The one who serves a great Espresso" diff --git a/vector/src/test/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModelTest.kt b/vector/src/test/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModelTest.kt index 506ac9c7d0..00828acbb8 100644 --- a/vector/src/test/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModelTest.kt @@ -22,6 +22,7 @@ import im.vector.app.test.InstantRxRule import im.vector.app.test.fakes.FakeSession import im.vector.app.test.fakes.FakeStringProvider import im.vector.app.test.test +import kotlinx.coroutines.test.runBlockingTest import org.junit.Rule import org.junit.Test import org.matrix.android.sdk.api.session.securestorage.IntegrityResult @@ -41,6 +42,7 @@ class SharedSecureStorageViewModelTest { @get:Rule val instantRx = InstantRxRule() + @get:Rule val mvrxTestRule = MvRxTestRule() @@ -50,78 +52,100 @@ class SharedSecureStorageViewModelTest { @Test fun `given a key info with passphrase when initialising then step is EnterPassphrase`() { - givenKey(KEY_INFO_WITH_PASSPHRASE) - - val viewModel = createViewModel() - - viewModel.test().assertState(aViewState( - hasPassphrase = true, - step = SharedSecureStorageViewState.Step.EnterPassphrase - )) + runBlockingTest { + givenKey(KEY_INFO_WITH_PASSPHRASE) + val viewModel = createViewModel() + viewModel + .test(this) + .assertState(aViewState( + hasPassphrase = true, + step = SharedSecureStorageViewState.Step.EnterPassphrase + )) + .finish() + } } @Test fun `given a key info without passphrase when initialising then step is EnterKey`() { - givenKey(KEY_INFO_WITHOUT_PASSPHRASE) + runBlockingTest { + givenKey(KEY_INFO_WITHOUT_PASSPHRASE) - val viewModel = createViewModel() + val viewModel = createViewModel() - viewModel.test().assertState(aViewState( - hasPassphrase = false, - step = SharedSecureStorageViewState.Step.EnterKey - )) + viewModel + .test(this) + .assertState(aViewState( + hasPassphrase = false, + step = SharedSecureStorageViewState.Step.EnterKey + )) + .finish() + } } @Test fun `given on EnterKey step when going back then dismisses`() { - givenKey(KEY_INFO_WITHOUT_PASSPHRASE) + runBlockingTest { + givenKey(KEY_INFO_WITHOUT_PASSPHRASE) - val viewModel = createViewModel() - val test = viewModel.test() - - viewModel.handle(SharedSecureStorageAction.Back) - - test.assertEvents(SharedSecureStorageViewEvent.Dismiss) + val viewModel = createViewModel() + val test = viewModel.test(this) + viewModel.handle(SharedSecureStorageAction.Back) + test + .assertEvents(SharedSecureStorageViewEvent.Dismiss) + .finish() + } } @Test fun `given on passphrase step when using key then step is EnterKey`() { - givenKey(KEY_INFO_WITH_PASSPHRASE) - val viewModel = createViewModel() - val test = viewModel.test() + runBlockingTest { + givenKey(KEY_INFO_WITH_PASSPHRASE) + val viewModel = createViewModel() + val test = viewModel.test(this) - viewModel.handle(SharedSecureStorageAction.UseKey) + viewModel.handle(SharedSecureStorageAction.UseKey) - test.assertState(aViewState( - hasPassphrase = true, - step = SharedSecureStorageViewState.Step.EnterKey - )) + test + .assertState(aViewState( + hasPassphrase = true, + step = SharedSecureStorageViewState.Step.EnterKey + )) + .finish() + } } @Test fun `given a key info with passphrase and on EnterKey step when going back then step is EnterPassphrase`() { - givenKey(KEY_INFO_WITH_PASSPHRASE) - val viewModel = createViewModel() - val test = viewModel.test() + runBlockingTest { + givenKey(KEY_INFO_WITH_PASSPHRASE) + val viewModel = createViewModel() + val test = viewModel.test(this) - viewModel.handle(SharedSecureStorageAction.UseKey) - viewModel.handle(SharedSecureStorageAction.Back) + viewModel.handle(SharedSecureStorageAction.UseKey) + viewModel.handle(SharedSecureStorageAction.Back) - test.assertState(aViewState( - hasPassphrase = true, - step = SharedSecureStorageViewState.Step.EnterPassphrase - )) + test + .assertState(aViewState( + hasPassphrase = true, + step = SharedSecureStorageViewState.Step.EnterPassphrase + )) + .finish() + } } @Test fun `given on passphrase step when going back then dismisses`() { - givenKey(KEY_INFO_WITH_PASSPHRASE) - val viewModel = createViewModel() - val test = viewModel.test() + runBlockingTest { + givenKey(KEY_INFO_WITH_PASSPHRASE) + val viewModel = createViewModel() + val test = viewModel.test(this) - viewModel.handle(SharedSecureStorageAction.Back) + viewModel.handle(SharedSecureStorageAction.Back) - test.assertEvents(SharedSecureStorageViewEvent.Dismiss) + test + .assertEvents(SharedSecureStorageViewEvent.Dismiss) + .finish() + } } private fun createViewModel(): SharedSecureStorageViewModel { diff --git a/vector/src/test/java/im/vector/app/test/Extensions.kt b/vector/src/test/java/im/vector/app/test/Extensions.kt index 5c0cfd265b..67b5090785 100644 --- a/vector/src/test/java/im/vector/app/test/Extensions.kt +++ b/vector/src/test/java/im/vector/app/test/Extensions.kt @@ -20,27 +20,33 @@ import com.airbnb.mvrx.MavericksState import im.vector.app.core.platform.VectorViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModelAction -import io.reactivex.observers.TestObserver +import kotlinx.coroutines.CoroutineScope import org.amshove.kluent.shouldBeEqualTo fun String.trimIndentOneLine() = trimIndent().replace("\n", "") -fun VectorViewModel.test(): ViewModelTest { +fun VectorViewModel.test(coroutineScope: CoroutineScope): ViewModelTest { val state = { com.airbnb.mvrx.withState(this) { it } } - //val viewEvents = viewEvents.stream().test() - return ViewModelTest(state) + val viewEvents = viewEvents.stream().test(coroutineScope) + return ViewModelTest(state, viewEvents) } class ViewModelTest( val state: () -> S, - //val viewEvents: TestObserver + val viewEvents: FlowTestObserver ) { - fun assertEvents(vararg expected: VE) { - //viewEvents.assertValues(*expected) + fun assertEvents(vararg expected: VE): ViewModelTest { + viewEvents.assertValues(*expected) + return this } - fun assertState(expected: S) { + fun assertState(expected: S): ViewModelTest { state() shouldBeEqualTo expected + return this + } + + fun finish(){ + viewEvents.finish() } } diff --git a/vector/src/test/java/im/vector/app/test/FlowTestObserver.kt b/vector/src/test/java/im/vector/app/test/FlowTestObserver.kt new file mode 100644 index 0000000000..955922d0c4 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/FlowTestObserver.kt @@ -0,0 +1,53 @@ +/* + * 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.test + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import org.junit.Assert.assertEquals + +fun Flow.test(scope: CoroutineScope): FlowTestObserver { + return FlowTestObserver(scope, this) +} + +class FlowTestObserver( + scope: CoroutineScope, + flow: Flow +) { + private val values = mutableListOf() + private val job: Job = flow + .onEach { + values.add(it) + }.launchIn(scope) + + fun assertNoValues(): FlowTestObserver { + assertEquals(emptyList(), this.values) + return this + } + + fun assertValues(vararg values: T): FlowTestObserver { + assertEquals(values.toList(), this.values) + return this + } + + fun finish() { + job.cancel() + } +} From 49c969601d3ee94fc4e2a72f6ddef673ea017d4b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Oct 2021 17:14:24 +0100 Subject: [PATCH 044/413] adding missing bottomsheet handling for displaying the join room sheet when linking from the public rooms - the activity is still finished causing the popup to not actually display --- .../features/roomdirectory/RoomDirectoryActivity.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt index dd4011a865..7ad8d0ce49 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt @@ -28,13 +28,15 @@ import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.popBackstack import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding +import im.vector.app.features.matrixto.MatrixToBottomSheet +import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomdirectory.createroom.CreateRoomArgs import im.vector.app.features.roomdirectory.createroom.CreateRoomFragment import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerFragment import javax.inject.Inject @AndroidEntryPoint -class RoomDirectoryActivity : VectorBaseActivity() { +class RoomDirectoryActivity : VectorBaseActivity(), MatrixToBottomSheet.InteractionListener { @Inject lateinit var roomDirectoryViewModelFactory: RoomDirectoryViewModel.Factory private val roomDirectoryViewModel: RoomDirectoryViewModel by viewModel() @@ -81,6 +83,14 @@ class RoomDirectoryActivity : VectorBaseActivity() { } } + override fun mxToBottomSheetNavigateToRoom(roomId: String) { + navigator.openRoom(this, roomId) + } + + override fun mxToBottomSheetSwitchToSpace(spaceId: String) { + navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None) + } + companion object { private const val INITIAL_FILTER = "INITIAL_FILTER" From 881157a725fc1f19a07902374ac4e8195634ce70 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Oct 2021 17:15:19 +0100 Subject: [PATCH 045/413] applying the room navigation interceptor to only the room activity navigation, not the bottomsheets - the bottomsheets require the activity to stay around as they host the sheet instance, fixes missing join sheets --- .../features/permalink/PermalinkHandler.kt | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index 90bcee3d04..d4eed6a41e 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -79,15 +79,14 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti return when (permalinkData) { is PermalinkData.RoomLink -> { val roomId = permalinkData.getRoomId() - if (navigationInterceptor?.navToRoom(roomId, permalinkData.eventId, rawLink) != true) { - openRoom( - context = context, - roomId = roomId, - permalinkData = permalinkData, - rawLink = rawLink, - buildTask = buildTask - ) - } + openRoom( + navigationInterceptor, + context = context, + roomId = roomId, + permalinkData = permalinkData, + rawLink = rawLink, + buildTask = buildTask + ) true } is PermalinkData.GroupLink -> { @@ -146,6 +145,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti * Open room either joined, or not */ private fun openRoom( + navigationInterceptor: NavigationInterceptor?, context: Context, roomId: String?, permalinkData: PermalinkData.RoomLink, @@ -167,7 +167,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti membership?.isActive().orFalse() -> { if (!isSpace && membership == Membership.JOIN) { // If it's a room you're in, let's just open it, you can tap back if needed - navigator.openRoom(context, roomId, eventId, buildTask) + navigationInterceptor.openJoinedRoomScreen(buildTask, roomId, eventId, rawLink, context) } else { // maybe open space preview navigator.openSpacePreview(context, roomId)? if already joined? navigator.openMatrixToBottomSheet(context, rawLink.toString()) @@ -180,6 +180,12 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti } } + private fun NavigationInterceptor?.openJoinedRoomScreen(buildTask: Boolean, roomId: String, eventId: String?, rawLink: Uri, context: Context) { + if (this?.navToRoom(roomId, eventId, rawLink) != true) { + navigator.openRoom(context, roomId, eventId, buildTask) + } + } + companion object { const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://" const val ROOM_LINK_PREFIX = "${MATRIX_TO_CUSTOM_SCHEME_URL_BASE}room/" From 43619260755094934e660ac6c5fb22cecd57c63d Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Oct 2021 17:22:26 +0100 Subject: [PATCH 046/413] adding changelog entry --- changelog.d/4255.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/4255.bugfix diff --git a/changelog.d/4255.bugfix b/changelog.d/4255.bugfix new file mode 100644 index 0000000000..8fc820d70f --- /dev/null +++ b/changelog.d/4255.bugfix @@ -0,0 +1 @@ +Fixes being unable to join rooms by name \ No newline at end of file From e8ccae8cd03804b8cb7379581d89423d78b1ce60 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 26 Oct 2021 18:38:15 +0200 Subject: [PATCH 047/413] Add API `LoginWizard.loginCustom(data: JsonDict): Session` to be able to login to a homeserver using arbitrary request content --- changelog.d/4266.removal | 1 + .../org/matrix/android/sdk/api/auth/login/LoginWizard.kt | 7 +++++++ .../java/org/matrix/android/sdk/internal/auth/AuthAPI.kt | 4 ++++ .../sdk/internal/auth/login/DefaultLoginWizard.kt | 9 +++++++++ 4 files changed, 21 insertions(+) create mode 100644 changelog.d/4266.removal diff --git a/changelog.d/4266.removal b/changelog.d/4266.removal new file mode 100644 index 0000000000..5ac757bc8a --- /dev/null +++ b/changelog.d/4266.removal @@ -0,0 +1 @@ +Add API `LoginWizard.loginCustom(data: JsonDict): Session` to be able to login to a homeserver using arbitrary request content \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt index a2a9373837..c176c27c21 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.api.auth.login import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.util.JsonDict /** * Set of methods to be able to login to an existing account on a homeserver. @@ -49,6 +50,12 @@ interface LoginWizard { */ suspend fun loginWithToken(loginToken: String): Session + /** + * Login to the homeserver by sending a custom JsonDict. + * The data should contain at least one entry "type" with a String value. + */ + suspend fun loginCustom(data: JsonDict): Session + /** * Ask the homeserver to reset the user password. The password will not be reset until * [resetPasswordMailConfirmed] is successfully called. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt index 50d9e5a06c..554e21ce55 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthAPI.kt @@ -121,6 +121,10 @@ internal interface AuthAPI { @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login") suspend fun login(@Body loginParams: TokenLoginParams): Credentials + @Headers("CONNECT_TIMEOUT:60000", "READ_TIMEOUT:60000", "WRITE_TIMEOUT:60000") + @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login") + suspend fun login(@Body loginParams: JsonDict): Credentials + /** * Ask the homeserver to reset the password associated with the provided email. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt index 854caf8a62..2178008404 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/login/DefaultLoginWizard.kt @@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.auth.login.LoginProfileInfo import org.matrix.android.sdk.api.auth.login.LoginWizard import org.matrix.android.sdk.api.auth.registration.RegisterThreePid import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.auth.AuthAPI import org.matrix.android.sdk.internal.auth.PendingSessionStore import org.matrix.android.sdk.internal.auth.SessionCreator @@ -79,6 +80,14 @@ internal class DefaultLoginWizard( return sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig) } + override suspend fun loginCustom(data: JsonDict): Session { + val credentials = executeRequest(null) { + authAPI.login(data) + } + + return sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig) + } + override suspend fun resetPassword(email: String, newPassword: String) { val param = RegisterAddThreePidTask.Params( RegisterThreePid.Email(email), From 272baa52ec2e10d0d4316dbd4259acf1f8137d85 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Oct 2021 17:56:22 +0100 Subject: [PATCH 048/413] adding remaining activity missing hilt injection annotations --- .../im/vector/app/features/debug/DebugPermissionActivity.kt | 2 ++ vector/src/main/java/im/vector/app/features/pin/PinActivity.kt | 2 ++ .../im/vector/app/features/signout/hard/SignedOutActivity.kt | 2 ++ .../java/im/vector/app/features/spaces/SpacePreviewActivity.kt | 2 ++ .../im/vector/app/features/spaces/people/SpacePeopleActivity.kt | 2 ++ 5 files changed, 10 insertions(+) diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt index 048c64bc3a..a35bb40f8f 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugPermissionActivity.kt @@ -22,6 +22,7 @@ import android.os.Build import android.widget.Toast import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.checkPermissions @@ -31,6 +32,7 @@ import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.databinding.ActivityDebugPermissionBinding import timber.log.Timber +@AndroidEntryPoint class DebugPermissionActivity : VectorBaseActivity() { override fun getBinding() = ActivityDebugPermissionBinding.inflate(layoutInflater) diff --git a/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt b/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt index 430be6bc1f..0978f0d5b5 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt @@ -20,12 +20,14 @@ import android.content.Context import android.content.Intent import com.airbnb.mvrx.Mavericks 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 import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding +@AndroidEntryPoint class PinActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedActivity { companion object { diff --git a/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt index 6f05a73f13..ee7557b402 100644 --- a/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt @@ -19,6 +19,7 @@ package im.vector.app.features.signout.hard import android.content.Context import android.content.Intent import android.os.Bundle +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySignedOutBinding import im.vector.app.features.MainActivity @@ -29,6 +30,7 @@ import timber.log.Timber /** * In this screen, the user is viewing a message informing that he has been logged out */ +@AndroidEntryPoint class SignedOutActivity : VectorBaseActivity() { override fun getBinding() = ActivitySignedOutBinding.inflate(layoutInflater) diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt index 59166529b9..ef65f35716 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpacePreviewActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import com.airbnb.mvrx.Mavericks +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.platform.VectorBaseActivity @@ -27,6 +28,7 @@ import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.spaces.preview.SpacePreviewArgs import im.vector.app.features.spaces.preview.SpacePreviewFragment +@AndroidEntryPoint class SpacePreviewActivity : VectorBaseActivity() { lateinit var sharedActionViewModel: SpacePreviewSharedActionViewModel diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt index 3b84a12bc1..1f08802137 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt @@ -22,6 +22,7 @@ import android.os.Bundle import androidx.core.view.isGone import androidx.core.view.isVisible import com.airbnb.mvrx.Mavericks +import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.hideKeyboard @@ -30,6 +31,7 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleLoadingBinding import im.vector.app.features.spaces.share.ShareSpaceBottomSheet +@AndroidEntryPoint class SpacePeopleActivity : VectorBaseActivity() { override fun getBinding() = ActivitySimpleLoadingBinding.inflate(layoutInflater) From e95d49a3aeeb01419118d88ca58e0e389ff610f4 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 8 Oct 2021 16:56:50 +0100 Subject: [PATCH 049/413] avoiding dispatching invitation accepted events - we only want to notify users when they receive an invititation, not when they've accepted it --- .../session/notification/ProcessEventForPushTask.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt index 1321f8dd62..d9e4f967ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt @@ -17,7 +17,11 @@ package org.matrix.android.sdk.internal.session.notification import org.matrix.android.sdk.api.pushrules.rest.PushRule +import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.task.Task @@ -51,11 +55,14 @@ internal class DefaultProcessEventForPushTask @Inject constructor( value.timeline?.events?.map { it.copy(roomId = key) } } .flatten() + .filterNot { it.isInvitationJoined() } + val inviteEvents = params.syncResponse.invite .mapNotNull { (key, value) -> value.inviteState?.events?.map { it.copy(roomId = key) } } .flatten() + val allEvents = (newJoinEvents + inviteEvents).filter { event -> when (event.type) { EventType.MESSAGE, @@ -93,3 +100,6 @@ internal class DefaultProcessEventForPushTask @Inject constructor( defaultPushRuleService.dispatchFinish() } } + +private fun Event.isInvitationJoined(): Boolean = type == EventType.STATE_ROOM_MEMBER && + content?.toModel()?.membership == Membership.INVITE From 0c809b5ed1f28eee2ee73ded2d9b5ec850f0df42 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 8 Oct 2021 17:02:59 +0100 Subject: [PATCH 050/413] now that we ignore duplicated invite joined events at the source we can avoid eager notification cancels and rely on the main notification refresh flow --- .../notifications/NotificationDrawerManager.kt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index e4b2ead93d..45c21bb028 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -212,12 +212,16 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } fun clearMemberShipNotificationForRoom(roomId: String) { - synchronized(eventList) { - eventList.removeAll { e -> - e is InviteNotifiableEvent && e.roomId == roomId - } + val shouldUpdate = removeAll { it is InviteNotifiableEvent && it.roomId == roomId } + if (shouldUpdate) { + refreshNotificationDrawerBg() + } + } + + private fun removeAll(predicate: (NotifiableEvent) -> Boolean): Boolean { + return synchronized(eventList) { + eventList.removeAll(predicate) } - notificationUtils.cancelNotificationMessage(roomId, ROOM_INVITATION_NOTIFICATION_ID) } private var firstThrottler = FirstThrottler(200) From 37a7d449ae1bbbaae9d05f9c48ab8f3e3bbedd9b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 11 Oct 2021 09:48:41 +0100 Subject: [PATCH 051/413] moving invitiation joined event filtering to the existing mapNotNull chain to avoid another list creation --- .../session/notification/ProcessEventForPushTask.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt index d9e4f967ee..865f942ee9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt @@ -52,10 +52,11 @@ internal class DefaultProcessEventForPushTask @Inject constructor( } val newJoinEvents = params.syncResponse.join .mapNotNull { (key, value) -> - value.timeline?.events?.map { it.copy(roomId = key) } + value.timeline?.events?.mapNotNull { + it.takeIf { !it.isInvitation() }?.copy(roomId = key) + } } .flatten() - .filterNot { it.isInvitationJoined() } val inviteEvents = params.syncResponse.invite .mapNotNull { (key, value) -> @@ -101,5 +102,5 @@ internal class DefaultProcessEventForPushTask @Inject constructor( } } -private fun Event.isInvitationJoined(): Boolean = type == EventType.STATE_ROOM_MEMBER && +private fun Event.isInvitation(): Boolean = type == EventType.STATE_ROOM_MEMBER && content?.toModel()?.membership == Membership.INVITE From 1c0d69674d9f081b6f78bd34cf012c150657a884 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 11 Oct 2021 17:09:50 +0100 Subject: [PATCH 052/413] moving is invitation help to the event file --- .../matrix/android/sdk/api/session/events/model/Event.kt | 5 +++++ .../session/notification/ProcessEventForPushTask.kt | 8 +------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index 169f90dbca..aad5fce33e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -22,6 +22,8 @@ import org.json.JSONObject import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageType import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent @@ -310,3 +312,6 @@ fun Event.isEdition(): Boolean { fun Event.getPresenceContent(): PresenceContent? { return content.toModel() } + +fun Event.isInvitation(): Boolean = type == EventType.STATE_ROOM_MEMBER && + content?.toModel()?.membership == Membership.INVITE diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt index 865f942ee9..3c74888eda 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt @@ -17,11 +17,8 @@ package org.matrix.android.sdk.internal.session.notification import org.matrix.android.sdk.api.pushrules.rest.PushRule -import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.model.RoomMemberContent +import org.matrix.android.sdk.api.session.events.model.isInvitation import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.task.Task @@ -101,6 +98,3 @@ internal class DefaultProcessEventForPushTask @Inject constructor( defaultPushRuleService.dispatchFinish() } } - -private fun Event.isInvitation(): Boolean = type == EventType.STATE_ROOM_MEMBER && - content?.toModel()?.membership == Membership.INVITE From 67211605aad72df13b6f1fa56d1aff33ef27f538 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 10:35:41 +0100 Subject: [PATCH 053/413] removing unused commented code --- .../fcm/VectorFirebaseMessagingService.kt | 83 ------------------- 1 file changed, 83 deletions(-) diff --git a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt index b1f0b43705..fadbeaa647 100755 --- a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt @@ -227,87 +227,4 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { } return false } - - private fun handleNotificationWithoutSyncingMode(data: Map, session: Session?) { - if (session == null) { - Timber.tag(loggerTag.value).e("## handleNotificationWithoutSyncingMode cannot find session") - return - } - - // The Matrix event ID of the event being notified about. - // This is required if the notification is about a particular Matrix event. - // It may be omitted for notifications that only contain updated badge counts. - // This ID can and should be used to detect duplicate notification requests. - val eventId = data["event_id"] ?: return // Just ignore - - val eventType = data["type"] - if (eventType == null) { - // Just add a generic unknown event - val simpleNotifiableEvent = SimpleNotifiableEvent( - session.myUserId, - eventId, - null, - true, // It's an issue in this case, all event will bing even if expected to be silent. - title = getString(R.string.notification_unknown_new_event), - description = "", - type = null, - timestamp = System.currentTimeMillis(), - soundName = Action.ACTION_OBJECT_VALUE_VALUE_DEFAULT, - isPushGatewayEvent = true - ) - notificationDrawerManager.onNotifiableEventReceived(simpleNotifiableEvent) - notificationDrawerManager.refreshNotificationDrawer() - } else { - val event = parseEvent(data) ?: return - - val notifiableEvent = notifiableEventResolver.resolveEvent(event, session) - - if (notifiableEvent == null) { - Timber.tag(loggerTag.value).e("Unsupported notifiable event $eventId") - if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) { - Timber.tag(loggerTag.value).e("--> $event") - } - } else { - if (notifiableEvent is NotifiableMessageEvent) { - if (notifiableEvent.senderName.isNullOrEmpty()) { - notifiableEvent.senderName = data["sender_display_name"] ?: data["sender"] ?: "" - } - if (notifiableEvent.roomName.isNullOrEmpty()) { - notifiableEvent.roomName = findRoomNameBestEffort(data, session) ?: "" - } - } - - notifiableEvent.isPushGatewayEvent = true - notifiableEvent.matrixID = session.myUserId - notificationDrawerManager.onNotifiableEventReceived(notifiableEvent) - notificationDrawerManager.refreshNotificationDrawer() - } - } - } - - private fun findRoomNameBestEffort(data: Map, session: Session?): String? { - var roomName: String? = data["room_name"] - val roomId = data["room_id"] - if (null == roomName && null != roomId) { - // Try to get the room name from our store - roomName = session?.getRoom(roomId)?.roomSummary()?.displayName - } - return roomName - } - - /** - * Try to create an event from the FCM data - * - * @param data the FCM data - * @return the event or null if required data are missing - */ - private fun parseEvent(data: Map?): Event? { - return Event( - eventId = data?.get("event_id") ?: return null, - senderId = data["sender"], - roomId = data["room_id"] ?: return null, - type = data["type"] ?: return null, - originServerTs = System.currentTimeMillis() - ) - } } From 51f7dee95232a905ca62a21abf91673ecd53a26e Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 11:09:30 +0100 Subject: [PATCH 054/413] removing non common properties form the base event --- .../notifications/InviteNotifiableEvent.kt | 14 +++++++------- .../app/features/notifications/NotifiableEvent.kt | 7 ------- .../notifications/NotifiableMessageEvent.kt | 14 ++++++-------- .../notifications/NotificationDrawerManager.kt | 4 ++-- .../notifications/SimpleNotifiableEvent.kt | 12 ++++++------ 5 files changed, 21 insertions(+), 30 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 61fd5c677a..488da60129 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -18,19 +18,19 @@ package im.vector.app.features.notifications import androidx.core.app.NotificationCompat data class InviteNotifiableEvent( - override var matrixID: String?, + var matrixID: String?, override val eventId: String, override val editedEventId: String?, var roomId: String, override var noisy: Boolean, - override val title: String, - override val description: String, - override val type: String?, - override val timestamp: Long, - override var soundName: String?, + val title: String, + val description: String, + val type: String?, + val timestamp: Long, + var soundName: String?, override var isPushGatewayEvent: Boolean = false) : NotifiableEvent { - override var hasBeenDisplayed: Boolean = false override var isRedacted: Boolean = false override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC + override var hasBeenDisplayed = false } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index a4f099b905..07833697b4 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -21,20 +21,13 @@ import java.io.Serializable * Parent interface for all events which can be displayed as a Notification */ interface NotifiableEvent : Serializable { - var matrixID: String? val eventId: String val editedEventId: String? var noisy: Boolean - val title: String - val description: String? - val type: String? - val timestamp: Long // NotificationCompat.VISIBILITY_PUBLIC , VISIBILITY_PRIVATE , VISIBILITY_SECRET var lockScreenVisibility: Int - // Compat: Only for android <7, for newer version the sound is defined in the channel - var soundName: String? var hasBeenDisplayed: Boolean var isRedacted: Boolean diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index fb9ca8d23c..721325e436 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -22,7 +22,7 @@ data class NotifiableMessageEvent( override val eventId: String, override val editedEventId: String?, override var noisy: Boolean, - override val timestamp: Long, + val timestamp: Long, var senderName: String?, var senderId: String?, var body: String?, @@ -31,8 +31,8 @@ data class NotifiableMessageEvent( var roomIsDirect: Boolean = false ) : NotifiableEvent { - override var matrixID: String? = null - override var soundName: String? = null + var matrixID: String? = null + var soundName: String? = null override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC override var hasBeenDisplayed: Boolean = false override var isRedacted: Boolean = false @@ -42,14 +42,12 @@ data class NotifiableMessageEvent( override var isPushGatewayEvent: Boolean = false - override val type: String - get() = EventType.MESSAGE + val type: String = EventType.MESSAGE - override val description: String? + val description: String get() = body ?: "" - override val title: String - get() = senderName ?: "" + val title: String = senderName ?: "" // This is used for >N notification, as the result of a smart reply var outGoingMessage = false diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 45c21bb028..8648490c6a 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -395,7 +395,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context textStyle = "bold" +String.format("%s: ", event.senderName) } - +(event.description ?: "") + +(event.description) } summaryInboxStyle.addLine(line) } else { @@ -404,7 +404,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context textStyle = "bold" +String.format("%s: %s ", roomName, event.senderName) } - +(event.description ?: "") + +(event.description) } summaryInboxStyle.addLine(line) } diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index 2f74737ba2..dbc04c6f65 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -18,15 +18,15 @@ package im.vector.app.features.notifications import androidx.core.app.NotificationCompat data class SimpleNotifiableEvent( - override var matrixID: String?, + var matrixID: String?, override val eventId: String, override val editedEventId: String?, override var noisy: Boolean, - override val title: String, - override val description: String, - override val type: String?, - override val timestamp: Long, - override var soundName: String?, + val title: String, + val description: String, + val type: String?, + val timestamp: Long, + var soundName: String?, override var isPushGatewayEvent: Boolean = false) : NotifiableEvent { override var hasBeenDisplayed: Boolean = false From 81da185d8b3a81bb43af5169f705b33b8d3bcaf3 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 11:23:23 +0100 Subject: [PATCH 055/413] making non overriden properties immutable by passing the values intro the constructor --- .../notifications/InviteNotifiableEvent.kt | 6 +-- .../notifications/NotifiableEventResolver.kt | 44 ++++++++----------- .../notifications/NotifiableMessageEvent.kt | 37 +++++++--------- .../NotificationBroadcastReceiver.kt | 22 +++++----- .../notifications/SimpleNotifiableEvent.kt | 4 +- 5 files changed, 52 insertions(+), 61 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 488da60129..7500ee3993 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -18,16 +18,16 @@ package im.vector.app.features.notifications import androidx.core.app.NotificationCompat data class InviteNotifiableEvent( - var matrixID: String?, + val matrixID: String?, override val eventId: String, override val editedEventId: String?, - var roomId: String, + val roomId: String, override var noisy: Boolean, val title: String, val description: String, val type: String?, val timestamp: Long, - var soundName: String?, + val soundName: String?, override var isPushGatewayEvent: Boolean = false) : NotifiableEvent { override var isRedacted: Boolean = false diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index 63c296f418..fa76a40835 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -142,7 +142,7 @@ class NotifiableEventResolver @Inject constructor( val roomName = stringProvider.getString(R.string.notification_unknown_room_name) val senderDisplayName = event.senderInfo.disambiguatedDisplayName - val notifiableEvent = NotifiableMessageEvent( + return NotifiableMessageEvent( eventId = event.root.eventId!!, editedEventId = event.getEditedEventId(), timestamp = event.root.originServerTs ?: 0, @@ -151,10 +151,9 @@ class NotifiableEventResolver @Inject constructor( senderId = event.root.senderId, body = body.toString(), roomId = event.root.roomId!!, - roomName = roomName) - - notifiableEvent.matrixID = session.myUserId - return notifiableEvent + roomName = roomName, + matrixID = session.myUserId + ) } else { if (event.root.isEncrypted() && event.root.mxDecryptionResult == null) { // TODO use a global event decryptor? attache to session and that listen to new sessionId? @@ -175,7 +174,7 @@ class NotifiableEventResolver @Inject constructor( val roomName = room.roomSummary()?.displayName ?: "" val senderDisplayName = event.senderInfo.disambiguatedDisplayName - val notifiableEvent = NotifiableMessageEvent( + return NotifiableMessageEvent( eventId = event.root.eventId!!, editedEventId = event.getEditedEventId(), timestamp = event.root.originServerTs ?: 0, @@ -185,25 +184,20 @@ class NotifiableEventResolver @Inject constructor( body = body, roomId = event.root.roomId!!, roomName = roomName, - roomIsDirect = room.roomSummary()?.isDirect ?: false) - - notifiableEvent.matrixID = session.myUserId - notifiableEvent.soundName = null - - // Get the avatars URL - notifiableEvent.roomAvatarPath = session.contentUrlResolver() - .resolveThumbnail(room.roomSummary()?.avatarUrl, - 250, - 250, - ContentUrlResolver.ThumbnailMethod.SCALE) - - notifiableEvent.senderAvatarPath = session.contentUrlResolver() - .resolveThumbnail(event.senderInfo.avatarUrl, - 250, - 250, - ContentUrlResolver.ThumbnailMethod.SCALE) - - return notifiableEvent + roomIsDirect = room.roomSummary()?.isDirect ?: false, + roomAvatarPath = session.contentUrlResolver() + .resolveThumbnail(room.roomSummary()?.avatarUrl, + 250, + 250, + ContentUrlResolver.ThumbnailMethod.SCALE), + senderAvatarPath = session.contentUrlResolver() + .resolveThumbnail(event.senderInfo.avatarUrl, + 250, + 250, + ContentUrlResolver.ThumbnailMethod.SCALE), + matrixID = session.myUserId, + soundName = null + ) } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index 721325e436..9370af5f5e 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -23,33 +23,30 @@ data class NotifiableMessageEvent( override val editedEventId: String?, override var noisy: Boolean, val timestamp: Long, - var senderName: String?, - var senderId: String?, - var body: String?, - var roomId: String, - var roomName: String?, - var roomIsDirect: Boolean = false + val senderName: String?, + val senderId: String?, + val body: String?, + val roomId: String, + val roomName: String?, + val roomIsDirect: Boolean = false, + val roomAvatarPath: String? = null, + val senderAvatarPath: String? = null, + + val matrixID: String? = null, + val soundName: String? = null, + + // This is used for >N notification, as the result of a smart reply + val outGoingMessage: Boolean = false, + val outGoingMessageFailed: Boolean = false + ) : NotifiableEvent { - var matrixID: String? = null - var soundName: String? = null override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC override var hasBeenDisplayed: Boolean = false override var isRedacted: Boolean = false - - var roomAvatarPath: String? = null - var senderAvatarPath: String? = null - override var isPushGatewayEvent: Boolean = false val type: String = EventType.MESSAGE - - val description: String - get() = body ?: "" - + val description: String = body ?: "" val title: String = senderName ?: "" - - // This is used for >N notification, as the result of a smart reply - var outGoingMessage = false - var outGoingMessageFailed = false } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt index 6583db6f69..60dfcca7a1 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt @@ -130,19 +130,19 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { val notifiableMessageEvent = NotifiableMessageEvent( // Generate a Fake event id - UUID.randomUUID().toString(), - null, - false, - System.currentTimeMillis(), - session.getRoomMember(session.myUserId, room.roomId)?.displayName + eventId = UUID.randomUUID().toString(), + editedEventId = null, + noisy = false, + timestamp = System.currentTimeMillis(), + senderName = session.getRoomMember(session.myUserId, room.roomId)?.displayName ?: context?.getString(R.string.notification_sender_me), - session.myUserId, - message, - room.roomId, - room.roomSummary()?.displayName ?: room.roomId, - room.roomSummary()?.isDirect == true + senderId = session.myUserId, + body = message, + roomId = room.roomId, + roomName = room.roomSummary()?.displayName ?: room.roomId, + roomIsDirect = room.roomSummary()?.isDirect == true, + outGoingMessage = true ) - notifiableMessageEvent.outGoingMessage = true notificationDrawerManager.onNotifiableEventReceived(notifiableMessageEvent) notificationDrawerManager.refreshNotificationDrawer() diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index dbc04c6f65..5d470158d9 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -18,7 +18,7 @@ package im.vector.app.features.notifications import androidx.core.app.NotificationCompat data class SimpleNotifiableEvent( - var matrixID: String?, + val matrixID: String?, override val eventId: String, override val editedEventId: String?, override var noisy: Boolean, @@ -26,7 +26,7 @@ data class SimpleNotifiableEvent( val description: String, val type: String?, val timestamp: Long, - var soundName: String?, + val soundName: String?, override var isPushGatewayEvent: Boolean = false) : NotifiableEvent { override var hasBeenDisplayed: Boolean = false From 89d643a4be739a7d45b5a7e7a6b91867108eaa74 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 11:28:54 +0100 Subject: [PATCH 056/413] removing unused property (written to but never read) --- .../app/features/notifications/InviteNotifiableEvent.kt | 3 --- .../im/vector/app/features/notifications/NotifiableEvent.kt | 3 --- .../app/features/notifications/NotifiableEventResolver.kt | 5 +---- .../app/features/notifications/NotifiableMessageEvent.kt | 2 -- .../app/features/notifications/SimpleNotifiableEvent.kt | 3 --- 5 files changed, 1 insertion(+), 15 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 7500ee3993..91cc216759 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -15,8 +15,6 @@ */ package im.vector.app.features.notifications -import androidx.core.app.NotificationCompat - data class InviteNotifiableEvent( val matrixID: String?, override val eventId: String, @@ -31,6 +29,5 @@ data class InviteNotifiableEvent( override var isPushGatewayEvent: Boolean = false) : NotifiableEvent { override var isRedacted: Boolean = false - override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC override var hasBeenDisplayed = false } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index 07833697b4..279bc192fd 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -25,9 +25,6 @@ interface NotifiableEvent : Serializable { val editedEventId: String? var noisy: Boolean - // NotificationCompat.VISIBILITY_PUBLIC , VISIBILITY_PRIVATE , VISIBILITY_SECRET - var lockScreenVisibility: Int - var hasBeenDisplayed: Boolean var isRedacted: Boolean diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index fa76a40835..9bc4194e49 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -15,7 +15,6 @@ */ package im.vector.app.features.notifications -import androidx.core.app.NotificationCompat import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.resources.StringProvider @@ -66,9 +65,7 @@ class NotifiableEventResolver @Inject constructor( return resolveMessageEvent(timelineEvent, session) } EventType.ENCRYPTED -> { - val messageEvent = resolveMessageEvent(timelineEvent, session) - messageEvent?.lockScreenVisibility = NotificationCompat.VISIBILITY_PRIVATE - return messageEvent + return resolveMessageEvent(timelineEvent, session) } else -> { // If the event can be displayed, display it as is diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index 9370af5f5e..f23c84afad 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -15,7 +15,6 @@ */ package im.vector.app.features.notifications -import androidx.core.app.NotificationCompat import org.matrix.android.sdk.api.session.events.model.EventType data class NotifiableMessageEvent( @@ -41,7 +40,6 @@ data class NotifiableMessageEvent( ) : NotifiableEvent { - override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC override var hasBeenDisplayed: Boolean = false override var isRedacted: Boolean = false override var isPushGatewayEvent: Boolean = false diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index 5d470158d9..7e776222af 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -15,8 +15,6 @@ */ package im.vector.app.features.notifications -import androidx.core.app.NotificationCompat - data class SimpleNotifiableEvent( val matrixID: String?, override val eventId: String, @@ -31,5 +29,4 @@ data class SimpleNotifiableEvent( override var hasBeenDisplayed: Boolean = false override var isRedacted: Boolean = false - override var lockScreenVisibility = NotificationCompat.VISIBILITY_PUBLIC } From c99dd4a615d672cef35c0029e156c114c21ea163 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 11:46:13 +0100 Subject: [PATCH 057/413] making the isRedacted event property immutable - also makes the notifiable events sealed interfaces so that we can copy the data classes with new redacted values when it changes --- .../notifications/InviteNotifiableEvent.kt | 5 +++-- .../features/notifications/NotifiableEvent.kt | 6 ++---- .../notifications/NotifiableMessageEvent.kt | 7 +++---- .../notifications/NotificationDrawerManager.kt | 17 ++++++++++++++--- .../notifications/SimpleNotifiableEvent.kt | 6 ++++-- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 91cc216759..9f958965ea 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -26,8 +26,9 @@ data class InviteNotifiableEvent( val type: String?, val timestamp: Long, val soundName: String?, - override var isPushGatewayEvent: Boolean = false) : NotifiableEvent { + override var isPushGatewayEvent: Boolean = false, + override val isRedacted: Boolean = false +) : NotifiableEvent { - override var isRedacted: Boolean = false override var hasBeenDisplayed = false } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index 279bc192fd..6365b1c7bf 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -20,14 +20,12 @@ import java.io.Serializable /** * Parent interface for all events which can be displayed as a Notification */ -interface NotifiableEvent : Serializable { +sealed interface NotifiableEvent : Serializable { val eventId: String val editedEventId: String? var noisy: Boolean - var hasBeenDisplayed: Boolean - var isRedacted: Boolean - // Used to know if event should be replaced with the one coming from eventstream var isPushGatewayEvent: Boolean + val isRedacted: Boolean } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index f23c84afad..7d9ef42f8e 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -36,12 +36,11 @@ data class NotifiableMessageEvent( // This is used for >N notification, as the result of a smart reply val outGoingMessage: Boolean = false, - val outGoingMessageFailed: Boolean = false - + val outGoingMessageFailed: Boolean = false, + override var hasBeenDisplayed: Boolean = false, + override val isRedacted: Boolean = false ) : NotifiableEvent { - override var hasBeenDisplayed: Boolean = false - override var isRedacted: Boolean = false override var isPushGatewayEvent: Boolean = false val type: String = EventType.MESSAGE diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 8648490c6a..5496dd6649 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -162,9 +162,12 @@ class NotificationDrawerManager @Inject constructor(private val context: Context fun onEventRedacted(eventId: String) { synchronized(eventList) { - eventList.find { it.eventId == eventId }?.apply { - isRedacted = true - hasBeenDisplayed = false + eventList.replace(eventId) { + when (it) { + is InviteNotifiableEvent -> it.copy(isRedacted = true).apply { hasBeenDisplayed = false } + is NotifiableMessageEvent -> it.copy(isRedacted = true).apply { hasBeenDisplayed = false } + is SimpleNotifiableEvent -> it.copy(isRedacted = true).apply { hasBeenDisplayed = false } + } } } } @@ -665,3 +668,11 @@ class NotificationDrawerManager @Inject constructor(private val context: Context private const val KEY_ALIAS_SECRET_STORAGE = "notificationMgr" } } + +private fun MutableList.replace(eventId: String, block: (NotifiableEvent) -> NotifiableEvent) { + val indexToReplace = indexOfFirst { it.eventId == eventId } + if (indexToReplace == -1) { + return + } + set(indexToReplace, block(get(indexToReplace))) +} diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index 7e776222af..49a69fc51a 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -25,8 +25,10 @@ data class SimpleNotifiableEvent( val type: String?, val timestamp: Long, val soundName: String?, - override var isPushGatewayEvent: Boolean = false) : NotifiableEvent { + override var isPushGatewayEvent: Boolean = false, + override val isRedacted: Boolean = false +) : NotifiableEvent { override var hasBeenDisplayed: Boolean = false - override var isRedacted: Boolean = false + } From db5d4ead38a466e052d6702efc82561ab4c278b0 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 11:52:54 +0100 Subject: [PATCH 058/413] making the noisy property immutable --- .../notifications/InviteNotifiableEvent.kt | 2 +- .../features/notifications/NotifiableEvent.kt | 1 - .../notifications/NotifiableEventResolver.kt | 30 +++++++------------ .../notifications/NotifiableMessageEvent.kt | 2 +- .../notifications/PushRuleTriggerListener.kt | 3 +- .../notifications/SimpleNotifiableEvent.kt | 2 +- 6 files changed, 14 insertions(+), 26 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 9f958965ea..81951df8ef 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -20,7 +20,7 @@ data class InviteNotifiableEvent( override val eventId: String, override val editedEventId: String?, val roomId: String, - override var noisy: Boolean, + val noisy: Boolean, val title: String, val description: String, val type: String?, diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index 6365b1c7bf..d6b7181610 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -23,7 +23,6 @@ import java.io.Serializable sealed interface NotifiableEvent : Serializable { val eventId: String val editedEventId: String? - var noisy: Boolean var hasBeenDisplayed: Boolean // Used to know if event should be replaced with the one coming from eventstream var isPushGatewayEvent: Boolean diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index 9bc4194e49..c2ffb0b1b3 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -53,19 +53,19 @@ class NotifiableEventResolver @Inject constructor( // private val eventDisplay = RiotEventDisplay(context) - fun resolveEvent(event: Event/*, roomState: RoomState?, bingRule: PushRule?*/, session: Session): NotifiableEvent? { + fun resolveEvent(event: Event/*, roomState: RoomState?, bingRule: PushRule?*/, session: Session, isNoisy: Boolean): NotifiableEvent? { val roomID = event.roomId ?: return null val eventId = event.eventId ?: return null if (event.getClearType() == EventType.STATE_ROOM_MEMBER) { - return resolveStateRoomEvent(event, session) + return resolveStateRoomEvent(event, session, isNoisy) } val timelineEvent = session.getRoom(roomID)?.getTimeLineEvent(eventId) ?: return null when (event.getClearType()) { EventType.MESSAGE -> { - return resolveMessageEvent(timelineEvent, session) + return resolveMessageEvent(timelineEvent, session, isNoisy) } EventType.ENCRYPTED -> { - return resolveMessageEvent(timelineEvent, session) + return resolveMessageEvent(timelineEvent, session, isNoisy) } else -> { // If the event can be displayed, display it as is @@ -111,24 +111,14 @@ class NotifiableEventResolver @Inject constructor( avatarUrl = user.avatarUrl ) ) - - val notifiableEvent = resolveMessageEvent(timelineEvent, session) - - if (notifiableEvent == null) { - Timber.d("## Failed to resolve event") - // TODO - null - } else { - notifiableEvent.noisy = !notificationAction.soundName.isNullOrBlank() - notifiableEvent - } + resolveMessageEvent(timelineEvent, session, isNoisy = !notificationAction.soundName.isNullOrBlank()) } else { Timber.d("Matched push rule is set to not notify") null } } - private fun resolveMessageEvent(event: TimelineEvent, session: Session): NotifiableEvent? { + private fun resolveMessageEvent(event: TimelineEvent, session: Session, isNoisy: Boolean): NotifiableEvent { // The event only contains an eventId, and roomId (type is m.room.*) , we need to get the displayable content (names, avatar, text, etc...) val room = session.getRoom(event.root.roomId!! /*roomID cannot be null*/) @@ -143,7 +133,7 @@ class NotifiableEventResolver @Inject constructor( eventId = event.root.eventId!!, editedEventId = event.getEditedEventId(), timestamp = event.root.originServerTs ?: 0, - noisy = false, // will be updated + noisy = isNoisy, senderName = senderDisplayName, senderId = event.root.senderId, body = body.toString(), @@ -175,7 +165,7 @@ class NotifiableEventResolver @Inject constructor( eventId = event.root.eventId!!, editedEventId = event.getEditedEventId(), timestamp = event.root.originServerTs ?: 0, - noisy = false, // will be updated + noisy = isNoisy, senderName = senderDisplayName, senderId = event.root.senderId, body = body, @@ -198,7 +188,7 @@ class NotifiableEventResolver @Inject constructor( } } - private fun resolveStateRoomEvent(event: Event, session: Session): NotifiableEvent? { + private fun resolveStateRoomEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? { val content = event.content?.toModel() ?: return null val roomId = event.roomId ?: return null val dName = event.senderId?.let { session.getRoomMember(it, roomId)?.displayName } @@ -211,7 +201,7 @@ class NotifiableEventResolver @Inject constructor( editedEventId = null, roomId = roomId, timestamp = event.originServerTs ?: 0, - noisy = false, // will be set later + noisy = isNoisy, title = stringProvider.getString(R.string.notification_new_invitation), description = body.toString(), soundName = null, // will be set later diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index 7d9ef42f8e..7f0c83ef7a 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -20,7 +20,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType data class NotifiableMessageEvent( override val eventId: String, override val editedEventId: String?, - override var noisy: Boolean, + val noisy: Boolean, val timestamp: Long, val senderName: String?, val senderId: String?, diff --git a/vector/src/main/java/im/vector/app/features/notifications/PushRuleTriggerListener.kt b/vector/src/main/java/im/vector/app/features/notifications/PushRuleTriggerListener.kt index 791803fa49..abbbd47f95 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/PushRuleTriggerListener.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/PushRuleTriggerListener.kt @@ -40,12 +40,11 @@ class PushRuleTriggerListener @Inject constructor( val notificationAction = actions.toNotificationAction() if (notificationAction.shouldNotify) { - val notifiableEvent = resolver.resolveEvent(event, safeSession) + val notifiableEvent = resolver.resolveEvent(event, safeSession, isNoisy = !notificationAction.soundName.isNullOrBlank()) if (notifiableEvent == null) { Timber.v("## Failed to resolve event") // TODO } else { - notifiableEvent.noisy = !notificationAction.soundName.isNullOrBlank() Timber.v("New event to notify") notificationDrawerManager.onNotifiableEventReceived(notifiableEvent) } diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index 49a69fc51a..a6f45a0f72 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -19,7 +19,7 @@ data class SimpleNotifiableEvent( val matrixID: String?, override val eventId: String, override val editedEventId: String?, - override var noisy: Boolean, + val noisy: Boolean, val title: String, val description: String, val type: String?, From b44a382893512a38bafe93263954cabcbc7a3e0f Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 11:57:32 +0100 Subject: [PATCH 059/413] separating the mutable vars from the immutable ones, they'll be removed or made immutable by the notification redesign --- .../app/features/notifications/InviteNotifiableEvent.kt | 2 +- .../app/features/notifications/NotifiableEventResolver.kt | 4 ++-- .../app/features/notifications/NotifiableMessageEvent.kt | 4 +--- .../app/features/notifications/SimpleNotifiableEvent.kt | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 81951df8ef..742be02eb5 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -26,9 +26,9 @@ data class InviteNotifiableEvent( val type: String?, val timestamp: Long, val soundName: String?, - override var isPushGatewayEvent: Boolean = false, override val isRedacted: Boolean = false ) : NotifiableEvent { + override var isPushGatewayEvent: Boolean = false override var hasBeenDisplayed = false } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index c2ffb0b1b3..a5ea176a86 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -205,8 +205,8 @@ class NotifiableEventResolver @Inject constructor( title = stringProvider.getString(R.string.notification_new_invitation), description = body.toString(), soundName = null, // will be set later - type = event.getClearType(), - isPushGatewayEvent = false) + type = event.getClearType() + ) } else { Timber.e("## unsupported notifiable event for eventId [${event.eventId}]") if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) { diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index 7f0c83ef7a..b806002a99 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -30,18 +30,16 @@ data class NotifiableMessageEvent( val roomIsDirect: Boolean = false, val roomAvatarPath: String? = null, val senderAvatarPath: String? = null, - val matrixID: String? = null, val soundName: String? = null, - // This is used for >N notification, as the result of a smart reply val outGoingMessage: Boolean = false, val outGoingMessageFailed: Boolean = false, - override var hasBeenDisplayed: Boolean = false, override val isRedacted: Boolean = false ) : NotifiableEvent { override var isPushGatewayEvent: Boolean = false + override var hasBeenDisplayed: Boolean = false val type: String = EventType.MESSAGE val description: String = body ?: "" diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index a6f45a0f72..c7aaf4aa6c 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -25,10 +25,10 @@ data class SimpleNotifiableEvent( val type: String?, val timestamp: Long, val soundName: String?, - override var isPushGatewayEvent: Boolean = false, override val isRedacted: Boolean = false ) : NotifiableEvent { + override var isPushGatewayEvent: Boolean = false override var hasBeenDisplayed: Boolean = false } From 86b500445fe0a15099a907d0606ad8c96da8dd39 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 12:19:35 +0100 Subject: [PATCH 060/413] updating the push gateway property to reflect that it mean the event can be replaced - makes the property immutable as only the creation of the event knows if it can be replace eg it came from a push or the /sync event stream --- .../fcm/VectorFirebaseMessagingService.kt | 8 +------ .../notifications/InviteNotifiableEvent.kt | 2 +- .../features/notifications/NotifiableEvent.kt | 2 +- .../notifications/NotifiableEventResolver.kt | 21 ++++++++++++------- .../notifications/NotifiableMessageEvent.kt | 2 +- .../NotificationBroadcastReceiver.kt | 3 ++- .../NotificationDrawerManager.kt | 4 ++-- .../notifications/SimpleNotifiableEvent.kt | 2 +- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt index fadbeaa647..63d50d4f97 100755 --- a/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt +++ b/vector/src/gplay/java/im/vector/app/gplay/push/fcm/VectorFirebaseMessagingService.kt @@ -29,16 +29,13 @@ 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.network.WifiDetector import im.vector.app.core.pushers.PushersManager import im.vector.app.features.badge.BadgeProxy import im.vector.app.features.notifications.NotifiableEventResolver -import im.vector.app.features.notifications.NotifiableMessageEvent import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.NotificationUtils -import im.vector.app.features.notifications.SimpleNotifiableEvent import im.vector.app.features.settings.VectorDataStore import im.vector.app.features.settings.VectorPreferences import im.vector.app.push.fcm.FcmHelper @@ -48,9 +45,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.logger.LoggerTag -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 @@ -201,12 +196,11 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() { Timber.tag(loggerTag.value).d("Fast lane: start request") val event = tryOrNull { session.getEvent(roomId, eventId) } ?: return@launch - val resolvedEvent = notifiableEventResolver.resolveInMemoryEvent(session, event) + val resolvedEvent = notifiableEventResolver.resolveInMemoryEvent(session, event, canBeReplaced = true) resolvedEvent ?.also { Timber.tag(loggerTag.value).d("Fast lane: notify drawer") } ?.let { - it.isPushGatewayEvent = true notificationDrawerManager.onNotifiableEventReceived(it) notificationDrawerManager.refreshNotificationDrawer() } diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 742be02eb5..2d891041b1 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -19,6 +19,7 @@ data class InviteNotifiableEvent( val matrixID: String?, override val eventId: String, override val editedEventId: String?, + override val canBeReplaced: Boolean, val roomId: String, val noisy: Boolean, val title: String, @@ -29,6 +30,5 @@ data class InviteNotifiableEvent( override val isRedacted: Boolean = false ) : NotifiableEvent { - override var isPushGatewayEvent: Boolean = false override var hasBeenDisplayed = false } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index d6b7181610..d9c0c22116 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -25,6 +25,6 @@ sealed interface NotifiableEvent : Serializable { val editedEventId: String? var hasBeenDisplayed: Boolean // Used to know if event should be replaced with the one coming from eventstream - var isPushGatewayEvent: Boolean + val canBeReplaced: Boolean val isRedacted: Boolean } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index a5ea176a86..552f96b5a0 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -57,15 +57,15 @@ class NotifiableEventResolver @Inject constructor( val roomID = event.roomId ?: return null val eventId = event.eventId ?: return null if (event.getClearType() == EventType.STATE_ROOM_MEMBER) { - return resolveStateRoomEvent(event, session, isNoisy) + return resolveStateRoomEvent(event, session, canBeReplaced = false, isNoisy = isNoisy) } val timelineEvent = session.getRoom(roomID)?.getTimeLineEvent(eventId) ?: return null when (event.getClearType()) { EventType.MESSAGE -> { - return resolveMessageEvent(timelineEvent, session, isNoisy) + return resolveMessageEvent(timelineEvent, session, canBeReplaced = false, isNoisy = isNoisy) } EventType.ENCRYPTED -> { - return resolveMessageEvent(timelineEvent, session, isNoisy) + return resolveMessageEvent(timelineEvent, session, canBeReplaced = false, isNoisy = isNoisy) } else -> { // If the event can be displayed, display it as is @@ -82,12 +82,14 @@ class NotifiableEventResolver @Inject constructor( description = bodyPreview, title = stringProvider.getString(R.string.notification_unknown_new_event), soundName = null, - type = event.type) + type = event.type, + canBeReplaced = false + ) } } } - fun resolveInMemoryEvent(session: Session, event: Event): NotifiableEvent? { + fun resolveInMemoryEvent(session: Session, event: Event, canBeReplaced: Boolean): NotifiableEvent? { if (event.getClearType() != EventType.MESSAGE) return null // Ignore message edition @@ -111,14 +113,14 @@ class NotifiableEventResolver @Inject constructor( avatarUrl = user.avatarUrl ) ) - resolveMessageEvent(timelineEvent, session, isNoisy = !notificationAction.soundName.isNullOrBlank()) + resolveMessageEvent(timelineEvent, session, canBeReplaced = canBeReplaced, isNoisy = !notificationAction.soundName.isNullOrBlank()) } else { Timber.d("Matched push rule is set to not notify") null } } - private fun resolveMessageEvent(event: TimelineEvent, session: Session, isNoisy: Boolean): NotifiableEvent { + private fun resolveMessageEvent(event: TimelineEvent, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): NotifiableEvent { // The event only contains an eventId, and roomId (type is m.room.*) , we need to get the displayable content (names, avatar, text, etc...) val room = session.getRoom(event.root.roomId!! /*roomID cannot be null*/) @@ -132,6 +134,7 @@ class NotifiableEventResolver @Inject constructor( return NotifiableMessageEvent( eventId = event.root.eventId!!, editedEventId = event.getEditedEventId(), + canBeReplaced = canBeReplaced, timestamp = event.root.originServerTs ?: 0, noisy = isNoisy, senderName = senderDisplayName, @@ -164,6 +167,7 @@ class NotifiableEventResolver @Inject constructor( return NotifiableMessageEvent( eventId = event.root.eventId!!, editedEventId = event.getEditedEventId(), + canBeReplaced = canBeReplaced, timestamp = event.root.originServerTs ?: 0, noisy = isNoisy, senderName = senderDisplayName, @@ -188,7 +192,7 @@ class NotifiableEventResolver @Inject constructor( } } - private fun resolveStateRoomEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? { + private fun resolveStateRoomEvent(event: Event, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): NotifiableEvent? { val content = event.content?.toModel() ?: return null val roomId = event.roomId ?: return null val dName = event.senderId?.let { session.getRoomMember(it, roomId)?.displayName } @@ -199,6 +203,7 @@ class NotifiableEventResolver @Inject constructor( session.myUserId, eventId = event.eventId!!, editedEventId = null, + canBeReplaced = canBeReplaced, roomId = roomId, timestamp = event.originServerTs ?: 0, noisy = isNoisy, diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index b806002a99..4a2152c417 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -20,6 +20,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType data class NotifiableMessageEvent( override val eventId: String, override val editedEventId: String?, + override val canBeReplaced: Boolean, val noisy: Boolean, val timestamp: Long, val senderName: String?, @@ -38,7 +39,6 @@ data class NotifiableMessageEvent( override val isRedacted: Boolean = false ) : NotifiableEvent { - override var isPushGatewayEvent: Boolean = false override var hasBeenDisplayed: Boolean = false val type: String = EventType.MESSAGE diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt index 60dfcca7a1..33e43cd7e4 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt @@ -141,7 +141,8 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { roomId = room.roomId, roomName = room.roomSummary()?.displayName ?: room.roomId, roomIsDirect = room.roomSummary()?.isDirect == true, - outGoingMessage = true + outGoingMessage = true, + canBeReplaced = false ) notificationDrawerManager.onNotifiableEventReceived(notifiableMessageEvent) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 5496dd6649..8c0e5fee5f 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -107,12 +107,12 @@ class NotificationDrawerManager @Inject constructor(private val context: Context if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) { Timber.d("onNotifiableEventReceived(): $notifiableEvent") } else { - Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.isPushGatewayEvent}") + Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.canBeReplaced}") } synchronized(eventList) { val existing = eventList.firstOrNull { it.eventId == notifiableEvent.eventId } if (existing != null) { - if (existing.isPushGatewayEvent) { + if (existing.canBeReplaced) { // Use the event coming from the event stream as it may contains more info than // the fcm one (like type/content/clear text) (e.g when an encrypted message from // FCM should be update with clear text after a sync) diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index c7aaf4aa6c..ca9b3f014e 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -25,10 +25,10 @@ data class SimpleNotifiableEvent( val type: String?, val timestamp: Long, val soundName: String?, + override var canBeReplaced: Boolean, override val isRedacted: Boolean = false ) : NotifiableEvent { - override var isPushGatewayEvent: Boolean = false override var hasBeenDisplayed: Boolean = false } From 56e2b79774c9f9c3480b3e118a8551817ecdb4d3 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 12:22:44 +0100 Subject: [PATCH 061/413] formatting --- .../java/im/vector/app/features/notifications/NotifiableEvent.kt | 1 + .../vector/app/features/notifications/SimpleNotifiableEvent.kt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index d9c0c22116..2f79da6795 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -24,6 +24,7 @@ sealed interface NotifiableEvent : Serializable { val eventId: String val editedEventId: String? var hasBeenDisplayed: Boolean + // Used to know if event should be replaced with the one coming from eventstream val canBeReplaced: Boolean val isRedacted: Boolean diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index ca9b3f014e..940d8a3770 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -30,5 +30,4 @@ data class SimpleNotifiableEvent( ) : NotifiableEvent { override var hasBeenDisplayed: Boolean = false - } From beff5ab821c544acd8ef711f079726b08b9989d9 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 12 Oct 2021 17:27:21 +0100 Subject: [PATCH 062/413] including the room name in the invitation event if the room sumary is available --- .../app/features/notifications/InviteNotifiableEvent.kt | 1 + .../app/features/notifications/NotifiableEventResolver.kt | 4 +++- .../im/vector/app/features/notifications/NotificationUtils.kt | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 2d891041b1..743b3587a8 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -21,6 +21,7 @@ data class InviteNotifiableEvent( override val editedEventId: String?, override val canBeReplaced: Boolean, val roomId: String, + val roomName: String?, val noisy: Boolean, val title: String, val description: String, diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index 552f96b5a0..d2db73af3d 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -197,7 +197,8 @@ class NotifiableEventResolver @Inject constructor( val roomId = event.roomId ?: return null val dName = event.senderId?.let { session.getRoomMember(it, roomId)?.displayName } if (Membership.INVITE == content.membership) { - val body = noticeEventFormatter.format(event, dName, isDm = session.getRoomSummary(roomId)?.isDirect.orFalse()) + val roomSummary = session.getRoomSummary(roomId) + val body = noticeEventFormatter.format(event, dName, isDm = roomSummary?.isDirect.orFalse()) ?: stringProvider.getString(R.string.notification_new_invitation) return InviteNotifiableEvent( session.myUserId, @@ -205,6 +206,7 @@ class NotifiableEventResolver @Inject constructor( editedEventId = null, canBeReplaced = canBeReplaced, roomId = roomId, + roomName = roomSummary?.displayName, timestamp = event.originServerTs ?: 0, noisy = isNoisy, title = stringProvider.getString(R.string.notification_new_invitation), diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index f3b34e1269..491302a225 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -642,7 +642,7 @@ class NotificationUtils @Inject constructor(private val context: Context, return NotificationCompat.Builder(context, channelID) .setOnlyAlertOnce(true) - .setContentTitle(stringProvider.getString(R.string.app_name)) + .setContentTitle(inviteNotifiableEvent.roomName ?: stringProvider.getString(R.string.app_name)) .setContentText(inviteNotifiableEvent.description) .setGroup(stringProvider.getString(R.string.app_name)) .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_ALL) From 6cc6cc58f095f642a416bfb66df796494e759cb8 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 12 Oct 2021 17:33:50 +0100 Subject: [PATCH 063/413] adding changelog entry --- changelog.d/582.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/582.feature diff --git a/changelog.d/582.feature b/changelog.d/582.feature new file mode 100644 index 0000000000..5f82e1b82c --- /dev/null +++ b/changelog.d/582.feature @@ -0,0 +1 @@ +Adding the room name to the invitation notification (if the room summary is available) \ No newline at end of file From 4459aab558b16c653d575fa186c6c961fc5e37e9 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 5 Oct 2021 16:55:28 +0100 Subject: [PATCH 064/413] making the event body non null and immutable to allow less cases to be handled - also puts in the basis for a separate notification refreshing implementation --- .../NotificationDrawerManager.kt | 511 +++++++++--------- 1 file changed, 258 insertions(+), 253 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 8c0e5fee5f..843b7208fd 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -250,31 +250,35 @@ class NotificationDrawerManager @Inject constructor(private val context: Context @WorkerThread private fun refreshNotificationDrawerBg() { Timber.v("refreshNotificationDrawerBg()") - val session = currentSession ?: return val user = session.getUser(session.myUserId) // myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash val myUserDisplayName = user?.toMatrixItem()?.getBestName() ?: session.myUserId val myUserAvatarUrl = session.contentUrlResolver().resolveThumbnail(user?.avatarUrl, avatarSize, avatarSize, ContentUrlResolver.ThumbnailMethod.SCALE) + synchronized(eventList) { - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER ") - // TMP code - var hasNewEvent = false - var summaryIsNoisy = false - val summaryInboxStyle = NotificationCompat.InboxStyle() + val useSplitNotifications = false + if (useSplitNotifications) { + // TODO + } else { + Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER ") + // TMP code + var hasNewEvent = false + var summaryIsNoisy = false + val summaryInboxStyle = NotificationCompat.InboxStyle() - // group events by room to create a single MessagingStyle notif - val roomIdToEventMap: MutableMap> = LinkedHashMap() - val simpleEvents: MutableList = ArrayList() - val invitationEvents: MutableList = ArrayList() + // group events by room to create a single MessagingStyle notif + val roomIdToEventMap: MutableMap> = LinkedHashMap() + val simpleEvents: MutableList = ArrayList() + val invitationEvents: MutableList = ArrayList() - val eventIterator = eventList.listIterator() - while (eventIterator.hasNext()) { - when (val event = eventIterator.next()) { - is NotifiableMessageEvent -> { - val roomId = event.roomId - val roomEvents = roomIdToEventMap.getOrPut(roomId) { ArrayList() } + val eventIterator = eventList.listIterator() + while (eventIterator.hasNext()) { + when (val event = eventIterator.next()) { + is NotifiableMessageEvent -> { + val roomId = event.roomId + val roomEvents = roomIdToEventMap.getOrPut(roomId) { ArrayList() } if (shouldIgnoreMessageEventInRoom(roomId) || outdatedDetector?.isMessageOutdated(event) == true) { // forget this event @@ -296,59 +300,59 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } } - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER ${roomIdToEventMap.size} room groups") + Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER ${roomIdToEventMap.size} room groups") - var globalLastMessageTimestamp = 0L + var globalLastMessageTimestamp = 0L - val newSettings = vectorPreferences.useCompleteNotificationFormat() - if (newSettings != useCompleteNotificationFormat) { - // Settings has changed, remove all current notifications - notificationUtils.cancelAllNotifications() - useCompleteNotificationFormat = newSettings - } - - var simpleNotificationRoomCounter = 0 - var simpleNotificationMessageCounter = 0 - - // events have been grouped by roomId - for ((roomId, events) in roomIdToEventMap) { - // Build the notification for the room - if (events.isEmpty() || events.all { it.isRedacted }) { - // Just clear this notification - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId has no more events") - notificationUtils.cancelNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID) - continue + val newSettings = vectorPreferences.useCompleteNotificationFormat() + if (newSettings != useCompleteNotificationFormat) { + // Settings has changed, remove all current notifications + notificationUtils.cancelAllNotifications() + useCompleteNotificationFormat = newSettings } - simpleNotificationRoomCounter++ - val roomName = events[0].roomName ?: events[0].senderName ?: "" + var simpleNotificationRoomCounter = 0 + var simpleNotificationMessageCounter = 0 - val roomEventGroupInfo = RoomEventGroupInfo( - roomId = roomId, - isDirect = events[0].roomIsDirect, - roomDisplayName = roomName) - - val style = NotificationCompat.MessagingStyle(Person.Builder() - .setName(myUserDisplayName) - .setIcon(iconLoader.getUserIcon(myUserAvatarUrl)) - .setKey(events[0].matrixID) - .build()) - - style.isGroupConversation = !roomEventGroupInfo.isDirect - - if (!roomEventGroupInfo.isDirect) { - style.conversationTitle = roomEventGroupInfo.roomDisplayName - } - - val largeBitmap = getRoomBitmap(events) - - for (event in events) { - // if all events in this room have already been displayed there is no need to update it - if (!event.hasBeenDisplayed && !event.isRedacted) { - roomEventGroupInfo.shouldBing = roomEventGroupInfo.shouldBing || event.noisy - roomEventGroupInfo.customSound = event.soundName + // events have been grouped by roomId + for ((roomId, events) in roomIdToEventMap) { + // Build the notification for the room + if (events.isEmpty() || events.all { it.isRedacted }) { + // Just clear this notification + Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId has no more events") + notificationUtils.cancelNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID) + continue } - roomEventGroupInfo.hasNewEvent = roomEventGroupInfo.hasNewEvent || !event.hasBeenDisplayed + + simpleNotificationRoomCounter++ + val roomName = events[0].roomName ?: events[0].senderName ?: "" + + val roomEventGroupInfo = RoomEventGroupInfo( + roomId = roomId, + isDirect = events[0].roomIsDirect, + roomDisplayName = roomName) + + val style = NotificationCompat.MessagingStyle(Person.Builder() + .setName(myUserDisplayName) + .setIcon(iconLoader.getUserIcon(myUserAvatarUrl)) + .setKey(events[0].matrixID) + .build()) + + style.isGroupConversation = !roomEventGroupInfo.isDirect + + if (!roomEventGroupInfo.isDirect) { + style.conversationTitle = roomEventGroupInfo.roomDisplayName + } + + val largeBitmap = getRoomBitmap(events) + + for (event in events) { + // if all events in this room have already been displayed there is no need to update it + if (!event.hasBeenDisplayed && !event.isRedacted) { + roomEventGroupInfo.shouldBing = roomEventGroupInfo.shouldBing || event.noisy + roomEventGroupInfo.customSound = event.soundName + } + roomEventGroupInfo.hasNewEvent = roomEventGroupInfo.hasNewEvent || !event.hasBeenDisplayed val senderPerson = if (event.outGoingMessage) { null @@ -373,211 +377,211 @@ class NotificationDrawerManager @Inject constructor(private val context: Context ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) } - if (event.outGoingMessage && event.outGoingMessageFailed) { - style.addMessage(stringProvider.getString(R.string.notification_inline_reply_failed), event.timestamp, senderPerson) - roomEventGroupInfo.hasSmartReplyError = true - } else { - if (!event.isRedacted) { - simpleNotificationMessageCounter++ - style.addMessage(event.body, event.timestamp, senderPerson) - } - } - event.hasBeenDisplayed = true // we can consider it as displayed - - // It is possible that this event was previously shown as an 'anonymous' simple notif. - // And now it will be merged in a single MessageStyle notif, so we can clean to be sure - notificationUtils.cancelNotificationMessage(event.eventId, ROOM_EVENT_NOTIFICATION_ID) - } - - try { - if (events.size == 1) { - val event = events[0] - if (roomEventGroupInfo.isDirect) { - val line = span { - span { - textStyle = "bold" - +String.format("%s: ", event.senderName) - } - +(event.description) - } - summaryInboxStyle.addLine(line) + if (event.outGoingMessage && event.outGoingMessageFailed) { + style.addMessage(stringProvider.getString(R.string.notification_inline_reply_failed), event.timestamp, senderPerson) + roomEventGroupInfo.hasSmartReplyError = true } else { - val line = span { - span { - textStyle = "bold" - +String.format("%s: %s ", roomName, event.senderName) - } - +(event.description) + if (!event.isRedacted) { + simpleNotificationMessageCounter++ + style.addMessage(event.body, event.timestamp, senderPerson) } - summaryInboxStyle.addLine(line) } + event.hasBeenDisplayed = true // we can consider it as displayed + + // It is possible that this event was previously shown as an 'anonymous' simple notif. + // And now it will be merged in a single MessageStyle notif, so we can clean to be sure + notificationUtils.cancelNotificationMessage(event.eventId, ROOM_EVENT_NOTIFICATION_ID) + } + + try { + if (events.size == 1) { + val event = events[0] + if (roomEventGroupInfo.isDirect) { + val line = span { + span { + textStyle = "bold" + +String.format("%s: ", event.senderName) + } + +(event.description) + } + summaryInboxStyle.addLine(line) + } else { + val line = span { + span { + textStyle = "bold" + +String.format("%s: %s ", roomName, event.senderName) + } + +(event.description) + } + summaryInboxStyle.addLine(line) + } + } else { + val summaryLine = stringProvider.getQuantityString( + R.plurals.notification_compat_summary_line_for_room, events.size, roomName, events.size) + summaryInboxStyle.addLine(summaryLine) + } + } catch (e: Throwable) { + // String not found or bad format + Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER failed to resolve string") + summaryInboxStyle.addLine(roomName) + } + + if (firstTime || roomEventGroupInfo.hasNewEvent) { + // Should update displayed notification + Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId need refresh") + val lastMessageTimestamp = events.last().timestamp + + if (globalLastMessageTimestamp < lastMessageTimestamp) { + globalLastMessageTimestamp = lastMessageTimestamp + } + + val tickerText = if (roomEventGroupInfo.isDirect) { + stringProvider.getString(R.string.notification_ticker_text_dm, events.last().senderName, events.last().description) + } else { + stringProvider.getString(R.string.notification_ticker_text_group, roomName, events.last().senderName, events.last().description) + } + + if (useCompleteNotificationFormat) { + val notification = notificationUtils.buildMessagesListNotification( + style, + roomEventGroupInfo, + largeBitmap, + lastMessageTimestamp, + myUserDisplayName, + tickerText) + + // is there an id for this room? + notificationUtils.showNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID, notification) + } + + hasNewEvent = true + summaryIsNoisy = summaryIsNoisy || roomEventGroupInfo.shouldBing } else { - val summaryLine = stringProvider.getQuantityString( - R.plurals.notification_compat_summary_line_for_room, events.size, roomName, events.size) - summaryInboxStyle.addLine(summaryLine) + Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId is up to date") } - } catch (e: Throwable) { - // String not found or bad format - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER failed to resolve string") - summaryInboxStyle.addLine(roomName) } - if (firstTime || roomEventGroupInfo.hasNewEvent) { - // Should update displayed notification - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId need refresh") - val lastMessageTimestamp = events.last().timestamp - - if (globalLastMessageTimestamp < lastMessageTimestamp) { - globalLastMessageTimestamp = lastMessageTimestamp + // Handle invitation events + for (event in invitationEvents) { + // We build a invitation notification + if (firstTime || !event.hasBeenDisplayed) { + if (useCompleteNotificationFormat) { + val notification = notificationUtils.buildRoomInvitationNotification(event, session.myUserId) + notificationUtils.showNotificationMessage(event.roomId, ROOM_INVITATION_NOTIFICATION_ID, notification) + } + event.hasBeenDisplayed = true // we can consider it as displayed + hasNewEvent = true + summaryIsNoisy = summaryIsNoisy || event.noisy + summaryInboxStyle.addLine(event.description) } + } - val tickerText = if (roomEventGroupInfo.isDirect) { - stringProvider.getString(R.string.notification_ticker_text_dm, events.last().senderName, events.last().description) + // Handle simple events + for (event in simpleEvents) { + // We build a simple notification + if (firstTime || !event.hasBeenDisplayed) { + if (useCompleteNotificationFormat) { + val notification = notificationUtils.buildSimpleEventNotification(event, session.myUserId) + notificationUtils.showNotificationMessage(event.eventId, ROOM_EVENT_NOTIFICATION_ID, notification) + } + event.hasBeenDisplayed = true // we can consider it as displayed + hasNewEvent = true + summaryIsNoisy = summaryIsNoisy || event.noisy + summaryInboxStyle.addLine(event.description) + } + } + + // ======== Build summary notification ========= + // On Android 7.0 (API level 24) and higher, the system automatically builds a summary for + // your group using snippets of text from each notification. The user can expand this + // notification to see each separate notification. + // To support older versions, which cannot show a nested group of notifications, + // you must create an extra notification that acts as the summary. + // This appears as the only notification and the system hides all the others. + // So this summary should include a snippet from all the other notifications, + // which the user can tap to open your app. + // The behavior of the group summary may vary on some device types such as wearables. + // To ensure the best experience on all devices and versions, always include a group summary when you create a group + // https://developer.android.com/training/notify-user/group + + if (eventList.isEmpty() || eventList.all { it.isRedacted }) { + notificationUtils.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID) + } else if (hasNewEvent) { + // FIXME roomIdToEventMap.size is not correct, this is the number of rooms + val nbEvents = roomIdToEventMap.size + simpleEvents.size + val sumTitle = stringProvider.getQuantityString(R.plurals.notification_compat_summary_title, nbEvents, nbEvents) + summaryInboxStyle.setBigContentTitle(sumTitle) + // TODO get latest event? + .setSummaryText(stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages, nbEvents, nbEvents)) + + if (useCompleteNotificationFormat) { + val notification = notificationUtils.buildSummaryListNotification( + summaryInboxStyle, + sumTitle, + noisy = hasNewEvent && summaryIsNoisy, + lastMessageTimestamp = globalLastMessageTimestamp) + + notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification) } else { - stringProvider.getString(R.string.notification_ticker_text_group, roomName, events.last().senderName, events.last().description) - } + // Add the simple events as message (?) + simpleNotificationMessageCounter += simpleEvents.size + val numberOfInvitations = invitationEvents.size - if (useCompleteNotificationFormat) { - val notification = notificationUtils.buildMessagesListNotification( - style, - roomEventGroupInfo, - largeBitmap, - lastMessageTimestamp, - myUserDisplayName, - tickerText) - - // is there an id for this room? - notificationUtils.showNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID, notification) - } - - hasNewEvent = true - summaryIsNoisy = summaryIsNoisy || roomEventGroupInfo.shouldBing - } else { - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId is up to date") - } - } - - // Handle invitation events - for (event in invitationEvents) { - // We build a invitation notification - if (firstTime || !event.hasBeenDisplayed) { - if (useCompleteNotificationFormat) { - val notification = notificationUtils.buildRoomInvitationNotification(event, session.myUserId) - notificationUtils.showNotificationMessage(event.roomId, ROOM_INVITATION_NOTIFICATION_ID, notification) - } - event.hasBeenDisplayed = true // we can consider it as displayed - hasNewEvent = true - summaryIsNoisy = summaryIsNoisy || event.noisy - summaryInboxStyle.addLine(event.description) - } - } - - // Handle simple events - for (event in simpleEvents) { - // We build a simple notification - if (firstTime || !event.hasBeenDisplayed) { - if (useCompleteNotificationFormat) { - val notification = notificationUtils.buildSimpleEventNotification(event, session.myUserId) - notificationUtils.showNotificationMessage(event.eventId, ROOM_EVENT_NOTIFICATION_ID, notification) - } - event.hasBeenDisplayed = true // we can consider it as displayed - hasNewEvent = true - summaryIsNoisy = summaryIsNoisy || event.noisy - summaryInboxStyle.addLine(event.description) - } - } - - // ======== Build summary notification ========= - // On Android 7.0 (API level 24) and higher, the system automatically builds a summary for - // your group using snippets of text from each notification. The user can expand this - // notification to see each separate notification. - // To support older versions, which cannot show a nested group of notifications, - // you must create an extra notification that acts as the summary. - // This appears as the only notification and the system hides all the others. - // So this summary should include a snippet from all the other notifications, - // which the user can tap to open your app. - // The behavior of the group summary may vary on some device types such as wearables. - // To ensure the best experience on all devices and versions, always include a group summary when you create a group - // https://developer.android.com/training/notify-user/group - - if (eventList.isEmpty() || eventList.all { it.isRedacted }) { - notificationUtils.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID) - } else if (hasNewEvent) { - // FIXME roomIdToEventMap.size is not correct, this is the number of rooms - val nbEvents = roomIdToEventMap.size + simpleEvents.size - val sumTitle = stringProvider.getQuantityString(R.plurals.notification_compat_summary_title, nbEvents, nbEvents) - summaryInboxStyle.setBigContentTitle(sumTitle) - // TODO get latest event? - .setSummaryText(stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages, nbEvents, nbEvents)) - - if (useCompleteNotificationFormat) { - val notification = notificationUtils.buildSummaryListNotification( - summaryInboxStyle, - sumTitle, - noisy = hasNewEvent && summaryIsNoisy, - lastMessageTimestamp = globalLastMessageTimestamp) - - notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification) - } else { - // Add the simple events as message (?) - simpleNotificationMessageCounter += simpleEvents.size - val numberOfInvitations = invitationEvents.size - - val privacyTitle = if (numberOfInvitations > 0) { - val invitationsStr = stringProvider.getQuantityString(R.plurals.notification_invitations, numberOfInvitations, numberOfInvitations) - if (simpleNotificationMessageCounter > 0) { - // Invitation and message + val privacyTitle = if (numberOfInvitations > 0) { + val invitationsStr = stringProvider.getQuantityString(R.plurals.notification_invitations, numberOfInvitations, numberOfInvitations) + if (simpleNotificationMessageCounter > 0) { + // Invitation and message + val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, + simpleNotificationMessageCounter, simpleNotificationMessageCounter) + if (simpleNotificationRoomCounter > 1) { + // In several rooms + val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, + simpleNotificationRoomCounter, simpleNotificationRoomCounter) + stringProvider.getString( + R.string.notification_unread_notified_messages_in_room_and_invitation, + messageStr, + roomStr, + invitationsStr + ) + } else { + // In one room + stringProvider.getString( + R.string.notification_unread_notified_messages_and_invitation, + messageStr, + invitationsStr + ) + } + } else { + // Only invitation + invitationsStr + } + } else { + // No invitation, only messages val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, simpleNotificationMessageCounter, simpleNotificationMessageCounter) if (simpleNotificationRoomCounter > 1) { // In several rooms val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, simpleNotificationRoomCounter, simpleNotificationRoomCounter) - stringProvider.getString( - R.string.notification_unread_notified_messages_in_room_and_invitation, - messageStr, - roomStr, - invitationsStr - ) + stringProvider.getString(R.string.notification_unread_notified_messages_in_room, messageStr, roomStr) } else { // In one room - stringProvider.getString( - R.string.notification_unread_notified_messages_and_invitation, - messageStr, - invitationsStr - ) + messageStr } - } else { - // Only invitation - invitationsStr - } - } else { - // No invitation, only messages - val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, - simpleNotificationMessageCounter, simpleNotificationMessageCounter) - if (simpleNotificationRoomCounter > 1) { - // In several rooms - val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, - simpleNotificationRoomCounter, simpleNotificationRoomCounter) - stringProvider.getString(R.string.notification_unread_notified_messages_in_room, messageStr, roomStr) - } else { - // In one room - messageStr } + val notification = notificationUtils.buildSummaryListNotification( + style = null, + compatSummary = privacyTitle, + noisy = hasNewEvent && summaryIsNoisy, + lastMessageTimestamp = globalLastMessageTimestamp) + + notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification) } - val notification = notificationUtils.buildSummaryListNotification( - style = null, - compatSummary = privacyTitle, - noisy = hasNewEvent && summaryIsNoisy, - lastMessageTimestamp = globalLastMessageTimestamp) - notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification) - } - - if (hasNewEvent && summaryIsNoisy) { - try { - // turn the screen on for 3 seconds - /* + if (hasNewEvent && summaryIsNoisy) { + try { + // turn the screen on for 3 seconds + /* TODO if (Matrix.getInstance(VectorApp.getInstance())!!.pushManager.isScreenTurnedOn) { val pm = VectorApp.getInstance().getSystemService()!! @@ -587,13 +591,14 @@ class NotificationDrawerManager @Inject constructor(private val context: Context wl.release() } */ - } catch (e: Throwable) { - Timber.e(e, "## Failed to turn screen on") + } catch (e: Throwable) { + Timber.e(e, "## Failed to turn screen on") + } } } + // notice that we can get bit out of sync with actual display but not a big issue + firstTime = false } - // notice that we can get bit out of sync with actual display but not a big issue - firstTime = false } } @@ -657,10 +662,10 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } companion object { - private const val SUMMARY_NOTIFICATION_ID = 0 - private const val ROOM_MESSAGES_NOTIFICATION_ID = 1 - private const val ROOM_EVENT_NOTIFICATION_ID = 2 - private const val ROOM_INVITATION_NOTIFICATION_ID = 3 + const val SUMMARY_NOTIFICATION_ID = 0 + const val ROOM_MESSAGES_NOTIFICATION_ID = 1 + const val ROOM_EVENT_NOTIFICATION_ID = 2 + const val ROOM_INVITATION_NOTIFICATION_ID = 3 // TODO Mutliaccount private const val ROOMS_NOTIFICATIONS_FILE_NAME = "im.vector.notifications.cache" From 7b0c4831345917975587752b2c62a31531d97e5e Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 6 Oct 2021 13:37:10 +0100 Subject: [PATCH 065/413] creating dedicated class for the processing the serialized events - updates the logic to track when events are removed as a way for the notifications to remove themselves, null events mean they've been removed --- .../notifications/NotifiableEventProcessor.kt | 73 +++++++ .../NotifiableEventProcessorTest.kt | 187 ++++++++++++++++++ .../app/test/fakes/FakeAutoAcceptInvites.kt | 27 +++ .../test/fakes/FakeOutdatedEventDetector.kt | 34 ++++ 4 files changed, 321 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt create mode 100644 vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeAutoAcceptInvites.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeOutdatedEventDetector.kt diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt new file mode 100644 index 0000000000..3f77ce54ca --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt @@ -0,0 +1,73 @@ +/* + * 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.features.notifications + +import im.vector.app.features.invite.AutoAcceptInvites +import timber.log.Timber +import javax.inject.Inject + +class NotifiableEventProcessor @Inject constructor( + private val outdatedDetector: OutdatedEventDetector, + private val autoAcceptInvites: AutoAcceptInvites +) { + + fun modifyAndProcess(eventList: MutableList, currentRoomId: String?): ProcessedNotificationEvents { + val roomIdToEventMap: MutableMap> = LinkedHashMap() + val simpleEvents: MutableMap = LinkedHashMap() + val invitationEvents: MutableMap = LinkedHashMap() + + val eventIterator = eventList.listIterator() + while (eventIterator.hasNext()) { + when (val event = eventIterator.next()) { + is NotifiableMessageEvent -> { + val roomId = event.roomId + val roomEvents = roomIdToEventMap.getOrPut(roomId) { ArrayList() } + + // should we limit to last 7 messages per room? + if (shouldIgnoreMessageEventInRoom(currentRoomId, roomId) || outdatedDetector.isMessageOutdated(event)) { + // forget this event + eventIterator.remove() + } else { + roomEvents.add(event) + } + } + is InviteNotifiableEvent -> { + if (autoAcceptInvites.hideInvites) { + // Forget this event + eventIterator.remove() + invitationEvents[event.roomId] = null + } else { + invitationEvents[event.roomId] = event + } + } + is SimpleNotifiableEvent -> simpleEvents[event.eventId] = event + else -> Timber.w("Type not handled") + } + } + return ProcessedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents) + } + + private fun shouldIgnoreMessageEventInRoom(currentRoomId: String?, roomId: String?): Boolean { + return currentRoomId != null && roomId == currentRoomId + } +} + +data class ProcessedNotificationEvents( + val roomEvents: Map>, + val simpleEvents: Map, + val invitationEvents: Map +) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt new file mode 100644 index 0000000000..a5bb9978dd --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -0,0 +1,187 @@ +/* + * 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.features.notifications + +import im.vector.app.test.fakes.FakeAutoAcceptInvites +import im.vector.app.test.fakes.FakeOutdatedEventDetector +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Test + +private val NOT_VIEWING_A_ROOM: String? = null + +class NotifiableEventProcessorTest { + + private val outdatedDetector = FakeOutdatedEventDetector() + private val autoAcceptInvites = FakeAutoAcceptInvites() + + private val eventProcessor = NotifiableEventProcessor(outdatedDetector.instance, autoAcceptInvites) + + @Test + fun `given simple events when processing then return without mutating`() { + val (events, originalEvents) = createEventsList( + aSimpleNotifiableEvent(eventId = "event-1"), + aSimpleNotifiableEvent(eventId = "event-2") + ) + + val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + + result shouldBeEqualTo aProcessedNotificationEvents( + simpleEvents = mapOf( + "event-1" to events[0] as SimpleNotifiableEvent, + "event-2" to events[1] as SimpleNotifiableEvent + ) + ) + events shouldBeEqualTo originalEvents + } + + @Test + fun `given invites are auto accepted when processing then remove invitations`() { + autoAcceptInvites._isEnabled = true + val events = mutableListOf( + anInviteNotifiableEvent(roomId = "room-1"), + anInviteNotifiableEvent(roomId = "room-2") + ) + + val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + + result shouldBeEqualTo aProcessedNotificationEvents( + invitationEvents = mapOf( + "room-1" to null, + "room-2" to null + ) + ) + events shouldBeEqualTo emptyList() + } + + @Test + fun `given invites are not auto accepted when processing then return without mutating`() { + autoAcceptInvites._isEnabled = false + val (events, originalEvents) = createEventsList( + anInviteNotifiableEvent(roomId = "room-1"), + anInviteNotifiableEvent(roomId = "room-2") + ) + + val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + + result shouldBeEqualTo aProcessedNotificationEvents( + invitationEvents = mapOf( + "room-1" to originalEvents[0] as InviteNotifiableEvent, + "room-2" to originalEvents[1] as InviteNotifiableEvent + ) + ) + events shouldBeEqualTo originalEvents + } + + @Test + fun `given out of date message event when processing then removes message`() { + val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) + outdatedDetector.givenEventIsOutOfDate(events[0]) + + val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + + result shouldBeEqualTo aProcessedNotificationEvents( + roomEvents = mapOf( + "room-1" to emptyList() + ) + ) + events shouldBeEqualTo emptyList() + } + + @Test + fun `given in date message event when processing then without mutating`() { + val (events, originalEvents) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) + outdatedDetector.givenEventIsInDate(events[0]) + + val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + + result shouldBeEqualTo aProcessedNotificationEvents( + roomEvents = mapOf( + "room-1" to listOf(events[0] as NotifiableMessageEvent) + ) + ) + events shouldBeEqualTo originalEvents + } + + @Test + fun `given viewing the same room as message event when processing then removes message`() { + val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) + + val result = eventProcessor.modifyAndProcess(events, currentRoomId = "room-1") + + result shouldBeEqualTo aProcessedNotificationEvents( + roomEvents = mapOf( + "room-1" to emptyList() + ) + ) + events shouldBeEqualTo emptyList() + } +} + +fun createEventsList(vararg event: NotifiableEvent): Pair, List> { + val mutableEvents = mutableListOf(*event) + val immutableEvents = mutableEvents.toList() + return mutableEvents to immutableEvents +} + +fun aProcessedNotificationEvents(simpleEvents: Map = emptyMap(), + invitationEvents: Map = emptyMap(), + roomEvents: Map> = emptyMap() +) = ProcessedNotificationEvents( + roomEvents = roomEvents, + simpleEvents = simpleEvents, + invitationEvents = invitationEvents, +) + +fun aSimpleNotifiableEvent(eventId: String) = SimpleNotifiableEvent( + matrixID = null, + eventId = eventId, + editedEventId = null, + noisy = false, + title = "title", + description = "description", + type = null, + timestamp = 0, + soundName = null, + isPushGatewayEvent = false +) + +fun anInviteNotifiableEvent(roomId: String) = InviteNotifiableEvent( + matrixID = null, + eventId = "event-id", + roomId = roomId, + editedEventId = null, + noisy = false, + title = "title", + description = "description", + type = null, + timestamp = 0, + soundName = null, + isPushGatewayEvent = false +) + +fun aNotifiableMessageEvent(eventId: String, roomId: String) = NotifiableMessageEvent( + eventId = eventId, + editedEventId = null, + noisy = false, + timestamp = 0, + senderName = "sender-name", + senderId = "sending-id", + body = "message-body", + roomId = roomId, + roomName = "room-name", + roomIsDirect = false +) diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeAutoAcceptInvites.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeAutoAcceptInvites.kt new file mode 100644 index 0000000000..778c2f113d --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeAutoAcceptInvites.kt @@ -0,0 +1,27 @@ +/* + * 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.test.fakes + +import im.vector.app.features.invite.AutoAcceptInvites + +class FakeAutoAcceptInvites : AutoAcceptInvites { + + var _isEnabled: Boolean = false + + override val isEnabled: Boolean + get() = _isEnabled +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeOutdatedEventDetector.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeOutdatedEventDetector.kt new file mode 100644 index 0000000000..0e1d617ca2 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeOutdatedEventDetector.kt @@ -0,0 +1,34 @@ +/* + * 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.test.fakes + +import im.vector.app.features.notifications.NotifiableEvent +import im.vector.app.features.notifications.OutdatedEventDetector +import io.mockk.every +import io.mockk.mockk + +class FakeOutdatedEventDetector { + val instance = mockk() + + fun givenEventIsOutOfDate(notifiableEvent: NotifiableEvent) { + every { instance.isMessageOutdated(notifiableEvent) } returns true + } + + fun givenEventIsInDate(notifiableEvent: NotifiableEvent) { + every { instance.isMessageOutdated(notifiableEvent) } returns false + } +} From 0f4ec65b7a501f4f0138f737fbee99f6896f0d32 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 6 Oct 2021 19:03:22 +0100 Subject: [PATCH 066/413] creating the notifications separate to where they're displayed - also handles when the event diff means the notifications should be removed --- .../notifications/NotificationFactory.kt | 106 +++++++++++++ .../notifications/RoomGroupMessageCreator.kt | 148 ++++++++++++++++++ .../SummaryGroupMessageCreator.kt | 140 +++++++++++++++++ .../notifications/NotificationFactoryTest.kt | 138 ++++++++++++++++ .../app/test/fakes/FakeNotificationUtils.kt | 41 +++++ .../test/fakes/FakeRoomGroupMessageCreator.kt | 37 +++++ .../fakes/FakeSummaryGroupMessageCreator.kt | 25 +++ 7 files changed, 635 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt create mode 100644 vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt create mode 100644 vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt create mode 100644 vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeNotificationUtils.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeRoomGroupMessageCreator.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeSummaryGroupMessageCreator.kt diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt new file mode 100644 index 0000000000..174a457334 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -0,0 +1,106 @@ +/* + * 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.features.notifications + +import android.app.Notification +import javax.inject.Inject + +class NotificationFactory @Inject constructor( + private val notificationUtils: NotificationUtils, + private val roomGroupMessageCreator: RoomGroupMessageCreator, + private val summaryGroupMessageCreator: SummaryGroupMessageCreator +) { + + fun Map>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { + return this.map { (roomId, events) -> + when { + events.hasNoEventsToDisplay() -> RoomNotification.EmptyRoom(roomId) + else -> roomGroupMessageCreator.createRoomMessage(events, roomId, myUserDisplayName, myUserAvatarUrl) + } + } + } + + private fun List.hasNoEventsToDisplay() = isEmpty() || all { it.canNotBeDisplayed() } + + private fun NotifiableMessageEvent.canNotBeDisplayed() = hasBeenDisplayed || isRedacted + + fun Map.toNotifications(myUserId: String): List { + return this.map { (roomId, event) -> + when (event) { + null -> OneShotNotification.Removed(key = roomId) + else -> OneShotNotification.Append( + notificationUtils.buildRoomInvitationNotification(event, myUserId), + OneShotNotification.Append.Meta(key = roomId, summaryLine = event.description, isNoisy = event.noisy) + ) + } + } + } + + @JvmName("toNotificationsSimpleNotifiableEvent") + fun Map.toNotifications(myUserId: String): List { + return this.map { (eventId, event) -> + when (event) { + null -> OneShotNotification.Removed(key = eventId) + else -> OneShotNotification.Append( + notificationUtils.buildSimpleEventNotification(event, myUserId), + OneShotNotification.Append.Meta(key = eventId, summaryLine = event.description, isNoisy = event.noisy) + ) + } + } + } + + fun createSummaryNotification(roomNotifications: List, + invitationNotifications: List, + simpleNotifications: List, + useCompleteNotificationFormat: Boolean): Notification { + return summaryGroupMessageCreator.createSummaryNotification( + roomNotifications = roomNotifications.mapToMeta(), + invitationNotifications = invitationNotifications.mapToMeta(), + simpleNotifications = simpleNotifications.mapToMeta(), + useCompleteNotificationFormat = useCompleteNotificationFormat + ) + } +} + +private fun List.mapToMeta() = filterIsInstance().map { it.meta } + +@JvmName("mapToMetaOneShotNotification") +private fun List.mapToMeta() = filterIsInstance().map { it.meta } + +sealed interface RoomNotification { + data class EmptyRoom(val roomId: String) : RoomNotification + data class Message(val notification: Notification, val meta: Meta) : RoomNotification { + data class Meta( + val summaryLine: CharSequence, + val messageCount: Int, + val latestTimestamp: Long, + val roomId: String, + val shouldBing: Boolean + ) + } +} + +sealed interface OneShotNotification { + data class Removed(val key: String) : OneShotNotification + data class Append(val notification: Notification, val meta: Meta) : OneShotNotification { + data class Meta( + val key: String, + val summaryLine: CharSequence, + val isNoisy: Boolean + ) + } +} diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt new file mode 100644 index 0000000000..786ce40046 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -0,0 +1,148 @@ +/* + * 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.features.notifications + +import android.graphics.Bitmap +import androidx.core.app.NotificationCompat +import androidx.core.app.Person +import im.vector.app.R +import im.vector.app.core.resources.StringProvider +import me.gujun.android.span.Span +import me.gujun.android.span.span +import timber.log.Timber +import javax.inject.Inject + +class RoomGroupMessageCreator @Inject constructor( + private val iconLoader: IconLoader, + private val bitmapLoader: BitmapLoader, + private val stringProvider: StringProvider, + private val notificationUtils: NotificationUtils +) { + + fun createRoomMessage(events: List, roomId: String, userDisplayName: String, userAvatarUrl: String?): RoomNotification.Message { + val firstKnownRoomEvent = events[0] + val roomName = firstKnownRoomEvent.roomName ?: firstKnownRoomEvent.senderName ?: "" + val roomIsGroup = !firstKnownRoomEvent.roomIsDirect + val style = NotificationCompat.MessagingStyle(Person.Builder() + .setName(userDisplayName) + .setIcon(iconLoader.getUserIcon(userAvatarUrl)) + .setKey(firstKnownRoomEvent.matrixID) + .build() + ).also { + it.conversationTitle = roomName.takeIf { roomIsGroup } + it.isGroupConversation = roomIsGroup + it.addMessagesFromEvents(events) + } + + val tickerText = if (roomIsGroup) { + stringProvider.getString(R.string.notification_ticker_text_group, roomName, events.last().senderName, events.last().description) + } else { + stringProvider.getString(R.string.notification_ticker_text_dm, events.last().senderName, events.last().description) + } + + val lastMessageTimestamp = events.last().timestamp + val smartReplyErrors = events.filter { it.isSmartReplyError() } + val messageCount = (events.size - smartReplyErrors.size) + val meta = RoomNotification.Message.Meta( + summaryLine = createRoomMessagesGroupSummaryLine(events, roomName, roomIsDirect = !roomIsGroup), + messageCount = messageCount, + latestTimestamp = lastMessageTimestamp, + roomId = roomId, + shouldBing = events.any { it.noisy } + ) + return RoomNotification.Message( + notificationUtils.buildMessagesListNotification( + style, + RoomEventGroupInfo(roomId, roomName, isDirect = !roomIsGroup).also { + it.hasSmartReplyError = smartReplyErrors.isNotEmpty() + it.shouldBing = meta.shouldBing + it.customSound = events.last().soundName + }, + largeIcon = getRoomBitmap(events), + lastMessageTimestamp, + userDisplayName, + tickerText + ), + meta + ) + } + + private fun NotificationCompat.MessagingStyle.addMessagesFromEvents(events: List) { + events.forEach { event -> + val senderPerson = Person.Builder() + .setName(event.senderName) + .setIcon(iconLoader.getUserIcon(event.senderAvatarPath)) + .setKey(event.senderId) + .build() + when { + event.isSmartReplyError() -> addMessage(stringProvider.getString(R.string.notification_inline_reply_failed), event.timestamp, senderPerson) + else -> addMessage(event.body, event.timestamp, senderPerson) + } + } + } + + private fun createRoomMessagesGroupSummaryLine(events: List, roomName: String, roomIsDirect: Boolean): CharSequence { + return try { + when (events.size) { + 1 -> createFirstMessageSummaryLine(events.first(), roomName, roomIsDirect) + else -> { + stringProvider.getQuantityString( + R.plurals.notification_compat_summary_line_for_room, + events.size, + roomName, + events.size + ) + } + } + } catch (e: Throwable) { + // String not found or bad format + Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER failed to resolve string") + roomName + } + } + + private fun createFirstMessageSummaryLine(event: NotifiableMessageEvent, roomName: String, roomIsDirect: Boolean): Span { + return if (roomIsDirect) { + span { + span { + textStyle = "bold" + +String.format("%s: ", event.senderName) + } + +(event.description) + } + } else { + span { + span { + textStyle = "bold" + +String.format("%s: %s ", roomName, event.senderName) + } + +(event.description) + } + } + } + + private fun getRoomBitmap(events: List): Bitmap? { + if (events.isEmpty()) return null + + // Use the last event (most recent?) + val roomAvatarPath = events.last().roomAvatarPath ?: events.last().senderAvatarPath + + return bitmapLoader.getRoomBitmap(roomAvatarPath) + } +} + +private fun NotifiableMessageEvent.isSmartReplyError() = this.outGoingMessage && this.outGoingMessageFailed diff --git a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt new file mode 100644 index 0000000000..38eac8b565 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt @@ -0,0 +1,140 @@ +/* + * 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.features.notifications + +import android.app.Notification +import androidx.core.app.NotificationCompat +import im.vector.app.R +import im.vector.app.core.resources.StringProvider +import javax.inject.Inject + +class SummaryGroupMessageCreator @Inject constructor( + private val stringProvider: StringProvider, + private val notificationUtils: NotificationUtils +) { + + /** + * ======== Build summary notification ========= + * On Android 7.0 (API level 24) and higher, the system automatically builds a summary for + * your group using snippets of text from each notification. The user can expand this + * notification to see each separate notification. + * To support older versions, which cannot show a nested group of notifications, + * you must create an extra notification that acts as the summary. + * This appears as the only notification and the system hides all the others. + * So this summary should include a snippet from all the other notifications, + * which the user can tap to open your app. + * The behavior of the group summary may vary on some device types such as wearables. + * To ensure the best experience on all devices and versions, always include a group summary when you create a group + * https://developer.android.com/training/notify-user/group + */ + fun createSummaryNotification(roomNotifications: List, + invitationNotifications: List, + simpleNotifications: List, + useCompleteNotificationFormat: Boolean): Notification { + val summaryInboxStyle = NotificationCompat.InboxStyle().also { style -> + roomNotifications.forEach { style.addLine(it.summaryLine) } + invitationNotifications.forEach { style.addLine(it.summaryLine) } + simpleNotifications.forEach { style.addLine(it.summaryLine) } + } + + val summaryIsNoisy = roomNotifications.any { it.shouldBing } + || invitationNotifications.any { it.isNoisy } + || simpleNotifications.any { it.isNoisy } + + val messageCount = roomNotifications.fold(initial = 0) { acc, current -> acc + current.messageCount } + + val lastMessageTimestamp1 = roomNotifications.last().latestTimestamp + + // FIXME roomIdToEventMap.size is not correct, this is the number of rooms + val nbEvents = roomNotifications.size + simpleNotifications.size + val sumTitle = stringProvider.getQuantityString(R.plurals.notification_compat_summary_title, nbEvents, nbEvents) + summaryInboxStyle.setBigContentTitle(sumTitle) + // TODO get latest event? + .setSummaryText(stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages, nbEvents, nbEvents)) + return if (useCompleteNotificationFormat + ) { + notificationUtils.buildSummaryListNotification( + summaryInboxStyle, + sumTitle, + noisy = summaryIsNoisy, + lastMessageTimestamp = lastMessageTimestamp1 + ) + } else { + processSimpleGroupSummary(summaryIsNoisy, messageCount, + simpleNotifications.size, invitationNotifications.size, + roomNotifications.size, lastMessageTimestamp1) + } + } + + private fun processSimpleGroupSummary(summaryIsNoisy: Boolean, + messageEventsCount: Int, + simpleEventsCount: Int, + invitationEventsCount: Int, + roomCount: Int, + lastMessageTimestamp: Long): Notification { + // Add the simple events as message (?) + val messageNotificationCount = messageEventsCount + simpleEventsCount + + val privacyTitle = if (invitationEventsCount > 0) { + val invitationsStr = stringProvider.getQuantityString(R.plurals.notification_invitations, invitationEventsCount, invitationEventsCount) + if (messageNotificationCount > 0) { + // Invitation and message + val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, + messageNotificationCount, messageNotificationCount) + if (roomCount > 1) { + // In several rooms + val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, + roomCount, roomCount) + stringProvider.getString( + R.string.notification_unread_notified_messages_in_room_and_invitation, + messageStr, + roomStr, + invitationsStr + ) + } else { + // In one room + stringProvider.getString( + R.string.notification_unread_notified_messages_and_invitation, + messageStr, + invitationsStr + ) + } + } else { + // Only invitation + invitationsStr + } + } else { + // No invitation, only messages + val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, + messageNotificationCount, messageNotificationCount) + if (roomCount > 1) { + // In several rooms + val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, roomCount, roomCount) + stringProvider.getString(R.string.notification_unread_notified_messages_in_room, messageStr, roomStr) + } else { + // In one room + messageStr + } + } + return notificationUtils.buildSummaryListNotification( + style = null, + compatSummary = privacyTitle, + noisy = summaryIsNoisy, + lastMessageTimestamp = lastMessageTimestamp + ) + } +} diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt new file mode 100644 index 0000000000..c42e0b21c1 --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt @@ -0,0 +1,138 @@ +/* + * 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.features.notifications + +import im.vector.app.test.fakes.FakeNotificationUtils +import im.vector.app.test.fakes.FakeRoomGroupMessageCreator +import im.vector.app.test.fakes.FakeSummaryGroupMessageCreator +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Test + +private const val MY_USER_ID = "user-id" +private const val A_ROOM_ID = "room-id" +private const val AN_EVENT_ID = "event-id" + +private val MY_AVATAR_URL: String? = null +private val AN_INVITATION_EVENT = anInviteNotifiableEvent(roomId = A_ROOM_ID) +private val A_SIMPLE_EVENT = aSimpleNotifiableEvent(eventId = AN_EVENT_ID) +private val A_MESSAGE_EVENT = aNotifiableMessageEvent(eventId = AN_EVENT_ID, roomId = A_ROOM_ID) + +class NotificationFactoryTest { + + private val notificationUtils = FakeNotificationUtils() + private val roomGroupMessageCreator = FakeRoomGroupMessageCreator() + private val summaryGroupMessageCreator = FakeSummaryGroupMessageCreator() + + private val notificationFactory = NotificationFactory( + notificationUtils.instance, + roomGroupMessageCreator.instance, + summaryGroupMessageCreator.instance + ) + + @Test + fun `given a room invitation when mapping to notification then is Append`() = testWith(notificationFactory) { + val expectedNotification = notificationUtils.givenBuildRoomInvitationNotificationFor(AN_INVITATION_EVENT, MY_USER_ID) + val roomInvitation = mapOf(A_ROOM_ID to AN_INVITATION_EVENT) + + val result = roomInvitation.toNotifications(MY_USER_ID) + + result shouldBeEqualTo listOf(OneShotNotification.Append( + notification = expectedNotification, + meta = OneShotNotification.Append.Meta( + key = A_ROOM_ID, + summaryLine = AN_INVITATION_EVENT.description, + isNoisy = AN_INVITATION_EVENT.noisy + )) + ) + } + + @Test + fun `given a missing event in room invitation when mapping to notification then is Removed`() = testWith(notificationFactory) { + val missingEventRoomInvitation: Map = mapOf(A_ROOM_ID to null) + + val result = missingEventRoomInvitation.toNotifications(MY_USER_ID) + + result shouldBeEqualTo listOf(OneShotNotification.Removed( + key = A_ROOM_ID + )) + } + + @Test + fun `given a simple event when mapping to notification then is Append`() = testWith(notificationFactory) { + val expectedNotification = notificationUtils.givenBuildSimpleInvitationNotificationFor(A_SIMPLE_EVENT, MY_USER_ID) + val roomInvitation = mapOf(AN_EVENT_ID to A_SIMPLE_EVENT) + + val result = roomInvitation.toNotifications(MY_USER_ID) + + result shouldBeEqualTo listOf(OneShotNotification.Append( + notification = expectedNotification, + meta = OneShotNotification.Append.Meta( + key = AN_EVENT_ID, + summaryLine = A_SIMPLE_EVENT.description, + isNoisy = A_SIMPLE_EVENT.noisy + )) + ) + } + + @Test + fun `given a missing simple event when mapping to notification then is Removed`() = testWith(notificationFactory) { + val missingEventRoomInvitation: Map = mapOf(AN_EVENT_ID to null) + + val result = missingEventRoomInvitation.toNotifications(MY_USER_ID) + + result shouldBeEqualTo listOf(OneShotNotification.Removed( + key = AN_EVENT_ID + )) + } + + @Test + fun `given room with message when mapping to notification then delegates to room group message creator`() = testWith(notificationFactory) { + val events = listOf(A_MESSAGE_EVENT) + val expectedNotification = roomGroupMessageCreator.givenCreatesRoomMessageFor(events, A_ROOM_ID, MY_USER_ID, MY_AVATAR_URL) + val roomWithMessage = mapOf(A_ROOM_ID to events) + + val result = roomWithMessage.toNotifications(MY_USER_ID, MY_AVATAR_URL) + + result shouldBeEqualTo listOf(expectedNotification) + } + + @Test + fun `given a room with no events to display when mapping to notification then is Empty`() = testWith(notificationFactory) { + val emptyRoom: Map> = mapOf(A_ROOM_ID to emptyList()) + + val result = emptyRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) + + result shouldBeEqualTo listOf(RoomNotification.EmptyRoom( + roomId = A_ROOM_ID + )) + } + + @Test + fun `given a room with only redacted events when mapping to notification then is Empty`() = testWith(notificationFactory) { + val redactedRoom = mapOf(A_ROOM_ID to listOf(A_MESSAGE_EVENT.copy().apply { isRedacted = true })) + + val result = redactedRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) + + result shouldBeEqualTo listOf(RoomNotification.EmptyRoom( + roomId = A_ROOM_ID + )) + } +} + +fun testWith(receiver: T, block: T.() -> Unit) { + receiver.block() +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationUtils.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationUtils.kt new file mode 100644 index 0000000000..39f2ad59ff --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationUtils.kt @@ -0,0 +1,41 @@ +/* + * 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.test.fakes + +import android.app.Notification +import im.vector.app.features.notifications.InviteNotifiableEvent +import im.vector.app.features.notifications.NotificationUtils +import im.vector.app.features.notifications.SimpleNotifiableEvent +import io.mockk.every +import io.mockk.mockk + +class FakeNotificationUtils { + + val instance = mockk() + + fun givenBuildRoomInvitationNotificationFor(event: InviteNotifiableEvent, myUserId: String): Notification { + val mockNotification = mockk() + every { instance.buildRoomInvitationNotification(event, myUserId) } returns mockNotification + return mockNotification + } + + fun givenBuildSimpleInvitationNotificationFor(event: SimpleNotifiableEvent, myUserId: String): Notification { + val mockNotification = mockk() + every { instance.buildSimpleEventNotification(event, myUserId) } returns mockNotification + return mockNotification + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeRoomGroupMessageCreator.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeRoomGroupMessageCreator.kt new file mode 100644 index 0000000000..c164b9a661 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeRoomGroupMessageCreator.kt @@ -0,0 +1,37 @@ +/* + * 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.test.fakes + +import im.vector.app.features.notifications.NotifiableMessageEvent +import im.vector.app.features.notifications.RoomGroupMessageCreator +import im.vector.app.features.notifications.RoomNotification +import io.mockk.every +import io.mockk.mockk + +class FakeRoomGroupMessageCreator { + + val instance = mockk() + + fun givenCreatesRoomMessageFor(events: List, + roomId: String, + userDisplayName: String, + userAvatarUrl: String?): RoomNotification.Message { + val mockMessage = mockk() + every { instance.createRoomMessage(events, roomId, userDisplayName, userAvatarUrl) } returns mockMessage + return mockMessage + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSummaryGroupMessageCreator.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSummaryGroupMessageCreator.kt new file mode 100644 index 0000000000..eef77298a0 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSummaryGroupMessageCreator.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.test.fakes + +import im.vector.app.features.notifications.SummaryGroupMessageCreator +import io.mockk.mockk + +class FakeSummaryGroupMessageCreator { + + val instance = mockk() +} From 3023cb4d39a819c4c85ad93da0d9fc7542f2c5e8 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 6 Oct 2021 20:28:29 +0100 Subject: [PATCH 067/413] chaining the event process, notification creation and display logic into a NotificationRender - extract the displaying into its own class to avoid leaking the entire notificationutils - cancel/display notification actions are completely driven by the event or abscense of event from the eventList - attempts to avoid redundant render passes by checking if the eventList has changed since the last render --- .../notifications/NotificationDisplayer.kt | 45 +++++ .../notifications/NotificationFactory.kt | 4 +- .../notifications/NotificationRenderer.kt | 101 ++++++++++ .../SummaryGroupMessageCreator.kt | 28 +-- .../notifications/NotificationFactoryTest.kt | 4 +- .../notifications/NotificationRendererTest.kt | 183 ++++++++++++++++++ .../fakes/FakeNotifiableEventProcessor.kt | 32 +++ .../test/fakes/FakeNotificationDisplayer.kt | 42 ++++ .../app/test/fakes/FakeNotificationFactory.kt | 56 ++++++ .../app/test/fakes/FakeVectorPreferences.kt | 30 +++ 10 files changed, 507 insertions(+), 18 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/notifications/NotificationDisplayer.kt create mode 100644 vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt create mode 100644 vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeNotificationDisplayer.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt create mode 100644 vector/src/test/java/im/vector/app/test/fakes/FakeVectorPreferences.kt diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDisplayer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDisplayer.kt new file mode 100644 index 0000000000..680ff32a52 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDisplayer.kt @@ -0,0 +1,45 @@ +/* + * 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.features.notifications + +import android.app.Notification +import android.content.Context +import androidx.core.app.NotificationManagerCompat +import timber.log.Timber +import javax.inject.Inject + +class NotificationDisplayer @Inject constructor(context: Context) { + + private val notificationManager = NotificationManagerCompat.from(context) + + fun showNotificationMessage(tag: String?, id: Int, notification: Notification) { + notificationManager.notify(tag, id, notification) + } + + fun cancelNotificationMessage(tag: String?, id: Int) { + notificationManager.cancel(tag, id) + } + + fun cancelAllNotifications() { + // Keep this try catch (reported by GA) + try { + notificationManager.cancelAll() + } catch (e: Exception) { + Timber.e(e, "## cancelAllNotifications() failed") + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 174a457334..55e9f7352d 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -28,7 +28,7 @@ class NotificationFactory @Inject constructor( fun Map>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { return this.map { (roomId, events) -> when { - events.hasNoEventsToDisplay() -> RoomNotification.EmptyRoom(roomId) + events.hasNoEventsToDisplay() -> RoomNotification.Removed(roomId) else -> roomGroupMessageCreator.createRoomMessage(events, roomId, myUserDisplayName, myUserAvatarUrl) } } @@ -82,7 +82,7 @@ private fun List.mapToMeta() = filterIsInstance.mapToMeta() = filterIsInstance().map { it.meta } sealed interface RoomNotification { - data class EmptyRoom(val roomId: String) : RoomNotification + data class Removed(val roomId: String) : RoomNotification data class Message(val notification: Notification, val meta: Meta) : RoomNotification { data class Meta( val summaryLine: CharSequence, diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt new file mode 100644 index 0000000000..257f998774 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -0,0 +1,101 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.app.features.notifications + +import androidx.annotation.WorkerThread +import im.vector.app.features.settings.VectorPreferences +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class NotificationRenderer @Inject constructor(private val notifiableEventProcessor: NotifiableEventProcessor, + private val notificationDisplayer: NotificationDisplayer, + private val vectorPreferences: VectorPreferences, + private val notificationFactory: NotificationFactory) { + + private var lastKnownEventList = -1 + private var useCompleteNotificationFormat = vectorPreferences.useCompleteNotificationFormat() + + @WorkerThread + fun render(currentRoomId: String?, myUserId: String, myUserDisplayName: String, myUserAvatarUrl: String?, eventList: MutableList) { + Timber.v("refreshNotificationDrawerBg()") + val newSettings = vectorPreferences.useCompleteNotificationFormat() + if (newSettings != useCompleteNotificationFormat) { + // Settings has changed, remove all current notifications + notificationDisplayer.cancelAllNotifications() + useCompleteNotificationFormat = newSettings + } + + val notificationEvents = notifiableEventProcessor.modifyAndProcess(eventList, currentRoomId) + if (lastKnownEventList == notificationEvents.hashCode()) { + Timber.d("Skipping notification update due to event list not changing") + } else { + processEvents(notificationEvents, myUserId, myUserDisplayName, myUserAvatarUrl) + lastKnownEventList = notificationEvents.hashCode() + } + } + + private fun processEvents(notificationEvents: ProcessedNotificationEvents, myUserId: String, myUserDisplayName: String, myUserAvatarUrl: String?) { + val (roomEvents, simpleEvents, invitationEvents) = notificationEvents + with(notificationFactory) { + val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) + val invitationNotifications = invitationEvents.toNotifications(myUserId) + val simpleNotifications = simpleEvents.toNotifications(myUserId) + + if (roomNotifications.isEmpty() && invitationNotifications.isEmpty() && simpleNotifications.isEmpty()) { + notificationDisplayer.cancelNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID) + } else { + val summaryNotification = createSummaryNotification( + roomNotifications = roomNotifications, + invitationNotifications = invitationNotifications, + simpleNotifications = simpleNotifications, + useCompleteNotificationFormat = useCompleteNotificationFormat + ) + roomNotifications.forEach { wrapper -> + when (wrapper) { + is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID) + is RoomNotification.Message -> if (useCompleteNotificationFormat) { + Timber.d("Updating room messages notification ${wrapper.meta.roomId}") + notificationDisplayer.showNotificationMessage(wrapper.meta.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, wrapper.notification) + } + } + } + + invitationNotifications.forEach { wrapper -> + when (wrapper) { + is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID) + is OneShotNotification.Append -> if (useCompleteNotificationFormat) { + Timber.d("Updating invitation notification ${wrapper.meta.key}") + notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID, wrapper.notification) + } + } + } + + simpleNotifications.forEach { wrapper -> + when (wrapper) { + is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID) + is OneShotNotification.Append -> if (useCompleteNotificationFormat) { + Timber.d("Updating simple notification ${wrapper.meta.key}") + notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, wrapper.notification) + } + } + } + notificationDisplayer.showNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, summaryNotification) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt index 38eac8b565..dc9ff92aa6 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt @@ -22,25 +22,25 @@ import im.vector.app.R import im.vector.app.core.resources.StringProvider import javax.inject.Inject +/** + * ======== Build summary notification ========= + * On Android 7.0 (API level 24) and higher, the system automatically builds a summary for + * your group using snippets of text from each notification. The user can expand this + * notification to see each separate notification. + * To support older versions, which cannot show a nested group of notifications, + * you must create an extra notification that acts as the summary. + * This appears as the only notification and the system hides all the others. + * So this summary should include a snippet from all the other notifications, + * which the user can tap to open your app. + * The behavior of the group summary may vary on some device types such as wearables. + * To ensure the best experience on all devices and versions, always include a group summary when you create a group + * https://developer.android.com/training/notify-user/group + */ class SummaryGroupMessageCreator @Inject constructor( private val stringProvider: StringProvider, private val notificationUtils: NotificationUtils ) { - /** - * ======== Build summary notification ========= - * On Android 7.0 (API level 24) and higher, the system automatically builds a summary for - * your group using snippets of text from each notification. The user can expand this - * notification to see each separate notification. - * To support older versions, which cannot show a nested group of notifications, - * you must create an extra notification that acts as the summary. - * This appears as the only notification and the system hides all the others. - * So this summary should include a snippet from all the other notifications, - * which the user can tap to open your app. - * The behavior of the group summary may vary on some device types such as wearables. - * To ensure the best experience on all devices and versions, always include a group summary when you create a group - * https://developer.android.com/training/notify-user/group - */ fun createSummaryNotification(roomNotifications: List, invitationNotifications: List, simpleNotifications: List, diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt index c42e0b21c1..c08be9e8c7 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt @@ -116,7 +116,7 @@ class NotificationFactoryTest { val result = emptyRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) - result shouldBeEqualTo listOf(RoomNotification.EmptyRoom( + result shouldBeEqualTo listOf(RoomNotification.Removed( roomId = A_ROOM_ID )) } @@ -127,7 +127,7 @@ class NotificationFactoryTest { val result = redactedRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) - result shouldBeEqualTo listOf(RoomNotification.EmptyRoom( + result shouldBeEqualTo listOf(RoomNotification.Removed( roomId = A_ROOM_ID )) } diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt new file mode 100644 index 0000000000..a07dd61368 --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -0,0 +1,183 @@ +/* + * 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.features.notifications + +import android.app.Notification +import im.vector.app.test.fakes.FakeNotifiableEventProcessor +import im.vector.app.test.fakes.FakeNotificationDisplayer +import im.vector.app.test.fakes.FakeNotificationFactory +import im.vector.app.test.fakes.FakeVectorPreferences +import io.mockk.mockk +import org.junit.Test + +private const val A_CURRENT_ROOM_ID = "current-room-id" +private const val MY_USER_ID = "my-user-id" +private const val MY_USER_DISPLAY_NAME = "display-name" +private const val MY_USER_AVATAR_URL = "avatar-url" +private const val AN_EVENT_ID = "event-id" +private const val A_ROOM_ID = "room-id" +private const val USE_COMPLETE_NOTIFICATION_FORMAT = true + +private val AN_EVENT_LIST = mutableListOf() +private val A_PROCESSED_EVENTS = ProcessedNotificationEvents(emptyMap(), emptyMap(), emptyMap()) +private val A_SUMMARY_NOTIFICATION = mockk() +private val A_NOTIFICATION = mockk() +private val MESSAGE_META = RoomNotification.Message.Meta( + summaryLine = "ignored", messageCount = 1, latestTimestamp = -1, roomId = A_ROOM_ID, shouldBing = false +) +private val ONE_SHOT_META = OneShotNotification.Append.Meta(key = "ignored", summaryLine = "ignored", isNoisy = false) + +class NotificationRendererTest { + + private val notifiableEventProcessor = FakeNotifiableEventProcessor() + private val notificationDisplayer = FakeNotificationDisplayer() + private val preferences = FakeVectorPreferences().also { + it.givenUseCompleteNotificationFormat(USE_COMPLETE_NOTIFICATION_FORMAT) + } + private val notificationFactory = FakeNotificationFactory() + + private val notificationRenderer = NotificationRenderer( + notifiableEventProcessor = notifiableEventProcessor.instance, + notificationDisplayer = notificationDisplayer.instance, + vectorPreferences = preferences.instance, + notificationFactory = notificationFactory.instance + ) + + @Test + fun `given no notifications when rendering then cancels summary notification`() { + givenNoNotifications() + + renderEventsAsNotifications() + + notificationDisplayer.verifySummaryCancelled() + notificationDisplayer.verifyNoOtherInteractions() + } + + @Test + fun `given a room message group notification is removed when rendering then remove the message notification and update summary`() { + givenNotifications(roomNotifications = listOf(RoomNotification.Removed(A_ROOM_ID))) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + cancelNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + } + } + + @Test + fun `given a room message group notification is added when rendering then show the message notification and update summary`() { + givenNotifications(roomNotifications = listOf(RoomNotification.Message( + A_NOTIFICATION, + MESSAGE_META + ))) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + showNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, A_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + } + } + + @Test + fun `given a simple notification is removed when rendering then remove the simple notification and update summary`() { + givenNotifications(simpleNotifications = listOf(OneShotNotification.Removed(AN_EVENT_ID))) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + cancelNotificationMessage(tag = AN_EVENT_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + } + } + + @Test + fun `given a simple notification is added when rendering then show the simple notification and update summary`() { + givenNotifications(simpleNotifications = listOf(OneShotNotification.Append( + A_NOTIFICATION, + ONE_SHOT_META.copy(key = AN_EVENT_ID) + ))) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + showNotificationMessage(tag = AN_EVENT_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, A_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + } + } + + @Test + fun `given an invitation notification is removed when rendering then remove the invitation notification and update summary`() { + givenNotifications(invitationNotifications = listOf(OneShotNotification.Removed(A_ROOM_ID))) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + cancelNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + } + } + + @Test + fun `given an invitation notification is added when rendering then show the invitation notification and update summary`() { + givenNotifications(simpleNotifications = listOf(OneShotNotification.Append( + A_NOTIFICATION, + ONE_SHOT_META.copy(key = A_ROOM_ID) + ))) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + showNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, A_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + } + } + + private fun renderEventsAsNotifications() { + notificationRenderer.render( + currentRoomId = A_CURRENT_ROOM_ID, + myUserId = MY_USER_ID, + myUserDisplayName = MY_USER_DISPLAY_NAME, + myUserAvatarUrl = MY_USER_AVATAR_URL, + eventList = AN_EVENT_LIST + ) + } + + private fun givenNoNotifications() { + givenNotifications(emptyList(), emptyList(), emptyList(), USE_COMPLETE_NOTIFICATION_FORMAT, A_SUMMARY_NOTIFICATION) + } + + private fun givenNotifications(roomNotifications: List = emptyList(), + invitationNotifications: List = emptyList(), + simpleNotifications: List = emptyList(), + useCompleteNotificationFormat: Boolean = USE_COMPLETE_NOTIFICATION_FORMAT, + summaryNotification: Notification = A_SUMMARY_NOTIFICATION) { + notifiableEventProcessor.givenProcessedEventsFor(AN_EVENT_LIST, A_CURRENT_ROOM_ID, A_PROCESSED_EVENTS) + notificationFactory.givenNotificationsFor( + processedEvents = A_PROCESSED_EVENTS, + myUserId = MY_USER_ID, + myUserDisplayName = MY_USER_DISPLAY_NAME, + myUserAvatarUrl = MY_USER_AVATAR_URL, + useCompleteNotificationFormat = useCompleteNotificationFormat, + roomNotifications = roomNotifications, + invitationNotifications = invitationNotifications, + simpleNotifications = simpleNotifications, + summaryNotification = summaryNotification + ) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt new file mode 100644 index 0000000000..93f5e40524 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt @@ -0,0 +1,32 @@ +/* + * 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.test.fakes + +import im.vector.app.features.notifications.NotifiableEvent +import im.vector.app.features.notifications.NotifiableEventProcessor +import im.vector.app.features.notifications.ProcessedNotificationEvents +import io.mockk.every +import io.mockk.mockk + +class FakeNotifiableEventProcessor { + + val instance = mockk() + + fun givenProcessedEventsFor(events: MutableList, currentRoomId: String?, processedEvents: ProcessedNotificationEvents) { + every { instance.modifyAndProcess(events, currentRoomId) } returns processedEvents + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationDisplayer.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationDisplayer.kt new file mode 100644 index 0000000000..2856b0f49c --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationDisplayer.kt @@ -0,0 +1,42 @@ +/* + * 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.test.fakes + +import im.vector.app.features.notifications.NotificationDisplayer +import im.vector.app.features.notifications.NotificationDrawerManager +import io.mockk.confirmVerified +import io.mockk.mockk +import io.mockk.verify +import io.mockk.verifyOrder + +class FakeNotificationDisplayer { + + val instance = mockk(relaxed = true) + + fun verifySummaryCancelled() { + verify { instance.cancelNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID) } + } + + fun verifyNoOtherInteractions() { + confirmVerified(instance) + } + + fun verifyInOrder(verifyBlock: NotificationDisplayer.() -> Unit) { + verifyOrder { verifyBlock(instance) } + verifyNoOtherInteractions() + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt new file mode 100644 index 0000000000..921999bd93 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt @@ -0,0 +1,56 @@ +/* + * 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.test.fakes + +import android.app.Notification +import im.vector.app.features.notifications.NotificationFactory +import im.vector.app.features.notifications.OneShotNotification +import im.vector.app.features.notifications.ProcessedNotificationEvents +import im.vector.app.features.notifications.RoomNotification +import io.mockk.every +import io.mockk.mockk + +class FakeNotificationFactory { + + val instance = mockk() + + fun givenNotificationsFor(processedEvents: ProcessedNotificationEvents, + myUserId: String, + myUserDisplayName: String, + myUserAvatarUrl: String?, + useCompleteNotificationFormat: Boolean, + roomNotifications: List, + invitationNotifications: List, + simpleNotifications: List, + summaryNotification: Notification) { + with(instance) { + every { processedEvents.roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) } returns roomNotifications + every { processedEvents.invitationEvents.toNotifications(myUserId) } returns invitationNotifications + every { processedEvents.simpleEvents.toNotifications(myUserId) } returns simpleNotifications + + every { + createSummaryNotification( + roomNotifications, + invitationNotifications, + simpleNotifications, + useCompleteNotificationFormat + ) + } returns summaryNotification + + } + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeVectorPreferences.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorPreferences.kt new file mode 100644 index 0000000000..eb8f9ac413 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorPreferences.kt @@ -0,0 +1,30 @@ +/* + * 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.test.fakes + +import im.vector.app.features.settings.VectorPreferences +import io.mockk.every +import io.mockk.mockk + +class FakeVectorPreferences { + + val instance = mockk() + + fun givenUseCompleteNotificationFormat(value: Boolean) { + every { instance.useCompleteNotificationFormat() } returns value + } +} From c85afa96d340e21f3cc31e1d048279db5290a3ef Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 08:22:45 +0100 Subject: [PATCH 068/413] lifting settings change to cancel all notifications out of the renderer - the renderer's responsibility it handling events --- .../NotificationDrawerManager.kt | 376 +----------------- .../notifications/NotificationFactory.kt | 4 +- .../notifications/NotificationRenderer.kt | 33 +- .../notifications/RoomGroupMessageCreator.kt | 39 +- .../notifications/NotificationRendererTest.kt | 5 +- 5 files changed, 62 insertions(+), 395 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 843b7208fd..a3a3e898ba 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -16,26 +16,15 @@ package im.vector.app.features.notifications import android.content.Context -import android.graphics.Bitmap -import android.os.Build import android.os.Handler import android.os.HandlerThread import androidx.annotation.WorkerThread -import androidx.core.app.NotificationCompat -import androidx.core.app.Person -import androidx.core.content.pm.ShortcutInfoCompat -import androidx.core.content.pm.ShortcutManagerCompat -import androidx.core.graphics.drawable.IconCompat import im.vector.app.ActiveSessionDataSource import im.vector.app.BuildConfig import im.vector.app.R -import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.FirstThrottler import im.vector.app.features.displayname.getBestName -import im.vector.app.features.home.room.detail.RoomDetailActivity -import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.settings.VectorPreferences -import me.gujun.android.span.span import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.api.util.toMatrixItem @@ -54,12 +43,8 @@ import javax.inject.Singleton class NotificationDrawerManager @Inject constructor(private val context: Context, private val notificationUtils: NotificationUtils, private val vectorPreferences: VectorPreferences, - private val stringProvider: StringProvider, private val activeSessionDataSource: ActiveSessionDataSource, - private val iconLoader: IconLoader, - private val bitmapLoader: BitmapLoader, - private val outdatedDetector: OutdatedEventDetector?, - private val autoAcceptInvites: AutoAcceptInvites) { + private val notificationRenderer: NotificationRenderer) { private val handlerThread: HandlerThread = HandlerThread("NotificationDrawerManager", Thread.MIN_PRIORITY) private var backgroundHandler: Handler @@ -69,13 +54,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context backgroundHandler = Handler(handlerThread.looper) } - // The first time the notification drawer is refreshed, we force re-render of all notifications - private var firstTime = true - private val eventList = loadEventInfo() - private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size) - private var currentRoomId: String? = null // TODO Multi-session: this will have to be improved @@ -258,359 +238,17 @@ class NotificationDrawerManager @Inject constructor(private val context: Context val myUserAvatarUrl = session.contentUrlResolver().resolveThumbnail(user?.avatarUrl, avatarSize, avatarSize, ContentUrlResolver.ThumbnailMethod.SCALE) synchronized(eventList) { - val useSplitNotifications = false - if (useSplitNotifications) { - // TODO - } else { - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER ") - // TMP code - var hasNewEvent = false - var summaryIsNoisy = false - val summaryInboxStyle = NotificationCompat.InboxStyle() - - // group events by room to create a single MessagingStyle notif - val roomIdToEventMap: MutableMap> = LinkedHashMap() - val simpleEvents: MutableList = ArrayList() - val invitationEvents: MutableList = ArrayList() - - val eventIterator = eventList.listIterator() - while (eventIterator.hasNext()) { - when (val event = eventIterator.next()) { - is NotifiableMessageEvent -> { - val roomId = event.roomId - val roomEvents = roomIdToEventMap.getOrPut(roomId) { ArrayList() } - - if (shouldIgnoreMessageEventInRoom(roomId) || outdatedDetector?.isMessageOutdated(event) == true) { - // forget this event - eventIterator.remove() - } else { - roomEvents.add(event) - } - } - is InviteNotifiableEvent -> { - if (autoAcceptInvites.hideInvites) { - // Forget this event - eventIterator.remove() - } else { - invitationEvents.add(event) - } - } - is SimpleNotifiableEvent -> simpleEvents.add(event) - else -> Timber.w("Type not handled") - } + val newSettings = vectorPreferences.useCompleteNotificationFormat() + if (newSettings != useCompleteNotificationFormat) { + // Settings has changed, remove all current notifications + notificationUtils.cancelAllNotifications() + useCompleteNotificationFormat = newSettings } - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER ${roomIdToEventMap.size} room groups") - - var globalLastMessageTimestamp = 0L - - val newSettings = vectorPreferences.useCompleteNotificationFormat() - if (newSettings != useCompleteNotificationFormat) { - // Settings has changed, remove all current notifications - notificationUtils.cancelAllNotifications() - useCompleteNotificationFormat = newSettings - } - - var simpleNotificationRoomCounter = 0 - var simpleNotificationMessageCounter = 0 - - // events have been grouped by roomId - for ((roomId, events) in roomIdToEventMap) { - // Build the notification for the room - if (events.isEmpty() || events.all { it.isRedacted }) { - // Just clear this notification - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId has no more events") - notificationUtils.cancelNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID) - continue - } - - simpleNotificationRoomCounter++ - val roomName = events[0].roomName ?: events[0].senderName ?: "" - - val roomEventGroupInfo = RoomEventGroupInfo( - roomId = roomId, - isDirect = events[0].roomIsDirect, - roomDisplayName = roomName) - - val style = NotificationCompat.MessagingStyle(Person.Builder() - .setName(myUserDisplayName) - .setIcon(iconLoader.getUserIcon(myUserAvatarUrl)) - .setKey(events[0].matrixID) - .build()) - - style.isGroupConversation = !roomEventGroupInfo.isDirect - - if (!roomEventGroupInfo.isDirect) { - style.conversationTitle = roomEventGroupInfo.roomDisplayName - } - - val largeBitmap = getRoomBitmap(events) - - for (event in events) { - // if all events in this room have already been displayed there is no need to update it - if (!event.hasBeenDisplayed && !event.isRedacted) { - roomEventGroupInfo.shouldBing = roomEventGroupInfo.shouldBing || event.noisy - roomEventGroupInfo.customSound = event.soundName - } - roomEventGroupInfo.hasNewEvent = roomEventGroupInfo.hasNewEvent || !event.hasBeenDisplayed - - val senderPerson = if (event.outGoingMessage) { - null - } else { - Person.Builder() - .setName(event.senderName) - .setIcon(iconLoader.getUserIcon(event.senderAvatarPath)) - .setKey(event.senderId) - .build() - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - val openRoomIntent = RoomDetailActivity.shortcutIntent(context, roomId) - - val shortcut = ShortcutInfoCompat.Builder(context, roomId) - .setLongLived(true) - .setIntent(openRoomIntent) - .setShortLabel(roomName) - .setIcon(largeBitmap?.let { IconCompat.createWithAdaptiveBitmap(it) } ?: iconLoader.getUserIcon(event.senderAvatarPath)) - .build() - - ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) - } - - if (event.outGoingMessage && event.outGoingMessageFailed) { - style.addMessage(stringProvider.getString(R.string.notification_inline_reply_failed), event.timestamp, senderPerson) - roomEventGroupInfo.hasSmartReplyError = true - } else { - if (!event.isRedacted) { - simpleNotificationMessageCounter++ - style.addMessage(event.body, event.timestamp, senderPerson) - } - } - event.hasBeenDisplayed = true // we can consider it as displayed - - // It is possible that this event was previously shown as an 'anonymous' simple notif. - // And now it will be merged in a single MessageStyle notif, so we can clean to be sure - notificationUtils.cancelNotificationMessage(event.eventId, ROOM_EVENT_NOTIFICATION_ID) - } - - try { - if (events.size == 1) { - val event = events[0] - if (roomEventGroupInfo.isDirect) { - val line = span { - span { - textStyle = "bold" - +String.format("%s: ", event.senderName) - } - +(event.description) - } - summaryInboxStyle.addLine(line) - } else { - val line = span { - span { - textStyle = "bold" - +String.format("%s: %s ", roomName, event.senderName) - } - +(event.description) - } - summaryInboxStyle.addLine(line) - } - } else { - val summaryLine = stringProvider.getQuantityString( - R.plurals.notification_compat_summary_line_for_room, events.size, roomName, events.size) - summaryInboxStyle.addLine(summaryLine) - } - } catch (e: Throwable) { - // String not found or bad format - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER failed to resolve string") - summaryInboxStyle.addLine(roomName) - } - - if (firstTime || roomEventGroupInfo.hasNewEvent) { - // Should update displayed notification - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId need refresh") - val lastMessageTimestamp = events.last().timestamp - - if (globalLastMessageTimestamp < lastMessageTimestamp) { - globalLastMessageTimestamp = lastMessageTimestamp - } - - val tickerText = if (roomEventGroupInfo.isDirect) { - stringProvider.getString(R.string.notification_ticker_text_dm, events.last().senderName, events.last().description) - } else { - stringProvider.getString(R.string.notification_ticker_text_group, roomName, events.last().senderName, events.last().description) - } - - if (useCompleteNotificationFormat) { - val notification = notificationUtils.buildMessagesListNotification( - style, - roomEventGroupInfo, - largeBitmap, - lastMessageTimestamp, - myUserDisplayName, - tickerText) - - // is there an id for this room? - notificationUtils.showNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID, notification) - } - - hasNewEvent = true - summaryIsNoisy = summaryIsNoisy || roomEventGroupInfo.shouldBing - } else { - Timber.v("%%%%%%%% REFRESH NOTIFICATION DRAWER $roomId is up to date") - } - } - - // Handle invitation events - for (event in invitationEvents) { - // We build a invitation notification - if (firstTime || !event.hasBeenDisplayed) { - if (useCompleteNotificationFormat) { - val notification = notificationUtils.buildRoomInvitationNotification(event, session.myUserId) - notificationUtils.showNotificationMessage(event.roomId, ROOM_INVITATION_NOTIFICATION_ID, notification) - } - event.hasBeenDisplayed = true // we can consider it as displayed - hasNewEvent = true - summaryIsNoisy = summaryIsNoisy || event.noisy - summaryInboxStyle.addLine(event.description) - } - } - - // Handle simple events - for (event in simpleEvents) { - // We build a simple notification - if (firstTime || !event.hasBeenDisplayed) { - if (useCompleteNotificationFormat) { - val notification = notificationUtils.buildSimpleEventNotification(event, session.myUserId) - notificationUtils.showNotificationMessage(event.eventId, ROOM_EVENT_NOTIFICATION_ID, notification) - } - event.hasBeenDisplayed = true // we can consider it as displayed - hasNewEvent = true - summaryIsNoisy = summaryIsNoisy || event.noisy - summaryInboxStyle.addLine(event.description) - } - } - - // ======== Build summary notification ========= - // On Android 7.0 (API level 24) and higher, the system automatically builds a summary for - // your group using snippets of text from each notification. The user can expand this - // notification to see each separate notification. - // To support older versions, which cannot show a nested group of notifications, - // you must create an extra notification that acts as the summary. - // This appears as the only notification and the system hides all the others. - // So this summary should include a snippet from all the other notifications, - // which the user can tap to open your app. - // The behavior of the group summary may vary on some device types such as wearables. - // To ensure the best experience on all devices and versions, always include a group summary when you create a group - // https://developer.android.com/training/notify-user/group - - if (eventList.isEmpty() || eventList.all { it.isRedacted }) { - notificationUtils.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID) - } else if (hasNewEvent) { - // FIXME roomIdToEventMap.size is not correct, this is the number of rooms - val nbEvents = roomIdToEventMap.size + simpleEvents.size - val sumTitle = stringProvider.getQuantityString(R.plurals.notification_compat_summary_title, nbEvents, nbEvents) - summaryInboxStyle.setBigContentTitle(sumTitle) - // TODO get latest event? - .setSummaryText(stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages, nbEvents, nbEvents)) - - if (useCompleteNotificationFormat) { - val notification = notificationUtils.buildSummaryListNotification( - summaryInboxStyle, - sumTitle, - noisy = hasNewEvent && summaryIsNoisy, - lastMessageTimestamp = globalLastMessageTimestamp) - - notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification) - } else { - // Add the simple events as message (?) - simpleNotificationMessageCounter += simpleEvents.size - val numberOfInvitations = invitationEvents.size - - val privacyTitle = if (numberOfInvitations > 0) { - val invitationsStr = stringProvider.getQuantityString(R.plurals.notification_invitations, numberOfInvitations, numberOfInvitations) - if (simpleNotificationMessageCounter > 0) { - // Invitation and message - val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, - simpleNotificationMessageCounter, simpleNotificationMessageCounter) - if (simpleNotificationRoomCounter > 1) { - // In several rooms - val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, - simpleNotificationRoomCounter, simpleNotificationRoomCounter) - stringProvider.getString( - R.string.notification_unread_notified_messages_in_room_and_invitation, - messageStr, - roomStr, - invitationsStr - ) - } else { - // In one room - stringProvider.getString( - R.string.notification_unread_notified_messages_and_invitation, - messageStr, - invitationsStr - ) - } - } else { - // Only invitation - invitationsStr - } - } else { - // No invitation, only messages - val messageStr = stringProvider.getQuantityString(R.plurals.room_new_messages_notification, - simpleNotificationMessageCounter, simpleNotificationMessageCounter) - if (simpleNotificationRoomCounter > 1) { - // In several rooms - val roomStr = stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages_in_room_rooms, - simpleNotificationRoomCounter, simpleNotificationRoomCounter) - stringProvider.getString(R.string.notification_unread_notified_messages_in_room, messageStr, roomStr) - } else { - // In one room - messageStr - } - } - val notification = notificationUtils.buildSummaryListNotification( - style = null, - compatSummary = privacyTitle, - noisy = hasNewEvent && summaryIsNoisy, - lastMessageTimestamp = globalLastMessageTimestamp) - - notificationUtils.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, notification) - } - - if (hasNewEvent && summaryIsNoisy) { - try { - // turn the screen on for 3 seconds - /* - TODO - if (Matrix.getInstance(VectorApp.getInstance())!!.pushManager.isScreenTurnedOn) { - val pm = VectorApp.getInstance().getSystemService()!! - val wl = pm.newWakeLock(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or PowerManager.ACQUIRE_CAUSES_WAKEUP, - NotificationDrawerManager::class.java.name) - wl.acquire(3000) - wl.release() - } - */ - } catch (e: Throwable) { - Timber.e(e, "## Failed to turn screen on") - } - } - } - // notice that we can get bit out of sync with actual display but not a big issue - firstTime = false - } + notificationRenderer.render(currentRoomId, session.myUserId, myUserDisplayName, myUserAvatarUrl, useCompleteNotificationFormat, eventList) } } - private fun getRoomBitmap(events: List): Bitmap? { - if (events.isEmpty()) return null - - // Use the last event (most recent?) - val roomAvatarPath = events.last().roomAvatarPath ?: events.last().senderAvatarPath - - return bitmapLoader.getRoomBitmap(roomAvatarPath) - } - fun shouldIgnoreMessageEventInRoom(roomId: String?): Boolean { return currentRoomId != null && roomId == currentRoomId } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 55e9f7352d..ec8e372c4e 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -17,6 +17,8 @@ package im.vector.app.features.notifications import android.app.Notification +import androidx.core.content.pm.ShortcutInfoCompat +import androidx.core.content.pm.ShortcutManagerCompat import javax.inject.Inject class NotificationFactory @Inject constructor( @@ -83,7 +85,7 @@ private fun List.mapToMeta() = filterIsInstance) { + fun render(currentRoomId: String?, + myUserId: String, + myUserDisplayName: String, + myUserAvatarUrl: String?, + useCompleteNotificationFormat: Boolean, + eventList: MutableList) { Timber.v("refreshNotificationDrawerBg()") - val newSettings = vectorPreferences.useCompleteNotificationFormat() - if (newSettings != useCompleteNotificationFormat) { - // Settings has changed, remove all current notifications - notificationDisplayer.cancelAllNotifications() - useCompleteNotificationFormat = newSettings - } - val notificationEvents = notifiableEventProcessor.modifyAndProcess(eventList, currentRoomId) if (lastKnownEventList == notificationEvents.hashCode()) { Timber.d("Skipping notification update due to event list not changing") } else { - processEvents(notificationEvents, myUserId, myUserDisplayName, myUserAvatarUrl) + processEvents(notificationEvents, myUserId, myUserDisplayName, myUserAvatarUrl, useCompleteNotificationFormat) lastKnownEventList = notificationEvents.hashCode() } } - private fun processEvents(notificationEvents: ProcessedNotificationEvents, myUserId: String, myUserDisplayName: String, myUserAvatarUrl: String?) { + private fun processEvents(notificationEvents: ProcessedNotificationEvents, myUserId: String, myUserDisplayName: String, myUserAvatarUrl: String?, useCompleteNotificationFormat: Boolean) { val (roomEvents, simpleEvents, invitationEvents) = notificationEvents with(notificationFactory) { val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) @@ -70,6 +72,9 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID) is RoomNotification.Message -> if (useCompleteNotificationFormat) { Timber.d("Updating room messages notification ${wrapper.meta.roomId}") + wrapper.shortcutInfo?.let { + ShortcutManagerCompat.pushDynamicShortcut(appContext, it) + } notificationDisplayer.showNotificationMessage(wrapper.meta.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, wrapper.notification) } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt index 786ce40046..56e3274515 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -16,11 +16,17 @@ package im.vector.app.features.notifications +import android.content.Context import android.graphics.Bitmap +import android.os.Build import androidx.core.app.NotificationCompat import androidx.core.app.Person +import androidx.core.content.pm.ShortcutInfoCompat +import androidx.core.content.pm.ShortcutManagerCompat +import androidx.core.graphics.drawable.IconCompat import im.vector.app.R import im.vector.app.core.resources.StringProvider +import im.vector.app.features.home.room.detail.RoomDetailActivity import me.gujun.android.span.Span import me.gujun.android.span.span import timber.log.Timber @@ -30,7 +36,8 @@ class RoomGroupMessageCreator @Inject constructor( private val iconLoader: IconLoader, private val bitmapLoader: BitmapLoader, private val stringProvider: StringProvider, - private val notificationUtils: NotificationUtils + private val notificationUtils: NotificationUtils, + private val appContext: Context ) { fun createRoomMessage(events: List, roomId: String, userDisplayName: String, userAvatarUrl: String?): RoomNotification.Message { @@ -54,6 +61,19 @@ class RoomGroupMessageCreator @Inject constructor( stringProvider.getString(R.string.notification_ticker_text_dm, events.last().senderName, events.last().description) } + val largeBitmap = getRoomBitmap(events) + val shortcutInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val openRoomIntent = RoomDetailActivity.shortcutIntent(appContext, roomId) + ShortcutInfoCompat.Builder(appContext, roomId) + .setLongLived(true) + .setIntent(openRoomIntent) + .setShortLabel(roomName) + .setIcon(largeBitmap?.let { IconCompat.createWithAdaptiveBitmap(it) } ?: iconLoader.getUserIcon(events.last().senderAvatarPath)) + .build() + } else { + null + } + val lastMessageTimestamp = events.last().timestamp val smartReplyErrors = events.filter { it.isSmartReplyError() } val messageCount = (events.size - smartReplyErrors.size) @@ -72,22 +92,27 @@ class RoomGroupMessageCreator @Inject constructor( it.shouldBing = meta.shouldBing it.customSound = events.last().soundName }, - largeIcon = getRoomBitmap(events), + largeIcon = largeBitmap, lastMessageTimestamp, userDisplayName, tickerText ), + shortcutInfo, meta ) } private fun NotificationCompat.MessagingStyle.addMessagesFromEvents(events: List) { events.forEach { event -> - val senderPerson = Person.Builder() - .setName(event.senderName) - .setIcon(iconLoader.getUserIcon(event.senderAvatarPath)) - .setKey(event.senderId) - .build() + val senderPerson = if (event.outGoingMessage) { + null + } else { + Person.Builder() + .setName(event.senderName) + .setIcon(iconLoader.getUserIcon(event.senderAvatarPath)) + .setKey(event.senderId) + .build() + } when { event.isSmartReplyError() -> addMessage(stringProvider.getString(R.string.notification_inline_reply_failed), event.timestamp, senderPerson) else -> addMessage(event.body, event.timestamp, senderPerson) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt index a07dd61368..74a11b6d0d 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -45,15 +45,11 @@ class NotificationRendererTest { private val notifiableEventProcessor = FakeNotifiableEventProcessor() private val notificationDisplayer = FakeNotificationDisplayer() - private val preferences = FakeVectorPreferences().also { - it.givenUseCompleteNotificationFormat(USE_COMPLETE_NOTIFICATION_FORMAT) - } private val notificationFactory = FakeNotificationFactory() private val notificationRenderer = NotificationRenderer( notifiableEventProcessor = notifiableEventProcessor.instance, notificationDisplayer = notificationDisplayer.instance, - vectorPreferences = preferences.instance, notificationFactory = notificationFactory.instance ) @@ -154,6 +150,7 @@ class NotificationRendererTest { myUserId = MY_USER_ID, myUserDisplayName = MY_USER_DISPLAY_NAME, myUserAvatarUrl = MY_USER_AVATAR_URL, + useCompleteNotificationFormat = USE_COMPLETE_NOTIFICATION_FORMAT, eventList = AN_EVENT_LIST ) } From 3d567d0dcdff7400f4a25ec5cb205091f420155a Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 14:18:27 +0100 Subject: [PATCH 069/413] removing no longer needed hasBeenDisplayed state, the eventList is our source of truth - when events have finished being displayed they should be removed from the eventList via notification delete actions --- .../features/notifications/InviteNotifiableEvent.kt | 5 +---- .../app/features/notifications/NotifiableEvent.kt | 1 - .../features/notifications/NotifiableMessageEvent.kt | 2 -- .../notifications/NotificationDrawerManager.kt | 7 +++---- .../app/features/notifications/NotificationFactory.kt | 2 +- .../features/notifications/SimpleNotifiableEvent.kt | 5 +---- .../notifications/NotifiableEventProcessorTest.kt | 10 +++++++--- .../features/notifications/NotificationFactoryTest.kt | 2 +- 8 files changed, 14 insertions(+), 20 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 743b3587a8..832f97bc4e 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -29,7 +29,4 @@ data class InviteNotifiableEvent( val timestamp: Long, val soundName: String?, override val isRedacted: Boolean = false -) : NotifiableEvent { - - override var hasBeenDisplayed = false -} +) : NotifiableEvent diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index 2f79da6795..52d8119cbb 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -23,7 +23,6 @@ import java.io.Serializable sealed interface NotifiableEvent : Serializable { val eventId: String val editedEventId: String? - var hasBeenDisplayed: Boolean // Used to know if event should be replaced with the one coming from eventstream val canBeReplaced: Boolean diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index 4a2152c417..161c9f74a6 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -39,8 +39,6 @@ data class NotifiableMessageEvent( override val isRedacted: Boolean = false ) : NotifiableEvent { - override var hasBeenDisplayed: Boolean = false - val type: String = EventType.MESSAGE val description: String = body ?: "" val title: String = senderName ?: "" diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index a3a3e898ba..4be1f6ee6e 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -101,7 +101,6 @@ class NotificationDrawerManager @Inject constructor(private val context: Context // Use setOnlyAlertOnce to ensure update notification does not interfere with sound // from first notify invocation as outlined in: // https://developer.android.com/training/notify-user/build-notification#Updating - notifiableEvent.hasBeenDisplayed = false eventList.remove(existing) eventList.add(notifiableEvent) } else { @@ -144,9 +143,9 @@ class NotificationDrawerManager @Inject constructor(private val context: Context synchronized(eventList) { eventList.replace(eventId) { when (it) { - is InviteNotifiableEvent -> it.copy(isRedacted = true).apply { hasBeenDisplayed = false } - is NotifiableMessageEvent -> it.copy(isRedacted = true).apply { hasBeenDisplayed = false } - is SimpleNotifiableEvent -> it.copy(isRedacted = true).apply { hasBeenDisplayed = false } + is InviteNotifiableEvent -> it.copy(isRedacted = true) + is NotifiableMessageEvent -> it.copy(isRedacted = true) + is SimpleNotifiableEvent -> it.copy(isRedacted = true) } } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index ec8e372c4e..f47e82e845 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -38,7 +38,7 @@ class NotificationFactory @Inject constructor( private fun List.hasNoEventsToDisplay() = isEmpty() || all { it.canNotBeDisplayed() } - private fun NotifiableMessageEvent.canNotBeDisplayed() = hasBeenDisplayed || isRedacted + private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted fun Map.toNotifications(myUserId: String): List { return this.map { (roomId, event) -> diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index 940d8a3770..8c72372204 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -27,7 +27,4 @@ data class SimpleNotifiableEvent( val soundName: String?, override var canBeReplaced: Boolean, override val isRedacted: Boolean = false -) : NotifiableEvent { - - override var hasBeenDisplayed: Boolean = false -} +) : NotifiableEvent diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt index a5bb9978dd..6f47e71500 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -156,7 +156,8 @@ fun aSimpleNotifiableEvent(eventId: String) = SimpleNotifiableEvent( type = null, timestamp = 0, soundName = null, - isPushGatewayEvent = false + canBeReplaced = false, + isRedacted = false ) fun anInviteNotifiableEvent(roomId: String) = InviteNotifiableEvent( @@ -170,7 +171,8 @@ fun anInviteNotifiableEvent(roomId: String) = InviteNotifiableEvent( type = null, timestamp = 0, soundName = null, - isPushGatewayEvent = false + canBeReplaced = false, + isRedacted = false ) fun aNotifiableMessageEvent(eventId: String, roomId: String) = NotifiableMessageEvent( @@ -183,5 +185,7 @@ fun aNotifiableMessageEvent(eventId: String, roomId: String) = NotifiableMessage body = "message-body", roomId = roomId, roomName = "room-name", - roomIsDirect = false + roomIsDirect = false, + canBeReplaced = false, + isRedacted = false ) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt index c08be9e8c7..f8e6813d9b 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt @@ -123,7 +123,7 @@ class NotificationFactoryTest { @Test fun `given a room with only redacted events when mapping to notification then is Empty`() = testWith(notificationFactory) { - val redactedRoom = mapOf(A_ROOM_ID to listOf(A_MESSAGE_EVENT.copy().apply { isRedacted = true })) + val redactedRoom = mapOf(A_ROOM_ID to listOf(A_MESSAGE_EVENT.copy(isRedacted = true))) val result = redactedRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) From 0d316e69ded9a16f9da4bc05ec8b74fa82df793d Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 16:03:52 +0100 Subject: [PATCH 070/413] handling creating the summary when notification events are filtered to empty due to only containing removals --- .../notifications/NotificationFactory.kt | 42 +++++++--- .../notifications/NotificationRenderer.kt | 78 ++++++++++--------- .../SummaryGroupMessageCreator.kt | 8 +- .../notifications/NotificationFactoryTest.kt | 6 +- .../notifications/NotificationRendererTest.kt | 21 ++--- .../app/test/fakes/FakeNotificationFactory.kt | 4 +- 6 files changed, 94 insertions(+), 65 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index f47e82e845..8189977ba8 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -46,7 +46,12 @@ class NotificationFactory @Inject constructor( null -> OneShotNotification.Removed(key = roomId) else -> OneShotNotification.Append( notificationUtils.buildRoomInvitationNotification(event, myUserId), - OneShotNotification.Append.Meta(key = roomId, summaryLine = event.description, isNoisy = event.noisy) + OneShotNotification.Append.Meta( + key = roomId, + summaryLine = event.description, + isNoisy = event.noisy, + timestamp = event.timestamp + ) ) } } @@ -59,7 +64,12 @@ class NotificationFactory @Inject constructor( null -> OneShotNotification.Removed(key = eventId) else -> OneShotNotification.Append( notificationUtils.buildSimpleEventNotification(event, myUserId), - OneShotNotification.Append.Meta(key = eventId, summaryLine = event.description, isNoisy = event.noisy) + OneShotNotification.Append.Meta( + key = eventId, + summaryLine = event.description, + isNoisy = event.noisy, + timestamp = event.timestamp + ) ) } } @@ -68,13 +78,19 @@ class NotificationFactory @Inject constructor( fun createSummaryNotification(roomNotifications: List, invitationNotifications: List, simpleNotifications: List, - useCompleteNotificationFormat: Boolean): Notification { - return summaryGroupMessageCreator.createSummaryNotification( - roomNotifications = roomNotifications.mapToMeta(), - invitationNotifications = invitationNotifications.mapToMeta(), - simpleNotifications = simpleNotifications.mapToMeta(), - useCompleteNotificationFormat = useCompleteNotificationFormat - ) + useCompleteNotificationFormat: Boolean): SummaryNotification { + val roomMeta = roomNotifications.mapToMeta() + val invitationMeta = invitationNotifications.mapToMeta() + val simpleMeta = simpleNotifications.mapToMeta() + return when { + roomMeta.isEmpty() && invitationMeta.isEmpty() && simpleMeta.isEmpty() -> SummaryNotification.Removed + else -> SummaryNotification.Update(summaryGroupMessageCreator.createSummaryNotification( + roomNotifications = roomMeta, + invitationNotifications = invitationMeta, + simpleNotifications = simpleMeta, + useCompleteNotificationFormat = useCompleteNotificationFormat + )) + } } } @@ -102,7 +118,13 @@ sealed interface OneShotNotification { data class Meta( val key: String, val summaryLine: CharSequence, - val isNoisy: Boolean + val isNoisy: Boolean, + val timestamp: Long, ) } } + +sealed interface SummaryNotification { + object Removed : SummaryNotification + data class Update(val notification: Notification) : SummaryNotification +} diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index 005cf04f07..749e3c61b6 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -16,12 +16,8 @@ package im.vector.app.features.notifications import android.content.Context -import android.os.Build import androidx.annotation.WorkerThread -import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutManagerCompat -import androidx.core.graphics.drawable.IconCompat -import im.vector.app.features.home.room.detail.RoomDetailActivity import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton @@ -41,7 +37,7 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces myUserAvatarUrl: String?, useCompleteNotificationFormat: Boolean, eventList: MutableList) { - Timber.v("refreshNotificationDrawerBg()") + Timber.v("Render notification events - count: ${eventList.size}") val notificationEvents = notifiableEventProcessor.modifyAndProcess(eventList, currentRoomId) if (lastKnownEventList == notificationEvents.hashCode()) { Timber.d("Skipping notification update due to event list not changing") @@ -57,49 +53,55 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) val invitationNotifications = invitationEvents.toNotifications(myUserId) val simpleNotifications = simpleEvents.toNotifications(myUserId) + val summaryNotification = createSummaryNotification( + roomNotifications = roomNotifications, + invitationNotifications = invitationNotifications, + simpleNotifications = simpleNotifications, + useCompleteNotificationFormat = useCompleteNotificationFormat + ) - if (roomNotifications.isEmpty() && invitationNotifications.isEmpty() && simpleNotifications.isEmpty()) { - notificationDisplayer.cancelNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID) - } else { - val summaryNotification = createSummaryNotification( - roomNotifications = roomNotifications, - invitationNotifications = invitationNotifications, - simpleNotifications = simpleNotifications, - useCompleteNotificationFormat = useCompleteNotificationFormat - ) - roomNotifications.forEach { wrapper -> - when (wrapper) { - is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID) - is RoomNotification.Message -> if (useCompleteNotificationFormat) { - Timber.d("Updating room messages notification ${wrapper.meta.roomId}") - wrapper.shortcutInfo?.let { - ShortcutManagerCompat.pushDynamicShortcut(appContext, it) - } - notificationDisplayer.showNotificationMessage(wrapper.meta.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, wrapper.notification) + roomNotifications.forEach { wrapper -> + when (wrapper) { + is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID) + is RoomNotification.Message -> if (useCompleteNotificationFormat) { + Timber.d("Updating room messages notification ${wrapper.meta.roomId}") + wrapper.shortcutInfo?.let { + ShortcutManagerCompat.pushDynamicShortcut(appContext, it) } + notificationDisplayer.showNotificationMessage(wrapper.meta.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, wrapper.notification) } } + } - invitationNotifications.forEach { wrapper -> - when (wrapper) { - is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID) - is OneShotNotification.Append -> if (useCompleteNotificationFormat) { - Timber.d("Updating invitation notification ${wrapper.meta.key}") - notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID, wrapper.notification) - } + invitationNotifications.forEach { wrapper -> + when (wrapper) { + is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID) + is OneShotNotification.Append -> if (useCompleteNotificationFormat) { + Timber.d("Updating invitation notification ${wrapper.meta.key}") + notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID, wrapper.notification) } } + } - simpleNotifications.forEach { wrapper -> - when (wrapper) { - is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID) - is OneShotNotification.Append -> if (useCompleteNotificationFormat) { - Timber.d("Updating simple notification ${wrapper.meta.key}") - notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, wrapper.notification) - } + simpleNotifications.forEach { wrapper -> + when (wrapper) { + is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID) + is OneShotNotification.Append -> if (useCompleteNotificationFormat) { + Timber.d("Updating simple notification ${wrapper.meta.key}") + notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, wrapper.notification) } } - notificationDisplayer.showNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, summaryNotification) + } + + when (summaryNotification) { + SummaryNotification.Removed -> { + Timber.d("Removing summary notification") + notificationDisplayer.cancelNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID) + } + is SummaryNotification.Update -> { + Timber.d("Updating summary notification") + notificationDisplayer.showNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, summaryNotification.notification) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt index dc9ff92aa6..821f24b436 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt @@ -57,7 +57,9 @@ class SummaryGroupMessageCreator @Inject constructor( val messageCount = roomNotifications.fold(initial = 0) { acc, current -> acc + current.messageCount } - val lastMessageTimestamp1 = roomNotifications.last().latestTimestamp + val lastMessageTimestamp = roomNotifications.lastOrNull()?.latestTimestamp + ?: invitationNotifications.lastOrNull()?.timestamp + ?: simpleNotifications.last().timestamp // FIXME roomIdToEventMap.size is not correct, this is the number of rooms val nbEvents = roomNotifications.size + simpleNotifications.size @@ -71,12 +73,12 @@ class SummaryGroupMessageCreator @Inject constructor( summaryInboxStyle, sumTitle, noisy = summaryIsNoisy, - lastMessageTimestamp = lastMessageTimestamp1 + lastMessageTimestamp = lastMessageTimestamp ) } else { processSimpleGroupSummary(summaryIsNoisy, messageCount, simpleNotifications.size, invitationNotifications.size, - roomNotifications.size, lastMessageTimestamp1) + roomNotifications.size, lastMessageTimestamp) } } diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt index f8e6813d9b..fc20f09811 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt @@ -55,7 +55,8 @@ class NotificationFactoryTest { meta = OneShotNotification.Append.Meta( key = A_ROOM_ID, summaryLine = AN_INVITATION_EVENT.description, - isNoisy = AN_INVITATION_EVENT.noisy + isNoisy = AN_INVITATION_EVENT.noisy, + timestamp = AN_INVITATION_EVENT.timestamp )) ) } @@ -83,7 +84,8 @@ class NotificationFactoryTest { meta = OneShotNotification.Append.Meta( key = AN_EVENT_ID, summaryLine = A_SIMPLE_EVENT.description, - isNoisy = A_SIMPLE_EVENT.noisy + isNoisy = A_SIMPLE_EVENT.noisy, + timestamp = AN_INVITATION_EVENT.timestamp )) ) } diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt index 74a11b6d0d..e3c97ad3cf 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -34,12 +34,13 @@ private const val USE_COMPLETE_NOTIFICATION_FORMAT = true private val AN_EVENT_LIST = mutableListOf() private val A_PROCESSED_EVENTS = ProcessedNotificationEvents(emptyMap(), emptyMap(), emptyMap()) -private val A_SUMMARY_NOTIFICATION = mockk() +private val A_SUMMARY_NOTIFICATION = SummaryNotification.Update(mockk()) +private val A_REMOVE_SUMMARY_NOTIFICATION = SummaryNotification.Removed private val A_NOTIFICATION = mockk() private val MESSAGE_META = RoomNotification.Message.Meta( summaryLine = "ignored", messageCount = 1, latestTimestamp = -1, roomId = A_ROOM_ID, shouldBing = false ) -private val ONE_SHOT_META = OneShotNotification.Append.Meta(key = "ignored", summaryLine = "ignored", isNoisy = false) +private val ONE_SHOT_META = OneShotNotification.Append.Meta(key = "ignored", summaryLine = "ignored", isNoisy = false, timestamp = -1) class NotificationRendererTest { @@ -71,7 +72,7 @@ class NotificationRendererTest { notificationDisplayer.verifyInOrder { cancelNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID) - showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification) } } @@ -86,7 +87,7 @@ class NotificationRendererTest { notificationDisplayer.verifyInOrder { showNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, A_NOTIFICATION) - showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification) } } @@ -98,7 +99,7 @@ class NotificationRendererTest { notificationDisplayer.verifyInOrder { cancelNotificationMessage(tag = AN_EVENT_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID) - showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification) } } @@ -113,7 +114,7 @@ class NotificationRendererTest { notificationDisplayer.verifyInOrder { showNotificationMessage(tag = AN_EVENT_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, A_NOTIFICATION) - showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification) } } @@ -125,7 +126,7 @@ class NotificationRendererTest { notificationDisplayer.verifyInOrder { cancelNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID) - showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification) } } @@ -140,7 +141,7 @@ class NotificationRendererTest { notificationDisplayer.verifyInOrder { showNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, A_NOTIFICATION) - showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION) + showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification) } } @@ -156,14 +157,14 @@ class NotificationRendererTest { } private fun givenNoNotifications() { - givenNotifications(emptyList(), emptyList(), emptyList(), USE_COMPLETE_NOTIFICATION_FORMAT, A_SUMMARY_NOTIFICATION) + givenNotifications(emptyList(), emptyList(), emptyList(), USE_COMPLETE_NOTIFICATION_FORMAT, A_REMOVE_SUMMARY_NOTIFICATION) } private fun givenNotifications(roomNotifications: List = emptyList(), invitationNotifications: List = emptyList(), simpleNotifications: List = emptyList(), useCompleteNotificationFormat: Boolean = USE_COMPLETE_NOTIFICATION_FORMAT, - summaryNotification: Notification = A_SUMMARY_NOTIFICATION) { + summaryNotification: SummaryNotification = A_SUMMARY_NOTIFICATION) { notifiableEventProcessor.givenProcessedEventsFor(AN_EVENT_LIST, A_CURRENT_ROOM_ID, A_PROCESSED_EVENTS) notificationFactory.givenNotificationsFor( processedEvents = A_PROCESSED_EVENTS, diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt index 921999bd93..da2dbc27da 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt @@ -16,11 +16,11 @@ package im.vector.app.test.fakes -import android.app.Notification import im.vector.app.features.notifications.NotificationFactory import im.vector.app.features.notifications.OneShotNotification import im.vector.app.features.notifications.ProcessedNotificationEvents import im.vector.app.features.notifications.RoomNotification +import im.vector.app.features.notifications.SummaryNotification import io.mockk.every import io.mockk.mockk @@ -36,7 +36,7 @@ class FakeNotificationFactory { roomNotifications: List, invitationNotifications: List, simpleNotifications: List, - summaryNotification: Notification) { + summaryNotification: SummaryNotification) { with(instance) { every { processedEvents.roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) } returns roomNotifications every { processedEvents.invitationEvents.toNotifications(myUserId) } returns invitationNotifications From 8fb6bef503a97720805df19029f4e7c104017ee7 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 16:29:20 +0100 Subject: [PATCH 071/413] removing this usages for project convention --- .../app/features/notifications/NotificationFactory.kt | 6 +++--- .../app/features/notifications/RoomGroupMessageCreator.kt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 8189977ba8..0c3aab7bd3 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -28,7 +28,7 @@ class NotificationFactory @Inject constructor( ) { fun Map>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { - return this.map { (roomId, events) -> + return map { (roomId, events) -> when { events.hasNoEventsToDisplay() -> RoomNotification.Removed(roomId) else -> roomGroupMessageCreator.createRoomMessage(events, roomId, myUserDisplayName, myUserAvatarUrl) @@ -41,7 +41,7 @@ class NotificationFactory @Inject constructor( private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted fun Map.toNotifications(myUserId: String): List { - return this.map { (roomId, event) -> + return map { (roomId, event) -> when (event) { null -> OneShotNotification.Removed(key = roomId) else -> OneShotNotification.Append( @@ -59,7 +59,7 @@ class NotificationFactory @Inject constructor( @JvmName("toNotificationsSimpleNotifiableEvent") fun Map.toNotifications(myUserId: String): List { - return this.map { (eventId, event) -> + return map { (eventId, event) -> when (event) { null -> OneShotNotification.Removed(key = eventId) else -> OneShotNotification.Append( diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt index 56e3274515..113dc21ebd 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -170,4 +170,4 @@ class RoomGroupMessageCreator @Inject constructor( } } -private fun NotifiableMessageEvent.isSmartReplyError() = this.outGoingMessage && this.outGoingMessageFailed +private fun NotifiableMessageEvent.isSmartReplyError() = outGoingMessage && outGoingMessageFailed From a94a1a0523340dc690ed8413509d94a95b7be757 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 7 Oct 2021 16:32:00 +0100 Subject: [PATCH 072/413] formatting --- .../notifications/NotificationFactory.kt | 13 +++++----- .../notifications/NotificationRenderer.kt | 26 ++++++++++++------- .../SummaryGroupMessageCreator.kt | 6 ++--- .../notifications/NotificationRendererTest.kt | 1 - 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 0c3aab7bd3..d5de0221f6 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -84,12 +84,13 @@ class NotificationFactory @Inject constructor( val simpleMeta = simpleNotifications.mapToMeta() return when { roomMeta.isEmpty() && invitationMeta.isEmpty() && simpleMeta.isEmpty() -> SummaryNotification.Removed - else -> SummaryNotification.Update(summaryGroupMessageCreator.createSummaryNotification( - roomNotifications = roomMeta, - invitationNotifications = invitationMeta, - simpleNotifications = simpleMeta, - useCompleteNotificationFormat = useCompleteNotificationFormat - )) + else -> SummaryNotification.Update( + summaryGroupMessageCreator.createSummaryNotification( + roomNotifications = roomMeta, + invitationNotifications = invitationMeta, + simpleNotifications = simpleMeta, + useCompleteNotificationFormat = useCompleteNotificationFormat + )) } } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index 749e3c61b6..844ea46f93 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -17,6 +17,10 @@ package im.vector.app.features.notifications import android.content.Context import androidx.annotation.WorkerThread +import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_EVENT_NOTIFICATION_ID +import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_INVITATION_NOTIFICATION_ID +import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_MESSAGES_NOTIFICATION_ID +import im.vector.app.features.notifications.NotificationDrawerManager.Companion.SUMMARY_NOTIFICATION_ID import androidx.core.content.pm.ShortcutManagerCompat import timber.log.Timber import javax.inject.Inject @@ -47,7 +51,11 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces } } - private fun processEvents(notificationEvents: ProcessedNotificationEvents, myUserId: String, myUserDisplayName: String, myUserAvatarUrl: String?, useCompleteNotificationFormat: Boolean) { + private fun processEvents(notificationEvents: ProcessedNotificationEvents, + myUserId: String, + myUserDisplayName: String, + myUserAvatarUrl: String?, + useCompleteNotificationFormat: Boolean) { val (roomEvents, simpleEvents, invitationEvents) = notificationEvents with(notificationFactory) { val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) @@ -62,33 +70,33 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces roomNotifications.forEach { wrapper -> when (wrapper) { - is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID) + is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, ROOM_MESSAGES_NOTIFICATION_ID) is RoomNotification.Message -> if (useCompleteNotificationFormat) { Timber.d("Updating room messages notification ${wrapper.meta.roomId}") wrapper.shortcutInfo?.let { ShortcutManagerCompat.pushDynamicShortcut(appContext, it) } - notificationDisplayer.showNotificationMessage(wrapper.meta.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, wrapper.notification) + notificationDisplayer.showNotificationMessage(wrapper.meta.roomId, ROOM_MESSAGES_NOTIFICATION_ID, wrapper.notification) } } } invitationNotifications.forEach { wrapper -> when (wrapper) { - is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID) + is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, ROOM_INVITATION_NOTIFICATION_ID) is OneShotNotification.Append -> if (useCompleteNotificationFormat) { Timber.d("Updating invitation notification ${wrapper.meta.key}") - notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID, wrapper.notification) + notificationDisplayer.showNotificationMessage(wrapper.meta.key, ROOM_INVITATION_NOTIFICATION_ID, wrapper.notification) } } } simpleNotifications.forEach { wrapper -> when (wrapper) { - is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID) + is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, ROOM_EVENT_NOTIFICATION_ID) is OneShotNotification.Append -> if (useCompleteNotificationFormat) { Timber.d("Updating simple notification ${wrapper.meta.key}") - notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, wrapper.notification) + notificationDisplayer.showNotificationMessage(wrapper.meta.key, ROOM_EVENT_NOTIFICATION_ID, wrapper.notification) } } } @@ -96,11 +104,11 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces when (summaryNotification) { SummaryNotification.Removed -> { Timber.d("Removing summary notification") - notificationDisplayer.cancelNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID) + notificationDisplayer.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID) } is SummaryNotification.Update -> { Timber.d("Updating summary notification") - notificationDisplayer.showNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, summaryNotification.notification) + notificationDisplayer.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, summaryNotification.notification) } } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt index 821f24b436..ddef31a0f5 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt @@ -51,9 +51,9 @@ class SummaryGroupMessageCreator @Inject constructor( simpleNotifications.forEach { style.addLine(it.summaryLine) } } - val summaryIsNoisy = roomNotifications.any { it.shouldBing } - || invitationNotifications.any { it.isNoisy } - || simpleNotifications.any { it.isNoisy } + val summaryIsNoisy = roomNotifications.any { it.shouldBing } || + invitationNotifications.any { it.isNoisy } || + simpleNotifications.any { it.isNoisy } val messageCount = roomNotifications.fold(initial = 0) { acc, current -> acc + current.messageCount } diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt index e3c97ad3cf..b0f1772fc7 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -20,7 +20,6 @@ import android.app.Notification import im.vector.app.test.fakes.FakeNotifiableEventProcessor import im.vector.app.test.fakes.FakeNotificationDisplayer import im.vector.app.test.fakes.FakeNotificationFactory -import im.vector.app.test.fakes.FakeVectorPreferences import io.mockk.mockk import org.junit.Test From 03fe45da609e61437ace8c71e109c5268733e2e4 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 8 Oct 2021 14:50:53 +0100 Subject: [PATCH 073/413] ensuring that we removing the summary group before removing individual notifications - adds some comments to explain the positioning --- .../notifications/NotificationRenderer.kt | 28 +++++++++++---- .../notifications/NotificationRendererTest.kt | 36 +++++++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index 844ea46f93..73ea65debc 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -68,9 +68,20 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces useCompleteNotificationFormat = useCompleteNotificationFormat ) + // Remove summary first to avoid briefly displaying it after dismissing the last notification + when (summaryNotification) { + SummaryNotification.Removed -> { + Timber.d("Removing summary notification") + notificationDisplayer.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID) + } + } + roomNotifications.forEach { wrapper -> when (wrapper) { - is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, ROOM_MESSAGES_NOTIFICATION_ID) + is RoomNotification.Removed -> { + Timber.d("Removing room messages notification ${wrapper.roomId}") + notificationDisplayer.cancelNotificationMessage(wrapper.roomId, ROOM_MESSAGES_NOTIFICATION_ID) + } is RoomNotification.Message -> if (useCompleteNotificationFormat) { Timber.d("Updating room messages notification ${wrapper.meta.roomId}") wrapper.shortcutInfo?.let { @@ -83,7 +94,10 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces invitationNotifications.forEach { wrapper -> when (wrapper) { - is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, ROOM_INVITATION_NOTIFICATION_ID) + is OneShotNotification.Removed -> { + Timber.d("Removing invitation notification ${wrapper.key}") + notificationDisplayer.cancelNotificationMessage(wrapper.key, ROOM_INVITATION_NOTIFICATION_ID) + } is OneShotNotification.Append -> if (useCompleteNotificationFormat) { Timber.d("Updating invitation notification ${wrapper.meta.key}") notificationDisplayer.showNotificationMessage(wrapper.meta.key, ROOM_INVITATION_NOTIFICATION_ID, wrapper.notification) @@ -93,7 +107,10 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces simpleNotifications.forEach { wrapper -> when (wrapper) { - is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, ROOM_EVENT_NOTIFICATION_ID) + is OneShotNotification.Removed -> { + Timber.d("Removing simple notification ${wrapper.key}") + notificationDisplayer.cancelNotificationMessage(wrapper.key, ROOM_EVENT_NOTIFICATION_ID) + } is OneShotNotification.Append -> if (useCompleteNotificationFormat) { Timber.d("Updating simple notification ${wrapper.meta.key}") notificationDisplayer.showNotificationMessage(wrapper.meta.key, ROOM_EVENT_NOTIFICATION_ID, wrapper.notification) @@ -101,11 +118,8 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces } } + // Update summary last to avoid briefly displaying it before other notifications when (summaryNotification) { - SummaryNotification.Removed -> { - Timber.d("Removing summary notification") - notificationDisplayer.cancelNotificationMessage(null, SUMMARY_NOTIFICATION_ID) - } is SummaryNotification.Update -> { Timber.d("Updating summary notification") notificationDisplayer.showNotificationMessage(null, SUMMARY_NOTIFICATION_ID, summaryNotification.notification) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt index b0f1772fc7..1c68dc4f68 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -63,6 +63,18 @@ class NotificationRendererTest { notificationDisplayer.verifyNoOtherInteractions() } + @Test + fun `given last room message group notification is removed when rendering then remove the summary and then remove message notification`() { + givenNotifications(roomNotifications = listOf(RoomNotification.Removed(A_ROOM_ID)), summaryNotification = A_REMOVE_SUMMARY_NOTIFICATION) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + cancelNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID) + cancelNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID) + } + } + @Test fun `given a room message group notification is removed when rendering then remove the message notification and update summary`() { givenNotifications(roomNotifications = listOf(RoomNotification.Removed(A_ROOM_ID))) @@ -90,6 +102,18 @@ class NotificationRendererTest { } } + @Test + fun `given last simple notification is removed when rendering then remove the summary and then remove simple notification`() { + givenNotifications(simpleNotifications = listOf(OneShotNotification.Removed(AN_EVENT_ID)), summaryNotification = A_REMOVE_SUMMARY_NOTIFICATION) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + cancelNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID) + cancelNotificationMessage(tag = AN_EVENT_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID) + } + } + @Test fun `given a simple notification is removed when rendering then remove the simple notification and update summary`() { givenNotifications(simpleNotifications = listOf(OneShotNotification.Removed(AN_EVENT_ID))) @@ -117,6 +141,18 @@ class NotificationRendererTest { } } + @Test + fun `given last invitation notification is removed when rendering then remove the summary and then remove invitation notification`() { + givenNotifications(invitationNotifications = listOf(OneShotNotification.Removed(A_ROOM_ID)), summaryNotification = A_REMOVE_SUMMARY_NOTIFICATION) + + renderEventsAsNotifications() + + notificationDisplayer.verifyInOrder { + cancelNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID) + cancelNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID) + } + } + @Test fun `given an invitation notification is removed when rendering then remove the invitation notification and update summary`() { givenNotifications(invitationNotifications = listOf(OneShotNotification.Removed(A_ROOM_ID))) From 587466e0096c2dc3193dabd39d748d2cdf80e2f3 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 11 Oct 2021 09:55:26 +0100 Subject: [PATCH 074/413] relying on the notification refreshing to cancel/update the notifications --- .../features/notifications/NotificationDrawerManager.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 4be1f6ee6e..042d2f1f88 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -165,14 +165,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context fun clearMessageEventOfRoom(roomId: String?) { Timber.v("clearMessageEventOfRoom $roomId") if (roomId != null) { - var shouldUpdate = false - synchronized(eventList) { - shouldUpdate = eventList.removeAll { e -> - e is NotifiableMessageEvent && e.roomId == roomId - } - } + val shouldUpdate = removeAll { it is NotifiableMessageEvent && it.roomId == roomId } if (shouldUpdate) { - notificationUtils.cancelNotificationMessage(roomId, ROOM_MESSAGES_NOTIFICATION_ID) refreshNotificationDrawer() } } From b7b4c01bde5a33e669f7b97356ab3c55719a2a43 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 11 Oct 2021 14:45:41 +0100 Subject: [PATCH 075/413] splitting the event processing from the rendering - this allows us to only synchronise of the event list modifications rather than the entire notification creation/rendering which should in turn reduce some of our ANRs https://github.com/vector-im/element-android/issues/4214 --- .../notifications/NotifiableEventProcessor.kt | 48 ++++------------- .../NotificationDrawerManager.kt | 36 ++++++++----- .../notifications/NotificationRenderer.kt | 54 ++++++++++--------- .../NotifiableEventProcessorTest.kt | 14 ++--- .../notifications/NotificationRendererTest.kt | 14 ++--- .../fakes/FakeNotifiableEventProcessor.kt | 6 --- .../app/test/fakes/FakeNotificationFactory.kt | 10 ++-- 7 files changed, 77 insertions(+), 105 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt index 3f77ce54ca..bf9e805fc8 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt @@ -17,7 +17,6 @@ package im.vector.app.features.notifications import im.vector.app.features.invite.AutoAcceptInvites -import timber.log.Timber import javax.inject.Inject class NotifiableEventProcessor @Inject constructor( @@ -25,49 +24,20 @@ class NotifiableEventProcessor @Inject constructor( private val autoAcceptInvites: AutoAcceptInvites ) { - fun modifyAndProcess(eventList: MutableList, currentRoomId: String?): ProcessedNotificationEvents { - val roomIdToEventMap: MutableMap> = LinkedHashMap() - val simpleEvents: MutableMap = LinkedHashMap() - val invitationEvents: MutableMap = LinkedHashMap() - - val eventIterator = eventList.listIterator() - while (eventIterator.hasNext()) { - when (val event = eventIterator.next()) { - is NotifiableMessageEvent -> { - val roomId = event.roomId - val roomEvents = roomIdToEventMap.getOrPut(roomId) { ArrayList() } - - // should we limit to last 7 messages per room? - if (shouldIgnoreMessageEventInRoom(currentRoomId, roomId) || outdatedDetector.isMessageOutdated(event)) { - // forget this event - eventIterator.remove() - } else { - roomEvents.add(event) + fun process(eventList: List, currentRoomId: String?): Map { + return eventList.associateBy { it.eventId } + .mapValues { (_, value) -> + when (value) { + is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) null else value + is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, value.roomId) || outdatedDetector.isMessageOutdated(value)) { + null + } else value + is SimpleNotifiableEvent -> value } } - is InviteNotifiableEvent -> { - if (autoAcceptInvites.hideInvites) { - // Forget this event - eventIterator.remove() - invitationEvents[event.roomId] = null - } else { - invitationEvents[event.roomId] = event - } - } - is SimpleNotifiableEvent -> simpleEvents[event.eventId] = event - else -> Timber.w("Type not handled") - } - } - return ProcessedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents) } private fun shouldIgnoreMessageEventInRoom(currentRoomId: String?, roomId: String?): Boolean { return currentRoomId != null && roomId == currentRoomId } } - -data class ProcessedNotificationEvents( - val roomEvents: Map>, - val simpleEvents: Map, - val invitationEvents: Map -) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 042d2f1f88..43d9eff185 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -44,6 +44,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context private val notificationUtils: NotificationUtils, private val vectorPreferences: VectorPreferences, private val activeSessionDataSource: ActiveSessionDataSource, + private val notifiableEventProcessor: NotifiableEventProcessor, private val notificationRenderer: NotificationRenderer) { private val handlerThread: HandlerThread = HandlerThread("NotificationDrawerManager", Thread.MIN_PRIORITY) @@ -55,6 +56,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } private val eventList = loadEventInfo() + private var renderedEventsList = emptyMap() private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size) private var currentRoomId: String? = null @@ -223,22 +225,32 @@ class NotificationDrawerManager @Inject constructor(private val context: Context @WorkerThread private fun refreshNotificationDrawerBg() { Timber.v("refreshNotificationDrawerBg()") - val session = currentSession ?: return - val user = session.getUser(session.myUserId) - // myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash - val myUserDisplayName = user?.toMatrixItem()?.getBestName() ?: session.myUserId - val myUserAvatarUrl = session.contentUrlResolver().resolveThumbnail(user?.avatarUrl, avatarSize, avatarSize, ContentUrlResolver.ThumbnailMethod.SCALE) + val newSettings = vectorPreferences.useCompleteNotificationFormat() + if (newSettings != useCompleteNotificationFormat) { + // Settings has changed, remove all current notifications + notificationUtils.cancelAllNotifications() + useCompleteNotificationFormat = newSettings + } - synchronized(eventList) { - val newSettings = vectorPreferences.useCompleteNotificationFormat() - if (newSettings != useCompleteNotificationFormat) { - // Settings has changed, remove all current notifications - notificationUtils.cancelAllNotifications() - useCompleteNotificationFormat = newSettings + val eventsToRender = synchronized(eventList) { + notifiableEventProcessor.process(eventList, currentRoomId).also { + eventList.clear() + eventList.addAll(it.values.filterNotNull()) } + } - notificationRenderer.render(currentRoomId, session.myUserId, myUserDisplayName, myUserAvatarUrl, useCompleteNotificationFormat, eventList) + if (renderedEventsList == eventsToRender) { + Timber.d("Skipping notification update due to event list not changing") + } else { + renderedEventsList = eventsToRender + val session = currentSession ?: return + val user = session.getUser(session.myUserId) + // myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash + val myUserDisplayName = user?.toMatrixItem()?.getBestName() ?: session.myUserId + val myUserAvatarUrl = session.contentUrlResolver().resolveThumbnail(user?.avatarUrl, avatarSize, avatarSize, ContentUrlResolver.ThumbnailMethod.SCALE) + + notificationRenderer.render(session.myUserId, myUserDisplayName, myUserAvatarUrl, useCompleteNotificationFormat, eventsToRender) } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index 73ea65debc..80391b1e06 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -15,7 +15,6 @@ */ package im.vector.app.features.notifications -import android.content.Context import androidx.annotation.WorkerThread import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_EVENT_NOTIFICATION_ID import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_INVITATION_NOTIFICATION_ID @@ -27,36 +26,16 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class NotificationRenderer @Inject constructor(private val notifiableEventProcessor: NotifiableEventProcessor, - private val notificationDisplayer: NotificationDisplayer, - private val notificationFactory: NotificationFactory, - private val appContext: Context) { - - private var lastKnownEventList = -1 +class NotificationRenderer @Inject constructor(private val notificationDisplayer: NotificationDisplayer, + private val notificationFactory: NotificationFactory) { @WorkerThread - fun render(currentRoomId: String?, - myUserId: String, + fun render(myUserId: String, myUserDisplayName: String, myUserAvatarUrl: String?, useCompleteNotificationFormat: Boolean, - eventList: MutableList) { - Timber.v("Render notification events - count: ${eventList.size}") - val notificationEvents = notifiableEventProcessor.modifyAndProcess(eventList, currentRoomId) - if (lastKnownEventList == notificationEvents.hashCode()) { - Timber.d("Skipping notification update due to event list not changing") - } else { - processEvents(notificationEvents, myUserId, myUserDisplayName, myUserAvatarUrl, useCompleteNotificationFormat) - lastKnownEventList = notificationEvents.hashCode() - } - } - - private fun processEvents(notificationEvents: ProcessedNotificationEvents, - myUserId: String, - myUserDisplayName: String, - myUserAvatarUrl: String?, - useCompleteNotificationFormat: Boolean) { - val (roomEvents, simpleEvents, invitationEvents) = notificationEvents + eventsToProcess: Map) { + val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType() with(notificationFactory) { val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) val invitationNotifications = invitationEvents.toNotifications(myUserId) @@ -128,3 +107,26 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces } } } + +private fun Map.groupByType(): GroupedNotificationEvents { + val roomIdToEventMap: MutableMap> = LinkedHashMap() + val simpleEvents: MutableMap = LinkedHashMap() + val invitationEvents: MutableMap = LinkedHashMap() + forEach { (_, value) -> + when (value) { + is InviteNotifiableEvent -> invitationEvents[value.roomId] + is NotifiableMessageEvent -> { + val roomEvents = roomIdToEventMap.getOrPut(value.roomId) { ArrayList() } + roomEvents.add(value) + } + is SimpleNotifiableEvent -> simpleEvents[value.eventId] = value + } + } + return GroupedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents) +} + +data class GroupedNotificationEvents( + val roomEvents: Map>, + val simpleEvents: Map, + val invitationEvents: Map +) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt index 6f47e71500..3e66f82bc3 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -37,7 +37,7 @@ class NotifiableEventProcessorTest { aSimpleNotifiableEvent(eventId = "event-2") ) - val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) result shouldBeEqualTo aProcessedNotificationEvents( simpleEvents = mapOf( @@ -56,7 +56,7 @@ class NotifiableEventProcessorTest { anInviteNotifiableEvent(roomId = "room-2") ) - val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) result shouldBeEqualTo aProcessedNotificationEvents( invitationEvents = mapOf( @@ -75,7 +75,7 @@ class NotifiableEventProcessorTest { anInviteNotifiableEvent(roomId = "room-2") ) - val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) result shouldBeEqualTo aProcessedNotificationEvents( invitationEvents = mapOf( @@ -91,7 +91,7 @@ class NotifiableEventProcessorTest { val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) outdatedDetector.givenEventIsOutOfDate(events[0]) - val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) result shouldBeEqualTo aProcessedNotificationEvents( roomEvents = mapOf( @@ -106,7 +106,7 @@ class NotifiableEventProcessorTest { val (events, originalEvents) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) outdatedDetector.givenEventIsInDate(events[0]) - val result = eventProcessor.modifyAndProcess(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) result shouldBeEqualTo aProcessedNotificationEvents( roomEvents = mapOf( @@ -120,7 +120,7 @@ class NotifiableEventProcessorTest { fun `given viewing the same room as message event when processing then removes message`() { val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) - val result = eventProcessor.modifyAndProcess(events, currentRoomId = "room-1") + val result = eventProcessor.process(events, currentRoomId = "room-1") result shouldBeEqualTo aProcessedNotificationEvents( roomEvents = mapOf( @@ -140,7 +140,7 @@ fun createEventsList(vararg event: NotifiableEvent): Pair = emptyMap(), invitationEvents: Map = emptyMap(), roomEvents: Map> = emptyMap() -) = ProcessedNotificationEvents( +) = GroupedNotificationEvents( roomEvents = roomEvents, simpleEvents = simpleEvents, invitationEvents = invitationEvents, diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt index 1c68dc4f68..bd0d1e8d3f 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -17,13 +17,11 @@ package im.vector.app.features.notifications import android.app.Notification -import im.vector.app.test.fakes.FakeNotifiableEventProcessor import im.vector.app.test.fakes.FakeNotificationDisplayer import im.vector.app.test.fakes.FakeNotificationFactory import io.mockk.mockk import org.junit.Test -private const val A_CURRENT_ROOM_ID = "current-room-id" private const val MY_USER_ID = "my-user-id" private const val MY_USER_DISPLAY_NAME = "display-name" private const val MY_USER_AVATAR_URL = "avatar-url" @@ -31,8 +29,8 @@ private const val AN_EVENT_ID = "event-id" private const val A_ROOM_ID = "room-id" private const val USE_COMPLETE_NOTIFICATION_FORMAT = true -private val AN_EVENT_LIST = mutableListOf() -private val A_PROCESSED_EVENTS = ProcessedNotificationEvents(emptyMap(), emptyMap(), emptyMap()) +private val AN_EVENT_LIST = mapOf() +private val A_PROCESSED_EVENTS = GroupedNotificationEvents(emptyMap(), emptyMap(), emptyMap()) private val A_SUMMARY_NOTIFICATION = SummaryNotification.Update(mockk()) private val A_REMOVE_SUMMARY_NOTIFICATION = SummaryNotification.Removed private val A_NOTIFICATION = mockk() @@ -43,12 +41,10 @@ private val ONE_SHOT_META = OneShotNotification.Append.Meta(key = "ignored", sum class NotificationRendererTest { - private val notifiableEventProcessor = FakeNotifiableEventProcessor() private val notificationDisplayer = FakeNotificationDisplayer() private val notificationFactory = FakeNotificationFactory() private val notificationRenderer = NotificationRenderer( - notifiableEventProcessor = notifiableEventProcessor.instance, notificationDisplayer = notificationDisplayer.instance, notificationFactory = notificationFactory.instance ) @@ -182,12 +178,11 @@ class NotificationRendererTest { private fun renderEventsAsNotifications() { notificationRenderer.render( - currentRoomId = A_CURRENT_ROOM_ID, myUserId = MY_USER_ID, myUserDisplayName = MY_USER_DISPLAY_NAME, myUserAvatarUrl = MY_USER_AVATAR_URL, useCompleteNotificationFormat = USE_COMPLETE_NOTIFICATION_FORMAT, - eventList = AN_EVENT_LIST + eventsToProcess = AN_EVENT_LIST ) } @@ -200,9 +195,8 @@ class NotificationRendererTest { simpleNotifications: List = emptyList(), useCompleteNotificationFormat: Boolean = USE_COMPLETE_NOTIFICATION_FORMAT, summaryNotification: SummaryNotification = A_SUMMARY_NOTIFICATION) { - notifiableEventProcessor.givenProcessedEventsFor(AN_EVENT_LIST, A_CURRENT_ROOM_ID, A_PROCESSED_EVENTS) notificationFactory.givenNotificationsFor( - processedEvents = A_PROCESSED_EVENTS, + groupedEvents = A_PROCESSED_EVENTS, myUserId = MY_USER_ID, myUserDisplayName = MY_USER_DISPLAY_NAME, myUserAvatarUrl = MY_USER_AVATAR_URL, diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt index 93f5e40524..6143c7a907 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt @@ -16,17 +16,11 @@ package im.vector.app.test.fakes -import im.vector.app.features.notifications.NotifiableEvent import im.vector.app.features.notifications.NotifiableEventProcessor -import im.vector.app.features.notifications.ProcessedNotificationEvents -import io.mockk.every import io.mockk.mockk class FakeNotifiableEventProcessor { val instance = mockk() - fun givenProcessedEventsFor(events: MutableList, currentRoomId: String?, processedEvents: ProcessedNotificationEvents) { - every { instance.modifyAndProcess(events, currentRoomId) } returns processedEvents - } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt index da2dbc27da..cc6f84f813 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt @@ -18,7 +18,7 @@ package im.vector.app.test.fakes import im.vector.app.features.notifications.NotificationFactory import im.vector.app.features.notifications.OneShotNotification -import im.vector.app.features.notifications.ProcessedNotificationEvents +import im.vector.app.features.notifications.GroupedNotificationEvents import im.vector.app.features.notifications.RoomNotification import im.vector.app.features.notifications.SummaryNotification import io.mockk.every @@ -28,7 +28,7 @@ class FakeNotificationFactory { val instance = mockk() - fun givenNotificationsFor(processedEvents: ProcessedNotificationEvents, + fun givenNotificationsFor(groupedEvents: GroupedNotificationEvents, myUserId: String, myUserDisplayName: String, myUserAvatarUrl: String?, @@ -38,9 +38,9 @@ class FakeNotificationFactory { simpleNotifications: List, summaryNotification: SummaryNotification) { with(instance) { - every { processedEvents.roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) } returns roomNotifications - every { processedEvents.invitationEvents.toNotifications(myUserId) } returns invitationNotifications - every { processedEvents.simpleEvents.toNotifications(myUserId) } returns simpleNotifications + every { groupedEvents.roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) } returns roomNotifications + every { groupedEvents.invitationEvents.toNotifications(myUserId) } returns invitationNotifications + every { groupedEvents.simpleEvents.toNotifications(myUserId) } returns simpleNotifications every { createSummaryNotification( From b27fb264fcff925419c18b9d8b9e36992e5bc77a Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 11 Oct 2021 15:32:12 +0100 Subject: [PATCH 076/413] using a process state of keep/removed rather than mapping to an ignored event id - this state will be used to diff the currently rendered events against the new ones --- .../notifications/NotifiableEventProcessor.kt | 30 ++++++++++++------- .../NotificationDrawerManager.kt | 6 ++-- .../notifications/NotificationFactory.kt | 24 +++++++-------- .../notifications/NotificationRenderer.kt | 27 +++++++++-------- .../NotifiableEventProcessorTest.kt | 12 ++++---- 5 files changed, 56 insertions(+), 43 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt index bf9e805fc8..782f70645b 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt @@ -17,6 +17,8 @@ package im.vector.app.features.notifications import im.vector.app.features.invite.AutoAcceptInvites +import im.vector.app.features.notifications.Processed.KEEP +import im.vector.app.features.notifications.Processed.REMOVE import javax.inject.Inject class NotifiableEventProcessor @Inject constructor( @@ -24,20 +26,26 @@ class NotifiableEventProcessor @Inject constructor( private val autoAcceptInvites: AutoAcceptInvites ) { - fun process(eventList: List, currentRoomId: String?): Map { - return eventList.associateBy { it.eventId } - .mapValues { (_, value) -> - when (value) { - is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) null else value - is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, value.roomId) || outdatedDetector.isMessageOutdated(value)) { - null - } else value - is SimpleNotifiableEvent -> value - } - } + fun process(eventList: List, currentRoomId: String?): List> { + return eventList.map { + when (it) { + is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) REMOVE else KEEP + is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, it.roomId) || outdatedDetector.isMessageOutdated(it)) { + REMOVE + } else KEEP + is SimpleNotifiableEvent -> KEEP + } to it + } } private fun shouldIgnoreMessageEventInRoom(currentRoomId: String?, roomId: String?): Boolean { return currentRoomId != null && roomId == currentRoomId } } + +enum class Processed { + KEEP, + REMOVE +} + +fun List>.onlyKeptEvents() = filter { it.first == KEEP }.map { it.second } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 43d9eff185..c73b4b2a9c 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -56,7 +56,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } private val eventList = loadEventInfo() - private var renderedEventsList = emptyMap() + private var renderedEventsList = emptyList>() private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size) private var currentRoomId: String? = null @@ -236,10 +236,12 @@ class NotificationDrawerManager @Inject constructor(private val context: Context val eventsToRender = synchronized(eventList) { notifiableEventProcessor.process(eventList, currentRoomId).also { eventList.clear() - eventList.addAll(it.values.filterNotNull()) + eventList.addAll(it.onlyKeptEvents()) } } + + if (renderedEventsList == eventsToRender) { Timber.d("Skipping notification update due to event list not changing") } else { diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index d5de0221f6..88f21a02a6 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -40,14 +40,14 @@ class NotificationFactory @Inject constructor( private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted - fun Map.toNotifications(myUserId: String): List { - return map { (roomId, event) -> - when (event) { - null -> OneShotNotification.Removed(key = roomId) - else -> OneShotNotification.Append( + fun List>.toNotifications(myUserId: String): List { + return map { (processed, event) -> + when (processed) { + Processed.REMOVE -> OneShotNotification.Removed(key = event.roomId) + Processed.KEEP -> OneShotNotification.Append( notificationUtils.buildRoomInvitationNotification(event, myUserId), OneShotNotification.Append.Meta( - key = roomId, + key = event.roomId, summaryLine = event.description, isNoisy = event.noisy, timestamp = event.timestamp @@ -58,14 +58,14 @@ class NotificationFactory @Inject constructor( } @JvmName("toNotificationsSimpleNotifiableEvent") - fun Map.toNotifications(myUserId: String): List { - return map { (eventId, event) -> - when (event) { - null -> OneShotNotification.Removed(key = eventId) - else -> OneShotNotification.Append( + fun List>.toNotifications(myUserId: String): List { + return map { (processed, event) -> + when (processed) { + Processed.REMOVE -> OneShotNotification.Removed(key = event.eventId) + Processed.KEEP -> OneShotNotification.Append( notificationUtils.buildSimpleEventNotification(event, myUserId), OneShotNotification.Append.Meta( - key = eventId, + key = event.eventId, summaryLine = event.description, isNoisy = event.noisy, timestamp = event.timestamp diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index 80391b1e06..31a99810e0 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -34,7 +34,7 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer myUserDisplayName: String, myUserAvatarUrl: String?, useCompleteNotificationFormat: Boolean, - eventsToProcess: Map) { + eventsToProcess: List>) { val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType() with(notificationFactory) { val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) @@ -108,25 +108,28 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer } } -private fun Map.groupByType(): GroupedNotificationEvents { +private fun List>.groupByType(): GroupedNotificationEvents { val roomIdToEventMap: MutableMap> = LinkedHashMap() - val simpleEvents: MutableMap = LinkedHashMap() - val invitationEvents: MutableMap = LinkedHashMap() - forEach { (_, value) -> - when (value) { - is InviteNotifiableEvent -> invitationEvents[value.roomId] + val simpleEvents: MutableList> = ArrayList() + val invitationEvents: MutableList> = ArrayList() + forEach { + when (val event = it.second) { + is InviteNotifiableEvent -> invitationEvents.add(it.asPair()) is NotifiableMessageEvent -> { - val roomEvents = roomIdToEventMap.getOrPut(value.roomId) { ArrayList() } - roomEvents.add(value) + val roomEvents = roomIdToEventMap.getOrPut(event.roomId) { ArrayList() } + roomEvents.add(event) } - is SimpleNotifiableEvent -> simpleEvents[value.eventId] = value + is SimpleNotifiableEvent -> simpleEvents.add(it.asPair()) } } return GroupedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents) } +@Suppress("UNCHECKED_CAST") +private fun Pair.asPair(): Pair = this as Pair + data class GroupedNotificationEvents( val roomEvents: Map>, - val simpleEvents: Map, - val invitationEvents: Map + val simpleEvents: List>, + val invitationEvents: List> ) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt index 3e66f82bc3..154763afae 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -37,7 +37,7 @@ class NotifiableEventProcessorTest { aSimpleNotifiableEvent(eventId = "event-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) result shouldBeEqualTo aProcessedNotificationEvents( simpleEvents = mapOf( @@ -56,7 +56,7 @@ class NotifiableEventProcessorTest { anInviteNotifiableEvent(roomId = "room-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) result shouldBeEqualTo aProcessedNotificationEvents( invitationEvents = mapOf( @@ -75,7 +75,7 @@ class NotifiableEventProcessorTest { anInviteNotifiableEvent(roomId = "room-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) result shouldBeEqualTo aProcessedNotificationEvents( invitationEvents = mapOf( @@ -91,7 +91,7 @@ class NotifiableEventProcessorTest { val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) outdatedDetector.givenEventIsOutOfDate(events[0]) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) result shouldBeEqualTo aProcessedNotificationEvents( roomEvents = mapOf( @@ -106,7 +106,7 @@ class NotifiableEventProcessorTest { val (events, originalEvents) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) outdatedDetector.givenEventIsInDate(events[0]) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) result shouldBeEqualTo aProcessedNotificationEvents( roomEvents = mapOf( @@ -120,7 +120,7 @@ class NotifiableEventProcessorTest { fun `given viewing the same room as message event when processing then removes message`() { val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) - val result = eventProcessor.process(events, currentRoomId = "room-1") + val result = eventProcessor.process(events, currentRoomId = "room-1", renderedEventsList = renderedEventsList) result shouldBeEqualTo aProcessedNotificationEvents( roomEvents = mapOf( From 0bdc65b47f65a395f1c602aed5b95a4e42bdf39b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 11 Oct 2021 16:39:52 +0100 Subject: [PATCH 077/413] diffing the notification events against the currently rendered events allow us to dismiss notifications from removed events --- .../notifications/NotifiableEventProcessor.kt | 21 ++-- .../NotificationDrawerManager.kt | 6 +- .../notifications/NotificationFactory.kt | 12 +- .../notifications/NotificationRenderer.kt | 14 +-- .../features/notifications/ProcessedEvent.kt} | 14 +-- .../NotifiableEventProcessorTest.kt | 111 ++++++++---------- .../notifications/NotificationFactoryTest.kt | 8 +- .../notifications/NotificationRendererTest.kt | 4 +- .../app/test/fakes/FakeNotificationFactory.kt | 3 +- 9 files changed, 86 insertions(+), 107 deletions(-) rename vector/src/{test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt => main/java/im/vector/app/features/notifications/ProcessedEvent.kt} (69%) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt index 782f70645b..88dc455e20 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt @@ -17,8 +17,8 @@ package im.vector.app.features.notifications import im.vector.app.features.invite.AutoAcceptInvites -import im.vector.app.features.notifications.Processed.KEEP -import im.vector.app.features.notifications.Processed.REMOVE +import im.vector.app.features.notifications.ProcessedType.KEEP +import im.vector.app.features.notifications.ProcessedType.REMOVE import javax.inject.Inject class NotifiableEventProcessor @Inject constructor( @@ -26,8 +26,8 @@ class NotifiableEventProcessor @Inject constructor( private val autoAcceptInvites: AutoAcceptInvites ) { - fun process(eventList: List, currentRoomId: String?): List> { - return eventList.map { + fun process(eventList: List, currentRoomId: String?, renderedEventsList: List>): List { + val processedEventList = eventList.map { when (it) { is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) REMOVE else KEEP is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, it.roomId) || outdatedDetector.isMessageOutdated(it)) { @@ -36,16 +36,15 @@ class NotifiableEventProcessor @Inject constructor( is SimpleNotifiableEvent -> KEEP } to it } + + val removedEventsDiff = renderedEventsList.filter { renderedEvent -> + eventList.none { it.eventId == renderedEvent.second.eventId } + }.map { REMOVE to it.second } + + return removedEventsDiff + processedEventList } private fun shouldIgnoreMessageEventInRoom(currentRoomId: String?, roomId: String?): Boolean { return currentRoomId != null && roomId == currentRoomId } } - -enum class Processed { - KEEP, - REMOVE -} - -fun List>.onlyKeptEvents() = filter { it.first == KEEP }.map { it.second } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index c73b4b2a9c..b7bb20237c 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -56,7 +56,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } private val eventList = loadEventInfo() - private var renderedEventsList = emptyList>() + private var renderedEventsList = emptyList>() private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size) private var currentRoomId: String? = null @@ -234,14 +234,12 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } val eventsToRender = synchronized(eventList) { - notifiableEventProcessor.process(eventList, currentRoomId).also { + notifiableEventProcessor.process(eventList, currentRoomId, renderedEventsList).also { eventList.clear() eventList.addAll(it.onlyKeptEvents()) } } - - if (renderedEventsList == eventsToRender) { Timber.d("Skipping notification update due to event list not changing") } else { diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 88f21a02a6..fe1671b58b 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -40,11 +40,11 @@ class NotificationFactory @Inject constructor( private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted - fun List>.toNotifications(myUserId: String): List { + fun List>.toNotifications(myUserId: String): List { return map { (processed, event) -> when (processed) { - Processed.REMOVE -> OneShotNotification.Removed(key = event.roomId) - Processed.KEEP -> OneShotNotification.Append( + ProcessedType.REMOVE -> OneShotNotification.Removed(key = event.roomId) + ProcessedType.KEEP -> OneShotNotification.Append( notificationUtils.buildRoomInvitationNotification(event, myUserId), OneShotNotification.Append.Meta( key = event.roomId, @@ -58,11 +58,11 @@ class NotificationFactory @Inject constructor( } @JvmName("toNotificationsSimpleNotifiableEvent") - fun List>.toNotifications(myUserId: String): List { + fun List>.toNotifications(myUserId: String): List { return map { (processed, event) -> when (processed) { - Processed.REMOVE -> OneShotNotification.Removed(key = event.eventId) - Processed.KEEP -> OneShotNotification.Append( + ProcessedType.REMOVE -> OneShotNotification.Removed(key = event.eventId) + ProcessedType.KEEP -> OneShotNotification.Append( notificationUtils.buildSimpleEventNotification(event, myUserId), OneShotNotification.Append.Meta( key = event.eventId, diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index 31a99810e0..7cf0a8872a 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -34,7 +34,7 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer myUserDisplayName: String, myUserAvatarUrl: String?, useCompleteNotificationFormat: Boolean, - eventsToProcess: List>) { + eventsToProcess: List>) { val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType() with(notificationFactory) { val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) @@ -108,10 +108,10 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer } } -private fun List>.groupByType(): GroupedNotificationEvents { +private fun List>.groupByType(): GroupedNotificationEvents { val roomIdToEventMap: MutableMap> = LinkedHashMap() - val simpleEvents: MutableList> = ArrayList() - val invitationEvents: MutableList> = ArrayList() + val simpleEvents: MutableList> = ArrayList() + val invitationEvents: MutableList> = ArrayList() forEach { when (val event = it.second) { is InviteNotifiableEvent -> invitationEvents.add(it.asPair()) @@ -126,10 +126,10 @@ private fun List>.groupByType(): GroupedNotific } @Suppress("UNCHECKED_CAST") -private fun Pair.asPair(): Pair = this as Pair +private fun Pair.asPair(): Pair = this as Pair data class GroupedNotificationEvents( val roomEvents: Map>, - val simpleEvents: List>, - val invitationEvents: List> + val simpleEvents: List>, + val invitationEvents: List> ) diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt similarity index 69% rename from vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt rename to vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt index 6143c7a907..0901757d02 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeNotifiableEventProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package im.vector.app.test.fakes +package im.vector.app.features.notifications -import im.vector.app.features.notifications.NotifiableEventProcessor -import io.mockk.mockk - -class FakeNotifiableEventProcessor { - - val instance = mockk() +typealias ProcessedEvent = Pair +enum class ProcessedType { + KEEP, + REMOVE } + +fun List.onlyKeptEvents() = filter { it.first == ProcessedType.KEEP }.map { it.second } diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt index 154763afae..1c0f5f9390 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -31,121 +31,104 @@ class NotifiableEventProcessorTest { private val eventProcessor = NotifiableEventProcessor(outdatedDetector.instance, autoAcceptInvites) @Test - fun `given simple events when processing then return without mutating`() { - val (events, originalEvents) = createEventsList( + fun `given simple events when processing then keep simple events`() { + val events = listOf( aSimpleNotifiableEvent(eventId = "event-1"), aSimpleNotifiableEvent(eventId = "event-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo aProcessedNotificationEvents( - simpleEvents = mapOf( - "event-1" to events[0] as SimpleNotifiableEvent, - "event-2" to events[1] as SimpleNotifiableEvent - ) + result shouldBeEqualTo listOf( + ProcessedType.KEEP to events[0], + ProcessedType.KEEP to events[1] ) - events shouldBeEqualTo originalEvents } @Test fun `given invites are auto accepted when processing then remove invitations`() { autoAcceptInvites._isEnabled = true - val events = mutableListOf( + val events = listOf( anInviteNotifiableEvent(roomId = "room-1"), anInviteNotifiableEvent(roomId = "room-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo aProcessedNotificationEvents( - invitationEvents = mapOf( - "room-1" to null, - "room-2" to null - ) + result shouldBeEqualTo listOf( + ProcessedType.REMOVE to events[0], + ProcessedType.REMOVE to events[1] ) - events shouldBeEqualTo emptyList() } @Test - fun `given invites are not auto accepted when processing then return without mutating`() { + fun `given invites are not auto accepted when processing then keep invitation events`() { autoAcceptInvites._isEnabled = false - val (events, originalEvents) = createEventsList( + val events = listOf( anInviteNotifiableEvent(roomId = "room-1"), anInviteNotifiableEvent(roomId = "room-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo aProcessedNotificationEvents( - invitationEvents = mapOf( - "room-1" to originalEvents[0] as InviteNotifiableEvent, - "room-2" to originalEvents[1] as InviteNotifiableEvent - ) + result shouldBeEqualTo listOf( + ProcessedType.KEEP to events[0], + ProcessedType.KEEP to events[1] ) - events shouldBeEqualTo originalEvents } @Test - fun `given out of date message event when processing then removes message`() { - val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) + fun `given out of date message event when processing then removes message event`() { + val events = listOf(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) outdatedDetector.givenEventIsOutOfDate(events[0]) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo aProcessedNotificationEvents( - roomEvents = mapOf( - "room-1" to emptyList() - ) + result shouldBeEqualTo listOf( + ProcessedType.REMOVE to events[0], ) - events shouldBeEqualTo emptyList() } @Test - fun `given in date message event when processing then without mutating`() { - val (events, originalEvents) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) + fun `given in date message event when processing then keep message event`() { + val events = listOf(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) outdatedDetector.givenEventIsInDate(events[0]) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo aProcessedNotificationEvents( - roomEvents = mapOf( - "room-1" to listOf(events[0] as NotifiableMessageEvent) - ) + result shouldBeEqualTo listOf( + ProcessedType.KEEP to events[0], ) - events shouldBeEqualTo originalEvents } @Test fun `given viewing the same room as message event when processing then removes message`() { - val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) + val events = listOf(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) - val result = eventProcessor.process(events, currentRoomId = "room-1", renderedEventsList = renderedEventsList) + val result = eventProcessor.process(events, currentRoomId = "room-1", renderedEventsList = emptyList()) - result shouldBeEqualTo aProcessedNotificationEvents( - roomEvents = mapOf( - "room-1" to emptyList() - ) + result shouldBeEqualTo listOf( + ProcessedType.REMOVE to events[0], + ) + } + + @Test + fun `given events are different to rendered events when processing then removes difference`() { + val events = listOf(aSimpleNotifiableEvent(eventId = "event-1")) + val renderedEvents = listOf( + ProcessedType.KEEP to events[0], + ProcessedType.KEEP to anInviteNotifiableEvent(roomId = "event-2") + ) + + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEvents) + + result shouldBeEqualTo listOf( + ProcessedType.REMOVE to renderedEvents[1].second, + ProcessedType.KEEP to renderedEvents[0].second ) - events shouldBeEqualTo emptyList() } } -fun createEventsList(vararg event: NotifiableEvent): Pair, List> { - val mutableEvents = mutableListOf(*event) - val immutableEvents = mutableEvents.toList() - return mutableEvents to immutableEvents -} - -fun aProcessedNotificationEvents(simpleEvents: Map = emptyMap(), - invitationEvents: Map = emptyMap(), - roomEvents: Map> = emptyMap() -) = GroupedNotificationEvents( - roomEvents = roomEvents, - simpleEvents = simpleEvents, - invitationEvents = invitationEvents, -) - fun aSimpleNotifiableEvent(eventId: String) = SimpleNotifiableEvent( matrixID = null, eventId = eventId, diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt index fc20f09811..98684f278d 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt @@ -46,7 +46,7 @@ class NotificationFactoryTest { @Test fun `given a room invitation when mapping to notification then is Append`() = testWith(notificationFactory) { val expectedNotification = notificationUtils.givenBuildRoomInvitationNotificationFor(AN_INVITATION_EVENT, MY_USER_ID) - val roomInvitation = mapOf(A_ROOM_ID to AN_INVITATION_EVENT) + val roomInvitation = listOf(ProcessedType.KEEP to AN_INVITATION_EVENT) val result = roomInvitation.toNotifications(MY_USER_ID) @@ -63,7 +63,7 @@ class NotificationFactoryTest { @Test fun `given a missing event in room invitation when mapping to notification then is Removed`() = testWith(notificationFactory) { - val missingEventRoomInvitation: Map = mapOf(A_ROOM_ID to null) + val missingEventRoomInvitation = listOf(ProcessedType.REMOVE to AN_INVITATION_EVENT) val result = missingEventRoomInvitation.toNotifications(MY_USER_ID) @@ -75,7 +75,7 @@ class NotificationFactoryTest { @Test fun `given a simple event when mapping to notification then is Append`() = testWith(notificationFactory) { val expectedNotification = notificationUtils.givenBuildSimpleInvitationNotificationFor(A_SIMPLE_EVENT, MY_USER_ID) - val roomInvitation = mapOf(AN_EVENT_ID to A_SIMPLE_EVENT) + val roomInvitation = listOf(ProcessedType.KEEP to A_SIMPLE_EVENT) val result = roomInvitation.toNotifications(MY_USER_ID) @@ -92,7 +92,7 @@ class NotificationFactoryTest { @Test fun `given a missing simple event when mapping to notification then is Removed`() = testWith(notificationFactory) { - val missingEventRoomInvitation: Map = mapOf(AN_EVENT_ID to null) + val missingEventRoomInvitation = listOf(ProcessedType.REMOVE to A_SIMPLE_EVENT) val result = missingEventRoomInvitation.toNotifications(MY_USER_ID) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt index bd0d1e8d3f..4f65c3861a 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -29,8 +29,8 @@ private const val AN_EVENT_ID = "event-id" private const val A_ROOM_ID = "room-id" private const val USE_COMPLETE_NOTIFICATION_FORMAT = true -private val AN_EVENT_LIST = mapOf() -private val A_PROCESSED_EVENTS = GroupedNotificationEvents(emptyMap(), emptyMap(), emptyMap()) +private val AN_EVENT_LIST = listOf>() +private val A_PROCESSED_EVENTS = GroupedNotificationEvents(emptyMap(), emptyList(), emptyList()) private val A_SUMMARY_NOTIFICATION = SummaryNotification.Update(mockk()) private val A_REMOVE_SUMMARY_NOTIFICATION = SummaryNotification.Removed private val A_NOTIFICATION = mockk() diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt index cc6f84f813..a6e7d1a078 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeNotificationFactory.kt @@ -16,9 +16,9 @@ package im.vector.app.test.fakes +import im.vector.app.features.notifications.GroupedNotificationEvents import im.vector.app.features.notifications.NotificationFactory import im.vector.app.features.notifications.OneShotNotification -import im.vector.app.features.notifications.GroupedNotificationEvents import im.vector.app.features.notifications.RoomNotification import im.vector.app.features.notifications.SummaryNotification import io.mockk.every @@ -50,7 +50,6 @@ class FakeNotificationFactory { useCompleteNotificationFormat ) } returns summaryNotification - } } } From c67b9ee81e3f34eaad3bd6d2357d463816c95e2e Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 11 Oct 2021 17:04:07 +0100 Subject: [PATCH 078/413] ensuring that we remove read messages when they come through by respecting the processed type when creating the notifications --- .../app/features/notifications/NotificationFactory.kt | 11 ++++++++--- .../features/notifications/NotificationRenderer.kt | 10 +++++----- .../features/notifications/NotificationFactoryTest.kt | 7 ++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index fe1671b58b..6be18371b1 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -27,16 +27,21 @@ class NotificationFactory @Inject constructor( private val summaryGroupMessageCreator: SummaryGroupMessageCreator ) { - fun Map>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { + fun Map>>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { return map { (roomId, events) -> when { events.hasNoEventsToDisplay() -> RoomNotification.Removed(roomId) - else -> roomGroupMessageCreator.createRoomMessage(events, roomId, myUserDisplayName, myUserAvatarUrl) + else -> { + val messageEvents = events.filter { it.first == ProcessedType.KEEP }.map { it.second } + roomGroupMessageCreator.createRoomMessage(messageEvents, roomId, myUserDisplayName, myUserAvatarUrl) + } } } } - private fun List.hasNoEventsToDisplay() = isEmpty() || all { it.canNotBeDisplayed() } + private fun List>.hasNoEventsToDisplay() = isEmpty() || all { + it.first == ProcessedType.REMOVE || it.second.canNotBeDisplayed() + } private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index 7cf0a8872a..ceeffd0bfa 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -34,7 +34,7 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer myUserDisplayName: String, myUserAvatarUrl: String?, useCompleteNotificationFormat: Boolean, - eventsToProcess: List>) { + eventsToProcess: List) { val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType() with(notificationFactory) { val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) @@ -108,8 +108,8 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer } } -private fun List>.groupByType(): GroupedNotificationEvents { - val roomIdToEventMap: MutableMap> = LinkedHashMap() +private fun List.groupByType(): GroupedNotificationEvents { + val roomIdToEventMap: MutableMap>> = LinkedHashMap() val simpleEvents: MutableList> = ArrayList() val invitationEvents: MutableList> = ArrayList() forEach { @@ -117,7 +117,7 @@ private fun List>.groupByType(): GroupedNot is InviteNotifiableEvent -> invitationEvents.add(it.asPair()) is NotifiableMessageEvent -> { val roomEvents = roomIdToEventMap.getOrPut(event.roomId) { ArrayList() } - roomEvents.add(event) + roomEvents.add(it.asPair()) } is SimpleNotifiableEvent -> simpleEvents.add(it.asPair()) } @@ -129,7 +129,7 @@ private fun List>.groupByType(): GroupedNot private fun Pair.asPair(): Pair = this as Pair data class GroupedNotificationEvents( - val roomEvents: Map>, + val roomEvents: Map>>, val simpleEvents: List>, val invitationEvents: List> ) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt index 98684f278d..84f59dcc21 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt @@ -105,7 +105,7 @@ class NotificationFactoryTest { fun `given room with message when mapping to notification then delegates to room group message creator`() = testWith(notificationFactory) { val events = listOf(A_MESSAGE_EVENT) val expectedNotification = roomGroupMessageCreator.givenCreatesRoomMessageFor(events, A_ROOM_ID, MY_USER_ID, MY_AVATAR_URL) - val roomWithMessage = mapOf(A_ROOM_ID to events) + val roomWithMessage = mapOf(A_ROOM_ID to listOf(ProcessedType.KEEP to A_MESSAGE_EVENT)) val result = roomWithMessage.toNotifications(MY_USER_ID, MY_AVATAR_URL) @@ -114,7 +114,8 @@ class NotificationFactoryTest { @Test fun `given a room with no events to display when mapping to notification then is Empty`() = testWith(notificationFactory) { - val emptyRoom: Map> = mapOf(A_ROOM_ID to emptyList()) + val events = listOf(ProcessedType.REMOVE to A_MESSAGE_EVENT) + val emptyRoom = mapOf(A_ROOM_ID to events) val result = emptyRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) @@ -125,7 +126,7 @@ class NotificationFactoryTest { @Test fun `given a room with only redacted events when mapping to notification then is Empty`() = testWith(notificationFactory) { - val redactedRoom = mapOf(A_ROOM_ID to listOf(A_MESSAGE_EVENT.copy(isRedacted = true))) + val redactedRoom = mapOf(A_ROOM_ID to listOf(ProcessedType.KEEP to A_MESSAGE_EVENT.copy(isRedacted = true))) val result = redactedRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) From 4bbb637ace4ab2ae0c77bb5d81c1d636def32a65 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 13 Oct 2021 11:21:26 +0100 Subject: [PATCH 079/413] adding documentation around the two notifiable event lists which act as our notification source of truth --- .../notifications/NotificationDrawerManager.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index b7bb20237c..0fb9739331 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -55,7 +55,21 @@ class NotificationDrawerManager @Inject constructor(private val context: Context backgroundHandler = Handler(handlerThread.looper) } + /** + * The notifiable events to render + * this is our source of truth for notifications, any changes to this list will be rendered as notifications + * when events are removed the previously rendered notifications will be cancelled + * when adding or updating, the notifications will be notified + * + * Events are unique by their properties, we should be careful not to insert multiple events with the same event-id + */ private val eventList = loadEventInfo() + + /** + * The last known rendered notifiable events + * we keep track of them in order to know which events have been removed from the eventList + * allowing us to cancel any notifications previous displayed by now removed events + */ private var renderedEventsList = emptyList>() private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size) private var currentRoomId: String? = null From 9fa09def96b4a34033e1e0bc4ab2645cdbe74ef6 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 13 Oct 2021 11:26:53 +0100 Subject: [PATCH 080/413] fixing line lengths --- .../features/notifications/NotifiableEventProcessor.kt | 2 +- .../features/notifications/NotificationDrawerManager.kt | 8 ++++++-- .../app/features/notifications/NotificationFactory.kt | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt index 88dc455e20..1acfcfc7ec 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt @@ -26,7 +26,7 @@ class NotifiableEventProcessor @Inject constructor( private val autoAcceptInvites: AutoAcceptInvites ) { - fun process(eventList: List, currentRoomId: String?, renderedEventsList: List>): List { + fun process(eventList: List, currentRoomId: String?, renderedEventsList: List): List { val processedEventList = eventList.map { when (it) { is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) REMOVE else KEEP diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 0fb9739331..3db1ab1f84 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -262,8 +262,12 @@ class NotificationDrawerManager @Inject constructor(private val context: Context val user = session.getUser(session.myUserId) // myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash val myUserDisplayName = user?.toMatrixItem()?.getBestName() ?: session.myUserId - val myUserAvatarUrl = session.contentUrlResolver().resolveThumbnail(user?.avatarUrl, avatarSize, avatarSize, ContentUrlResolver.ThumbnailMethod.SCALE) - + val myUserAvatarUrl = session.contentUrlResolver().resolveThumbnail( + contentUrl = user?.avatarUrl, + width = avatarSize, + height = avatarSize, + method = ContentUrlResolver.ThumbnailMethod.SCALE + ) notificationRenderer.render(session.myUserId, myUserDisplayName, myUserAvatarUrl, useCompleteNotificationFormat, eventsToRender) } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 6be18371b1..019b37d61a 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -21,13 +21,15 @@ import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutManagerCompat import javax.inject.Inject +private typealias ProcessedMessageEvent = Pair + class NotificationFactory @Inject constructor( private val notificationUtils: NotificationUtils, private val roomGroupMessageCreator: RoomGroupMessageCreator, private val summaryGroupMessageCreator: SummaryGroupMessageCreator ) { - fun Map>>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { + fun Map>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { return map { (roomId, events) -> when { events.hasNoEventsToDisplay() -> RoomNotification.Removed(roomId) From 86ce6a404ec26f09781c4e668434a48b74ffd9bf Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 13 Oct 2021 11:30:29 +0100 Subject: [PATCH 081/413] adding missing fixture parameter from rebase --- .../app/features/notifications/NotifiableEventProcessorTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt index 1c0f5f9390..c85d01a603 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -147,6 +147,7 @@ fun anInviteNotifiableEvent(roomId: String) = InviteNotifiableEvent( matrixID = null, eventId = "event-id", roomId = roomId, + roomName = "a room name", editedEventId = null, noisy = false, title = "title", From 4748a385ea7f3081b3edf28e56f7b62e7d98e636 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 13 Oct 2021 11:32:48 +0100 Subject: [PATCH 082/413] inlining single use extension functions --- .../app/features/notifications/NotificationFactory.kt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 019b37d61a..afea56c5b9 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -86,9 +86,9 @@ class NotificationFactory @Inject constructor( invitationNotifications: List, simpleNotifications: List, useCompleteNotificationFormat: Boolean): SummaryNotification { - val roomMeta = roomNotifications.mapToMeta() - val invitationMeta = invitationNotifications.mapToMeta() - val simpleMeta = simpleNotifications.mapToMeta() + val roomMeta = roomNotifications.filterIsInstance().map { it.meta } + val invitationMeta = invitationNotifications.filterIsInstance().map { it.meta } + val simpleMeta = simpleNotifications.filterIsInstance().map { it.meta } return when { roomMeta.isEmpty() && invitationMeta.isEmpty() && simpleMeta.isEmpty() -> SummaryNotification.Removed else -> SummaryNotification.Update( @@ -102,11 +102,6 @@ class NotificationFactory @Inject constructor( } } -private fun List.mapToMeta() = filterIsInstance().map { it.meta } - -@JvmName("mapToMetaOneShotNotification") -private fun List.mapToMeta() = filterIsInstance().map { it.meta } - sealed interface RoomNotification { data class Removed(val roomId: String) : RoomNotification data class Message(val notification: Notification, val shortcutInfo: ShortcutInfoCompat?, val meta: Meta) : RoomNotification { From c16e3e09e611b3e350c65b51b1054f48f9cc6f48 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 14 Oct 2021 16:56:15 +0100 Subject: [PATCH 083/413] adding missing parameter from rebase and removing no longer needed singleton annotation --- .../app/features/notifications/NotificationRenderer.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index ceeffd0bfa..ea54fdaf92 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -15,6 +15,7 @@ */ package im.vector.app.features.notifications +import android.content.Context import androidx.annotation.WorkerThread import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_EVENT_NOTIFICATION_ID import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_INVITATION_NOTIFICATION_ID @@ -23,11 +24,10 @@ import im.vector.app.features.notifications.NotificationDrawerManager.Companion. import androidx.core.content.pm.ShortcutManagerCompat import timber.log.Timber import javax.inject.Inject -import javax.inject.Singleton -@Singleton class NotificationRenderer @Inject constructor(private val notificationDisplayer: NotificationDisplayer, - private val notificationFactory: NotificationFactory) { + private val notificationFactory: NotificationFactory, + private val appContext: Context) { @WorkerThread fun render(myUserId: String, From a6e47d8b85d64f91a9ac0fb60323c1e79a48553f Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 14 Oct 2021 16:58:31 +0100 Subject: [PATCH 084/413] replacing notification utils usage with the displayer and removing unused method --- .../features/notifications/NotificationDrawerManager.kt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 3db1ab1f84..f324318988 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -41,7 +41,7 @@ import javax.inject.Singleton */ @Singleton class NotificationDrawerManager @Inject constructor(private val context: Context, - private val notificationUtils: NotificationUtils, + private val notificationDisplayer: NotificationDisplayer, private val vectorPreferences: VectorPreferences, private val activeSessionDataSource: ActiveSessionDataSource, private val notifiableEventProcessor: NotifiableEventProcessor, @@ -243,7 +243,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context val newSettings = vectorPreferences.useCompleteNotificationFormat() if (newSettings != useCompleteNotificationFormat) { // Settings has changed, remove all current notifications - notificationUtils.cancelAllNotifications() + notificationDisplayer.cancelAllNotifications() useCompleteNotificationFormat = newSettings } @@ -318,10 +318,6 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } } - fun displayDiagnosticNotification() { - notificationUtils.displayDiagnosticNotification() - } - companion object { const val SUMMARY_NOTIFICATION_ID = 0 const val ROOM_MESSAGES_NOTIFICATION_ID = 1 From 6fb7faa3604eb05b8a17abd812ce3026af933f6a Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 14 Oct 2021 16:59:32 +0100 Subject: [PATCH 085/413] removing unused imports --- .../im/vector/app/features/notifications/NotificationFactory.kt | 1 - .../vector/app/features/notifications/NotificationRenderer.kt | 2 +- .../app/features/notifications/RoomGroupMessageCreator.kt | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index afea56c5b9..288268a00c 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -18,7 +18,6 @@ package im.vector.app.features.notifications import android.app.Notification import androidx.core.content.pm.ShortcutInfoCompat -import androidx.core.content.pm.ShortcutManagerCompat import javax.inject.Inject private typealias ProcessedMessageEvent = Pair diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index ea54fdaf92..e72b9c7110 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -17,11 +17,11 @@ package im.vector.app.features.notifications import android.content.Context import androidx.annotation.WorkerThread +import androidx.core.content.pm.ShortcutManagerCompat import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_EVENT_NOTIFICATION_ID import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_INVITATION_NOTIFICATION_ID import im.vector.app.features.notifications.NotificationDrawerManager.Companion.ROOM_MESSAGES_NOTIFICATION_ID import im.vector.app.features.notifications.NotificationDrawerManager.Companion.SUMMARY_NOTIFICATION_ID -import androidx.core.content.pm.ShortcutManagerCompat import timber.log.Timber import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt index 113dc21ebd..35a1c12d0c 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -22,7 +22,6 @@ import android.os.Build import androidx.core.app.NotificationCompat import androidx.core.app.Person import androidx.core.content.pm.ShortcutInfoCompat -import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.drawable.IconCompat import im.vector.app.R import im.vector.app.core.resources.StringProvider From 63090ef681e93aa2cff6de5b3604f662b0de931c Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 14 Oct 2021 17:19:14 +0100 Subject: [PATCH 086/413] updating tests with shortcut placement changes --- .../app/features/notifications/NotificationRendererTest.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt index 4f65c3861a..c086a3ee4d 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -17,6 +17,7 @@ package im.vector.app.features.notifications import android.app.Notification +import im.vector.app.test.fakes.FakeContext import im.vector.app.test.fakes.FakeNotificationDisplayer import im.vector.app.test.fakes.FakeNotificationFactory import io.mockk.mockk @@ -41,12 +42,14 @@ private val ONE_SHOT_META = OneShotNotification.Append.Meta(key = "ignored", sum class NotificationRendererTest { + private val context = FakeContext() private val notificationDisplayer = FakeNotificationDisplayer() private val notificationFactory = FakeNotificationFactory() private val notificationRenderer = NotificationRenderer( notificationDisplayer = notificationDisplayer.instance, - notificationFactory = notificationFactory.instance + notificationFactory = notificationFactory.instance, + appContext = context.instance ) @Test @@ -87,6 +90,7 @@ class NotificationRendererTest { fun `given a room message group notification is added when rendering then show the message notification and update summary`() { givenNotifications(roomNotifications = listOf(RoomNotification.Message( A_NOTIFICATION, + shortcutInfo = null, MESSAGE_META ))) From d3234b33d37c1b5208a9b3eb653ce70ce215d286 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 14 Oct 2021 17:42:47 +0100 Subject: [PATCH 087/413] increase enum class allowance by 1 --- tools/check/forbidden_strings_in_code.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt index 8f8625fe1c..29077c3a76 100644 --- a/tools/check/forbidden_strings_in_code.txt +++ b/tools/check/forbidden_strings_in_code.txt @@ -160,7 +160,7 @@ Formatter\.formatShortFileSize===1 # android\.text\.TextUtils ### This is not a rule, but a warning: the number of "enum class" has changed. For Json classes, it is mandatory that they have `@JsonClass(generateAdapter = false)`. If the enum is not used as a Json class, change the value in file forbidden_strings_in_code.txt -enum class===106 +enum class===107 ### Do not import temporary legacy classes import org.matrix.android.sdk.internal.legacy.riot===3 From d1f6db4236aab4e24e6ba978e1bdc842c21499ab Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 19 Oct 2021 11:38:34 +0100 Subject: [PATCH 088/413] using dedicated ProcessedEvent data class instead of type alias for passing around the process notificatiable events - also includes @JvmName on all conflicting extensions for consistency --- .../notifications/NotifiableEventProcessor.kt | 17 ++++--- .../NotificationDrawerManager.kt | 2 +- .../notifications/NotificationFactory.kt | 23 ++++----- .../notifications/NotificationRenderer.kt | 26 +++++----- .../features/notifications/ProcessedEvent.kt | 14 ++++-- .../NotifiableEventProcessorTest.kt | 47 ++++++++++--------- .../notifications/NotificationFactoryTest.kt | 15 +++--- .../notifications/NotificationRendererTest.kt | 2 +- 8 files changed, 80 insertions(+), 66 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt index 1acfcfc7ec..338c3d58eb 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt @@ -17,29 +17,32 @@ package im.vector.app.features.notifications import im.vector.app.features.invite.AutoAcceptInvites -import im.vector.app.features.notifications.ProcessedType.KEEP -import im.vector.app.features.notifications.ProcessedType.REMOVE +import im.vector.app.features.notifications.ProcessedEvent.Type.KEEP +import im.vector.app.features.notifications.ProcessedEvent.Type.REMOVE import javax.inject.Inject +private typealias ProcessedEvents = List> + class NotifiableEventProcessor @Inject constructor( private val outdatedDetector: OutdatedEventDetector, private val autoAcceptInvites: AutoAcceptInvites ) { - fun process(eventList: List, currentRoomId: String?, renderedEventsList: List): List { + fun process(eventList: List, currentRoomId: String?, renderedEventsList: ProcessedEvents): ProcessedEvents { val processedEventList = eventList.map { - when (it) { + val type = when (it) { is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) REMOVE else KEEP is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, it.roomId) || outdatedDetector.isMessageOutdated(it)) { REMOVE } else KEEP is SimpleNotifiableEvent -> KEEP - } to it + } + ProcessedEvent(type, it) } val removedEventsDiff = renderedEventsList.filter { renderedEvent -> - eventList.none { it.eventId == renderedEvent.second.eventId } - }.map { REMOVE to it.second } + eventList.none { it.eventId == renderedEvent.event.eventId } + }.map { ProcessedEvent(REMOVE, it.event) } return removedEventsDiff + processedEventList } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index f324318988..5d2212ba1e 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -70,7 +70,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context * we keep track of them in order to know which events have been removed from the eventList * allowing us to cancel any notifications previous displayed by now removed events */ - private var renderedEventsList = emptyList>() + private var renderedEventsList = emptyList>() private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size) private var currentRoomId: String? = null diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 288268a00c..5dff009cec 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -20,7 +20,7 @@ import android.app.Notification import androidx.core.content.pm.ShortcutInfoCompat import javax.inject.Inject -private typealias ProcessedMessageEvent = Pair +private typealias ProcessedMessageEvents = List> class NotificationFactory @Inject constructor( private val notificationUtils: NotificationUtils, @@ -28,29 +28,30 @@ class NotificationFactory @Inject constructor( private val summaryGroupMessageCreator: SummaryGroupMessageCreator ) { - fun Map>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { + fun Map.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List { return map { (roomId, events) -> when { events.hasNoEventsToDisplay() -> RoomNotification.Removed(roomId) else -> { - val messageEvents = events.filter { it.first == ProcessedType.KEEP }.map { it.second } + val messageEvents = events.onlyKeptEvents() roomGroupMessageCreator.createRoomMessage(messageEvents, roomId, myUserDisplayName, myUserAvatarUrl) } } } } - private fun List>.hasNoEventsToDisplay() = isEmpty() || all { - it.first == ProcessedType.REMOVE || it.second.canNotBeDisplayed() + private fun ProcessedMessageEvents.hasNoEventsToDisplay() = isEmpty() || all { + it.type == ProcessedEvent.Type.REMOVE || it.event.canNotBeDisplayed() } private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted - fun List>.toNotifications(myUserId: String): List { + @JvmName("toNotificationsInviteNotifiableEvent") + fun List>.toNotifications(myUserId: String): List { return map { (processed, event) -> when (processed) { - ProcessedType.REMOVE -> OneShotNotification.Removed(key = event.roomId) - ProcessedType.KEEP -> OneShotNotification.Append( + ProcessedEvent.Type.REMOVE -> OneShotNotification.Removed(key = event.roomId) + ProcessedEvent.Type.KEEP -> OneShotNotification.Append( notificationUtils.buildRoomInvitationNotification(event, myUserId), OneShotNotification.Append.Meta( key = event.roomId, @@ -64,11 +65,11 @@ class NotificationFactory @Inject constructor( } @JvmName("toNotificationsSimpleNotifiableEvent") - fun List>.toNotifications(myUserId: String): List { + fun List>.toNotifications(myUserId: String): List { return map { (processed, event) -> when (processed) { - ProcessedType.REMOVE -> OneShotNotification.Removed(key = event.eventId) - ProcessedType.KEEP -> OneShotNotification.Append( + ProcessedEvent.Type.REMOVE -> OneShotNotification.Removed(key = event.eventId) + ProcessedEvent.Type.KEEP -> OneShotNotification.Append( notificationUtils.buildSimpleEventNotification(event, myUserId), OneShotNotification.Append.Meta( key = event.eventId, diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt index e72b9c7110..5afff89402 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationRenderer.kt @@ -34,7 +34,7 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer myUserDisplayName: String, myUserAvatarUrl: String?, useCompleteNotificationFormat: Boolean, - eventsToProcess: List) { + eventsToProcess: List>) { val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType() with(notificationFactory) { val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) @@ -108,28 +108,28 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer } } -private fun List.groupByType(): GroupedNotificationEvents { - val roomIdToEventMap: MutableMap>> = LinkedHashMap() - val simpleEvents: MutableList> = ArrayList() - val invitationEvents: MutableList> = ArrayList() +private fun List>.groupByType(): GroupedNotificationEvents { + val roomIdToEventMap: MutableMap>> = LinkedHashMap() + val simpleEvents: MutableList> = ArrayList() + val invitationEvents: MutableList> = ArrayList() forEach { - when (val event = it.second) { - is InviteNotifiableEvent -> invitationEvents.add(it.asPair()) + when (val event = it.event) { + is InviteNotifiableEvent -> invitationEvents.add(it.castedToEventType()) is NotifiableMessageEvent -> { val roomEvents = roomIdToEventMap.getOrPut(event.roomId) { ArrayList() } - roomEvents.add(it.asPair()) + roomEvents.add(it.castedToEventType()) } - is SimpleNotifiableEvent -> simpleEvents.add(it.asPair()) + is SimpleNotifiableEvent -> simpleEvents.add(it.castedToEventType()) } } return GroupedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents) } @Suppress("UNCHECKED_CAST") -private fun Pair.asPair(): Pair = this as Pair +private fun ProcessedEvent.castedToEventType(): ProcessedEvent = this as ProcessedEvent data class GroupedNotificationEvents( - val roomEvents: Map>>, - val simpleEvents: List>, - val invitationEvents: List> + val roomEvents: Map>>, + val simpleEvents: List>, + val invitationEvents: List> ) diff --git a/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt index 0901757d02..7c58c81f46 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt @@ -16,11 +16,15 @@ package im.vector.app.features.notifications -typealias ProcessedEvent = Pair +data class ProcessedEvent( + val type: Type, + val event: T +) { -enum class ProcessedType { - KEEP, - REMOVE + enum class Type { + KEEP, + REMOVE + } } -fun List.onlyKeptEvents() = filter { it.first == ProcessedType.KEEP }.map { it.second } +fun List>.onlyKeptEvents() = filter { it.type == ProcessedEvent.Type.KEEP }.map { it.event } diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt index c85d01a603..342567753c 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -16,6 +16,7 @@ package im.vector.app.features.notifications +import im.vector.app.features.notifications.ProcessedEvent.Type import im.vector.app.test.fakes.FakeAutoAcceptInvites import im.vector.app.test.fakes.FakeOutdatedEventDetector import org.amshove.kluent.shouldBeEqualTo @@ -39,9 +40,9 @@ class NotifiableEventProcessorTest { val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo listOf( - ProcessedType.KEEP to events[0], - ProcessedType.KEEP to events[1] + result shouldBeEqualTo listOfProcessedEvents( + Type.KEEP to events[0], + Type.KEEP to events[1] ) } @@ -55,9 +56,9 @@ class NotifiableEventProcessorTest { val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo listOf( - ProcessedType.REMOVE to events[0], - ProcessedType.REMOVE to events[1] + result shouldBeEqualTo listOfProcessedEvents( + Type.REMOVE to events[0], + Type.REMOVE to events[1] ) } @@ -71,9 +72,9 @@ class NotifiableEventProcessorTest { val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo listOf( - ProcessedType.KEEP to events[0], - ProcessedType.KEEP to events[1] + result shouldBeEqualTo listOfProcessedEvents( + Type.KEEP to events[0], + Type.KEEP to events[1] ) } @@ -84,8 +85,8 @@ class NotifiableEventProcessorTest { val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo listOf( - ProcessedType.REMOVE to events[0], + result shouldBeEqualTo listOfProcessedEvents( + Type.REMOVE to events[0], ) } @@ -96,8 +97,8 @@ class NotifiableEventProcessorTest { val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) - result shouldBeEqualTo listOf( - ProcessedType.KEEP to events[0], + result shouldBeEqualTo listOfProcessedEvents( + Type.KEEP to events[0], ) } @@ -107,26 +108,30 @@ class NotifiableEventProcessorTest { val result = eventProcessor.process(events, currentRoomId = "room-1", renderedEventsList = emptyList()) - result shouldBeEqualTo listOf( - ProcessedType.REMOVE to events[0], + result shouldBeEqualTo listOfProcessedEvents( + Type.REMOVE to events[0], ) } @Test fun `given events are different to rendered events when processing then removes difference`() { val events = listOf(aSimpleNotifiableEvent(eventId = "event-1")) - val renderedEvents = listOf( - ProcessedType.KEEP to events[0], - ProcessedType.KEEP to anInviteNotifiableEvent(roomId = "event-2") + val renderedEvents = listOf>( + ProcessedEvent(Type.KEEP, events[0]), + ProcessedEvent(Type.KEEP, anInviteNotifiableEvent(roomId = "event-2")) ) val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEvents) - result shouldBeEqualTo listOf( - ProcessedType.REMOVE to renderedEvents[1].second, - ProcessedType.KEEP to renderedEvents[0].second + result shouldBeEqualTo listOfProcessedEvents( + Type.REMOVE to renderedEvents[1].event, + Type.KEEP to renderedEvents[0].event ) } + + private fun listOfProcessedEvents(vararg event: Pair) = event.map { + ProcessedEvent(it.first, it.second) + } } fun aSimpleNotifiableEvent(eventId: String) = SimpleNotifiableEvent( diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt index 84f59dcc21..d3d48630c9 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt @@ -16,6 +16,7 @@ package im.vector.app.features.notifications +import im.vector.app.features.notifications.ProcessedEvent.Type import im.vector.app.test.fakes.FakeNotificationUtils import im.vector.app.test.fakes.FakeRoomGroupMessageCreator import im.vector.app.test.fakes.FakeSummaryGroupMessageCreator @@ -46,7 +47,7 @@ class NotificationFactoryTest { @Test fun `given a room invitation when mapping to notification then is Append`() = testWith(notificationFactory) { val expectedNotification = notificationUtils.givenBuildRoomInvitationNotificationFor(AN_INVITATION_EVENT, MY_USER_ID) - val roomInvitation = listOf(ProcessedType.KEEP to AN_INVITATION_EVENT) + val roomInvitation = listOf(ProcessedEvent(Type.KEEP, AN_INVITATION_EVENT)) val result = roomInvitation.toNotifications(MY_USER_ID) @@ -63,7 +64,7 @@ class NotificationFactoryTest { @Test fun `given a missing event in room invitation when mapping to notification then is Removed`() = testWith(notificationFactory) { - val missingEventRoomInvitation = listOf(ProcessedType.REMOVE to AN_INVITATION_EVENT) + val missingEventRoomInvitation = listOf(ProcessedEvent(Type.REMOVE, AN_INVITATION_EVENT)) val result = missingEventRoomInvitation.toNotifications(MY_USER_ID) @@ -75,7 +76,7 @@ class NotificationFactoryTest { @Test fun `given a simple event when mapping to notification then is Append`() = testWith(notificationFactory) { val expectedNotification = notificationUtils.givenBuildSimpleInvitationNotificationFor(A_SIMPLE_EVENT, MY_USER_ID) - val roomInvitation = listOf(ProcessedType.KEEP to A_SIMPLE_EVENT) + val roomInvitation = listOf(ProcessedEvent(Type.KEEP, A_SIMPLE_EVENT)) val result = roomInvitation.toNotifications(MY_USER_ID) @@ -92,7 +93,7 @@ class NotificationFactoryTest { @Test fun `given a missing simple event when mapping to notification then is Removed`() = testWith(notificationFactory) { - val missingEventRoomInvitation = listOf(ProcessedType.REMOVE to A_SIMPLE_EVENT) + val missingEventRoomInvitation = listOf(ProcessedEvent(Type.REMOVE, A_SIMPLE_EVENT)) val result = missingEventRoomInvitation.toNotifications(MY_USER_ID) @@ -105,7 +106,7 @@ class NotificationFactoryTest { fun `given room with message when mapping to notification then delegates to room group message creator`() = testWith(notificationFactory) { val events = listOf(A_MESSAGE_EVENT) val expectedNotification = roomGroupMessageCreator.givenCreatesRoomMessageFor(events, A_ROOM_ID, MY_USER_ID, MY_AVATAR_URL) - val roomWithMessage = mapOf(A_ROOM_ID to listOf(ProcessedType.KEEP to A_MESSAGE_EVENT)) + val roomWithMessage = mapOf(A_ROOM_ID to listOf(ProcessedEvent(Type.KEEP, A_MESSAGE_EVENT))) val result = roomWithMessage.toNotifications(MY_USER_ID, MY_AVATAR_URL) @@ -114,7 +115,7 @@ class NotificationFactoryTest { @Test fun `given a room with no events to display when mapping to notification then is Empty`() = testWith(notificationFactory) { - val events = listOf(ProcessedType.REMOVE to A_MESSAGE_EVENT) + val events = listOf(ProcessedEvent(Type.REMOVE, A_MESSAGE_EVENT)) val emptyRoom = mapOf(A_ROOM_ID to events) val result = emptyRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) @@ -126,7 +127,7 @@ class NotificationFactoryTest { @Test fun `given a room with only redacted events when mapping to notification then is Empty`() = testWith(notificationFactory) { - val redactedRoom = mapOf(A_ROOM_ID to listOf(ProcessedType.KEEP to A_MESSAGE_EVENT.copy(isRedacted = true))) + val redactedRoom = mapOf(A_ROOM_ID to listOf(ProcessedEvent(Type.KEEP, A_MESSAGE_EVENT.copy(isRedacted = true)))) val result = redactedRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt index c086a3ee4d..f726ff1b54 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationRendererTest.kt @@ -30,7 +30,7 @@ private const val AN_EVENT_ID = "event-id" private const val A_ROOM_ID = "room-id" private const val USE_COMPLETE_NOTIFICATION_FORMAT = true -private val AN_EVENT_LIST = listOf>() +private val AN_EVENT_LIST = listOf>() private val A_PROCESSED_EVENTS = GroupedNotificationEvents(emptyMap(), emptyList(), emptyList()) private val A_SUMMARY_NOTIFICATION = SummaryNotification.Update(mockk()) private val A_REMOVE_SUMMARY_NOTIFICATION = SummaryNotification.Removed From 743a71c78da6be0f23f18f5ee94984b725d72439 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 20 Oct 2021 09:42:19 +0100 Subject: [PATCH 089/413] renaming event lists to give more context and remove the list suffix/inconsistencies --- .../notifications/NotifiableEventProcessor.kt | 10 ++-- .../NotificationDrawerManager.kt | 52 +++++++++---------- .../NotifiableEventProcessorTest.kt | 14 ++--- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt index 338c3d58eb..858df81bf6 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt @@ -28,8 +28,8 @@ class NotifiableEventProcessor @Inject constructor( private val autoAcceptInvites: AutoAcceptInvites ) { - fun process(eventList: List, currentRoomId: String?, renderedEventsList: ProcessedEvents): ProcessedEvents { - val processedEventList = eventList.map { + fun process(queuedEvents: List, currentRoomId: String?, renderedEvents: ProcessedEvents): ProcessedEvents { + val processedEvents = queuedEvents.map { val type = when (it) { is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) REMOVE else KEEP is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, it.roomId) || outdatedDetector.isMessageOutdated(it)) { @@ -40,11 +40,11 @@ class NotifiableEventProcessor @Inject constructor( ProcessedEvent(type, it) } - val removedEventsDiff = renderedEventsList.filter { renderedEvent -> - eventList.none { it.eventId == renderedEvent.event.eventId } + val removedEventsDiff = renderedEvents.filter { renderedEvent -> + queuedEvents.none { it.eventId == renderedEvent.event.eventId } }.map { ProcessedEvent(REMOVE, it.event) } - return removedEventsDiff + processedEventList + return removedEventsDiff + processedEvents } private fun shouldIgnoreMessageEventInRoom(currentRoomId: String?, roomId: String?): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 5d2212ba1e..c052de650e 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -63,14 +63,14 @@ class NotificationDrawerManager @Inject constructor(private val context: Context * * Events are unique by their properties, we should be careful not to insert multiple events with the same event-id */ - private val eventList = loadEventInfo() + private val queuedEvents = loadEventInfo() /** * The last known rendered notifiable events * we keep track of them in order to know which events have been removed from the eventList * allowing us to cancel any notifications previous displayed by now removed events */ - private var renderedEventsList = emptyList>() + private var renderedEvents = emptyList>() private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size) private var currentRoomId: String? = null @@ -105,8 +105,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } else { Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.canBeReplaced}") } - synchronized(eventList) { - val existing = eventList.firstOrNull { it.eventId == notifiableEvent.eventId } + synchronized(queuedEvents) { + val existing = queuedEvents.firstOrNull { it.eventId == notifiableEvent.eventId } if (existing != null) { if (existing.canBeReplaced) { // Use the event coming from the event stream as it may contains more info than @@ -117,8 +117,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context // Use setOnlyAlertOnce to ensure update notification does not interfere with sound // from first notify invocation as outlined in: // https://developer.android.com/training/notify-user/build-notification#Updating - eventList.remove(existing) - eventList.add(notifiableEvent) + queuedEvents.remove(existing) + queuedEvents.add(notifiableEvent) } else { // keep the existing one, do not replace } @@ -126,7 +126,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context // Check if this is an edit if (notifiableEvent.editedEventId != null) { // This is an edition - val eventBeforeEdition = eventList.firstOrNull { + val eventBeforeEdition = queuedEvents.firstOrNull { // Edition of an event it.eventId == notifiableEvent.editedEventId || // or edition of an edition @@ -135,9 +135,9 @@ class NotificationDrawerManager @Inject constructor(private val context: Context if (eventBeforeEdition != null) { // Replace the existing notification with the new content - eventList.remove(eventBeforeEdition) + queuedEvents.remove(eventBeforeEdition) - eventList.add(notifiableEvent) + queuedEvents.add(notifiableEvent) } else { // Ignore an edit of a not displayed event in the notification drawer } @@ -148,7 +148,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context Timber.d("onNotifiableEventReceived(): skipping event, already seen") } else { seenEventIds.put(notifiableEvent.eventId) - eventList.add(notifiableEvent) + queuedEvents.add(notifiableEvent) } } } @@ -156,8 +156,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } fun onEventRedacted(eventId: String) { - synchronized(eventList) { - eventList.replace(eventId) { + synchronized(queuedEvents) { + queuedEvents.replace(eventId) { when (it) { is InviteNotifiableEvent -> it.copy(isRedacted = true) is NotifiableMessageEvent -> it.copy(isRedacted = true) @@ -171,8 +171,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context * Clear all known events and refresh the notification drawer */ fun clearAllEvents() { - synchronized(eventList) { - eventList.clear() + synchronized(queuedEvents) { + queuedEvents.clear() } refreshNotificationDrawer() } @@ -194,7 +194,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context */ fun setCurrentRoom(roomId: String?) { var hasChanged: Boolean - synchronized(eventList) { + synchronized(queuedEvents) { hasChanged = roomId != currentRoomId currentRoomId = roomId } @@ -211,8 +211,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } private fun removeAll(predicate: (NotifiableEvent) -> Boolean): Boolean { - return synchronized(eventList) { - eventList.removeAll(predicate) + return synchronized(queuedEvents) { + queuedEvents.removeAll(predicate) } } @@ -247,17 +247,17 @@ class NotificationDrawerManager @Inject constructor(private val context: Context useCompleteNotificationFormat = newSettings } - val eventsToRender = synchronized(eventList) { - notifiableEventProcessor.process(eventList, currentRoomId, renderedEventsList).also { - eventList.clear() - eventList.addAll(it.onlyKeptEvents()) + val eventsToRender = synchronized(queuedEvents) { + notifiableEventProcessor.process(queuedEvents, currentRoomId, renderedEvents).also { + queuedEvents.clear() + queuedEvents.addAll(it.onlyKeptEvents()) } } - if (renderedEventsList == eventsToRender) { + if (renderedEvents == eventsToRender) { Timber.d("Skipping notification update due to event list not changing") } else { - renderedEventsList = eventsToRender + renderedEvents = eventsToRender val session = currentSession ?: return val user = session.getUser(session.myUserId) // myUserDisplayName cannot be empty else NotificationCompat.MessagingStyle() will crash @@ -277,8 +277,8 @@ class NotificationDrawerManager @Inject constructor(private val context: Context } fun persistInfo() { - synchronized(eventList) { - if (eventList.isEmpty()) { + synchronized(queuedEvents) { + if (queuedEvents.isEmpty()) { deleteCachedRoomNotifications() return } @@ -286,7 +286,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context val file = File(context.applicationContext.cacheDir, ROOMS_NOTIFICATIONS_FILE_NAME) if (!file.exists()) file.createNewFile() FileOutputStream(file).use { - currentSession?.securelyStoreObject(eventList, KEY_ALIAS_SECRET_STORAGE, it) + currentSession?.securelyStoreObject(queuedEvents, KEY_ALIAS_SECRET_STORAGE, it) } } catch (e: Throwable) { Timber.e(e, "## Failed to save cached notification info") diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt index 342567753c..f6938cb4ae 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -38,7 +38,7 @@ class NotifiableEventProcessorTest { aSimpleNotifiableEvent(eventId = "event-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEvents = emptyList()) result shouldBeEqualTo listOfProcessedEvents( Type.KEEP to events[0], @@ -54,7 +54,7 @@ class NotifiableEventProcessorTest { anInviteNotifiableEvent(roomId = "room-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEvents = emptyList()) result shouldBeEqualTo listOfProcessedEvents( Type.REMOVE to events[0], @@ -70,7 +70,7 @@ class NotifiableEventProcessorTest { anInviteNotifiableEvent(roomId = "room-2") ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEvents = emptyList()) result shouldBeEqualTo listOfProcessedEvents( Type.KEEP to events[0], @@ -83,7 +83,7 @@ class NotifiableEventProcessorTest { val events = listOf(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) outdatedDetector.givenEventIsOutOfDate(events[0]) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEvents = emptyList()) result shouldBeEqualTo listOfProcessedEvents( Type.REMOVE to events[0], @@ -95,7 +95,7 @@ class NotifiableEventProcessorTest { val events = listOf(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) outdatedDetector.givenEventIsInDate(events[0]) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList()) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEvents = emptyList()) result shouldBeEqualTo listOfProcessedEvents( Type.KEEP to events[0], @@ -106,7 +106,7 @@ class NotifiableEventProcessorTest { fun `given viewing the same room as message event when processing then removes message`() { val events = listOf(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1")) - val result = eventProcessor.process(events, currentRoomId = "room-1", renderedEventsList = emptyList()) + val result = eventProcessor.process(events, currentRoomId = "room-1", renderedEvents = emptyList()) result shouldBeEqualTo listOfProcessedEvents( Type.REMOVE to events[0], @@ -121,7 +121,7 @@ class NotifiableEventProcessorTest { ProcessedEvent(Type.KEEP, anInviteNotifiableEvent(roomId = "event-2")) ) - val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEvents) + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEvents = renderedEvents) result shouldBeEqualTo listOfProcessedEvents( Type.REMOVE to renderedEvents[1].event, From e8bd27e78536f2e60c678047aff56f020262fcf9 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Wed, 20 Oct 2021 15:47:11 +0100 Subject: [PATCH 090/413] adding changelog entries --- changelog.d/3395.bugfix | 1 + changelog.d/4152.bugfix | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelog.d/3395.bugfix create mode 100644 changelog.d/4152.bugfix diff --git a/changelog.d/3395.bugfix b/changelog.d/3395.bugfix new file mode 100644 index 0000000000..9482e1bc7e --- /dev/null +++ b/changelog.d/3395.bugfix @@ -0,0 +1 @@ +Fixes marking individual notifications as read causing other notifications to be dismissed \ No newline at end of file diff --git a/changelog.d/4152.bugfix b/changelog.d/4152.bugfix new file mode 100644 index 0000000000..1ff45609b5 --- /dev/null +++ b/changelog.d/4152.bugfix @@ -0,0 +1 @@ +Tentatively fixing the doubled notifications by updating the group summary at specific points in the notification rendering cycle \ No newline at end of file From c56101d2274394b8e8a3d94cc81c75de33cdaae9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Oct 2021 18:07:23 +0200 Subject: [PATCH 091/413] Do not use the room member avatar as a room avatar --- .../app/features/notifications/RoomGroupMessageCreator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt index 35a1c12d0c..8e8a5d5e8a 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -163,7 +163,7 @@ class RoomGroupMessageCreator @Inject constructor( if (events.isEmpty()) return null // Use the last event (most recent?) - val roomAvatarPath = events.last().roomAvatarPath ?: events.last().senderAvatarPath + val roomAvatarPath = events.last().roomAvatarPath return bitmapLoader.getRoomBitmap(roomAvatarPath) } From 2bd2cbf84eba09773a5273aaf437ab09f7d96575 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Oct 2021 18:10:42 +0200 Subject: [PATCH 092/413] Compact code --- .../app/features/notifications/RoomGroupMessageCreator.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt index 8e8a5d5e8a..bdd7d026f9 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -160,12 +160,10 @@ class RoomGroupMessageCreator @Inject constructor( } private fun getRoomBitmap(events: List): Bitmap? { - if (events.isEmpty()) return null - // Use the last event (most recent?) - val roomAvatarPath = events.last().roomAvatarPath - - return bitmapLoader.getRoomBitmap(roomAvatarPath) + return events.lastOrNull() + ?.roomAvatarPath + ?.let { bitmapLoader.getRoomBitmap(it) } } } From be67836a3eaea8df5276522e9bb18ce58825a0db Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Oct 2021 21:33:52 +0200 Subject: [PATCH 093/413] Tiny formatting --- .../notifications/SummaryGroupMessageCreator.kt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt index ddef31a0f5..91163434c2 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SummaryGroupMessageCreator.kt @@ -67,8 +67,7 @@ class SummaryGroupMessageCreator @Inject constructor( summaryInboxStyle.setBigContentTitle(sumTitle) // TODO get latest event? .setSummaryText(stringProvider.getQuantityString(R.plurals.notification_unread_notified_messages, nbEvents, nbEvents)) - return if (useCompleteNotificationFormat - ) { + return if (useCompleteNotificationFormat) { notificationUtils.buildSummaryListNotification( summaryInboxStyle, sumTitle, @@ -76,9 +75,14 @@ class SummaryGroupMessageCreator @Inject constructor( lastMessageTimestamp = lastMessageTimestamp ) } else { - processSimpleGroupSummary(summaryIsNoisy, messageCount, - simpleNotifications.size, invitationNotifications.size, - roomNotifications.size, lastMessageTimestamp) + processSimpleGroupSummary( + summaryIsNoisy, + messageCount, + simpleNotifications.size, + invitationNotifications.size, + roomNotifications.size, + lastMessageTimestamp + ) } } From b146501f2983152f935a69b6f42380c6151b24ea Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 21 Oct 2021 12:03:41 +0100 Subject: [PATCH 094/413] avoiding multiple list iterations via mapNotNull --- .../im/vector/app/features/notifications/ProcessedEvent.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt index 7c58c81f46..8bd9819ca9 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/ProcessedEvent.kt @@ -27,4 +27,6 @@ data class ProcessedEvent( } } -fun List>.onlyKeptEvents() = filter { it.type == ProcessedEvent.Type.KEEP }.map { it.event } +fun List>.onlyKeptEvents() = mapNotNull { processedEvent -> + processedEvent.event.takeIf { processedEvent.type == ProcessedEvent.Type.KEEP } +} From a5fe6f7212bbf5b8bb6071793980886a7c5680dd Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 21 Oct 2021 11:31:02 +0100 Subject: [PATCH 095/413] removing redacted events from the room notification message list --- .../features/notifications/NotificationFactory.kt | 2 +- .../notifications/NotificationFactoryTest.kt | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt index 5dff009cec..adc4e44bcc 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationFactory.kt @@ -33,7 +33,7 @@ class NotificationFactory @Inject constructor( when { events.hasNoEventsToDisplay() -> RoomNotification.Removed(roomId) else -> { - val messageEvents = events.onlyKeptEvents() + val messageEvents = events.onlyKeptEvents().filterNot { it.isRedacted } roomGroupMessageCreator.createRoomMessage(messageEvents, roomId, myUserDisplayName, myUserAvatarUrl) } } diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt index d3d48630c9..d720881bac 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationFactoryTest.kt @@ -135,6 +135,20 @@ class NotificationFactoryTest { roomId = A_ROOM_ID )) } + + @Test + fun `given a room with redacted and non redacted message events when mapping to notification then redacted events are removed`() = testWith(notificationFactory) { + val roomWithRedactedMessage = mapOf(A_ROOM_ID to listOf( + ProcessedEvent(Type.KEEP, A_MESSAGE_EVENT.copy(isRedacted = true)), + ProcessedEvent(Type.KEEP, A_MESSAGE_EVENT.copy(eventId = "not-redacted")) + )) + val withRedactedRemoved = listOf(A_MESSAGE_EVENT.copy(eventId = "not-redacted")) + val expectedNotification = roomGroupMessageCreator.givenCreatesRoomMessageFor(withRedactedRemoved, A_ROOM_ID, MY_USER_ID, MY_AVATAR_URL) + + val result = roomWithRedactedMessage.toNotifications(MY_USER_ID, MY_AVATAR_URL) + + result shouldBeEqualTo listOf(expectedNotification) + } } fun testWith(receiver: T, block: T.() -> Unit) { From 6d9877d79c156fdb2137c036e4e02995a8444f00 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 21 Oct 2021 11:51:28 +0100 Subject: [PATCH 096/413] filtering out redacted simple message events, we handle them by updating the notifications --- .../notifications/NotifiableEventProcessor.kt | 6 +++++- .../NotifiableEventProcessorTest.kt | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt index 858df81bf6..3d10d74fe3 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventProcessor.kt @@ -19,6 +19,7 @@ package im.vector.app.features.notifications import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.notifications.ProcessedEvent.Type.KEEP import im.vector.app.features.notifications.ProcessedEvent.Type.REMOVE +import org.matrix.android.sdk.api.session.events.model.EventType import javax.inject.Inject private typealias ProcessedEvents = List> @@ -35,7 +36,10 @@ class NotifiableEventProcessor @Inject constructor( is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, it.roomId) || outdatedDetector.isMessageOutdated(it)) { REMOVE } else KEEP - is SimpleNotifiableEvent -> KEEP + is SimpleNotifiableEvent -> when (it.type) { + EventType.REDACTION -> REMOVE + else -> KEEP + } } ProcessedEvent(type, it) } diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt index f6938cb4ae..229ab39d1d 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotifiableEventProcessorTest.kt @@ -21,6 +21,7 @@ import im.vector.app.test.fakes.FakeAutoAcceptInvites import im.vector.app.test.fakes.FakeOutdatedEventDetector import org.amshove.kluent.shouldBeEqualTo import org.junit.Test +import org.matrix.android.sdk.api.session.events.model.EventType private val NOT_VIEWING_A_ROOM: String? = null @@ -46,6 +47,17 @@ class NotifiableEventProcessorTest { ) } + @Test + fun `given redacted simple event when processing then remove redaction event`() { + val events = listOf(aSimpleNotifiableEvent(eventId = "event-1", type = EventType.REDACTION)) + + val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEvents = emptyList()) + + result shouldBeEqualTo listOfProcessedEvents( + Type.REMOVE to events[0] + ) + } + @Test fun `given invites are auto accepted when processing then remove invitations`() { autoAcceptInvites._isEnabled = true @@ -134,14 +146,14 @@ class NotifiableEventProcessorTest { } } -fun aSimpleNotifiableEvent(eventId: String) = SimpleNotifiableEvent( +fun aSimpleNotifiableEvent(eventId: String, type: String? = null) = SimpleNotifiableEvent( matrixID = null, eventId = eventId, editedEventId = null, noisy = false, title = "title", description = "description", - type = null, + type = type, timestamp = 0, soundName = null, canBeReplaced = false, From 124061e1dbe5de1eecd0179e91d83f3d29868002 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Thu, 21 Oct 2021 12:27:12 +0100 Subject: [PATCH 097/413] adding changelog entry --- changelog.d/1491.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1491.bugfix diff --git a/changelog.d/1491.bugfix b/changelog.d/1491.bugfix new file mode 100644 index 0000000000..0ff6bd2c11 --- /dev/null +++ b/changelog.d/1491.bugfix @@ -0,0 +1 @@ +Stops showing a dedicated redacted event notification, the message notifications will update accordingly \ No newline at end of file From 82b3d17db634eb782e994911cc920fae3e84bdbc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Oct 2021 23:08:52 +0000 Subject: [PATCH 098/413] Bump libphonenumber from 8.12.35 to 8.12.36 Bumps [libphonenumber](https://github.com/google/libphonenumber) from 8.12.35 to 8.12.36. - [Release notes](https://github.com/google/libphonenumber/releases) - [Changelog](https://github.com/google/libphonenumber/blob/master/making-metadata-changes.md) - [Commits](https://github.com/google/libphonenumber/compare/v8.12.35...v8.12.36) --- updated-dependencies: - dependency-name: com.googlecode.libphonenumber:libphonenumber dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- matrix-sdk-android/build.gradle | 2 +- vector/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 2405e2ee4e..deea87e8a3 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -156,7 +156,7 @@ dependencies { implementation libs.apache.commonsImaging // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.35' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.36' testImplementation libs.tests.junit testImplementation 'org.robolectric:robolectric:4.6.1' diff --git a/vector/build.gradle b/vector/build.gradle index 7e2f5d72d6..c963e8b661 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -372,7 +372,7 @@ dependencies { implementation 'com.facebook.stetho:stetho:1.6.0' // Phone number https://github.com/google/libphonenumber - implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.35' + implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.36' // rx implementation libs.rx.rxKotlin From 66198805ca61d64d2bbb1e9a336921aa99105772 Mon Sep 17 00:00:00 2001 From: DUCKCHI Date: Mon, 25 Oct 2021 16:05:14 +0000 Subject: [PATCH 099/413] Translated using Weblate (Korean) Currently translated at 49.6% (1326 of 2672 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ko/ --- vector/src/main/res/values-ko/strings.xml | 67 +++++++++++++++++------ 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/vector/src/main/res/values-ko/strings.xml b/vector/src/main/res/values-ko/strings.xml index 3adf75e722..f691609567 100644 --- a/vector/src/main/res/values-ko/strings.xml +++ b/vector/src/main/res/values-ko/strings.xml @@ -162,13 +162,13 @@ 음성 통화 시작하기 영상 통화 시작하기 정말로 %s님과 새 대화를 시작하시겠습니까\? - 정말 음성통화를 시작하시겠어요? - 정말 영상통화를 시작하시겠어요? + 정말 음성통화를 시작하시겠습니까\? + 정말 영상통화를 시작하시겠습니까\? 파일 보내기 스티커 보내기 - 사진이나 영상 찍기 - 사진 찍기 - 영상 찍기 + 사진이나 영상 촬영 + 사진 촬영 + 영상 촬영 로그인 계정 만들기 제출하기 @@ -193,7 +193,7 @@ 머물기 넘기기 완료 - 정말 로그아웃하시겠어요\? + 정말 로그아웃하시겠습니까\? 읽음으로 표시 ${app_name}이 연락처에 접근할 수 없게 되어 있습니다 @@ -246,7 +246,7 @@ 무시하고 통화 수락하기 중단 - 무시 + 차단 세계 검색 즐겨찾기 필터 사람 필터 @@ -348,7 +348,7 @@ 미디어 연결 실패 카메라를 초기화할 수 없습니다 다른 곳에서 전화 응답 - 사진이나 영상 찍기 + 사진이나 영상 촬영 영상을 촬영할 수 없음 정보 첨부 파일을 보내고 저장하려면 ${app_name}은 영상과 사진 보관함에 접근하는 권한이 필요합니다. @@ -432,8 +432,8 @@ 일반 사용자로 재 설정 중재자로 하기 관리자로 하기 - 이 사용자의 모든 메시지 숨기기 - 이 사용자의 모든 메시지 보이기 + 차단 + 차단 해제 사용자 ID, 이름 혹은 이메일 언급 기기 목록 보이기 @@ -475,7 +475,7 @@ 신뢰함 신뢰하지 않음 로그아웃 - 무시하기 + 무시 핑거프린트 (%s): 원격 서버의 ID를 확인할 수 없습니다. 이는 누군가가 당신의 트래픽을 악의적으로 가로채고 있거나, 휴대 전화가 원격 서버에서 제공한 인증서를 신뢰하지 않는 것입니다. @@ -665,7 +665,7 @@ 미디어 캐시 지우기 사용자 설정 알림 - 차단한 사용자 + 차단된 사용자 기타 고급 암호화 @@ -747,7 +747,7 @@ 비밀번호 갱신 실패 비밀번호가 올바르지 않습니다 당신의 비밀번호가 갱신되었습니다 - %s님의 모든 메시지를 보이겠습니까\? + %s님의 모든 메시지를 표시하시겠습니까\? \n \n이 동작은 앱을 다시 시작하고 일정 시간이 걸릴 수 있습니다. 비밀번호가 맞지 않음 @@ -1411,19 +1411,19 @@ 이 내용 신고하기 이 내용을 신고하는 이유 신고 - 사용자 출입 금지 + 사용자 차단 내용 신고됨 이 내용을 신고했습니다. \n -\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다 +\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다. 스팸 문자로 신고됨 이 내용을 스팸 메일로 신고했습니다. \n -\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다 +\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다. 부적절한 문자로 신고됨 이 내용을 부적절한 문자로 신고했습니다. \n -\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다 +\n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다. ${app_name}은 종단간 키를 디스크에 저장하려면 권한이 필요합니다. \n \n키를 수동으로 내보내려면 다음 팝업에서 접근을 허용해주세요. @@ -1483,4 +1483,37 @@ 일시 정지 재생 음성 메시지를 보내려면 마이크 권한을 허용해주세요. + 삭제된 메시지 + 복사 + 차단 해제 + 차단한 사용자가 없습니다 + 차단 + 차단을 해제하고, 차단 해제한 사용자의 메시지를 다시 표시합니다 + 사용자를 차단하고, 차단한 사용자의 모든 메시지를 숨깁니다 + 차단 해제한 사용자의 모든 메시지가 표시됩니다. + 차단 해제 + 타임라인 + 읽지 않은 메시지 + 항상 묻기 + 현재 세션 + + %d개의 활성 세션 + + 이 세션에서 로그아웃 + 세션 관리 + 모든 세션 보기 + 활성 세션 + 보안 설정 + ${app_name}을 2분 동안 사용하지 않으면 PIN을 사용하도록 설정합니다. + 2분 후 PIN 잠금 + 방 이름이나 메시지 내용같은 자세한 정보를 표시합니다. + 알림에 내용 표시 + 설정된 PIN을 변경합니다 + PIN 변경 + PIN을 재설정하고 싶다면 PIN 분실을 눌러 로그아웃 후 재설정을 진행할 수 있습니다. + 지문 인식이나 얼굴 인식과 같은 생체 인증을 활성화합니다. + 생체 인증 활성화 + PIN 활성화 + PIN이나 생체 인증으로 보안 접근을 사용합니다. + 보안 접근 \ No newline at end of file From 93ed2dcbbf5d6be30bf174c35c4f87f43f6ebd65 Mon Sep 17 00:00:00 2001 From: libexus Date: Mon, 25 Oct 2021 18:10:13 +0000 Subject: [PATCH 100/413] Translated using Weblate (German) Currently translated at 97.8% (2615 of 2672 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- vector/src/main/res/values-de/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 73f0a9eb70..de4eb4dad6 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2175,7 +2175,7 @@ Verifiziere alle deine Sitzungen, um sicherzustellen, dass dein Konto & deine Nachrichten sicher sind Bestätige neue Anmeldung zu deinem Konto: %1$s Verifiziere manuell mit einem Text - Verifiziere Anmeldung + Anmeldung verifizieren Verifiziere interaktiv mit Emojis Bestätige deine Identität, indem du diesen Login von einer deiner anderen Sitzungen verifizierst, um Zugriff auf deine verschlüsselten Nachrichten zu erhalten. Als vertraut markieren @@ -2800,7 +2800,7 @@ Einen Space erstellen Nur für mich Welche Art von Space möchtest du erstellen\? - Space hinzufügen + Space erstellen Space erstellen Jeder, der sich in einem Space mit diesem Raum befindet, kann diesen Raum finden und ihm beitreten. Nur die Administratoren des Raums können diesen zu einem Space hinzufügen. Nur Space-Mitglieder From f6f4cec94770962c47a20ab3824a42407299ec38 Mon Sep 17 00:00:00 2001 From: random Date: Mon, 25 Oct 2021 08:24:12 +0000 Subject: [PATCH 101/413] Translated using Weblate (Italian) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/it/ --- fastlane/metadata/android/it-IT/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/40103040.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/40103040.txt b/fastlane/metadata/android/it-IT/changelogs/40103040.txt new file mode 100644 index 0000000000..e28ce08e03 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40103040.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: aggiunto supporto alla presenza per messaggi diretti (nota: la presenza è disattivata su matrix.org). Aggiunto di nuovo il supporto ad Android Auto. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From 188e0dbec722735bf258067b73349e9916aa1f41 Mon Sep 17 00:00:00 2001 From: random Date: Mon, 25 Oct 2021 08:24:58 +0000 Subject: [PATCH 102/413] Translated using Weblate (Italian) Currently translated at 99.8% (2669 of 2672 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- vector/src/main/res/values-it/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 8d323c56e5..663e186ddf 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -1071,7 +1071,7 @@ Imposta i poteri di un utente Rimuove il rango di operatore dall\'utente con l\'ID specificato Invita l\'utente con l\'ID specificato nella stanza corrente - Entra nella stanza con un determinato nome + Entra nella stanza con l\'indirizzo scelto Esci dalla stanza Imposta l\'argomento della stanza Butta fuori l\'utente con l\'ID specificato From d969549ce6978963d90a79810550fc14e02d9937 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 25 Oct 2021 01:45:16 +0000 Subject: [PATCH 103/413] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/ --- fastlane/metadata/android/zh-TW/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40103040.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40103040.txt b/fastlane/metadata/android/zh-TW/changelogs/40103040.txt new file mode 100644 index 0000000000..bd82b54e45 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40103040.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:為直接訊息聊天室新增 Presence 支援(請注意:此功能在 matrix.org 上停用)。加回 Android Auto 支援。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.3.4 From 86d651be6093fdd065a0347c87a092284debb9fa Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Mon, 25 Oct 2021 23:08:02 +0000 Subject: [PATCH 104/413] Translated using Weblate (Persian) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40103040.txt diff --git a/fastlane/metadata/android/fa/changelogs/40103040.txt b/fastlane/metadata/android/fa/changelogs/40103040.txt new file mode 100644 index 0000000000..5da14baf6e --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40103040.txt @@ -0,0 +1,2 @@ +تغییرات اصلی در این نگارش: افزودن پشتیبانی حضور برای اتاق پیام خصوصی (توجه: حضور روی matrix.org از کار افتاده است). افزودن دوبارهٔ پشتیبانی اندروید خودرو. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.3.4 From abd83f3d7c611685a3eb5378d46861add8c05ab3 Mon Sep 17 00:00:00 2001 From: libexus Date: Tue, 26 Oct 2021 20:19:35 +0000 Subject: [PATCH 105/413] Translated using Weblate (German) Currently translated at 100.0% (35 of 35 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/de/ --- fastlane/metadata/android/de-DE/changelogs/40103000.txt | 2 ++ fastlane/metadata/android/de-DE/changelogs/40103010.txt | 2 ++ fastlane/metadata/android/de-DE/changelogs/40103020.txt | 2 ++ fastlane/metadata/android/de-DE/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/de-DE/changelogs/40103040.txt | 4 ++++ fastlane/metadata/android/de-DE/full_description.txt | 3 +++ 6 files changed, 15 insertions(+) create mode 100644 fastlane/metadata/android/de-DE/changelogs/40103000.txt create mode 100644 fastlane/metadata/android/de-DE/changelogs/40103010.txt create mode 100644 fastlane/metadata/android/de-DE/changelogs/40103020.txt create mode 100644 fastlane/metadata/android/de-DE/changelogs/40103030.txt create mode 100644 fastlane/metadata/android/de-DE/changelogs/40103040.txt diff --git a/fastlane/metadata/android/de-DE/changelogs/40103000.txt b/fastlane/metadata/android/de-DE/changelogs/40103000.txt new file mode 100644 index 0000000000..85386226db --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40103000.txt @@ -0,0 +1,2 @@ +Hauptänderungen: Organisiere deine Räume mit Spaces! +Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.0 diff --git a/fastlane/metadata/android/de-DE/changelogs/40103010.txt b/fastlane/metadata/android/de-DE/changelogs/40103010.txt new file mode 100644 index 0000000000..3323a37a59 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40103010.txt @@ -0,0 +1,2 @@ +Hauptänderungen: Organisiere deine Räume mit Spaces, Crash aus 1.3.0 gefixt. +Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.1 diff --git a/fastlane/metadata/android/de-DE/changelogs/40103020.txt b/fastlane/metadata/android/de-DE/changelogs/40103020.txt new file mode 100644 index 0000000000..880ec71c4d --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40103020.txt @@ -0,0 +1,2 @@ +Hauptänderungen: Unterstützung für Android Auto, Viele Fehlerbehebungen +Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.2 diff --git a/fastlane/metadata/android/de-DE/changelogs/40103030.txt b/fastlane/metadata/android/de-DE/changelogs/40103030.txt new file mode 100644 index 0000000000..da3451fb0d --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Hauptänderungen: Bedingungen des Identitätsservers in Einstellungen anzeigen. Unterstützung für Android Auto temporär entfernt. +Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/de-DE/changelogs/40103040.txt b/fastlane/metadata/android/de-DE/changelogs/40103040.txt new file mode 100644 index 0000000000..37ab9ccd8f --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/40103040.txt @@ -0,0 +1,4 @@ +Hauptänderungen: +- Anwesenheiten in Direktnachrichten anzeigen (Momentan auf Matrix.org deaktiviert) +- Android Auto wird wieder unterstützt +Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.4 diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt index 30eb153ee9..c4fecf7674 100644 --- a/fastlane/metadata/android/de-DE/full_description.txt +++ b/fastlane/metadata/android/de-DE/full_description.txt @@ -37,3 +37,6 @@ Kurznachrichten, Sprach- und Videoanrufe, Dateifreigaben, Bildschirmübertragung Da Weitermachen, wo Sie aufgehört haben Bleiben Sie in Kontakt, egal wo Sie sind, mit vollständig synchronisiertem Nachrichtenverlauf quer über all Ihre Geräte und im Netz auf https://app.element.io + +Open source +Element ist ein Open-Source-Projekt und wird auf GitHub gehostet. Solltest du Fehler in Element finden, melde diese bitte hier: https://github.com/vector-im/element-android From 5c4ac897c13676918925e83f88a054ecd8a6058e Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Mon, 25 Oct 2021 02:33:27 +0000 Subject: [PATCH 106/413] Translated using Weblate (Ukrainian) Currently translated at 91.6% (2448 of 2672 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/ --- vector/src/main/res/values-uk/strings.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 06906804df..c24e9c292e 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -991,7 +991,7 @@ Визначити рівень повноважень користувача Скинути рівень доступу користувача із вказаним ID Запросити користувача із вказаним ID до поточної кімнати - Приєднатися до кімнати із вказаним псевдонімом + Приєднує до кімнати із вказаною адресою Вийти з кімнати Встановити тему кімнати Копнути користувача із вказаним ID @@ -2860,4 +2860,14 @@ Не застосовуйте пароль облікового запису повторно. Введіть %s ще раз, щоб підтвердити. Захистіть та розблокуйте зашифровані повідомлення та перевіряйте довіреність за допомогою %s. + Політика + Перестає нехтувати користувача, показує їхні подальші повідомлення + Нехтує користувача, ховає їхні повідомлення від вас + Сховати політику ідентифікації сервера + Показати політику ідентифікації сервера + Показує відомості про користувача + Змінює ваш аватар лише у поточній кімнаті + Змінює аватар поточної кімнати + Змінює ваше показуване ім\'я лише у поточній кімнаті + Установлює назву кімнати \ No newline at end of file From ede8933059e327e10a92c2d48cdf04c86fc95ab2 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Mon, 25 Oct 2021 23:08:55 +0000 Subject: [PATCH 107/413] Translated using Weblate (Persian) Currently translated at 100.0% (2672 of 2672 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/ --- vector/src/main/res/values-fa/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index ea798cac52..c2b55bb06c 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -2260,7 +2260,7 @@ اخراج کاربر با شناسه داده شده تنظیم موضوع اتاق ترک اتاق - با نام مستعار داده‌شده به اتاق بپیوندید + به اتاق با نشانی داده شده می‌پیوندد کاربر با شناسه داده شده را به این اتاق دعوت می کند کاربر با شناسه داده شده را غیر‌فعال می‌کند سطح قدرت کاربر را تعریف می‌کند From 6cee266a959fa58c0ff55d312399cb7da85f4164 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 27 Oct 2021 13:10:01 +0300 Subject: [PATCH 108/413] Create poll UI implementation. --- .../features/createpoll/CreatePollAction.kt | 5 + .../createpoll/CreatePollController.kt | 100 ++++++++++++++++++ .../features/createpoll/CreatePollFragment.kt | 36 ++++++- .../createpoll/CreatePollViewModel.kt | 57 ++++++++++ .../createpoll/CreatePollViewState.kt | 3 +- .../form/FormEditTextWithDeleteItem.kt | 87 +++++++++++++++ .../main/res/layout/fragment_create_poll.xml | 18 ++++ .../item_form_text_input_with_delete.xml | 43 ++++++++ vector/src/main/res/values/strings.xml | 6 ++ 9 files changed, 353 insertions(+), 2 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/createpoll/CreatePollController.kt create mode 100644 vector/src/main/java/im/vector/app/features/form/FormEditTextWithDeleteItem.kt create mode 100644 vector/src/main/res/layout/item_form_text_input_with_delete.xml diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollAction.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollAction.kt index ad8da6e208..0812248487 100644 --- a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollAction.kt +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollAction.kt @@ -19,4 +19,9 @@ package im.vector.app.features.createpoll import im.vector.app.core.platform.VectorViewModelAction sealed class CreatePollAction : VectorViewModelAction { + data class OnQuestionChanged(val question: String) : CreatePollAction() + data class OnOptionChanged(val index: Int, val option: String) : CreatePollAction() + data class OnDeleteOption(val index: Int) : CreatePollAction() + object OnAddOption : CreatePollAction() + object OnCreatePoll : CreatePollAction() } diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollController.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollController.kt new file mode 100644 index 0000000000..cf4ec19581 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollController.kt @@ -0,0 +1,100 @@ +/* + * 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.features.createpoll + +import com.airbnb.epoxy.EpoxyController +import im.vector.app.R +import im.vector.app.core.resources.ColorProvider +import im.vector.app.core.resources.StringProvider +import im.vector.app.core.ui.list.ItemStyle +import im.vector.app.core.ui.list.genericButtonItem +import im.vector.app.core.ui.list.genericItem +import im.vector.app.features.form.formEditTextItem +import im.vector.app.features.form.formEditTextWithDeleteItem +import javax.inject.Inject + +class CreatePollController @Inject constructor( + private val stringProvider: StringProvider, + private val colorProvider: ColorProvider +) : EpoxyController() { + + private var state: CreatePollViewState? = null + var callback: Callback? = null + + fun setData(state: CreatePollViewState) { + this.state = state + requestModelBuild() + } + + override fun buildModels() { + val currentState = state ?: return + val host = this + + genericItem { + id("question_title") + style(ItemStyle.BIG_TEXT) + title(host.stringProvider.getString(R.string.create_poll_question_title)) + } + + formEditTextItem { + id("question") + value(currentState.question) + hint(host.stringProvider.getString(R.string.create_poll_question_hint)) + singleLine(false) + maxLength(500) + onTextChange { + host.callback?.onQuestionChanged(it) + } + } + + genericItem { + id("options_title") + style(ItemStyle.BIG_TEXT) + title(host.stringProvider.getString(R.string.create_poll_options_title)) + } + + currentState.options.forEachIndexed { index, option -> + formEditTextWithDeleteItem { + id("option_$index") + value(option) + hint(host.stringProvider.getString(R.string.create_poll_options_hint, (index + 1))) + onTextChange { + host.callback?.onOptionChanged(index, it) + } + onDeleteClicked { + host.callback?.onDeleteOption(index) + } + } + } + + genericButtonItem { + id("add_option") + text(host.stringProvider.getString(R.string.create_poll_add_option)) + textColor(host.colorProvider.getColor(R.color.palette_element_green)) + buttonClickAction { + host.callback?.onAddOption() + } + } + } + + interface Callback { + fun onQuestionChanged(question: String) + fun onOptionChanged(index: Int, option: String) + fun onDeleteOption(index: Int) + fun onAddOption() + } +} diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollFragment.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollFragment.kt index 706d58e489..ad366da62e 100644 --- a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollFragment.kt +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollFragment.kt @@ -20,11 +20,18 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import com.airbnb.mvrx.activityViewModel +import com.airbnb.mvrx.withState +import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentCreatePollBinding import javax.inject.Inject -class CreatePollFragment @Inject constructor() : VectorBaseFragment() { +class CreatePollFragment @Inject constructor( + private val controller: CreatePollController +) : VectorBaseFragment(), CreatePollController.Callback { + + private val viewModel: CreatePollViewModel by activityViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentCreatePollBinding { return FragmentCreatePollBinding.inflate(inflater, container, false) @@ -34,8 +41,35 @@ class CreatePollFragment @Inject constructor() : VectorBaseFragment handleOnCreatePoll() + CreatePollAction.OnAddOption -> handleOnAddOption() + is CreatePollAction.OnDeleteOption -> handleOnDeleteOption(action.index) + is CreatePollAction.OnOptionChanged -> handleOnOptionChanged(action.index, action.option) + is CreatePollAction.OnQuestionChanged -> handleOnQuestionChanged(action.question) + } + } + + private fun handleOnCreatePoll() = withState { state -> + Timber.d(state.toString()) + } + + private fun handleOnAddOption() { + setState { + val extendedOptions = options + "" + copy( + options = extendedOptions + ) + } + } + + private fun handleOnDeleteOption(index: Int) { + setState { + val filteredOptions = options.filterIndexed { ind, _ -> ind != index } + copy( + options = filteredOptions + ) + } + } + + private fun handleOnOptionChanged(index: Int, option: String) { + setState { + val changedOptions = options.mapIndexed { ind, s -> if(ind == index) option else s } + copy( + options = changedOptions + ) + } + } + + private fun handleOnQuestionChanged(question: String) { + setState { + copy( + question = question + ) + } } } diff --git a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewState.kt b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewState.kt index f53e7b2843..f9d46d5605 100644 --- a/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewState.kt +++ b/vector/src/main/java/im/vector/app/features/createpoll/CreatePollViewState.kt @@ -19,5 +19,6 @@ package im.vector.app.features.createpoll import com.airbnb.mvrx.MavericksState data class CreatePollViewState( - val question: String = "" + val question: String = "", + val options: List = emptyList() ) : MavericksState diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextWithDeleteItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextWithDeleteItem.kt new file mode 100644 index 0000000000..a4e378a5b9 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextWithDeleteItem.kt @@ -0,0 +1,87 @@ +/* + * 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.features.form + +import android.text.Editable +import android.widget.ImageButton +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.google.android.material.textfield.TextInputEditText +import com.google.android.material.textfield.TextInputLayout +import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.TextListener +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.epoxy.addTextChangedListenerOnce +import im.vector.app.core.epoxy.onClick +import im.vector.app.core.extensions.setTextIfDifferent +import im.vector.app.core.platform.SimpleTextWatcher + +@EpoxyModelClass(layout = R.layout.item_form_text_input_with_delete) +abstract class FormEditTextWithDeleteItem : VectorEpoxyModel() { + + @EpoxyAttribute + var hint: String? = null + + @EpoxyAttribute + var value: String? = null + + @EpoxyAttribute + var enabled: Boolean = true + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var onTextChange: TextListener? = null + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var onDeleteClicked: ClickListener? = null + + private val onTextChangeListener = object : SimpleTextWatcher() { + override fun afterTextChanged(s: Editable) { + onTextChange?.invoke(s.toString()) + } + } + + override fun bind(holder: Holder) { + super.bind(holder) + holder.textInputLayout.isEnabled = enabled + holder.textInputLayout.hint = hint + + holder.textInputEditText.setTextIfDifferent(value) + + holder.textInputEditText.isEnabled = enabled + + holder.textInputEditText.addTextChangedListenerOnce(onTextChangeListener) + + holder.textInputDeleteButton.onClick(onDeleteClicked) + } + + override fun shouldSaveViewState(): Boolean { + return false + } + + override fun unbind(holder: Holder) { + super.unbind(holder) + holder.textInputEditText.removeTextChangedListener(onTextChangeListener) + } + + class Holder : VectorEpoxyHolder() { + val textInputLayout by bind(R.id.formTextInputTextInputLayout) + val textInputEditText by bind(R.id.formTextInputTextInputEditText) + val textInputDeleteButton by bind(R.id.formTextInputDeleteButton) + } +} diff --git a/vector/src/main/res/layout/fragment_create_poll.xml b/vector/src/main/res/layout/fragment_create_poll.xml index 76c744c6c5..0616b76150 100644 --- a/vector/src/main/res/layout/fragment_create_poll.xml +++ b/vector/src/main/res/layout/fragment_create_poll.xml @@ -60,4 +60,22 @@ + + +