From 8d2f95d5db618426399593c77ffa38ffa3378efe Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 10 Sep 2021 14:27:39 +0200 Subject: [PATCH 001/970] Store device key in SharedSessionEntity Code review changes Fix database migraiton Fix wrong self assignement + comment --- .../algorithms/megolm/MXMegolmEncryption.kt | 10 ++++----- .../algorithms/megolm/SharedWithHelper.kt | 11 ++++++++-- .../internal/crypto/store/IMXCryptoStore.kt | 5 +++-- .../crypto/store/db/RealmCryptoStore.kt | 19 +++++++++++++--- .../store/db/RealmCryptoStoreMigration.kt | 20 ++++++++++++++++- .../store/db/model/SharedSessionEntity.kt | 1 + .../store/db/query/SharedSessionQueries.kt | 22 ++++++++++++++----- 7 files changed, 70 insertions(+), 18 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index a756444475..540280d8a2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -170,7 +170,7 @@ internal class MXMegolmEncryption( val deviceIds = devicesInRoom.getUserDeviceIds(userId) for (deviceId in deviceIds!!) { val deviceInfo = devicesInRoom.getObject(userId, deviceId) - if (deviceInfo != null && !cryptoStore.getSharedSessionInfo(roomId, safeSession.sessionId, userId, deviceId).found) { + if (deviceInfo != null && !cryptoStore.getSharedSessionInfo(roomId, safeSession.sessionId, deviceInfo).found) { val devices = shareMap.getOrPut(userId) { ArrayList() } devices.add(deviceInfo) } @@ -270,8 +270,8 @@ internal class MXMegolmEncryption( // for dead devices on every message. val gossipingEventBuffer = arrayListOf() for ((userId, devicesToShareWith) in devicesByUser) { - for ((deviceId) in devicesToShareWith) { - session.sharedWithHelper.markedSessionAsShared(userId, deviceId, chainIndex) + for (deviceInfo in devicesToShareWith) { + session.sharedWithHelper.markedSessionAsShared(deviceInfo, chainIndex) gossipingEventBuffer.add( Event( type = EventType.ROOM_KEY, @@ -279,7 +279,7 @@ internal class MXMegolmEncryption( content = submap.apply { this["session_key"] = "" // we add a fake key for trail - this["_dest"] = "$userId|$deviceId" + this["_dest"] = "$userId|${deviceInfo.deviceId}" } )) } @@ -429,7 +429,7 @@ internal class MXMegolmEncryption( .also { Timber.w("## Crypto reshareKey: Device not found") } // Get the chain index of the key we previously sent this device - val wasSessionSharedWithUser = cryptoStore.getSharedSessionInfo(roomId, sessionId, userId, deviceId) + val wasSessionSharedWithUser = cryptoStore.getSharedSessionInfo(roomId, sessionId, deviceInfo) if (!wasSessionSharedWithUser.found) { // This session was never shared with this user // Send a room key with held diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt index f17168a6d2..a64e5af0d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto.algorithms.megolm +import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore @@ -28,7 +29,13 @@ internal class SharedWithHelper( return cryptoStore.getSharedWithInfo(roomId, sessionId) } - fun markedSessionAsShared(userId: String, deviceId: String, chainIndex: Int) { - cryptoStore.markedSessionAsShared(roomId, sessionId, userId, deviceId, chainIndex) + fun markedSessionAsShared(deviceInfo: CryptoDeviceInfo, chainIndex: Int) { + cryptoStore.markedSessionAsShared( + roomId = roomId, + sessionId = sessionId, + userId = deviceInfo.userId, + deviceId = deviceInfo.deviceId, + deviceIdentityKey = deviceInfo.identityKey() ?: "", + chainIndex = chainIndex) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 3d12e74fcd..238d06738c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -450,7 +450,8 @@ internal interface IMXCryptoStore { fun addWithHeldMegolmSession(withHeldContent: RoomKeyWithHeldContent) fun getWithHeldMegolmSession(roomId: String, sessionId: String): RoomKeyWithHeldContent? - fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int) + fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String, + deviceIdentityKey: String, chainIndex: Int) /** * Query for information on this session sharing history. @@ -459,7 +460,7 @@ internal interface IMXCryptoStore { * in this case chainIndex is not nullindicates the ratchet position. * In found is false, chainIndex is null */ - fun getSharedSessionInfo(roomId: String?, sessionId: String, userId: String, deviceId: String): SharedSessionResult + fun getSharedSessionInfo(roomId: String?, sessionId: String, deviceInfo: CryptoDeviceInfo): SharedSessionResult data class SharedSessionResult(val found: Boolean, val chainIndex: Int?) fun getSharedWithInfo(roomId: String?, sessionId: String): MXUsersDevicesMap diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 3c8353e83e..860bba7404 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -1681,7 +1681,12 @@ internal class RealmCryptoStore @Inject constructor( } } - override fun markedSessionAsShared(roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int) { + override fun markedSessionAsShared(roomId: String?, + sessionId: String, + userId: String, + deviceId: String, + deviceIdentityKey: String, + chainIndex: Int) { doRealmTransaction(realmConfiguration) { realm -> SharedSessionEntity.create( realm = realm, @@ -1689,14 +1694,22 @@ internal class RealmCryptoStore @Inject constructor( sessionId = sessionId, userId = userId, deviceId = deviceId, + deviceIdentityKey = deviceIdentityKey, chainIndex = chainIndex ) } } - override fun getSharedSessionInfo(roomId: String?, sessionId: String, userId: String, deviceId: String): IMXCryptoStore.SharedSessionResult { + override fun getSharedSessionInfo(roomId: String?, sessionId: String, deviceInfo: CryptoDeviceInfo): IMXCryptoStore.SharedSessionResult { return doWithRealm(realmConfiguration) { realm -> - SharedSessionEntity.get(realm, roomId, sessionId, userId, deviceId)?.let { + SharedSessionEntity.get( + realm = realm, + roomId = roomId, + sessionId = sessionId, + userId = deviceInfo.userId, + deviceId = deviceInfo.deviceId, + deviceIdentityKey = deviceInfo.identityKey() + )?.let { IMXCryptoStore.SharedSessionResult(true, it.chainIndex) } ?: IMXCryptoStore.SharedSessionResult(false, null) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt index 2846be9932..f73cbaf480 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt @@ -55,7 +55,7 @@ internal object RealmCryptoStoreMigration : RealmMigration { // 0, 1, 2: legacy Riot-Android // 3: migrate to RiotX schema // 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6) - const val CRYPTO_STORE_SCHEMA_VERSION = 13L + const val CRYPTO_STORE_SCHEMA_VERSION = 14L private fun RealmObjectSchema.addFieldIfNotExists(fieldName: String, fieldType: Class<*>): RealmObjectSchema { if (!hasField(fieldName)) { @@ -94,6 +94,7 @@ internal object RealmCryptoStoreMigration : RealmMigration { if (oldVersion <= 10) migrateTo11(realm) if (oldVersion <= 11) migrateTo12(realm) if (oldVersion <= 12) migrateTo13(realm) + if (oldVersion <= 13) migrateTo14(realm) } private fun migrateTo1Legacy(realm: DynamicRealm) { @@ -554,4 +555,21 @@ internal object RealmCryptoStoreMigration : RealmMigration { Timber.e("TrustLevelEntity cleanup: Something is not correct...") } } + + // Version 14L Update the way we remember key sharing + private fun migrateTo14(realm: DynamicRealm) { + Timber.d("Step 13 -> 14") + realm.schema.get("SharedSessionEntity") + ?.addField(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, String::class.java) + ?.addIndex(SharedSessionEntityFields.DEVICE_IDENTITY_KEY) + ?.transform { + val sharedUserId = it.getString(SharedSessionEntityFields.USER_ID) + val sharedDeviceId = it.getString(SharedSessionEntityFields.DEVICE_ID) + val knownDevice = realm.where("DeviceInfoEntity") + .equalTo(DeviceInfoEntityFields.USER_ID, sharedUserId) + .equalTo(DeviceInfoEntityFields.DEVICE_ID, sharedDeviceId) + .findFirst() + it.setString(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, knownDevice?.getString(DeviceInfoEntityFields.IDENTITY_KEY)) + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt index c0ed1ac409..e2ae512afd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/SharedSessionEntity.kt @@ -30,6 +30,7 @@ internal open class SharedSessionEntity( @Index var sessionId: String? = null, @Index var userId: String? = null, @Index var deviceId: String? = null, + @Index var deviceIdentityKey: String? = null, var chainIndex: Int? = null ) : RealmObject() { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt index fa37734fe5..39117512bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt @@ -16,15 +16,20 @@ package org.matrix.android.sdk.internal.crypto.store.db.query -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity -import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields import io.realm.Realm import io.realm.RealmResults import io.realm.kotlin.createObject import io.realm.kotlin.where +import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity +import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields -internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, sessionId: String, userId: String, deviceId: String) +internal fun SharedSessionEntity.Companion.get(realm: Realm, + roomId: String?, + sessionId: String, + userId: String, + deviceId: String, + deviceIdentityKey: String?) : SharedSessionEntity? { return realm.where() .equalTo(SharedSessionEntityFields.ROOM_ID, roomId) @@ -32,6 +37,7 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, se .equalTo(SharedSessionEntityFields.ALGORITHM, MXCRYPTO_ALGORITHM_MEGOLM) .equalTo(SharedSessionEntityFields.USER_ID, userId) .equalTo(SharedSessionEntityFields.DEVICE_ID, deviceId) + .equalTo(SharedSessionEntityFields.DEVICE_IDENTITY_KEY, deviceIdentityKey) .findFirst() } @@ -44,7 +50,12 @@ internal fun SharedSessionEntity.Companion.get(realm: Realm, roomId: String?, se .findAll() } -internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?, sessionId: String, userId: String, deviceId: String, chainIndex: Int) +internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?, + sessionId: String, + userId: String, + deviceId: String, + deviceIdentityKey: String, + chainIndex: Int) : SharedSessionEntity { return realm.createObject().apply { this.roomId = roomId @@ -52,6 +63,7 @@ internal fun SharedSessionEntity.Companion.create(realm: Realm, roomId: String?, this.sessionId = sessionId this.userId = userId this.deviceId = deviceId + this.deviceIdentityKey = deviceIdentityKey this.chainIndex = chainIndex } } From cccf812906268324eecff0af0be5420083eab58c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 13 Sep 2021 15:25:56 +0200 Subject: [PATCH 002/970] Version++ (1.2.2) --- vector/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/build.gradle b/vector/build.gradle index 9d3cc7ec3c..9576ba86c0 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 = 2 -ext.versionPatch = 1 +ext.versionPatch = 2 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From cbcb620ad1d5a449949ad430bb63ee643d0959d8 Mon Sep 17 00:00:00 2001 From: yostyle Date: Thu, 7 Oct 2021 11:36:29 +0200 Subject: [PATCH 003/970] 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 256cb7093dfe3b3dacb18604a278ee26140eefdc Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 12 Oct 2021 16:37:40 +0100 Subject: [PATCH 004/970] catching ensureOlmSessionsForDevicesAction errors during the event decryption flow - we currently can't do much but log here as we've asynchronously start the fallback flow, catching the error at least stops a hard crash --- .../sdk/internal/crypto/EventDecryptor.kt | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt index 70081ebdd7..b1680d5153 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt @@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.internal.crypto.model.MXOlmSessionResult import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore @@ -36,7 +37,6 @@ import org.matrix.android.sdk.internal.extensions.foldToCallback import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber import javax.inject.Inject -import kotlin.jvm.Throws @SessionScope internal class EventDecryptor @Inject constructor( @@ -146,29 +146,36 @@ internal class EventDecryptor @Inject constructor( // offload this from crypto thread (?) cryptoCoroutineScope.launch(coroutineDispatchers.computation) { - val ensured = ensureOlmSessionsForDevicesAction.handle(mapOf(senderId to listOf(deviceInfo)), force = true) + runCatching { ensureOlmSessionsForDevicesAction.handle(mapOf(senderId to listOf(deviceInfo)), force = true) }.fold( + onSuccess = { sendDummyToDevice(ensured = it, deviceInfo, senderId) }, + onFailure = { + Timber.e("## CRYPTO | markOlmSessionForUnwedging() : failed to ensure device info ${senderId}${deviceInfo.deviceId}") + } + ) + } + } - Timber.i("## CRYPTO | markOlmSessionForUnwedging() : ensureOlmSessionsForDevicesAction isEmpty:${ensured.isEmpty}") + private suspend fun sendDummyToDevice(ensured: MXUsersDevicesMap, deviceInfo: CryptoDeviceInfo, senderId: String) { + Timber.i("## CRYPTO | markOlmSessionForUnwedging() : ensureOlmSessionsForDevicesAction isEmpty:${ensured.isEmpty}") - // Now send a blank message on that session so the other side knows about it. - // (The keyshare request is sent in the clear so that won't do) - // We send this first such that, as long as the toDevice messages arrive in the - // same order we sent them, the other end will get this first, set up the new session, - // then get the keyshare request and send the key over this new session (because it - // is the session it has most recently received a message on). - val payloadJson = mapOf("type" to EventType.DUMMY) + // Now send a blank message on that session so the other side knows about it. + // (The keyshare request is sent in the clear so that won't do) + // We send this first such that, as long as the toDevice messages arrive in the + // same order we sent them, the other end will get this first, set up the new session, + // then get the keyshare request and send the key over this new session (because it + // is the session it has most recently received a message on). + val payloadJson = mapOf("type" to EventType.DUMMY) - val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo)) - val sendToDeviceMap = MXUsersDevicesMap() - sendToDeviceMap.setObject(senderId, deviceInfo.deviceId, encodedPayload) - Timber.i("## CRYPTO | markOlmSessionForUnwedging() : sending dummy to $senderId:${deviceInfo.deviceId}") - withContext(coroutineDispatchers.io) { - val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap) - try { - sendToDeviceTask.execute(sendToDeviceParams) - } catch (failure: Throwable) { - Timber.e(failure, "## CRYPTO | markOlmSessionForUnwedging() : failed to send dummy to $senderId:${deviceInfo.deviceId}") - } + val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo)) + val sendToDeviceMap = MXUsersDevicesMap() + sendToDeviceMap.setObject(senderId, deviceInfo.deviceId, encodedPayload) + Timber.i("## CRYPTO | markOlmSessionForUnwedging() : sending dummy to $senderId:${deviceInfo.deviceId}") + withContext(coroutineDispatchers.io) { + val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap) + try { + sendToDeviceTask.execute(sendToDeviceParams) + } catch (failure: Throwable) { + Timber.e(failure, "## CRYPTO | markOlmSessionForUnwedging() : failed to send dummy to $senderId:${deviceInfo.deviceId}") } } } From db4c4520ea07fe8b72dc46ff8beb397a53d49ee7 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 12 Oct 2021 17:37:11 +0100 Subject: [PATCH 005/970] adding changelog entry --- changelog.d/3608.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/3608.bugfix diff --git a/changelog.d/3608.bugfix b/changelog.d/3608.bugfix new file mode 100644 index 0000000000..5f219ab319 --- /dev/null +++ b/changelog.d/3608.bugfix @@ -0,0 +1 @@ +Catching event decryption crash and logging when attempting to markOlmSessionForUnwedging fails \ No newline at end of file From ff53cf4db996696d7cd2085aa75b90c599add796 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 14 Oct 2021 18:47:28 +0200 Subject: [PATCH 006/970] 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 007/970] 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 008/970] 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 009/970] 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 010/970] 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 011/970] 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 bdbe1dd6064d77d8dcb7911a3405432415f1d313 Mon Sep 17 00:00:00 2001 From: Zet Date: Sun, 17 Oct 2021 16:03:19 +0000 Subject: [PATCH 012/970] Translated using Weblate (Arabic) Currently translated at 38.9% (1040 of 2672 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ar/ --- vector/src/main/res/values-ar/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vector/src/main/res/values-ar/strings.xml b/vector/src/main/res/values-ar/strings.xml index a37fad08d2..8483f4d026 100644 --- a/vector/src/main/res/values-ar/strings.xml +++ b/vector/src/main/res/values-ar/strings.xml @@ -1325,4 +1325,9 @@ تصاريح ناقصة لإرسال رسائل صوتية امنح تصريح الوصول للميكريفون. لإكمال هذا الإجراء امنح تصريح الوصول للكميرا عبر إعدادات النظام. + ينشئ نسخة احتياطية + عيّن عبارة مرور + أمّن النسخ الاختياطي بعبارة مرور. + تصدير المفاتيح يدويًا + (متقدم) \ No newline at end of file From 84253586349bfc5f1e54c0fef69e8ac281e74b7e Mon Sep 17 00:00:00 2001 From: zeritti Date: Sun, 17 Oct 2021 08:49:30 +0000 Subject: [PATCH 013/970] Translated using Weblate (Czech) 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/cs/ --- vector/src/main/res/values-cs/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index 40ded266ab..c6b57e47ff 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -3058,4 +3058,7 @@ Nastaví název místnosti Přestane ignorovat uživatele a zobrazí jeho zprávy Ignoruje uživatele a skrývá jeho zprávy + Nedostupný + Offline + Online \ No newline at end of file From ee301bc35571c43ea64e1a6d6b13241f559108c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sat, 16 Oct 2021 16:34:37 +0000 Subject: [PATCH 014/970] Translated using Weblate (Estonian) 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/et/ --- vector/src/main/res/values-et/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index 22e967b783..27c332b605 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -3002,4 +3002,7 @@ Määrab jututoa nime Lõpeta kasutaja eiramine ja näita edaspidi tema sõnumeid Eirab kasutajat peites kõik tema sõnumid sinu eest + Pole leitav + Võrgust väljas + Võrgus \ No newline at end of file From 0c80f6b8a5872accf5d0e22cb1ef7604d7857beb Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Sat, 16 Oct 2021 11:03:07 +0000 Subject: [PATCH 015/970] 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 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index 01d8185700..ea798cac52 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -3002,4 +3002,7 @@ نام اتاق را تنظیم می‌کند به کاربری چشم گشوده و پیام‌های بعدیش را نشان می‌دهد از کاربری چشم‌پوشی کرده و پیام‌هایش را از شما پنهان می‌کند + ناموجود + برون‌خط + برخط \ No newline at end of file From ab5b907b7d95ebb4477fa9a97a67ea6e72323156 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 16 Oct 2021 09:40:29 +0000 Subject: [PATCH 016/970] Translated using Weblate (Hungarian) 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/hu/ --- vector/src/main/res/values-hu/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 64b9f8fee4..1926a40115 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -3007,4 +3007,7 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró Szobanév beállítása A felhasználó újbóli figyelembe vétele, és az üzenetei megjelenítése a jövőben Figyelmen kívül hagy egy felhasználót, elrejtve előled az üzeneteit + Elérhetetlen + Kapcsolat nélkül + Kapcsolódva \ No newline at end of file From 1787a8a3587ab404b4ed21de72b9b30ef4e57c65 Mon Sep 17 00:00:00 2001 From: Linerly Date: Sat, 16 Oct 2021 12:12:08 +0000 Subject: [PATCH 017/970] Translated using Weblate (Indonesian) 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/id/ --- vector/src/main/res/values-in/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 6dbb2a764c..ab86b35e6c 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -2950,4 +2950,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mengubah avatar ruangan saat ini Mengubah avatar Anda di ruangan saat ini saja Menampilkan + Tidak Tersedia + Offline + Online \ No newline at end of file From e425532953876d5f26c20349b9f34a298c17de0a Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Sat, 16 Oct 2021 12:22:47 +0000 Subject: [PATCH 018/970] Translated using Weblate (Portuguese (Brazil)) 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/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index 7e4d837573..ff824445eb 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -3072,4 +3072,7 @@ Define o nome da sala Para de ignorar um/uma usuário(a), mostrando as mensagens dele/dela de agora em diante Ignora um/uma usuário(a), escondendo as mensagens dele/dela de você + Indisponível + Offline + Online \ No newline at end of file From 9b1b35084cc6d59c9b73575a3e08a49407235030 Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Sat, 16 Oct 2021 10:23:18 +0000 Subject: [PATCH 019/970] Translated using Weblate (Russian) 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/ru/ --- vector/src/main/res/values-ru/strings.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index b96f77a040..bfc82d9a95 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -312,7 +312,7 @@ Просмотр расшифрованного исходного кода Удалить Переименовать - Содержание отчёта + Пожаловаться на содержимое Активный вызов Ongoing conference call. \nПрисоединиться как %1$s или %2$s @@ -3150,7 +3150,7 @@ Остановить запись Добавляет ( ͡° ͜ʖ ͡°) к текстовому сообщению Правила - Отсутствие политики, предоставляемой сервером идентификации + Нет правил, предоставляемых сервером идентификации Скрыть правила сервера идентификации Показать правила сервера идентификации Отображает информацию о пользователе @@ -3160,4 +3160,7 @@ Устанавливает имя комнаты Прекращение игнорирования пользователя, показывает его сообщения в дальнейшем Игнорирует пользователя, скрывая его сообщения от вас + Недоступен + Не в сети + В сети \ No newline at end of file From 41167cdc23457df48e70f4e7d6a8a2d61096a5d4 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Sat, 16 Oct 2021 09:39:49 +0000 Subject: [PATCH 020/970] Translated using Weblate (Albanian) Currently translated at 99.3% (2655 of 2672 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- vector/src/main/res/values-sq/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 1426a0ea85..379cd4b1f1 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -2991,4 +2991,6 @@ Cakton emrin e dhomës E ndal shpërfilljen e një përdoruesi, duke i shfaqur mesazhet e tyre pas kësaj Shpërfill një përdorues, duke fshehur mesazhet e tij prej jush + Jo në linjë + Në linjë \ No newline at end of file From b83a96e1c149d3e9b5a99def0c83fd63658aefc7 Mon Sep 17 00:00:00 2001 From: joshua Date: Sun, 17 Oct 2021 10:15:52 +0000 Subject: [PATCH 021/970] Translated using Weblate (Swedish) 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/sv/ --- vector/src/main/res/values-sv/strings.xml | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index a3dec653a1..8a9e4974ce 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -747,7 +747,7 @@ Byt nätverk Alla gemenskaper Allmänt - Alternativ + Inställningar Namn eller ID (#example:matrix.org) Du kommer inte att verifiera %1$s (%2$s) om du avbryter nu. Börja igen i hens användarprofil. Meddelanden i det här rummet är totalsträckskrypterade. Lär dig mer och verifiera användare i deras profiler. @@ -2778,8 +2778,8 @@ Känner du dig äventyrlig\? \nDu kan lägga till existerande utrymmen till ett utrymme. Lägg till rum - Du är administratör för det här utrymmet, se till att du har överfört administratörsrättigheter till en annan medlem innan du lämnar. - Det här utrymmet är inte offentligt. Du kommer inte att kunna gå med igen utan en inbjudan. + Du är den enda administratören av detta utrymme. Att lämna det betyder att ingen har kontroll över det. + Du kommer inte att kunna gå med igen om du inte är inbjuden igen. Du är den enda personen här. Om du lämnar så kommer ingen kunna gå med i framtiden, inklusive du. Bjud in till %s Den här funktionen är i beta @@ -2821,13 +2821,13 @@ Tryck på din inspelning för att stoppa eller lyssna %1$d lämnade Håll in för att spela in, släpp för att skicka - Radera inspelat röstmeddelande + Ta bort inspelningen Spelar in röstmeddelande Pausa röstmeddelande Spela röstmeddelande Röstmeddelandelås Svep för att avbryta - Starta röstmeddelande + Börja röstmeddelande Tyvärr så inträffade ett fel vid försök att gå med i: %s Uppgradera till rekommenderad rumsversion Det är rummet kör rumsversion %s, vilken den hör hemservern har markerat som instabil. @@ -2985,4 +2985,17 @@ Se och uppdatera rollerna som krävs för att ändra diverse delar av utrymmet. Vilka är dina lagkamrater\? Lägg till till det angivna utrymmet + Sluta spela in + Lägg till ett mellanslag till alla utrymmen du hanterar. + Lägg till befintliga utrymmen + Lägg till befintliga rum + Välj saker att lämna + Lämna specifika rum och utrymmen… + Lämna inga rum och utrymmen + Du kommer att lämna alla rum och utrymmen i %s. + Lämna alla rum och utrymmen + Är du säker på att du vill lämna %s\? + Discovery (%s) + Slutför konfigurationen + Se till att rätt personer har tillgång till %s företag. Du kan bjuda in mer senare. \ No newline at end of file From 68591f3ddde015a9ee689cbbd21a06111d883fc9 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sun, 17 Oct 2021 09:11:01 +0000 Subject: [PATCH 022/970] Translated using Weblate (Swedish) 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/sv/ --- vector/src/main/res/values-sv/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 8a9e4974ce..f8ac8eba58 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -2998,4 +2998,11 @@ Discovery (%s) Slutför konfigurationen Se till att rätt personer har tillgång till %s företag. Du kan bjuda in mer senare. + Bjud in med e-post, hitta kontakter och mer… + Slutför inställning av upptäckbarhet. + Du använder för närvarande ingen identitetsserver. För att bjuda in teammedlemmar och kunna upptäckas av dem, konfigurera en nedan. + Bjud in med användarnamn eller e-postadress + Otillgänglig + Offline + Online \ No newline at end of file From be874d99274adcfb78c8889ff7f5c7ff0d577e1b Mon Sep 17 00:00:00 2001 From: sr093906 Date: Sun, 17 Oct 2021 01:01:10 +0000 Subject: [PATCH 023/970] Translated using Weblate (Chinese (Simplified)) 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/zh_Hans/ --- vector/src/main/res/values-zh-rCN/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index 92a5c757e3..28d2c8e250 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -2956,4 +2956,7 @@ 设置聊天室名称 停止忽略用户,继续显示他们的消息 忽略用户,隐藏他们的消息 + 不可用 + 离线 + 在线 \ No newline at end of file From 964937db98b7e8c3b0f3f4dbe28d650c772a90f6 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Sat, 16 Oct 2021 09:39:55 +0000 Subject: [PATCH 024/970] Translated using Weblate (Hungarian) Currently translated at 100.0% (34 of 34 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/40103030.txt | 2 ++ fastlane/metadata/android/hu-HU/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/hu-HU/changelogs/40103030.txt diff --git a/fastlane/metadata/android/hu-HU/changelogs/40103030.txt b/fastlane/metadata/android/hu-HU/changelogs/40103030.txt new file mode 100644 index 0000000000..8795818607 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: Azonosítási szerver feltételek megjelenítése a beállításoknál. Ideiglenesen az Android Auto támogatás eltávolítása. +Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/hu-HU/full_description.txt b/fastlane/metadata/android/hu-HU/full_description.txt index 032346ccb8..899b4cd978 100644 --- a/fastlane/metadata/android/hu-HU/full_description.txt +++ b/fastlane/metadata/android/hu-HU/full_description.txt @@ -38,3 +38,6 @@ Igazi végpontok között titkosítás (csak a beszélgetésben résztvevők tud Vedd fel a fonalat Maradj kapcsolatban bárhol minden eszközödön a szinkronizált üzenetekkel és a weben a https://app.element.io oldallal + +Nyílt forráskód +Element Android egy nyílt forráskódú projekt a GitHubon. Küldj hibajegyet és/vagy vegyél részt a fejlesztésében itt: https://github.com/vector-im/element-android From 99bb0f994fbd9765e634c35127080c2215054776 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Sat, 16 Oct 2021 12:26:13 +0000 Subject: [PATCH 025/970] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (34 of 34 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/pt_BR/ --- .../metadata/android/pt-BR/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/pt-BR/full_description.txt | 11 +++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 fastlane/metadata/android/pt-BR/changelogs/40103030.txt diff --git a/fastlane/metadata/android/pt-BR/changelogs/40103030.txt b/fastlane/metadata/android/pt-BR/changelogs/40103030.txt new file mode 100644 index 0000000000..12ababb2ce --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Fazer política(s) de servidor de identidade visível(is) nas configurações. Remover temporariamente suporte a Android Auto. +Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/pt-BR/full_description.txt b/fastlane/metadata/android/pt-BR/full_description.txt index 7bb3d0981d..fe560cdda0 100644 --- a/fastlane/metadata/android/pt-BR/full_description.txt +++ b/fastlane/metadata/android/pt-BR/full_description.txt @@ -1,4 +1,4 @@ -Element é tanto um mensageiro seguro como um app de colaboração de time de produtividade que é ideal para chats de grupo enquanto se trabalha remotamente. Este app de chat usa encriptação ponta-a-ponta para prover conferência de vídeo, compartilhamento de arquivo e chamadas de voz poderasos. +Element é tanto um mensageiro seguro como um app de colaboração de time de produtividade que é ideal para chats de grupo enquanto se trabalha remotamente. Este app de chat usa encriptação ponta-a-ponta para prover conferência de vídeo, compartilhamento de arquivo e chamadas de voz poderosos. As funções de Element incluem: - Ferramentas de comunicação online avançadas @@ -22,9 +22,9 @@ Para permitir mais controle de seus dados e conversas sensíveis, Element pode s Você decide onde manter seus dados e mensagens. Sem o risco de data mining ou acesso de terceiros. Element põe você em controle de diferentes maneiras: -1. Pegar uma conta grátis no servidor público matrix.org hospedado pelos desenvolvedores Matrix, ou escolha de milhares de servidores públicos hospedados por pessoas se voluntariando -2. Auto-hospedar sua conta ao rodar um servidor em sua própria infraestrutura de TI -3. Fazer signup para uma conta num servidor personalizado ao simplesmente assinar a plataforma de hospedagem Element Matrix Services +1. Pegue uma conta grátis no servidor público matrix.org hospedado pelos desenvolvedores Matrix, ou escolha de milhares de servidores públicos hospedados por pessoas se voluntariando +2. Auto-hospede sua conta ao rodar um servidor em sua própria infraestrutura de TI +3. Faça signup para uma conta num servidor personalizado ao simplesmente assinar a plataforma de hospedagem Element Matrix Services Mensageria e colaboração abertos Você pode fazer chat com qualquer pessoa na rede Matrix, caso ela esteja usando Element, um outro app de Matrix ou mesmo se ela estiver usando um app de mensageria diferente. @@ -37,3 +37,6 @@ Messageria, chamadas de voz e vídeo, compartilhamento de arquivo, compartilhame Continue de onde você parou Fique em contato onde quer que você esteja com histórico de mensagem completamente sincronizado por todos os seus dispositivos e na web em https://app.element.io + +Open source +Element Android é um projeto open source, hospedado por GitHub. Por favor reporte bugs e/ou contribua para seu desenvolvimento em https://github.com/vector-im/element-android From 28ccfbdc0d112256449c2ae398b8b2474a36c197 Mon Sep 17 00:00:00 2001 From: Nikita Epifanov Date: Sat, 16 Oct 2021 10:25:45 +0000 Subject: [PATCH 026/970] Translated using Weblate (Russian) Currently translated at 100.0% (34 of 34 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/ru/ --- fastlane/metadata/android/ru-RU/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/ru-RU/full_description.txt | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 fastlane/metadata/android/ru-RU/changelogs/40103030.txt diff --git a/fastlane/metadata/android/ru-RU/changelogs/40103030.txt b/fastlane/metadata/android/ru-RU/changelogs/40103030.txt new file mode 100644 index 0000000000..94b43e5f30 --- /dev/null +++ b/fastlane/metadata/android/ru-RU/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Основные изменения в этой версии: Правила сервера идентификации теперь видимы в настройках. Временно убрана поддержка Android Auto. +Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/ru-RU/full_description.txt b/fastlane/metadata/android/ru-RU/full_description.txt index 3d21b20a90..3d8949e466 100644 --- a/fastlane/metadata/android/ru-RU/full_description.txt +++ b/fastlane/metadata/android/ru-RU/full_description.txt @@ -37,3 +37,7 @@ Element дает вам возможность контролировать си Восстанавливайте связь с того места, где остановились. Оставайтесь на связи, где бы вы ни находились, с полностью синхронизированной историей сообщений на всех ваших устройствах и в Интернете по адресу https://app.element.io + + +Открытый исходный код +Element Android - это проект с открытым исходным кодом, размещенный на GitHub. Пожалуйста, сообщайте об ошибках и/или вносите вклад в его развитие по адресу https://github.com/vector-im/element-android. From 5a8298194401b40897d7ad03d89b4250ee9f4ae2 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Sat, 16 Oct 2021 18:15:55 +0000 Subject: [PATCH 027/970] Translated using Weblate (Swedish) Currently translated at 100.0% (34 of 34 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/40103030.txt | 2 ++ fastlane/metadata/android/sv-SE/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/sv-SE/changelogs/40103030.txt diff --git a/fastlane/metadata/android/sv-SE/changelogs/40103030.txt b/fastlane/metadata/android/sv-SE/changelogs/40103030.txt new file mode 100644 index 0000000000..3d55703e86 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Gör identitetsserverpolicy(er) synliga i inställningarna. Ta tillfälligt bort stöd för Android Auto. +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/sv-SE/full_description.txt b/fastlane/metadata/android/sv-SE/full_description.txt index 5302976ed7..03d837626e 100644 --- a/fastlane/metadata/android/sv-SE/full_description.txt +++ b/fastlane/metadata/android/sv-SE/full_description.txt @@ -37,3 +37,6 @@ Meddelanden, röst- och videosamtal, fildelning, skärmdelning och massa integra Fortsätt där du lämnade Håll kontakten vart du än är med fullt synkroniserad meddelandehistorik på alla dina enheter och på webben på https://app.element.io + +Öppen källkod +Element Android är projekt baserat på öppen källkod, som ligger på GitHub. Vänligen rapportera buggar och/eller bidra till dess utveckling på https://github.com/vector-im/element-android From f8850f5eb8de6d5c8d4d7f5ad2c12ba3c170578d Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Sat, 16 Oct 2021 23:40:20 +0000 Subject: [PATCH 028/970] Translated using Weblate (Ukrainian) Currently translated at 100.0% (34 of 34 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/uk/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40103030.txt diff --git a/fastlane/metadata/android/uk/changelogs/40103030.txt b/fastlane/metadata/android/uk/changelogs/40103030.txt new file mode 100644 index 0000000000..af25d23c42 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: додано політику ідентифікації сервера (IES) у налаштуваннях. Тимчасово вилучено автозаповнення Android. +Усі зміни: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/uk/full_description.txt b/fastlane/metadata/android/uk/full_description.txt index 285f577452..3c59d860ac 100644 --- a/fastlane/metadata/android/uk/full_description.txt +++ b/fastlane/metadata/android/uk/full_description.txt @@ -37,3 +37,6 @@ Element надає такі можливості на вибір: Продовжуйте, де зупинилися Залишайтеся на зв'язку, де б ви не знаходились, з повністю синхронізованою історією повідомлень на всіх своїх пристроях та в Інтернеті за адресою https://app.element.io + +Відкритий код +Element для Android це проєкт з відкритим кодом, розміщений GitHub. Будь ласка, повідомте про помилки та/або сприяйте його розвитку на https://github.com/vector-im/element-android From 022452cd45ec7aecd00c9884069131590f9b733c Mon Sep 17 00:00:00 2001 From: sr093906 Date: Sun, 17 Oct 2021 00:58:08 +0000 Subject: [PATCH 029/970] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (34 of 34 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/40103030.txt | 2 ++ fastlane/metadata/android/zh-CN/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/zh-CN/changelogs/40103030.txt diff --git a/fastlane/metadata/android/zh-CN/changelogs/40103030.txt b/fastlane/metadata/android/zh-CN/changelogs/40103030.txt new file mode 100644 index 0000000000..1f6ff391e1 --- /dev/null +++ b/fastlane/metadata/android/zh-CN/changelogs/40103030.txt @@ -0,0 +1,2 @@ +此版本中的主要更改:使身份服务器策略在设置中可见。 暂时移除 Android Auto 支持。 +完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt index fa6b00f1e4..3dae8deb67 100644 --- a/fastlane/metadata/android/zh-CN/full_description.txt +++ b/fastlane/metadata/android/zh-CN/full_description.txt @@ -37,3 +37,6 @@ Element 透过不同的方式让你掌控一切: 从上次离开的地方开始 无论你身在何处,都可以透过在你所有设备与网页 https://app.element.io 间完全同步的信息历史保持联络 + +开源 + Element Android 是一个开源项目,由 GitHub 托管。 请在 https://github.com/vector-im/element-android 报告错误和/或为其开发做出贡献 From 4a1f1a9fa541be475ec2b8fb635b691e596acb2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sat, 16 Oct 2021 16:33:46 +0000 Subject: [PATCH 030/970] Translated using Weblate (Estonian) Currently translated at 100.0% (34 of 34 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/et/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40103030.txt diff --git a/fastlane/metadata/android/et/changelogs/40103030.txt b/fastlane/metadata/android/et/changelogs/40103030.txt new file mode 100644 index 0000000000..6293ccab85 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: Isikutuvastusserveri kasutustingimused on leitavad seadistustest ja ajutiselt eemaldasime Android Auto toe. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/et/full_description.txt b/fastlane/metadata/android/et/full_description.txt index ee0adef9ac..a3a3bc37e2 100644 --- a/fastlane/metadata/android/et/full_description.txt +++ b/fastlane/metadata/android/et/full_description.txt @@ -37,3 +37,6 @@ Sõnumid, hääl- ja videokõned, failide jagamine, ekraani jagamine ja terve hu Jätka sealt, kus pooleli jäid Saad suhelda kõigis oma seadmetes ja ka veebis aadressil https://app.element.io ning sealjuures täielikult sünkroonitud sõnumite ajalooga. + +Avatud lähtekoodiga tarkvara +Element Android on Github'is hallatud avatud lähtekoodiga tarkvaraprojekt. Palun teata vigadest ja/või osale arenduses https://github.com/vector-im/element-android lehel From 87bd145e8e8e117d722b2f29de37d3ea64760769 Mon Sep 17 00:00:00 2001 From: Danial Behzadi Date: Sat, 16 Oct 2021 11:07:06 +0000 Subject: [PATCH 031/970] Translated using Weblate (Persian) Currently translated at 100.0% (34 of 34 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/ --- fastlane/metadata/android/fa/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/fa/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/fa/changelogs/40103030.txt diff --git a/fastlane/metadata/android/fa/changelogs/40103030.txt b/fastlane/metadata/android/fa/changelogs/40103030.txt new file mode 100644 index 0000000000..49efae1951 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40103030.txt @@ -0,0 +1,2 @@ +تغییرات اصلی در این نگارش: نمایان کردن سیاست(های) کارساز هویت در تنظیمات. برداشتن موقّتی پشتیبانی اندروید خودرو. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/fa/full_description.txt b/fastlane/metadata/android/fa/full_description.txt index cd2d4eb4c1..98055857bb 100644 --- a/fastlane/metadata/android/fa/full_description.txt +++ b/fastlane/metadata/android/fa/full_description.txt @@ -37,3 +37,6 @@ ادامه از جایی که رها کرده‌اید هر کجا که هستید، با هم‌گام سازی کامل تاریخچهٔ پیام‌ها بین همهٔ افزاره‌هایتان و وب روی https://app.element.io در دسترس باشید + +نرم‌افزار آزاد +المنت اندروید، یک پروژهٔ نرم‌افزار آزاد میزبانی‌شده روی گیت‌هاب است. لطفاً گزارش مشکلات و مشارکت‌ها را به توسه‌اش به این نشانی بفرستید: https://github.com/vector-im/element-android From 6cb254e74345487682ae89a312e7aa7be296f14e Mon Sep 17 00:00:00 2001 From: Linerly Date: Sat, 16 Oct 2021 12:54:47 +0000 Subject: [PATCH 032/970] Translated using Weblate (Indonesian) Currently translated at 100.0% (34 of 34 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/id/ --- fastlane/metadata/android/id/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/id/full_description.txt | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/id/changelogs/40103030.txt diff --git a/fastlane/metadata/android/id/changelogs/40103030.txt b/fastlane/metadata/android/id/changelogs/40103030.txt new file mode 100644 index 0000000000..630593a107 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Membuat kebijakan server identitas terlihat di pengaturan. Menghilangkan dukungan Android Auto untuk sementara. +Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/id/full_description.txt b/fastlane/metadata/android/id/full_description.txt index bd357bb161..dfa9c8c826 100644 --- a/fastlane/metadata/android/id/full_description.txt +++ b/fastlane/metadata/android/id/full_description.txt @@ -30,10 +30,13 @@ Element menempatkan Anda dalam kendali dengan cara yang berbeda: Anda dapat mengobrol dengan siapa saja di jaringan Matrix, apakah mereka menggunakan Element, aplikasi Matrix lain atau bahkan jika mereka menggunakan aplikasi perpesanan yang berbeda. Sangat aman -Enkripsi ujung-ke-ujung beneran (hanya mereka yang dalam percakapan dapat mendekripsi pesan), dan verifikasi perangkat yang ditanda tangani silang. +Enkripsi ujung-ke-ujung yang nyata (hanya mereka yang dalam percakapan dapat mendekripsi pesan), dan verifikasi perangkat menggunakan penandatanganan-silang. Komunikasi dan integrasi lengkap Perpesanan, panggilan suara dan video, berbagi file, berbagi layar dan banyak integrasi, bot dan widget. Buat ruangan, komunitas, tetap terhubung dan selesaikan hal-hal. Ambil di mana Anda tinggalkan Tetap terhubung di mana pun Anda berada dengan riwayat pesan yang sepenuhnya disinkronkan di semua perangkat Anda dan di web di https://app.element.io + +Open source +Element Android adalah proyek sumber terbuka, di-host oleh GitHub. Silakan melaporkan bug dan/atau membuat kontribusi ke pengembangannya di https://github.com/vector-im/element-android From 1c119c2c5d64746d77f340e37acfc04435ca64de Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Sat, 16 Oct 2021 09:38:41 +0000 Subject: [PATCH 033/970] Translated using Weblate (Albanian) Currently translated at 100.0% (34 of 34 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/ --- fastlane/metadata/android/sq/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/sq/full_description.txt | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/sq/changelogs/40103030.txt diff --git a/fastlane/metadata/android/sq/changelogs/40103030.txt b/fastlane/metadata/android/sq/changelogs/40103030.txt new file mode 100644 index 0000000000..e52e91eed4 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Bërje të dukshëm e rregullit(ave) të shërbyesit të identiteteve te rregullimet. Heqje përkohësisht e mbulimit për Android Auto. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/sq/full_description.txt b/fastlane/metadata/android/sq/full_description.txt index 96cf102272..ff0ea20da7 100644 --- a/fastlane/metadata/android/sq/full_description.txt +++ b/fastlane/metadata/android/sq/full_description.txt @@ -1,4 +1,4 @@ -Element-i është si aplikacion shkëmbyes i sigurt mesazhesh, ashtu edhe bashkëpunimi prodhimtar ekipi, i cili është ideal për fjalosje në grup, teksa punohet së largët. Ky aplikacion fjalosjeje përdor fshehtëzim skaj-më-skaj për të furnizuar konferencë video, shkëmbim kartelash dhe thirrje me zë të fuqishme. +Element-i është si aplikacion shkëmbyes i sigurt mesazhesh, ashtu edhe bashkëpunimi prodhimtar ekipi, i cili është ideal për fjalosje në grup, teksa punohet së largëti. Ky aplikacion fjalosjeje përdor fshehtëzim skaj-më-skaj për të furnizuar konferencë video, shkëmbim kartelash dhe thirrje me zë të fuqishme. Në veçoritë e Element-it përfshihen: - Mjete të thelluara komunikimi internetor @@ -8,7 +8,7 @@ Element-i është si aplikacion shkëmbyes i sigurt mesazhesh, ashtu edhe bashk - Fjalosje video të llojit VoIP dhe tregim ekrani - Integrim i kollajtë me mjetet tuaja të parapëlqyera të bashkëpunimit internetor, mjete administrimi projektesh, shërbime VoIP dhe aplikacione të tjera shkëmbimi mesazhesh në ekip -Element-i është plotësisht i ndryshëm nga aplikacione të tjera shkëmbimi mesazhesh dhe bashkëpunimi. Funksionimi i tij bazohet në Matrix, një rrjet i hapët për mesazhe të siguruar dhe komunikim të decentralizuar. Lejon vetëstrehim, për t’u lejuar përdoruesve pronësi dhe kontroll maksimal të të dhënave dhe mesazheve të tyre. +Element-i është plotësisht i ndryshëm nga aplikacione të tjera shkëmbimi mesazhesh dhe bashkëpunimi. Funksionimi i tij bazohet në Matrix, një rrjet i hapët për mesazhe të siguruar dhe komunikim të decentralizuar. Lejon vetëstrehim, për t’u dhënë përdoruesve pronësi dhe kontroll maksimal të të dhënave dhe mesazheve të tyre. Privatësi dhe shkëmbim mesazhesh të fshehtëzuar Element-i ju mbron nga reklama të padëshiruara, shfrytëzim të dhënash dhe vatha dixhitale. Ai siguron gjithashtu krejt të dhënat tuaja, komunikime tek-për-tek me video dhe me zë, përmes fshehtëzimi skaj-më-skaj dhe verifikim “cross-signed” pajisjesh. @@ -37,3 +37,6 @@ Shkëmbim mesazhesh, thirrje me zë dhe me video, shkëmbim kartelash, tregim ek Rifillojani atje ku e latë Jini në dijeni, kudo ku gjendeni, me historik plotësisht të njëkohësuar mesazhesh nëpër krejt pajisjet tuaja dhe në internet te https://app.element.io + +Me burim të hapët +Element-i për Android është një projekt me burim të hapët, strehuar në GitHub. Ju lutemi, njoftoni të meta dhe/ose jepni ndihmesë në zhvillimin e tij te https://github.com/vector-im/element-android From ca79e87e004aa49d0e73b425d3c7fd1d3e977331 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 18 Oct 2021 16:13:22 +0100 Subject: [PATCH 034/970] applying a retry when attempting to send dummy payload to device --- .../org/matrix/android/sdk/internal/crypto/EventDecryptor.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt index b1680d5153..57381eacfb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt @@ -38,6 +38,8 @@ import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber import javax.inject.Inject +private const val SEND_TO_DEVICE_RETRY_COUNT = 3 + @SessionScope internal class EventDecryptor @Inject constructor( private val cryptoCoroutineScope: CoroutineScope, @@ -173,7 +175,7 @@ internal class EventDecryptor @Inject constructor( withContext(coroutineDispatchers.io) { val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap) try { - sendToDeviceTask.execute(sendToDeviceParams) + sendToDeviceTask.executeRetry(sendToDeviceParams, remainingRetry = SEND_TO_DEVICE_RETRY_COUNT) } catch (failure: Throwable) { Timber.e(failure, "## CRYPTO | markOlmSessionForUnwedging() : failed to send dummy to $senderId:${deviceInfo.deviceId}") } From c8a8d2e0bf8446809e405036aac3d59fc58975d1 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 18 Oct 2021 16:15:07 +0100 Subject: [PATCH 035/970] applying a retry when attempting to fetch one time keys, tries to catch flaky network conditions --- .../crypto/actions/EnsureOlmSessionsForDevicesAction.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt index 52876b0fff..3979ff1fb4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt @@ -25,6 +25,8 @@ import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDevi import timber.log.Timber import javax.inject.Inject +private const val ONE_TIME_KEYS_RETRY_COUNT = 3 + internal class EnsureOlmSessionsForDevicesAction @Inject constructor( private val olmDevice: MXOlmDevice, private val oneTimeKeysForUsersDeviceTask: ClaimOneTimeKeysForUsersDeviceTask) { @@ -72,7 +74,7 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor( Timber.i("## CRYPTO | claimOneTimeKeysForUsersDevices() : $usersDevicesToClaim") val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(usersDevicesToClaim) - val oneTimeKeys = oneTimeKeysForUsersDeviceTask.execute(claimParams) + val oneTimeKeys = oneTimeKeysForUsersDeviceTask.executeRetry(claimParams, remainingRetry = ONE_TIME_KEYS_RETRY_COUNT) Timber.v("## CRYPTO | claimOneTimeKeysForUsersDevices() : keysClaimResponse.oneTimeKeys: $oneTimeKeys") for ((userId, deviceInfos) in devicesByUser) { for (deviceInfo in deviceInfos) { From 1d73077184ea6083c3bdd52664a27eaeaf808e02 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 18 Oct 2021 18:21:22 +0200 Subject: [PATCH 036/970] 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 f5eaf2f05fe7134d58e6b1fa1abd70c14ed4ba0f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Oct 2021 11:35:49 +0200 Subject: [PATCH 037/970] Align wording with Element Web --- .../src/main/java/im/vector/app/features/command/Command.kt | 4 ++-- vector/src/main/res/values/strings.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index 33ccd08d22..68fcfec555 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -34,8 +34,8 @@ enum class Command(val command: String, val parameters: String, @StringRes val d RESET_USER_POWER_LEVEL("/deop", "", R.string.command_description_deop_user, false), ROOM_NAME("/roomname", "", R.string.command_description_room_name, false), INVITE("/invite", " [reason]", R.string.command_description_invite_user, false), - JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room, false), - PART("/part", " [reason]", R.string.command_description_part_room, false), + JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room, false), + PART("/part", " [reason]", R.string.command_description_part_room, false), TOPIC("/topic", "", R.string.command_description_topic, false), KICK_USER("/kick", " [reason]", R.string.command_description_kick_user, false), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick, false), diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 7fa4918266..274753ee3f 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1837,7 +1837,7 @@ Deops user with given id Sets the room name Invites user with given id to current room - Joins room with given alias + Joins room with given address Leave room Set the room topic Kicks user with given id From fe2ba2844147171b72c756716bfac5a96d10aa83 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Oct 2021 11:55:09 +0200 Subject: [PATCH 038/970] Implement /part command, with or without parameter --- changelog.d/2909.feature | 1 + .../im/vector/app/features/command/Command.kt | 2 +- .../app/features/command/CommandParser.kt | 19 ++++--------------- .../app/features/command/ParsedCommand.kt | 2 +- .../detail/composer/TextComposerViewModel.kt | 18 ++++++++++++++++-- 5 files changed, 23 insertions(+), 19 deletions(-) create mode 100644 changelog.d/2909.feature diff --git a/changelog.d/2909.feature b/changelog.d/2909.feature new file mode 100644 index 0000000000..4d72734192 --- /dev/null +++ b/changelog.d/2909.feature @@ -0,0 +1 @@ +Implement /part command, with or without parameter \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/command/Command.kt b/vector/src/main/java/im/vector/app/features/command/Command.kt index 68fcfec555..ccabd25ff4 100644 --- a/vector/src/main/java/im/vector/app/features/command/Command.kt +++ b/vector/src/main/java/im/vector/app/features/command/Command.kt @@ -35,7 +35,7 @@ enum class Command(val command: String, val parameters: String, @StringRes val d ROOM_NAME("/roomname", "", R.string.command_description_room_name, false), INVITE("/invite", " [reason]", R.string.command_description_invite_user, false), JOIN_ROOM("/join", " [reason]", R.string.command_description_join_room, false), - PART("/part", " [reason]", R.string.command_description_part_room, false), + PART("/part", "[]", R.string.command_description_part_room, false), TOPIC("/topic", "", R.string.command_description_topic, false), KICK_USER("/kick", " [reason]", R.string.command_description_kick_user, false), CHANGE_DISPLAY_NAME("/nick", "", R.string.command_description_nick, false), diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index e570033d35..3a6b005d6f 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -158,21 +158,10 @@ object CommandParser { } } Command.PART.command -> { - if (messageParts.size >= 2) { - val roomAlias = messageParts[1] - - if (roomAlias.isNotEmpty()) { - ParsedCommand.PartRoom( - roomAlias, - textMessage.substring(Command.PART.length + roomAlias.length) - .trim() - .takeIf { it.isNotBlank() } - ) - } else { - ParsedCommand.ErrorSyntax(Command.PART) - } - } else { - ParsedCommand.ErrorSyntax(Command.PART) + when (messageParts.size) { + 1 -> ParsedCommand.PartRoom(null) + 2 -> ParsedCommand.PartRoom(messageParts[1]) + else -> ParsedCommand.ErrorSyntax(Command.PART) } } Command.ROOM_NAME.command -> { diff --git a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt index bafb9153e6..89aa8d9188 100644 --- a/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt +++ b/vector/src/main/java/im/vector/app/features/command/ParsedCommand.kt @@ -49,7 +49,7 @@ sealed class ParsedCommand { class Invite(val userId: String, val reason: String?) : ParsedCommand() class Invite3Pid(val threePid: ThreePid) : ParsedCommand() class JoinRoom(val roomAlias: String, val reason: String?) : ParsedCommand() - class PartRoom(val roomAlias: String, val reason: String?) : ParsedCommand() + class PartRoom(val roomAlias: String?) : ParsedCommand() class ChangeTopic(val topic: String) : ParsedCommand() class KickUser(val userId: String, val reason: String?) : ParsedCommand() class ChangeDisplayName(val displayName: String) : ParsedCommand() 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..08f44f30f7 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 @@ -225,8 +225,8 @@ class TextComposerViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.PartRoom -> { - // TODO - _viewEvents.post(TextComposerViewEvents.SlashCommandNotImplemented) + handlePartSlashCommand(slashCommandResult) + popDraft() } is ParsedCommand.SendEmote -> { room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) @@ -578,6 +578,20 @@ class TextComposerViewModel @AssistedInject constructor( } } + private fun handlePartSlashCommand(command: ParsedCommand.PartRoom) { + launchSlashCommandFlowSuspendable { + if (command.roomAlias == null) { + // Leave the current room + room + } else { + session.getRoomSummary(roomIdOrAlias = command.roomAlias) + ?.roomId + ?.let { session.getRoom(it) } + } + ?.leave(reason = null) + } + } + private fun handleKickSlashCommand(kick: ParsedCommand.KickUser) { launchSlashCommandFlowSuspendable { room.kick(kick.userId, kick.reason) From 364654b685c64b40ec2a914cac2fc6ba8c246fc8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Oct 2021 12:33:47 +0200 Subject: [PATCH 039/970] Fix crash on slash commands Exceptions --- changelog.d/4261.bugfix | 1 + .../features/home/room/detail/composer/TextComposerViewModel.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/4261.bugfix diff --git a/changelog.d/4261.bugfix b/changelog.d/4261.bugfix new file mode 100644 index 0000000000..4283335131 --- /dev/null +++ b/changelog.d/4261.bugfix @@ -0,0 +1 @@ +Fix crash on slash commands Exceptions \ No newline at end of file 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 08f44f30f7..73b400e8d5 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 @@ -709,7 +709,7 @@ class TextComposerViewModel @AssistedInject constructor( val event = try { block() TextComposerViewEvents.SlashCommandResultOk - } catch (failure: Exception) { + } catch (failure: Throwable) { TextComposerViewEvents.SlashCommandResultError(failure) } _viewEvents.post(event) From 46261997613d89bea77cf31284591d3df036e07f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Oct 2021 13:49:18 +0200 Subject: [PATCH 040/970] Slash commands: popDraft() only in case of success, and display a loading dialog during processing --- .../home/room/detail/RoomDetailFragment.kt | 7 +- .../detail/composer/TextComposerViewEvents.kt | 4 +- .../detail/composer/TextComposerViewModel.kt | 69 +++++++++---------- 3 files changed, 38 insertions(+), 42 deletions(-) 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..473a993395 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 @@ -1451,8 +1451,8 @@ class RoomDetailFragment @Inject constructor( private fun renderSendMessageResult(sendMessageResult: TextComposerViewEvents.SendMessageResult) { when (sendMessageResult) { - is TextComposerViewEvents.SlashCommandHandled -> { - sendMessageResult.messageRes?.let { showSnackWithMessage(getString(it)) } + is TextComposerViewEvents.SlashCommandLoading -> { + showLoading(null) } is TextComposerViewEvents.SlashCommandError -> { displayCommandError(getString(R.string.command_problem_with_parameters, sendMessageResult.command.command)) @@ -1461,9 +1461,12 @@ class RoomDetailFragment @Inject constructor( displayCommandError(getString(R.string.unrecognized_command, sendMessageResult.command)) } is TextComposerViewEvents.SlashCommandResultOk -> { + dismissLoadingDialog() views.composerLayout.setTextIfDifferent("") + sendMessageResult.messageRes?.let { showSnackWithMessage(getString(it)) } } is TextComposerViewEvents.SlashCommandResultError -> { + dismissLoadingDialog() displayCommandError(errorFormatter.toHumanReadable(sendMessageResult.throwable)) } is TextComposerViewEvents.SlashCommandNotImplemented -> { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewEvents.kt index 691ed4d93e..ff4a09ad71 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewEvents.kt @@ -32,8 +32,8 @@ sealed class TextComposerViewEvents : VectorViewEvents { data class JoinRoomCommandSuccess(val roomId: String) : SendMessageResult() class SlashCommandError(val command: Command) : SendMessageResult() class SlashCommandUnknown(val command: String) : SendMessageResult() - data class SlashCommandHandled(@StringRes val messageRes: Int? = null) : SendMessageResult() - object SlashCommandResultOk : SendMessageResult() + object SlashCommandLoading : SendMessageResult() + data class SlashCommandResultOk(@StringRes val messageRes: Int? = null) : SendMessageResult() class SlashCommandResultError(val throwable: Throwable) : SendMessageResult() data class OpenRoomMemberProfile(val userId: String) : TextComposerViewEvents() 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 73b400e8d5..b635602189 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 @@ -176,19 +176,15 @@ class TextComposerViewModel @AssistedInject constructor( } is ParsedCommand.ChangeRoomName -> { handleChangeRoomNameSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.Invite -> { handleInviteSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.Invite3Pid -> { handleInvite3pidSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.SetUserPowerLevel -> { handleSetUserPowerLevel(slashCommandResult) - popDraft() } is ParsedCommand.ClearScalarToken -> { // TODO @@ -196,29 +192,24 @@ class TextComposerViewModel @AssistedInject constructor( } is ParsedCommand.SetMarkdown -> { vectorPreferences.setMarkdownEnabled(slashCommandResult.enable) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled( + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk( if (slashCommandResult.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) popDraft() } is ParsedCommand.BanUser -> { handleBanSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.UnbanUser -> { handleUnbanSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.IgnoreUser -> { handleIgnoreSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.UnignoreUser -> { handleUnignoreSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.KickUser -> { handleKickSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.JoinRoom -> { handleJoinToAnotherRoomSlashCommand(slashCommandResult) @@ -226,25 +217,24 @@ class TextComposerViewModel @AssistedInject constructor( } is ParsedCommand.PartRoom -> { handlePartSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.SendEmote -> { room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendRainbow -> { slashCommandResult.message.toString().let { room.sendFormattedTextMessage(it, rainbowGenerator.generate(it)) } - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendRainbowEmote -> { slashCommandResult.message.toString().let { room.sendFormattedTextMessage(it, rainbowGenerator.generate(it), MessageType.MSGTYPE_EMOTE) } - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendSpoiler -> { @@ -252,61 +242,56 @@ class TextComposerViewModel @AssistedInject constructor( "[${stringProvider.getString(R.string.spoiler)}](${slashCommandResult.message})", "${slashCommandResult.message}" ) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendShrug -> { sendPrefixedMessage("¯\\_(ツ)_/¯", slashCommandResult.message) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendLenny -> { sendPrefixedMessage("( ͡° ͜ʖ ͡°)", slashCommandResult.message) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendChatEffect -> { sendChatEffect(slashCommandResult) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.SendPoll -> { room.sendPoll(slashCommandResult.question, slashCommandResult.options.mapIndexed { index, s -> OptionItem(s, "$index. $s") }) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } is ParsedCommand.ChangeTopic -> { handleChangeTopicSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.ChangeDisplayName -> { handleChangeDisplayNameSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.ChangeDisplayNameForRoom -> { handleChangeDisplayNameForRoomSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.ChangeRoomAvatar -> { handleChangeRoomAvatarSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.ChangeAvatarForRoom -> { handleChangeAvatarForRoomSlashCommand(slashCommandResult) - popDraft() } is ParsedCommand.ShowUser -> { - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) handleWhoisSlashCommand(slashCommandResult) popDraft() } is ParsedCommand.DiscardSession -> { if (room.isEncrypted()) { session.cryptoService().discardOutboundSession(room.roomId) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } else { - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) _viewEvents.post( TextComposerViewEvents .ShowMessage(stringProvider.getString(R.string.command_description_discard_session_not_handled)) @@ -314,6 +299,7 @@ class TextComposerViewModel @AssistedInject constructor( } } is ParsedCommand.CreateSpace -> { + _viewEvents.post(TextComposerViewEvents.SlashCommandLoading) viewModelScope.launch(Dispatchers.IO) { try { val params = CreateSpaceParams().apply { @@ -328,14 +314,16 @@ class TextComposerViewModel @AssistedInject constructor( null, true ) + popDraft() + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) } catch (failure: Throwable) { _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) } } - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) - popDraft() + Unit } is ParsedCommand.AddToSpace -> { + _viewEvents.post(TextComposerViewEvents.SlashCommandLoading) viewModelScope.launch(Dispatchers.IO) { try { session.spaceService().getSpace(slashCommandResult.spaceId) @@ -345,34 +333,38 @@ class TextComposerViewModel @AssistedInject constructor( null, false ) + popDraft() + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) } catch (failure: Throwable) { _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) } } - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) - popDraft() + Unit } is ParsedCommand.JoinSpace -> { + _viewEvents.post(TextComposerViewEvents.SlashCommandLoading) viewModelScope.launch(Dispatchers.IO) { try { session.spaceService().joinSpace(slashCommandResult.spaceIdOrAlias) + popDraft() + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) } catch (failure: Throwable) { _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) } } - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) - popDraft() + Unit } is ParsedCommand.LeaveRoom -> { viewModelScope.launch(Dispatchers.IO) { try { session.getRoom(slashCommandResult.roomId)?.leave(null) + popDraft() + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) } catch (failure: Throwable) { _viewEvents.post(TextComposerViewEvents.SlashCommandResultError(failure)) } } - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) - popDraft() + Unit } is ParsedCommand.UpgradeRoom -> { _viewEvents.post( @@ -381,7 +373,7 @@ class TextComposerViewModel @AssistedInject constructor( room.roomSummary()?.isPublic ?: false ) ) - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandResultOk()) popDraft() } }.exhaustive @@ -704,11 +696,12 @@ class TextComposerViewModel @AssistedInject constructor( } private fun launchSlashCommandFlowSuspendable(block: suspend () -> Unit) { - _viewEvents.post(TextComposerViewEvents.SlashCommandHandled()) + _viewEvents.post(TextComposerViewEvents.SlashCommandLoading) viewModelScope.launch { val event = try { block() - TextComposerViewEvents.SlashCommandResultOk + popDraft() + TextComposerViewEvents.SlashCommandResultOk() } catch (failure: Throwable) { TextComposerViewEvents.SlashCommandResultError(failure) } From 61c64a872dc26d17cc6dd869483f1d3ed35028c8 Mon Sep 17 00:00:00 2001 From: Linerly Date: Mon, 18 Oct 2021 22:42:33 +0000 Subject: [PATCH 041/970] Translated using Weblate (Indonesian) 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/id/ --- vector/src/main/res/values-in/strings.xml | 162 +++++++++++----------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index ab86b35e6c..f899be6bff 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -89,7 +89,7 @@ Laporan bug Aplikasi gagal saat terakhir digunakan. Apakah Anda ingin membuka halaman laporan kegagalan\? Gabung di Ruangan - URL Server Identitas + URL server identitas Mulai Panggilan Suara Masuk Buat Akun @@ -135,7 +135,7 @@ Tolak Nanti Kirim Saja - ${app_name} belum diijinkan untuk mengakses kontak lokal + ${app_name} belum diizinkan untuk mengakses kontak lokal Kirim log gangguan Raksasa Kecil @@ -157,8 +157,8 @@ \nBergabung sebagai %1$s atau %2$s suara video - Beberapa fitur tidak dapat digunakan karena aplikasi belum mendapat ijin… - Anda membutuhkan ijin mengundang untuk memulai panggilan massal di ruang ini + Beberapa fitur tidak dapat digunakan karena aplikasi belum mendapat izin… + Anda membutuhkan izin mengundang untuk memulai panggilan massal di ruang ini Panggilan massal tidak dapat diselenggarakan di ruang terenkripsi Jejak Percakapan Gandakan ke clipboard @@ -215,7 +215,7 @@ Panggilan Suara Masuk Panggilan Sedang Berlangsung… Hubungan Media Gagal - Server Identitas: + Server identitas: Tidak dapat memulai kamera panggilan terjawab di tempat lain Ambil gambar atau video @@ -375,7 +375,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Kirim ulang pesan yang belum terkirim Hapus pesan yang belum terkirim Berkas tidak ditemukan - Anda tidak mempunyai ijin untuk mengirim di ruang ini. + Anda tidak mempunyai izin untuk mengirim di ruang ini. %d pesan baru @@ -437,7 +437,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Hanya sebutan Diamkan Favorit - Menurunkan prioritas + Turunkan prioritas Percakapan Langsung Tinggalkan Percakapan Lupakan @@ -448,7 +448,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Syarat & ketentuan Pemberitahuan pihak ketiga Hak Cipta - Kebijakan Pribadi + Kebijakan privasi Gambar Profil Nama Layar Email @@ -565,7 +565,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Untuk terus menggunakan homeserver %1$s Anda harus membaca dan menyetujui syarat dan ketentuan. Avatar Baca sekarang - Deaktivasi Akun + Nonaktifkan Akun Ini akan mengakibatkan akun Anda tidak dapat digunakan secara permanen. Anda tidak akan dapat masuk dan orang lain tidak dapat mendaftar ulang dengan ID pengguna yang sama. Ini akan mengakibatkan akun Anda keluar dari semua ruang tempat Anda berpartisipasi serta menghapus semua detail akun dari server identitas Anda. Tindakan ini tidak dapat diubah. \n \nMenonaktifkan akun Anda tidak membuat kami melupakan pesan-pesan yang Anda kirim secara default. Jika Anda ingin kami melupakan pesan-pesan Anda, mohon centang kotak berikut. @@ -573,7 +573,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan \nKeterbacaan pesan di Matrix serupa dengan email. Dengan kami melupakan pesan-pesan Anda berarti pesan-pesan yang Anda kirim tidak akan dibagikan kepada pengguna baru ataupun yang belum terdaftar, tetapi pengguna yang terdaftar yang mempunyai mengakses pesan-pesan tersebut masih bisa mengakses salinan mereka. Mohon lupakan semua pesan yang telah saya kirim ketika akun saya dideaktivasi (Peringatan: ini akan mengakibatkan pengguna di masa depan melihat percakapan yang tidak lengkap) Untuk melanjutkan, masukkan kata sandi Anda: - Deaktivasi Akun + Nonaktifkan Akun Mohon masukkan kata sandi Anda. Ruangan ini telah berubah dan tidak lagi aktif. Percakapan berlanjut di sini @@ -643,7 +643,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Lanjutan ID internal ruang ini Alamat - Lab + Uji Coba Ini adalah fitur uji coba dan mungkin rusak tanpa terduga. Hati-hati menggunakannya. Enkripsi Ujung-ke-Ujung Enkripsi Ujung-ke-Ujung aktif @@ -698,13 +698,13 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mendengarkan peristiwa Pemberitahuan pihak ketiga Hak Cipta - Kebijakan Pribadi + Kebijakan privasi Bersihkan cache Bersihkan cache media Pertahankan media - Pengaturan pengguna + Pengaturan Pengguna Pemberitahuan - Pengguna yang diabaikan + Pengguna yang Diabaikan Lainnya Lanjutan Kriptografi @@ -721,16 +721,16 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Tampilkan waktu kirim dalam format 12 jam Bergetar ketika menyebut seorang pengguna Pratinjau media sebelum dikirim - Deaktivasi akun - Deaktivasi akunku + Nonaktifkan akun + Nonaktifkan akun saya Kerahasiaan Notifikasi ${app_name} dapat beroperasi di balik layar untuk mengurus pemberitahuan Anda dengan aman dan rahasia. Ini dapat mempengaruhi masa tahan baterai. - Kabulkan permisi + Beri izin Pilih opsi lain Analitik Kirim data analitik ${app_name} mengumpulkan data analitik anonim dalam upaya kami meningkatkan aplikasi. - Mohon aktifkan analitik untuk membantu kami meningkatkan ${app_name}. + Silakan aktifkan analitik untuk membantu kami meningkatkan ${app_name}. Ya, saya ingin membantu! Mode hemat data Rincian perangkat @@ -743,10 +743,10 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. \nUntuk melanjutkan operasi ini, mohon masukkan kata sandi anda. Otentikasi Kata Sandi: - Serahkan + Kirim Masuk sebagai Homeserver - Server Identitas + Server identitas Antarmuka pengguna Bahasa Pilih bahasa @@ -797,7 +797,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Error Mohon telaah dan terima kebijakan homeserver ini: Panggilan - Gunakan nada dering semula ${app_name} untuk panggilan masuk + Gunakan nada dering bawaan ${app_name} untuk panggilan masuk Nada dering panggilan masuk Pilih nada dering untuk panggilan: Panggilan Video Sedang Berlangsung… @@ -902,16 +902,16 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Kirim pemberitahuan mengetik Beritahu pengguna lain bahwa Anda sedang mengetik. Format markdown - Format pesan menggunakan sintaks markdown sebelum dikirim. Ini mengijinkan format lanjutan seperti menggunakan tanda bintang untuk menunjukkan teks miring. + Format pesan menggunakan sintaks markdown sebelum dikirim. Ini mengizinkan format lanjutan seperti menggunakan tanda bintang untuk menunjukkan teks miring. Tunjukkan tanda telah dibaca Klik tanda telah dibaca untuk daftar yang lebih rinci. Tunjukkan kejadian bergabung dan meninggalkan Undangan, pengeluaran, dan larangan tidak terpengaruh. Tunjukkan kejadian akun - • Server-server yang cocok dengan %s diizinkan. - • Server-server yang cocok dengan %s dilarangkan. - Anda mengatur server ACL untuk ruangan ini. - %s mengatur server ACL untuk ruangan ini. + • Server yang cocok dengan %s diizinkan. + • Server yang cocok dengan %s dilarangkan. + Anda mengatur ACL server untuk ruangan ini. + %s mengatur ACL server untuk ruangan ini. Anda meningkatkan di sini. %s meningkatkan di sini. Anda meningkatkan ruangan ini. @@ -919,69 +919,69 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Anda mengaktifkan enkripsi ujung-ke-ujung (%1$s) %1$s mengaktifkan enkripsi ujung-ke-ujung (%2$s) tidak diketahui (%s). - siapa pun. + siapa saja. semua anggota ruangan. - semua anggota ruangan, dari kapan mereka bergabung. - semua anggota ruangan, dari kapan mereka diundang. + semua anggota ruangan, sejak mereka bergabung. + semua anggota ruangan, sejak mereka diundang. Anda membuat riwayat pesanan masa depan terlihat dengan %1$s %1$s membuat riwayat pesanan masa depan terlihat dengan %2$s Anda membuat riwayat ruangan masa depan terlihat dengan %1$s %1$s membuat riwayat ruangan masa depan terlihat dengan %2$s - Anda mengakhiri panggilan. - %s mengakhiri panggilan. + Anda mengakhiri panggilan ini. + %s mengakhiri panggilan ini. %s mengirimkan data untuk mengatur panggilan. Anda mengirimkan data untuk mengatur panggilan. - %s menjawab panggilan. - Anda menjawab panggilan. - Anda menempatkan panggilan suara. - %s menempatkan panggilan suara. - Anda menempatkan panggilan video. - %s menempatkan panggilan video. + %s menjawab panggilan ini. + Anda menjawab panggilan ini. + Anda melakukan panggilan suara. + %s melakukan panggilan suara. + Anda melakukan panggilan video. + %s melakukan panggilan video. Anda mengubah nama kamar menjadi: %1$s %1$s mengubah nama ruangan menjadi: %2$s - Anda mengubah avatar ruangan - %1$s mengubah avatar ruangan + Anda mengubah avatar ruangan ini + %1$s mengubah avatar ruangan ini Anda mengubah topik menjadi: %1$s %1$s mengubah topik menjadi: %2$s Anda menghapus nama tampilan Anda (sebelumnya adalah %1$s) Anda mengubah nama tampilan Anda dari %1$s ke %2$s - %1$s menghapus nama tampilan mereka (sebelumnya adalah %2$s) - %1$s mengubah nama tampilan mereka dari %2$s ke %3$s + %1$s menghapus nama tampilannya (sebelumnya adalah %2$s) + %1$s mengubah nama tampilannya dari %2$s ke %3$s Anda menetapkan nama tampilan Anda ke %1$s %1$s menetapkan nama tampilannya ke %2$s Anda mengubah avatar Anda %1$s mengubah avatarnya - Anda menarik undangannya %1$s - %1$s menarik undangannya %2$s + Anda menghapus undangannya %1$s + %1$s menghapus undangannya %2$s Anda mencekal %1$s %1$s mencekal %2$s - Anda membatalkan pencekalan %1$s - %1$s membatalkan pencekalan %2$s + Anda menghilangkan pencekalan %1$s + %1$s menghilangkan pencekalan %2$s Anda mengeluarkan %1$s %1$s mengeluarkan %2$s - Anda menolak undangan - %1$s menolak undangan - Anda meninggalkan ruangan - %1$s meninggalkan ruangan - Anda meninggalkan ruangan - %1$s meninggalkan ruangan + Anda menolak undangannya + %1$s menolak undangannya + Anda meninggalkan ruangan ini + %1$s meninggalkan ruangan ini + Anda meninggalkan ruangan ini + %1$s meninggalkan ruangan ini Anda bergabung %1$s bergabung - Anda bergabung ruangan - %1$s bergabung ruangan + Anda bergabung ke ruangan ini + %1$s bergabung ke ruangan ini %1$s mengundang Anda Anda mengundang %1$s %1$s mengundang %2$s Anda membuat diskusi %1$s membuat diskusi - Anda membuat ruangan - %1$s menciptakan ruangan + Anda membuat ruangan ini + %1$s membuat ruangan ini Undangan Anda Undangan %s - Anda mengirim sticker. - %1$s mengirim stiker. - Anda mengirim gambar. - %1$s mengirim gambar. + Anda mengirim sebuah sticker. + %1$s mengirim sebuah stiker. + Anda mengirim sebuah gambar. + %1$s mengirim sebuah gambar. %1$s: %2$s Dioptimalkan untuk real-time ${app_name} akan mengsinkron di latar belakang dengan cara yang akan mempertahankan sumber daya (baterai) yang terbatas. @@ -1021,12 +1021,12 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mengubah widget Beritahu semuanya Menghapus pesan yang dikirim dari yang lain - Mengubah pengaturan + Ubah pengaturan Role bawaan Anda tidak diizinkan untuk memperbarui peran yang diperlukan untuk mengubah berbagai bagian ruangan Pilih role yang diperlukan untuk mengubah berbagai bagian ruangan Izin - Lihat dan perbarui role yang diperlukan untuk mengubah berbagai bagian ruangan. + Lihat dan perbarui peran yang diperlukan untuk mengubah berbagai bagian ruangan. Izin ruangan Membatalkan pencekalan pengguna akan mengizinkan mereka untuk bergabung ke ruangan. Batalkan pencekalan pengguna @@ -1106,7 +1106,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Panggilan gagal karena konfigurasi server yang salah URL API homeserver Kirim sejarah permintaan pemberian kunci - Spaces + Space Undangan Tampilkan semua ruangan di direktori ruangan, termasuk ruangan dengan konten eksplisit. Tampilkan ruangan dengan konten eksplisit @@ -1433,12 +1433,12 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Space atau ruangan lain yang mungkin tidak Anda ketahui Space yang Anda tahu berisi ruangan ini Tentukan siapa yang dapat menemukan dan bergabung ruangan ini. - Tap untuk mengedit space + Ketuk untuk mengedit space Pilih space Tentukan space mana yang dapat mengakses ruangan ini. Jika space dipilih, anggotanya dapat menemukan dan bergabung dengan nama Ruangan. Space yang dapat diakses Izinkan anggota space untuk menemukan dan akses. - Anggota Space %s bisa menemukan, pratinjau, dan bergabung. + Anggota space %s bisa menemukan, pratinjau, dan bergabung. Siapa saja di space dengan ruangan ini dapat menemukan dan bergabung. Hanya admin ruang ini yang dapat menambahkannya ke space. Anggota space saja Siapa saja dapat menemukan ruangan ini dan bergabung @@ -1446,7 +1446,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Hanya orang yang diundang yang dapat menemukan dan bergabung Pribadi (Undangan Saja) Pribadi - Setelan akses yang tidak diketahui (%s) + Pengaturan akses yang tidak diketahui (%s) Siapa saja dapat mengetuk ruangan, anggota kemudian dapat menerima atau menolak Tidak dapat mengambil visibilitas direktori ruangan saat ini (%1$s). Publikasikan ruangan ini ke publik di direktori ruangan %1$s\? @@ -1477,7 +1477,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Izinkan tamu untuk bergabung Akses ruangan Perubahan siapa yang dapat membaca riwayat hanya akan berlaku untuk pesan berikutnya di ruang ini. Visibilitas sejarah yang ada tidak akan berubah. - Setelan akun + Pengaturan akun Anda dapat mengelola notifikasi di %1$s. Harap dicatat bahwa sebutan & pemberitahuan keyword tidak tersedia di ruangan terenkripsi di ponsel. Beritahu saya untuk @@ -1491,12 +1491,12 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Terjadi kesalahan saat memverifikasi nomor telepon Anda. Sandi tidak cocok Kelola email dan nomor telepon yang ditautkan ke akun Matrix Anda - Surel dan nomor telepon + Email dan nomor telepon Sandi tidak valid Sandi Perbarui Sandi Terjadi kesalahan saat memverifikasi email Anda. - Aktifkan \'Izinkan integrasi\' di Setelan untuk melakukan ini. + Aktifkan \'Izinkan integrasi\' di Pengaturan untuk melakukan ini. Integrasi dinonaktifkan Pengelola integrasi Berikan izin @@ -1560,8 +1560,8 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Lainnya Sebutan dan Keyword Notifikasi Bawaan - Tidak Ada - Hanya Sebutan & Keyword + Tidak ada + Hanya sebutan & keyword Mengakhiri panggilan… Tidak ada jawaban Pengguna yang Anda panggil sedang sibuk. @@ -1569,7 +1569,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Panggilan suara dengan %s Panggilan video dengan %s Panggilan berdering… - Spaces + Space Pelajari Lebih Lanjut Kami mengirimi Anda email konfirmasi ke %s, mohon periksa email Anda dan klik tautan konfirmasi Opsi penemuan akan muncul setelah Anda menambahkan email. @@ -1745,7 +1745,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Surel yang dapat ditemukan Saat ini Anda tidak menggunakan server identitas. Untuk menemukan dan dapat ditemukan oleh kontak yang Anda kenal, atur salah satu di bawah ini. Saat ini Anda menggunakan %1$s untuk menemukan dan dapat ditemukan oleh kontak yang Anda kenal. - Ganti server identitas + Ubah server identitas Atur server identitas Putuskan server identitas Server identitas @@ -1794,9 +1794,9 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Terima kasih, saran Anda telah dikirim Terima kasih, masukan Anda telah dikirim Anda dapat menghubungi saya jika Anda memiliki pertanyaan lanjutan - Anda menggunakan versi beta space. Masukan Anda akan membantu menginformasikan versi berikutnya. Platform dan nama pengguna Anda akan dicatat untuk membantu kami menggunakan masukan Anda sebanyak yang kami bisa. + Anda menggunakan space versi beta. Masukan Anda akan membantu menginformasikan versi berikutnya. Platform dan nama pengguna Anda akan dicatat untuk membantu kami menggunakan masukan Anda sebanyak yang kami bisa. Masukan - Masukan spaces + Masukan tentang space Saran gagal dikirim (%s) Jelaskan saran Anda di sini Masukkan saran Anda di bawah. @@ -2215,7 +2215,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Rageshake Mode pengembang akan mengaktifkan fitur tersembunyi dan mungkin juga membuat aplikasinya kurang stabil. Untuk pengembang saja! Mode pengembang - Pengaturan lanjutan + Pengaturan Lanjutan Lihat semua sesi saya Sinkronisasi Awal… Deskripsi terlalu pendek @@ -2366,7 +2366,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. \nAnda tidak memiliki izin untuk menambahkan ruangan. Space ini belum ada ruangan Mohon kontak admin homeserver Anda untuk informasi lanjut - Sepertinya homeserver Anda belum mendukung Spaces + Sepertinya homeserver Anda belum mendukung fitur space Merasa eksperimental\? \nAnda dapat menambahkan space yang sudah ada ke space. Semua ruangan yang Anda berada akan ditampilkan juga di Beranda. @@ -2402,7 +2402,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. %d orang yang Anda tahu telah bergabung - Selamat datang ke %1$s, %2$s. + Selamat datang di %1$s, %2$s. Anda tidak berada di ruangan apapun saat ini. Di bawah adalah ruangan yang disarankan, tetapi Anda bisa mencari lebih banyak dengan tombol hijau di bawah kanan. Penjelajahan (%s) Selesaikan penyiapan @@ -2452,7 +2452,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Pastikan orang yang tepat memiliki akses ke %s. Anda dapat mengubahnya nanti. Dengan siapa Anda bekerja\? Untuk bergabung ke space yang sudah ada, Anda membutuhkan undangan ke space itu. - Anda bisa mengubahnya nanti + Anda dapat mengubahnya nanti Tipe space apa yang Anda ingin buat\? Space adalah cara baru untuk mengelompokkan ruangan dan pengguna Space privat Anda @@ -2470,9 +2470,9 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan. Mengirim Meningkatkan ruangan ke versi baru Tinggalkan ruangan dengan ID yang diberikan (atau ruangan saat ini jika null) - Bergabung ke Space dengan ID yang diberikan - Tambah ke Space yang dicantumkan - Buat Space + Bergabung ke space dengan ID yang diberikan + Tambah ke space yang dicantumkan + Buat sebuah Space Konten peristiwa Peristiwa keadaan dikirim! Peristiwa dikirim! From 5cb55cb0d304df53f4a1b6eda4867e6b479a9366 Mon Sep 17 00:00:00 2001 From: random Date: Mon, 18 Oct 2021 14:32:45 +0000 Subject: [PATCH 042/970] 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 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index 04d01e8f95..8d323c56e5 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -3055,4 +3055,7 @@ Imposta il nome della stanza Smetti di ignorare un utente, mostrando i suoi messaggi successivi Ignora un utente, non mostrandoti i suoi messaggi + Non disponibile + Offline + Online \ No newline at end of file From bda95fcc5ef9bfb6b68ba0650c1f382944d6b150 Mon Sep 17 00:00:00 2001 From: Viacheslav Raskulin Date: Mon, 18 Oct 2021 15:11:42 +0000 Subject: [PATCH 043/970] Translated using Weblate (Russian) 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/ru/ --- vector/src/main/res/values-ru/strings.xml | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/vector/src/main/res/values-ru/strings.xml b/vector/src/main/res/values-ru/strings.xml index bfc82d9a95..3a2491850d 100644 --- a/vector/src/main/res/values-ru/strings.xml +++ b/vector/src/main/res/values-ru/strings.xml @@ -349,7 +349,7 @@ Комнаты Фильтр названия комнаты - Фильтр избраного + Фильтр избранного Фильтр людей Фильтр названия комнаты @@ -425,7 +425,7 @@ Введен некорректный номер телефона Этот адрес электронной почты уже используется. Отсутствует email - Отстутсвует номер телефона + Отсутствует номер телефона Отсутствует номер телефона или email Токен не действителен Пароли не совпадают @@ -468,7 +468,7 @@ Чтение списка вступивших - Откравить как + Отправить как Оригинал Крупный Средний @@ -769,7 +769,7 @@ Все у кого есть ссылка на комнату, кроме гостей Все у кого есть ссылка на комнату, включая гостей - Забаненые пользователи + Забаненные пользователи Дополнительно Внутренний ID комнаты @@ -807,7 +807,7 @@ Curve25519 идентификационный ключ Необходим отпечаток Ed25519-ключа Алгоритм - ID сесии + ID сессии Ошибка дешифровки Информация о сессии отправителя Публичное имя @@ -1284,7 +1284,7 @@ Показывать события аккаунта Включает изменения аватара и отображаемого имени. Необходимо минимизировать влияние на фоновое соединение для надёжности уведомлений. -\nНа следующем экране вам будет предложено разрешить Райоту всегда работать в фоновом режиме, пожалуйста, примите. +\nНа следующем экране вам будет предложено разрешить ${app_name} всегда работать в фоновом режиме, пожалуйста, примите. Использовать системную камеру вместо камеры Element. Показать информацию %1$s: @@ -1494,7 +1494,7 @@ \nЕсли вы не открывали новую сессию - проигнорируйте этот запрос. Подтвердить Поделиться - Запрос поделится ключем + Запрос поделится ключом Игнорировать Ошибка отклика сервера Дополнить параметры сервера @@ -1505,7 +1505,7 @@ Начать проверку Входящий запрос о проверке Проверьте эту сессию, чтобы отметить её как доверенную. Доверие сессиям партнеров позволяет быть уверенным в надёжности сквозного шифрования сообщений. - Потдверждение этой сессии пометит её доверенной для вас и вашего партнёра. + Подтверждение этой сессии пометит её доверенной для вас и вашего партнёра. Подтвердите эту сессию, убедившись, что следующие смайлики появляются на экране партнера Подтвердите эту сессию, убедившись, что следующие цифры появляются на экране партнера Вы получили входящий запрос на подтверждение. @@ -2028,7 +2028,7 @@ \n \nВы можете отменить это действие в любое время в общих настройках. Перестать игнорировать пользователя - Если вы перестаните игнорировать этого пользователя, то все его сообщения вновь будут отображаться. + Если вы перестанете игнорировать этого пользователя, то все его сообщения вновь будут отображаться. Отменить приглашение Вы уверены, что хотите отменить приглашение для этого пользователя\? Выгнать пользователя @@ -2124,7 +2124,7 @@ Вы отменили %s принято Вы приняли - Подтверждениие отправлено + Подтверждение отправлено Запрос на подтверждение Подтвердите эту сессию Подтверждение вручную @@ -2175,7 +2175,7 @@ Сравните уникальные эмодзи, убедившись, что они появились в том же порядке. Сравните код с тем, который отображается на экране другого пользователя. Сообщения с этим пользователем полностью зашифрованы и не могут быть прочитаны третьими лицами. - Ваша новая сесия теперь подтверждена. Она имеет доступ к вашим зашифрованным сообщениям, и другие пользователи будут считать её надежной. + Ваша новая сессия теперь подтверждена. Она имеет доступ к вашим зашифрованным сообщениям, и другие пользователи будут считать её надежной. Кросс-подпись Кросс-подпись включена \nПриватные ключи хранятся на устройстве. @@ -2220,7 +2220,7 @@ Настроить безопасное резервное копирование Безопасное резервное копирование Эта сессия является доверенной для безопасного обмена сообщениями, потому что вы проверили её: - Подтвердите эту сессию, чтобы пометить её доверенной и предоставить ей доступ к зашифрованным сообщениям. Если вы не входили в эту сессю, ваша учетная запись может быть скомпрометирована: + Подтвердите эту сессию, чтобы пометить её доверенной и предоставить ей доступ к зашифрованным сообщениям. Если вы не входили в эту сессию, ваша учетная запись может быть скомпрометирована: Другие пользователи могут не доверять ему Завершите настройку безопасности Верифицировать @@ -2810,7 +2810,7 @@ Настройки комнаты Покинуть текущую конференцию и перейти к другой\? Версия комнаты - Показать все команты в списке комнат, в том числе с чувствительным содержанием. + Показать все комнаты в списке комнат, в том числе с чувствительным содержанием. Показать комнаты с деликатным содержанием Список комнат Новое значение @@ -2852,7 +2852,7 @@ Управление комнатами и пространствами Отметить как не рекомендуется Отметить как рекомендуется - Предложенно + Предложено Сделайте это пространство публичным Управление комнатами Ищете кого-то не в %s\? @@ -2924,7 +2924,7 @@ Пространства - это новый способ группировки комнат и людей Ваше приватное пространство Ваше публичное пространство - Добавить простанство + Добавить пространство Приватное пространство Публичное пространство Обновляет комнату до новой версии From 803d1458921e9623678fa0e18b3b50dd5c9edc34 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Tue, 19 Oct 2021 07:29:48 +0000 Subject: [PATCH 044/970] Translated using Weblate (Swedish) 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/sv/ --- vector/src/main/res/values-sv/strings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index f8ac8eba58..5ff62fa1eb 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -747,7 +747,7 @@ Byt nätverk Alla gemenskaper Allmänt - Inställningar + Alternativ Namn eller ID (#example:matrix.org) Du kommer inte att verifiera %1$s (%2$s) om du avbryter nu. Börja igen i hens användarprofil. Meddelanden i det här rummet är totalsträckskrypterade. Lär dig mer och verifiera användare i deras profiler. @@ -2778,8 +2778,8 @@ Känner du dig äventyrlig\? \nDu kan lägga till existerande utrymmen till ett utrymme. Lägg till rum - Du är den enda administratören av detta utrymme. Att lämna det betyder att ingen har kontroll över det. - Du kommer inte att kunna gå med igen om du inte är inbjuden igen. + Du är den enda administratören av detta utrymme. Om du lämnar det kommer ingen att ha kontroll över det. + Du kommer inte att kunna gå med igen om du inte bjuds in igen. Du är den enda personen här. Om du lämnar så kommer ingen kunna gå med i framtiden, inklusive du. Bjud in till %s Den här funktionen är i beta @@ -2821,13 +2821,13 @@ Tryck på din inspelning för att stoppa eller lyssna %1$d lämnade Håll in för att spela in, släpp för att skicka - Ta bort inspelningen + Radera inspelning Spelar in röstmeddelande Pausa röstmeddelande Spela röstmeddelande Röstmeddelandelås Svep för att avbryta - Börja röstmeddelande + Spela in röstmeddelande Tyvärr så inträffade ett fel vid försök att gå med i: %s Uppgradera till rekommenderad rumsversion Det är rummet kör rumsversion %s, vilken den hör hemservern har markerat som instabil. @@ -2986,7 +2986,7 @@ Vilka är dina lagkamrater\? Lägg till till det angivna utrymmet Sluta spela in - Lägg till ett mellanslag till alla utrymmen du hanterar. + Lägg till ett utrymme till alla utrymmen du hanterar. Lägg till befintliga utrymmen Lägg till befintliga rum Välj saker att lämna @@ -2995,9 +2995,9 @@ Du kommer att lämna alla rum och utrymmen i %s. Lämna alla rum och utrymmen Är du säker på att du vill lämna %s\? - Discovery (%s) + Upptäckt (%s) Slutför konfigurationen - Se till att rätt personer har tillgång till %s företag. Du kan bjuda in mer senare. + Se till att rätt personer har tillgång till %s företag. Du kan bjuda in fler senare. Bjud in med e-post, hitta kontakter och mer… Slutför inställning av upptäckbarhet. Du använder för närvarande ingen identitetsserver. För att bjuda in teammedlemmar och kunna upptäckas av dem, konfigurera en nedan. From 497d053c5dddf9bb161d11f160cfa467fd84d6a8 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 18 Oct 2021 02:13:47 +0000 Subject: [PATCH 045/970] Translated using Weblate (Chinese (Traditional)) 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/zh_Hant/ --- vector/src/main/res/values-zh-rTW/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index f8ca44ab7a..66120d9429 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2946,4 +2946,7 @@ 設定聊天室名稱 停止忽略使用者,繼續顯示他們的訊息 忽略使用者,為您隱藏他們的訊息 + 不可用 + 離線 + 線上 \ No newline at end of file From 16a8cf6d5198e21c74d5c1a8bf9e06f9f404cca4 Mon Sep 17 00:00:00 2001 From: random Date: Mon, 18 Oct 2021 14:35:15 +0000 Subject: [PATCH 046/970] Translated using Weblate (Italian) Currently translated at 100.0% (34 of 34 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/40103030.txt | 2 ++ fastlane/metadata/android/it-IT/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/40103030.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/40103030.txt b/fastlane/metadata/android/it-IT/changelogs/40103030.txt new file mode 100644 index 0000000000..e5c12d2b5e --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: rese visibili le informative dei server d'identità nelle impostazioni. Rimosso temporaneamente il supporto per Android Auto. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/it-IT/full_description.txt b/fastlane/metadata/android/it-IT/full_description.txt index dd7716ffbf..f0e4c04477 100644 --- a/fastlane/metadata/android/it-IT/full_description.txt +++ b/fastlane/metadata/android/it-IT/full_description.txt @@ -37,3 +37,6 @@ Messaggi, chiamate audio e video, condivisione file e schermo, un vasto numero d Riprendi da dove ti eri fermato Resta in contatto ovunque tu sia con la cronologia dei messaggi sincronizzata tra tutti i tuoi dispositivi e in rete su https://app.element.io + +Open source +Element Android è un progetto open source, ospitato su GitHub. Segnala errori e/o contribuisci al suo sviluppo su https://github.com/vector-im/element-android From 1d831b3a1b7464bced0c8b8d70cac32190be005f Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 18 Oct 2021 02:11:58 +0000 Subject: [PATCH 047/970] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (34 of 34 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/40103030.txt | 2 ++ fastlane/metadata/android/zh-TW/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/zh-TW/changelogs/40103030.txt diff --git a/fastlane/metadata/android/zh-TW/changelogs/40103030.txt b/fastlane/metadata/android/zh-TW/changelogs/40103030.txt new file mode 100644 index 0000000000..7531d1d4a2 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40103030.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:讓身份伺服器政策在設定中可見。暫時移除 Android Auto 支援。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/zh-TW/full_description.txt b/fastlane/metadata/android/zh-TW/full_description.txt index 90c0eb4c4c..eda511c4af 100644 --- a/fastlane/metadata/android/zh-TW/full_description.txt +++ b/fastlane/metadata/android/zh-TW/full_description.txt @@ -37,3 +37,6 @@ Element 透過不同的方式讓您掌控一切: 從上次離開的地方開始 無論您身在何處,都可以透過在您所有裝置與網頁 https://app.element.io 間完全同步的訊息歷史保持聯絡 + +開放原始碼 +Android 版的 Element 是開放原始碼專案,託管於 GitHub 上。請在 https://github.com/vector-im/element-android 上回報臭蟲及/或貢獻其開發 From c056dc27ca1f5835835bb61cc09006fb280ef4ce Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Mon, 18 Oct 2021 05:20:25 +0000 Subject: [PATCH 048/970] Translated using Weblate (Czech) Currently translated at 100.0% (34 of 34 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/40103030.txt | 2 ++ fastlane/metadata/android/cs-CZ/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/cs-CZ/changelogs/40103030.txt diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40103030.txt b/fastlane/metadata/android/cs-CZ/changelogs/40103030.txt new file mode 100644 index 0000000000..8faffd36ed --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Umožňuje v nastavení zviditelnit zásady serveru identit. Dočasně odstraňuje podporu pro Android Auto. +Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/cs-CZ/full_description.txt b/fastlane/metadata/android/cs-CZ/full_description.txt index 6732b33fe3..a74c58b413 100644 --- a/fastlane/metadata/android/cs-CZ/full_description.txt +++ b/fastlane/metadata/android/cs-CZ/full_description.txt @@ -37,3 +37,6 @@ Zprávy, hlasové a videohovory, sdílení souborů, sdílení obrazovky a celá Navažte tam, kde jste skončili Zůstaňte v kontaktu, ať jste kdekoli, díky plně synchronizované historii zpráv ve všech zařízeních a na webu https://app.element.io + +Open source +Element Android je projekt s otevřeným zdrojovým kódem, který je hostován na GitHubu. Nahlaste prosím chyby a přispějte k jeho vývoji na adrese https://github.com/vector-im/element-android From 097694f6ef995189e5b15c95e033005baa945128 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Oct 2021 17:31:51 +0200 Subject: [PATCH 049/970] Make MegolmBackupAuthData.signatures optional for robustness --- changelog.d/4162.bugfix | 1 + .../internal/crypto/keysbackup/DefaultKeysBackupService.kt | 6 +++--- .../crypto/keysbackup/model/MegolmBackupAuthData.kt | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 changelog.d/4162.bugfix diff --git a/changelog.d/4162.bugfix b/changelog.d/4162.bugfix new file mode 100644 index 0000000000..833ed2f1b8 --- /dev/null +++ b/changelog.d/4162.bugfix @@ -0,0 +1 @@ +Make MegolmBackupAuthData.signatures optional for robustness \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index fe2de6aa9c..b20168eaa3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -410,7 +410,7 @@ internal class DefaultKeysBackupService @Inject constructor( val keysBackupVersionTrust = KeysBackupVersionTrust() val authData = keysBackupVersion.getAuthDataAsMegolmBackupAuthData() - if (authData == null || authData.publicKey.isEmpty() || authData.signatures.isEmpty()) { + if (authData == null || authData.publicKey.isEmpty() || authData.signatures.isNullOrEmpty()) { Timber.v("getKeysBackupTrust: Key backup is absent or missing required data") return keysBackupVersionTrust } @@ -478,7 +478,7 @@ internal class DefaultKeysBackupService @Inject constructor( cryptoCoroutineScope.launch(coroutineDispatchers.main) { val updateKeysBackupVersionBody = withContext(coroutineDispatchers.crypto) { // Get current signatures, or create an empty set - val myUserSignatures = authData.signatures[userId].orEmpty().toMutableMap() + val myUserSignatures = authData.signatures?.get(userId).orEmpty().toMutableMap() if (trust) { // Add current device signature @@ -497,7 +497,7 @@ internal class DefaultKeysBackupService @Inject constructor( // Create an updated version of KeysVersionResult val newMegolmBackupAuthData = authData.copy() - val newSignatures = newMegolmBackupAuthData.signatures.toMutableMap() + val newSignatures = newMegolmBackupAuthData.signatures.orEmpty().toMutableMap() newSignatures[userId] = myUserSignatures val newMegolmBackupAuthDataWithNewSignature = newMegolmBackupAuthData.copy( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt index 54b92546e9..17c895762c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt @@ -51,7 +51,7 @@ data class MegolmBackupAuthData( * userId -> (deviceSignKeyId -> signature) */ @Json(name = "signatures") - val signatures: Map> + val signatures: Map>? = null ) { fun toJsonDict(): JsonDict { From bb68e735f74f01b0bbf431bc7d030b4c57f5d6b8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 19 Oct 2021 16:31:22 +0200 Subject: [PATCH 050/970] 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 051/970] 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 97464969ea49ba8c78a15664af1f86cefb35b5cb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Oct 2021 19:04:32 +0200 Subject: [PATCH 052/970] Small formatting --- dependencies.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index be6ce3f04f..a487b36c93 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -126,11 +126,11 @@ ext.libs = [ 'jjwtImpl' : "io.jsonwebtoken:jjwt-impl:$jjwt", 'jjwtOrgjson' : "io.jsonwebtoken:jjwt-orgjson:$jjwt" ], - vanniktech: [ + vanniktech : [ 'emojiMaterial' : "com.vanniktech:emoji-material:$vanniktechEmoji", 'emojiGoogle' : "com.vanniktech:emoji-google:$vanniktechEmoji" ], - apache:[ + apache : [ 'commonsImaging' : "org.apache.sanselan:sanselan:0.97-incubator" ], tests : [ From 85983562fa968387fe1db30c4f51ee59b30b4ee0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Oct 2021 19:06:27 +0200 Subject: [PATCH 053/970] No need to add explicit dependencies on stdlib, this is added by the gradle plugin since 1.4 https://kotlinlang.org/docs/whatsnew14.html#dependency-on-the-standard-library-added-by-default --- attachment-viewer/build.gradle | 1 - dependencies.gradle | 2 -- matrix-sdk-android-flow/build.gradle | 1 - matrix-sdk-android/build.gradle | 2 -- multipicker/build.gradle | 1 - vector/build.gradle | 1 - 6 files changed, 8 deletions(-) diff --git a/attachment-viewer/build.gradle b/attachment-viewer/build.gradle index 064f497dc7..02fbfc794c 100644 --- a/attachment-viewer/build.gradle +++ b/attachment-viewer/build.gradle @@ -53,7 +53,6 @@ dependencies { implementation libs.rx.rxKotlin implementation libs.rx.rxAndroid - implementation libs.jetbrains.kotlinStdlib implementation libs.androidx.core implementation libs.androidx.appCompat implementation libs.androidx.recyclerview diff --git a/dependencies.gradle b/dependencies.gradle index a487b36c93..7fa42a666f 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -37,8 +37,6 @@ ext.libs = [ 'kotlinPlugin' : "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin" ], jetbrains : [ - 'kotlinStdlibJdk7' : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin", - 'kotlinStdlib' : "org.jetbrains.kotlin:kotlin-stdlib:$kotlin", 'coroutinesCore' : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines", 'coroutinesAndroid' : "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutines", 'coroutinesRx2' : "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$kotlinCoroutines" diff --git a/matrix-sdk-android-flow/build.gradle b/matrix-sdk-android-flow/build.gradle index fd2e2e0824..ea43ce20c8 100644 --- a/matrix-sdk-android-flow/build.gradle +++ b/matrix-sdk-android-flow/build.gradle @@ -35,7 +35,6 @@ dependencies { implementation project(":matrix-sdk-android") implementation libs.androidx.appCompat - implementation libs.jetbrains.kotlinStdlibJdk7 implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid implementation libs.androidx.lifecycleLivedata diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 43ca243ec5..b547ae037a 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -100,8 +100,6 @@ static def gitRevisionDate() { } dependencies { - - implementation libs.jetbrains.kotlinStdlibJdk7 implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid diff --git a/multipicker/build.gradle b/multipicker/build.gradle index 437499df7b..bb98a2f852 100644 --- a/multipicker/build.gradle +++ b/multipicker/build.gradle @@ -38,7 +38,6 @@ android { } dependencies { - implementation libs.jetbrains.kotlinStdlibJdk7 implementation libs.androidx.appCompat implementation libs.androidx.fragmentKtx implementation libs.androidx.exifinterface diff --git a/vector/build.gradle b/vector/build.gradle index d06779d61c..31a4f1639c 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -340,7 +340,6 @@ dependencies { implementation project(":library:ui-styles") implementation 'androidx.multidex:multidex:2.0.1' - implementation libs.jetbrains.kotlinStdlibJdk7 implementation libs.jetbrains.coroutinesCore implementation libs.jetbrains.coroutinesAndroid From d764bb659f58e30f6adce59e1d7816f1e10f68f5 Mon Sep 17 00:00:00 2001 From: DUCKCHI Date: Tue, 19 Oct 2021 20:13:01 +0000 Subject: [PATCH 054/970] Translated using Weblate (Korean) Currently translated at 48.3% (1292 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 | 347 ++++------------------ 1 file changed, 54 insertions(+), 293 deletions(-) diff --git a/vector/src/main/res/values-ko/strings.xml b/vector/src/main/res/values-ko/strings.xml index dbd48a6c67..3adf75e722 100644 --- a/vector/src/main/res/values-ko/strings.xml +++ b/vector/src/main/res/values-ko/strings.xml @@ -1,10 +1,9 @@ - + %1$s: %2$s %s님의 초대 %1$s님이 사진을 보냈습니다. %1$s님이 스티커를 보냈습니다. - %1$s님이 %2$s님을 초대했습니다 %1$s님이 당신을 초대했습니다 %1$s님이 참가했습니다 @@ -32,11 +31,9 @@ 알 수 없음 (%s). %1$s님이 종단간 암호화를 켰습니다 (%2$s) %s님이 방을 업그레이드했습니다. - %1$s님이 VoIP 회의를 요청했습니다 VoIP 회의가 시작했습니다 VoIP 회의가 끝났습니다 - (아바타도 변경됨) %1$s님이 방 이름을 삭제했습니다 %1$s님이 방 주제를 삭제했습니다 @@ -47,34 +44,23 @@ %1$s님이 프로필 %2$s을(를) 업데이트했습니다 %1$s님이 %2$s님에게 방 초대를 보냈습니다 %1$s님이 %2$s의 초대를 수락했습니다 - ** 암호를 복호화할 수 없음: %s ** 발신인의 기기에서 이 메시지의 키를 보내지 않았습니다. - 검열할 수 없습니다 메시지를 보낼 수 없습니다 - 사진 업로드에 실패했습니다 - 네트워크 오류 Matrix 오류 - 현재 빈 방에 다시 들어갈 수 없습니다. - 이메일 주소 전화번호 - %s에서 초대함 방 초대 - %1$s님과 %2$s님 - %1$s님 외 %2$d명 - 빈 방 - 초기 동기화: \n계정 가져오는 중… 초기 동기화: @@ -91,15 +77,12 @@ \n커뮤니티 가져오는 중 초기 동기화: \n계정 데이터 가져오는 중 - 메시지 보내는 중… 전송 대기 열 지우기 - %1$s님이 %2$s님에게 방에 참가하라고 보낸 초대를 취소했습니다 밝은 테마 어두운 테마 검정 테마 - 동기화 중… 메시지 @@ -107,11 +90,8 @@ 기록 버그 신고 스티커 보내기 - 제 3자 라이선스 - 불러오는 중… - 취소 저장 @@ -132,14 +112,13 @@ 영상 전화를 걸 수 없습니다, 나중에 다시 시도해주세요 권한이 없어졌기 때문에, 일부 기능이 빠졌을 수 있습니다… - 권한이 없어졌기 때문에, 이 행동을 할 수 없습니다. + 현재 권한이 없기 때문에 이 작업을 수행할 수 없습니다. 전화를 걸 수 없습니다 기기 정보 무시하고 보내기 또는 초대 오프라인 - 나가기 활동 로그아웃 @@ -152,22 +131,17 @@ 닫기 클립보드에 복사되었습니다 비활성화 - 확인 경고 오류 - 즐겨찾기 사람 커뮤니티 - 방 이름 필터 시스템 알림 - 결과 없음 - 로그 보내기 충돌 로그 보내기 @@ -184,21 +158,17 @@ 홈서버 URL ID 서버 URL 검색 - 새 대화 시작하기 음성 통화 시작하기 영상 통화 시작하기 - 정말로 %s님과 새 대화를 시작하시겠습니까\? 정말 음성통화를 시작하시겠어요? 정말 영상통화를 시작하시겠어요? - 파일 보내기 스티커 보내기 사진이나 영상 찍기 사진 찍기 영상 찍기 - 로그인 계정 만들기 제출하기 @@ -207,17 +177,14 @@ 비밀번호 새 비밀번호 사용자 이름 - 서비스 초기화 중 소리로 알림 소리 없이 알림 - 구성원 정보 커뮤니티 정보 키 백업 키 백업하기 기기 확인 - 키 백업이 끝나지 않았습니다, 기다려주세요… 지금 로그아웃하면 암호화된 메세지가 사라집니다 키 백업하기 @@ -232,19 +199,15 @@ %d명의 사용자 - 초대 커뮤니티 최근에 애플리케이션이 충돌한 것 같습니다. 충돌 보고서를 열까요\? 읽음 - 사용자 이름 음성 보내기 - 스티커팩이 하나도 없습니다. \n \n뭐라도 추가할까요\? - 로그인 화면으로 돌아가기 이메일 주소 이메일 주소 (선택) @@ -265,14 +228,12 @@ 비밀번호가 초기화되었습니다. \n \n모든 기기에서 로그아웃되고 알림도 가지 않을 거에요. 다시 알림을 받으려면, 각 기기에 다시 로그인하세요. - 이벤트 청취하기 키 백업이 진행 중입니다. 지금 로그아웃하면 암호화된 메시지에 접근할 수 없습니다. 암호화된 메시지에 대한 접근을 읽지 않도록 모든 장치에서 보안 키 백업이 활성화되어 있어야 합니다. 암호화된 메시지를 원하지 않습니다 키 백업 중… 로그아웃하기 전에 키를 백업하지 않으면 암호화된 메시지에 접근할 수 없습니다. - 말하기 지우기 @@ -286,13 +247,11 @@ 수락하기 중단 무시 - 세계 검색 즐겨찾기 필터 사람 필터 방 이름 필터 커뮤니티 이름 필터 - 초대 중요하지 않음 대화 @@ -304,18 +263,14 @@ 방 없음 이용할 수 있는 공공 방이 없음 그룹 없음 - 문제를 진단하기 위해, 이 클라이언트의 로그는 버그 보고서와 함께 전송됩니다. 이 버그 보고서에는 로그와 스크린샷이 포함되면 공개적으로 표시되지 않습니다. 위의 텍스트만 보내려면 다음을 선택 해제하세요: 좌절감에 휴대 전화를 흔들고 있는 것 같네요. 버그 보고서 화면을 열어보겠습니까\? 분노의 흔들기로 버그 신고하기 - 진행 (%s%%) - 여기로 보내기 방 들어가기 계속… 죄송합니다, 이 작업을 완료하기 위한 외부 애플리케이션이 없습니다. - 통합 인증으로 로그인 재 설정 이메일 보내기 사용자 이름은 문자, 숫자, 점, 하이픈 및 밑줄만 포함할 수 있습니다 @@ -337,7 +292,6 @@ 이메일 %s(으)로 전송했습니다. 이메일에 포함된 링크를 들어갔다면, 아래를 클릭해주세요. 이메일 주소를 확인할 수 없습니다: 이메일에 있는 링크를 클릭했는 지 확인하세요 이 홈서버의 규칙을 숙지한 후 수락하세요: - URL은 http[s]://로 시작해야 합니다 로그인할 수 없음: 네트워크 오류 로그인할 수 없음 @@ -354,44 +308,32 @@ 너무 많은 요청을 보냈습니다 이 사용자 이름은 이미 사용 중입니다 이메일 링크를 아직 클릭하지 않았습니다 - 다른 기기에서 온 다시 요청된 암호 키. - 키 요청을 보냈습니다. - 요청 보냄 다른 기기에서 ${app_name}을 설치해서 메시지를 암호화하고 이 기기로 키를 보내도록 합니다. - 읽은 기록 읽기 - 그룹 목록 - %d명의 구성원 변경 사항 - 이렇게 보내기 원본 크게 중간 작게 - 다운로드를 취소하겠습니까\? 업로드를 취소하겠습니까\? %d초 %1$d분 %2$d초 - 어제 오늘 - 방 이름 방 주제 - 전화 수신 전화에 ${app_name} 기본 벨소리를 사용합니다 수신 전화 벨소리 전화에 사용할 벨소리를 선택하세요: - 전화 전화 연결됨 전화 연결 중… @@ -402,15 +344,12 @@ 수신 음성 통화 전화 진행 중… 영상 통화 진행 중… - 상대방이 전화를 받지 못했습니다. 미디어 연결 실패 카메라를 초기화할 수 없습니다 다른 곳에서 전화 응답 - 사진이나 영상 찍기 영상을 촬영할 수 없음 - 정보 첨부 파일을 보내고 저장하려면 ${app_name}은 영상과 사진 보관함에 접근하는 권한이 필요합니다. \n @@ -430,32 +369,26 @@ "${app_name}은 당신의 연락처를 확인하여 이메일과 전화번호를 기반으로 다른 Matrix 사용자를 찾을 수 있습니다. \n \n이런 이유로 연락처를 공유하는 것을 허용하겠습니까\?" - 죄송합니다. 권한이 없어서, 작업이 수행되지 않았습니다 - 저장됨 다운로드 폴더에 저장하겠습니까\? 아니오 계속 - 제거 참가 미리보기 받지 않기 - 구성원 목록 헤더 열기 동기화 중… 읽지 않은 첫 부분으로 이동하기. - %s님이 이 방알 초대했습니다 이 초대장은 %s님이 보냈습니다, 이 계정과는 관련이 없습니다. \n다른 계정으로 로그인하거나, 이 이메일을 계정에 추가할 수 있습니다. %s 방으로 접근하려고 했습니다. 토론에 참여하기 위해 참가하는 것입니까\? 이 방의 미리보기입니다. 방 상호작용이 비활성화됩니다. - 새 대화 구성원 추가 @@ -465,7 +398,6 @@ %d명의 구성원 1명의 구성원 - %d초 @@ -478,23 +410,19 @@ %d일 - 방 떠나기 방을 떠나겠습니까\? 이 대화에서 %s을(를) 삭제하겠습니까\? 만들기 - 온라인 오프라인 휴식 %1$s 상태 %2$s 전 %1$s 상태였음 - 관리자 도구 전화 다이렉트 대화 기기 - 초대 이 방 떠나기 이 방에서 삭제하기 @@ -511,24 +439,19 @@ 기기 목록 보이기 사용자를 자신과 동일한 권한 등급으로 승격시키는 것은 취소할 수 없습니다. \n확신합니까\? - 이 사용자를 이 대화에서 출입 금지하겠습니까\? 이유 - %s님을 이 대화에 초대하겠습니까\? "%1$s님, " %1$s님과 %2$s님 %1$s %2$s님 - ID로 초대 로컬 연락처 (%d) 사용자 목록 (%s) Matrix 사용자만 - ID로 사용자 초대 이메일 주소나 Matrix ID를 입력해주세요 이메일 혹은 Matrix ID - 검색 %s님이 입력 중… %1$s님과 %2$s님이 입력 중… @@ -549,7 +472,6 @@ %d개의 새 메시지 - 신뢰함 신뢰하지 않음 로그아웃 @@ -561,7 +483,6 @@ 인증서가 휴대 전화가 신뢰하는 인증서에서 변경되었습니다. 이것은 매우 비정상적입니다. 새 인증서에 수락하지 않는 것을 권합니다. 이전 신뢰하던 인증서에서 신뢰하지 않는 인증서로 변경되었습니다. 서버가 인증서를 새로 갱신했을 수 있습니다. 예상되는 핑거프린트는 서버 관리자에게 문의하세요. 서버 관리자가 위의 핑거프린트와 일치하는 것을 게시하는 경우에만 인증서를 수락할 수 있습니다. - 방 세부 사항 사람 파일 @@ -572,14 +493,12 @@ 잘못된 ID입니다. 이메일 주소나 \'@localpart:domain\'와 같은 Matrix ID이어야 합니다 초대받음 참가함 - 이 내용을 신고하는 이유 이 사용자의 모든 메시지를 숨기겠습니까\? \n \n이 동작은 앱을 다시 시작하며 일정 시간이 걸릴 수 있습니다. 업로드 취소 다운로드 취소 - 검색 방 구성원 필터 결과 없음 @@ -587,7 +506,6 @@ 메시지 사람 파일 - 참가 목록 즐겨찾기 @@ -599,7 +517,6 @@ 방 참가하기 방 참가하기 방 ID나 방 별칭을 입력 - 목록 찾기 %d개의 방 @@ -608,7 +525,6 @@ %2$s 검색 결과로 %1$s개의 방을 찾음 목록 검색 중… - 모든 메시지 (소리) 모든 메시지 언급만 @@ -619,7 +535,6 @@ 대화 떠나기 잊기 홈 화면에 단축 아이콘 추가 - 메시지 설정 버전 @@ -628,7 +543,6 @@ 제 3자 고지 저작권 개인 정보 정책 - 프로필 사진 표시 이름 이메일 @@ -637,11 +551,8 @@ 전화번호 추가 애플리케이션 정보 시스템 설정에서 애플리케이션 정보를 표시하세요. - - 고급 알림 설정 이벤트 별 알림 중요도 - 알림 개인 정보 알림 문제 해결 문제 해결 진단 @@ -650,37 +561,31 @@ 기본 진단은 괜찮습니다. 여전히 알림을 받지 못하고 있다면, 버그를 신고해서 우리가 조사할 수 있도록 도와주세요. 1개 이상의 테스트가 실패했습니다, 제안된 수정을 시도하세요. 1개 이상의 테스트가 실패했습니다, 버그를 신고해서 우리가 조사할 수 있도록 도와주세요. - 시스템 설정. 알림이 시스템 설정에서 켜집니다. 알림이 시스템 설정에서 꺼집니다. \n시스템 설정을 확인해주세요. 설정 열기 - 계정 설정. 알림이 당신의 계정에서 켜집니다. 알림이 당신의 계정에서 꺼집니다. \n계정 설정을 확인해주세요. 켜기 - 기기 설정. 알림이 이 기기에서 켜집니다. 알림이 이 기기에서 허용되지 않습니다. \n${app_name} 설정을 확인해주세요. 켜기 - 맞춤 설정. 일부 메시지 유형은 조용하게 설정되어 있습니다 (소리가 없는 알림을 생성합니다). 일부 알림이 맞춤 설정에서 꺼집니다. 맞춤 규칙을 불러오는 데 실패했습니다, 다시 시도해주세요. 설정 확인 - Play 서비스 확인 Google Play 서비스 APK는 최신 버전입니다. ${app_name}은 Google Play 서비스를 사용해 푸시 메시지를 보내지만 올바르게 설정되지 않은 모양입니다: \n%1$s Play 서비스 고치기 - Firebase 토큰 FCM 토큰이 성공적으로 검색되었습니다: \n%1$s @@ -693,27 +598,22 @@ [%1$s] \n이 오류는 ${app_name}의 통제 밖에 있습니다. 휴대 전화에 Google 계정이 없습니다. 계정 관리자를 열어 Google 계정을 추가하세요. 계정 추가 - 토큰 등록 FCM 토큰이 성공적으로 홈서버에 등록되었습니다. FCM 토큰을 홈서버에 등록 실패: \n%1$s - 알림 서비스 알림 서비스가 실행 중입니다. 알림 서비스가 실행 중이 아닙니다. \n애플리케이션을 다시 실행해보세요. 서비스 시작 - 알림 서비스 자동 다시 시작 서비스가 종료되고 자동으로 다시 시작되었습니다. 서비스 다시 시작에 실패함 - 부팅 시 시작 기기가 다시 시작되면 서비스가 시작됩니다. 기기가 다시 시작될 때 서비스가 시작되지 않습니다, 다시 시작한 후 ${app_name}을 한 번이라도 열지 않으면 알림을 받을 수 없습니다. 부팅 시 시작 활성화 - 백그라운드 제한 사항 확인 ${app_name}에 대한 백그라운드 제한 사항을 비활성화합니다. 이 테스트는 모바일 데이터를 사용해야 합니다 (WIFI 없음). \n%1$s @@ -721,12 +621,10 @@ \n앱이 백그라운드에서 작업하는 동안 앱이 시도하는 작업은 적극적으로 제한되며, 이는 알림에 영향을 줄 수 있습니다. \n%1$s 제한 사항 비활성화 - 배터리 최적화 ${app_name}은 배터리 최적화의 영향을 받지 않습니다. 사용자가 기기 화면을 끈 상태로 일정 시간 동안 연결되지 않은 상태로 두면, 기기는 Doze 모드에 들어갑니다. 이렇게 하면 앱이 네트워크에 접근하지 못하고 작업, 동기화 및 표준 경보가 지연됩니다. 최적화 무시하기 - 보통 감소된 개인 정보 보호 앱을 백그라운드에서 실행하려면 권한이 필요합니다 @@ -736,7 +634,6 @@ • 알림의 메시지 내용은 Matrix 홈서버에서 안전하게 직접 배치됩니다 • 알림은 메타데이터와 메시지 데이터를 갖습니다 • 알림은 메시지 내용을 보여주지 않습니다 - 알림 소리 이 계정에서 알림 켜기 이 기기에서 알림 켜기 @@ -745,8 +642,6 @@ 전화 알림 설정 조용한 알림 설정 LED 색상, 진동, 소리를 고르세요… - - 내 표시 이름이 들어있는 메시지 내 사용자 이름이 들어있는 메시지 1:1 대화 메시지 @@ -754,13 +649,11 @@ 방에 초대받았을 때 전화 초대 봇에게 받은 메시지 - 백그라운드 동기화 부팅 시 시작 백그라운드 동기화 켜기 동기화 요청 시간 초과 각 동기화 간 딜레이 - 버전 olm 버전 이용 약관 @@ -770,10 +663,9 @@ 미디어 유지 캐시 지우기 미디어 캐시 지우기 - 사용자 설정 알림 - 무시한 사용자 + 차단한 사용자 기타 고급 암호화 @@ -804,29 +696,23 @@ 보내기 전 미디어 미리보기 엔터 키로 메시지 보내기 가상 키보드의 엔터 버튼으로 줄 바꿈을 하는 대신 메시지를 보냅니다 - 계정 비활성화 내 계정 비활성화 - 알림 개인 정보 ${app_name}은 백그라운드에서 실행되어 알림을 안전하고 은밀하게 관리할 수 있습니다. 이것은 배터리 사용량에 영향을 줄 수 있습니다. 권한 부여 다른 설정을 선택하세요 - 백그라운드 연결 ${app_name}은 신뢰가 있는 알림을 위해 낮은 영향의 백그라운드 연결을 유지해야 합니다. \n다른 화면에서 ${app_name}이 항상 백그라운드에서 실행하도록 허용하는 메시지가 표시됩니다, 수락해주세요. 권한 부여 - 정보 분석 정보 분석 데이터 보내기 ${app_name}은 애플리케이션을 개선할 수 있도록 익명의 분석을 수집합니다. 분석을 활성화해서 ${app_name}이 개선할 수 있도록 도와주세요. 예, 저도 돕고 싶습니다! - 데이터 절약 모드 데이터 절약 모드는 특정 필터를 적용하여 현재 상태 업데이트와 입력 중 알림을 걸러냅니다. - 기기 정보 ID 공개 이름 @@ -838,16 +724,13 @@ 인증 비밀번호: 제출하기 - 이것으로 로그인 홈서버 ID 서버 통합 관리자 - 사용자 인터페이스 언어 언어를 선택하세요 - 확인 보류 중 이메일을 인증해서 거기에 있는 링크를 클릭하세요. 모두 끝나면, 계속하기를 클릭하세요. 이메일 주소를 확인할 수 없습니다. 이메일을 인증해서 거기에 있는 링크를 클릭하세요. 모두 끝나면, 계속하기를 클릭하세요. @@ -855,7 +738,6 @@ 이 이메일 주소를 찾을 수 없습니다. 이 전화번호는 이미 사용 중입니다. 이메일 주소를 확인하는 중 오류가 발생했습니다. - 비밀번호 비밀번호 변경 현재 비밀번호 @@ -869,13 +751,9 @@ \n \n이 동작은 앱을 다시 시작하고 일정 시간이 걸릴 수 있습니다. 비밀번호가 맞지 않음 - 이 알림 대상을 제거하겠습니까\? - %1$s %2$s님을 제거하겠습니까\? - 나라를 선택하세요 - 나라 나라를 선택해주세요 전화번호 @@ -887,32 +765,26 @@ 코드 전화번호를 확인하는 중 오류가 발생했습니다. 추가 정보: %s - 미디어 기본 압축 선택 기본 미디어 소스 선택 셔터 소리 재생하기 - 재능 현재는 어떤 커뮤니티의 구성원이 아닙니다. - 3일 1주 1달 영원히 - 방 사진 방 이름 주제 방 태그 이것으로 태그됨: - 즐겨찾기 중요하지 않음 없음 - 접근성 및 가시성 이 방을 방 목록에 놓기 알림 @@ -920,19 +792,15 @@ 방 기록 읽기 권한 누가 기록을 읽을 수 있나요\? 누가 이 방에 접근할 수 있나요\? - 누구나 (이 설정을 선택한 시점부터) 구성원만 (초대받은 시점부터) 구성원만 (참가한 시점부터) 구성원만 - 이 방에 링크를 타고 오려면 주소가 있어야 합니다. 초대받은 사람들만 방의 링크를 아는 누구나, 손님 제외 방의 링크를 아는 누구나, 손님 포함 - 출입 금지한 사용자 - 고급 이 방의 내부 ID 주소 @@ -943,38 +811,28 @@ 암호화를 켜기 위해 로그아웃을 해야 합니다. 확인된 기기로만 암호화 이 기기로는 방에서 확인되지 않은 기기로 암호화된 메시지를 절대 보내지 않기. - 이 방은 로컬 주소가 없습니다 새 주소 (예: #foo:matrix.org) - 이 방은 어떤 커뮤니티에도 재능을 표시하지 않습니다 새 커뮤니니 ID (예: +foo:matrix.org) 올바르지 않은 커뮤니티 ID \'%s\'은(는) 올바르지 않은 커뮤니티 ID입니다 - - 올바르지 않은 별칭 형식 \'%s\'은(는) 별칭에 올바르지 않은 형식입니다 이 방에 지정된 메인 주소가 없습니다. 메인 주소 경고 - 메인 주소로 설정 메인 주소로 설정 해제 방 ID 복사 방 주소 복사 - 이 방에서 암호화가 켜졌습니다. 이 방에서 암호화가 꺼졌습니다. 암호화 활성화 \n(경고: 다시 비활성화할 수 없음!) - 목록 테마 - %s님이 이 방의 특정 지점을 불러오려 했으나 찾을 수 없었습니다. - 종단간 암호화 정보 - 이벤트 정보 사용자 ID Curve25519 ID 키 @@ -982,7 +840,6 @@ 알고리즘 세션 ID 암호 복호화 오류 - 발신자 기기 정보 공개 이름 공개 이름 @@ -990,7 +847,6 @@ 기기 키 확인 Ed25519 핑거프린트 - 종단간 암호화 방 키 내보내기 방 키 내보내기 로컬 파일로 키 내보내기 @@ -999,51 +855,41 @@ 종단간 암호화 방 키가 \'%s\'에 저장되었습니다. \n \n경고: 애플리케이션을 삭제하면 이 파일도 삭제됩니다. - 암호화된 메시지 복구 키 백업 관리 - 종단간 암호화 방 키 가져오기 방 키 가져오기 로컬 파일에서 키 가져오기 가져오기 확인된 기기로만 암호화 이 기기에서 확인되지 않은 기기로 절대 암호화된 메시지를 보내지 않습니다. - 확인되지 않음 확인됨 블랙리스트 대상 - 알 수 없는 기기 알 수 없는 ip 없음 - 확인 확인하지 않음 블랙리스트 블랙리스트 제외 - 기기 확인 이 기기가 신뢰할 수 있는 지 확인하려면, 다른 방법을 사용하여 소유자에게 연락하세요 (예: 현실에서 혹은 전화로) 그리고 이 기기의 사용자 설정에서 표시된 키가 아래에 있는 키와 맞는지 물어보세요: 그것이 맞다면, 아래의 확인 버튼을 누르세요. 맞지 않다면, 다른 사람이 이 기기를 가로채고 있는 것이고 블랙리스트에 올려야 합니다. 앞으로 이 확인 절차는 더 정교해질 것입니다. 키가 맞다는 것은 확인합니다 - 알 수 없는 기기가 있는 방 이 방에는 확인되지 않은 알 수 없는 기기가 있습니다. \n즉, 사용자에 속해 있다고 주장하는 기기라는 보장이 없습니다. \n저희는 계속하기 전에 각 기기에 확인 절차를 하기를 권합니다, 하지만 원한다면 확인하지 않고 바로 메시지를 보낼 수 있습니다. \n \n알 수 없는 기기: - 방 목록 선택 서버를 이용할 수 없거나 과부하 상태입니다 공개 서버를 표시할 홈서버를 입력하세요 홈서버 URL %s 서버의 모든 방 모든 기본 %s 방 - 여기에 입력… - %d개의 읽지 않은 알림 메시지 @@ -1053,14 +899,12 @@ %d개의 방 - %1$s: %2$d개의 메시지 %d개의 알림 - %2$s에서 %1$s님 새 이벤트 @@ -1068,9 +912,7 @@ 새 초대 ** 보내기 실패 - 방을 열어주세요 - 기록 검색 - 글씨 크기 매우 작게 작게 @@ -1079,7 +921,6 @@ 더 크게 매우 크게 가장 크게 - 이 방에서 위젯을 다루려면 권한이 있어야 합니다 위젯 생성 실패 Jitsi로 회의 전화 만들기 @@ -1087,9 +928,7 @@ %d개의 활성 위젯 - 죄송합니다, Jitsi로 회의 전화는 오래된 기기에서 지원하지 않습니다 (안드로이드 OS가 6.0 이하인 기기) - 위젯을 만들 수 없습니다. 요청을 보낼 수 없습니다. 권한 등급은 양의 정수이어야 합니다. @@ -1107,7 +946,6 @@ 키보드 엔터 키로 메시지 보내기 음성 메시지 보내기 이 설정은 메시지를 기록하기 위한 제 3자 애플리케이션이 필요합니다. - 새 기기 \'%s\'을(를) 추가했습니다, 여기에는 암호화 키가 필요합니다. 새 기기에는 암호화 키가 필요합니다. \n기기 이름: %1$s @@ -1118,7 +956,6 @@ \n기기 이름: %1$s \n마지막으로 본 순간: %2$s \n다른 기기에서 로그인하지 않았다면, 이 요청을 무시하세요. - 확인 시작 확인 확인하지 않고 공유 @@ -1126,10 +963,8 @@ 키 공유 요청 요청 무시하기 무시 - 경고! 회의 전화는 개발 중이며 신뢰할 수 없을 수 있습니다. - 명령어 오류 인식할 수 없는 명령어: %s \"%s\" 명령어는 더 많은 매개 변수가 필요하거나, 일부 매개 변수가 옳지 않습니다. @@ -1146,56 +981,44 @@ 표시 별명 바꾸기 마크다운 On/Off Matrix 앱 관리 문제를 해결하려면 - 마크다운이 켜졌습니다. 마크다운이 꺼졌습니다. - 조용히 소리 - 암호화된 메시지 - 만들기 커뮤니티 만들기 커뮤니티 이름 예시 커뮤니티 ID 예시 - 사람 사용자 없음 - 참가함 초대받음 구성원 그룹 필터 방 그룹 필터 - %d명의 구성원 - %d개의 방 커뮤니티 관리자가 이 커뮤니티에 대한 자세한 설명을 제공하지 않았습니다. - %2$s님에 의해 %1$s 방에서 추방당했습니다 %2$s님에 의해 %1$s 방에서 출입 금지당했습니다 이유: %1$s 다시 참가하기 방 잊어버리기 - 아바타 메모 아바타 공지 아바타 - %1$s 홈서버를 계속 사용하려면 이용 약관을 검토하고 승인해야 합니다. 지금 검토하기 - 계정 비활성화 이것으로 계정은 영구적으로 사용할 수 없게 됩니다. 로그인할 수 없고 누구도 같은 사용자 ID로 다시 등록할 수 없게 됩니다. 이 계정으로 참가한 모든 방에서 떠나게 되고, ID 서버의 계정 세부 사항도 삭제됩니다. 이 행동은 돌이킬 수 없습니다. \n @@ -1205,58 +1028,44 @@ 내 계정을 비활성화하면 내가 보낸 모든 메시지는 잊어주세요 (경고: 이것은 미래 사용자가 불완전한 대화를 읽게 됩니다) 계속하려면, 비밀번호를 입력하세요: 계정 비활성화 - 사용자 이름을 입력하세요. 비밀번호를 입력하세요. 이 방은 교체되었으며 더 이상 활동하지 않습니다 대화는 여기서 계속됩니다 이 방은 다른 대화의 연장선입니다 오래된 메시지를 보려면 여기를 클릭 - 리소스 한도 초과됨 관리자 연락 - 서비스 관리자에게 연락 - 이 홈서버가 리소스 한도를 초과해서 일부 사용자는 로그인할 수 없습니다. 이 홈서버가 리소스 한도를 초과했습니다. - 이 홈서버가 월 간 활성 사용자 한도를 초과해서 일부 사용자는 로그인할 수 없습니다. 이 홈서버가 월 간 활성 사용자 한도를 초과했습니다. - 한도를 높이려면 %s하세요. 이 서비스 사용을 계속하려면 %s하세요. - 방 구성원 불러오기 지연 첫 화면에서 방 멤버만 불러옴으로써 퍼포먼스를 향상시킵니다. 아직 홈서버가 방 구성원 불러오기 지연을 지원하지 않습니다. 나중에 시도하세요. - 죄송합니다, 오류가 발생했습니다 - 펼치기 접기 - 정보 영역 보이기 항상 메시지와 오류일 시 오류만 - %1$s: %1$s: %2$s +%d %d+ 올바른 Google Play 서비스 APK를 찾을 수 없습니다. 알림이 제대로 작동하지 않을 수 있습니다. - 암호 만들기 암호 확인 암호 입력 암호가 맞지 않음 암호를 입력하세요 암호가 너무 약합니다 - ${app_name}으로 복구 키를 생성하려면 암호를 지워주세요. 이용할 수 있는 Matrix 세션이 없음 - 암호화된 메시지를 잃지 마세요 암호화된 방의 메시지는 종단간 암호화로 보호됩니다. 자신과 수신자만이 메시지를 읽을 수 있는 키를 갖습니다. \n @@ -1264,7 +1073,6 @@ 키 백업 시작 (고급) 수동으로 키 내보내기 - 암호로 백업을 보호하세요. 홈서버에 암호화된 키의 사본을 저장합니다. 보안을 유지하기 위해 암호로 백업을 보호하세요. \n @@ -1286,12 +1094,10 @@ 복구 키가 \'%s\'(으)로 저장되었습니다. \n \n경고: 이 파일은 애플리케이션이 삭제되면 함께 삭제됩니다. - 백업이 이미 홈서버에 존재합니다 이미 키 백업을 다른 기기에 설정한 모양입니다. 만들고 있는 것으로 바꾸겠습니까\? 바꾸기 멈추기 - 사본을 만들어 주세요 복구 키 공유… 암호를 사용해 복구 키를 생성하는 것은 시간이 걸릴 수 있습니다. @@ -1299,25 +1105,18 @@ 예기치 않은 오류 백업 시작함 이제 암호화 키가 백그라운드에서 홈서버로 백업됩니다. 처음 백업에는 몇 분이 걸릴 수 있습니다. - - 확신합니까\? 로그아웃을 하거나 이 기기를 잃어버리면 메시지에 접근할 수 없게 될지도 모릅니다. - 백업 버전 가져오는 중… 복구 암호를 사용해서 암호화된 메시지 기록을 풀기 복구 키를 사용 복구 암호가 기억나지 않는다면, %s할 수 있습니다. - 복구 키를 사용해서 암호화된 메시지 기록을 풀기 복구 키 입력 - 메시지 복구 - 복구 키를 잃어버렸나요\? 설정에서 새로운 키를 만들 수 있습니다. 이 암호로 백업을 복호화할 수 없습니다: 올바른 복구 암호를 입력해서 확인해주세요. 네트워크 오류: 인터넷 연결 상태를 확인하고 다시 시도해주세요. - 백업 복구: 복구 키 계산 중… 키 다운로드 중… @@ -1325,7 +1124,6 @@ 기록 풀기 복구 키를 입력하세요 이 복구 키로 백업을 복호화할 수 없습니다: 올바른 복구 키를 입력해서 확인해주세요. - 백업이 복구되었습니다 %s ! %d개의 키와 함께 백업을 복구했습니다. @@ -1333,18 +1131,13 @@ %d개의 새 키가 이 기기에 추가되었습니다. - 최신 복구 키 버전을 가져오는 데 실패했습니다 (%s). 세션 암호화가 활성화되지 않았습니다 - - 백업에서 복구 백업 삭제 - 이 기기를 위한 키 백업이 올바르게 설정되었습니다. 이 기기에서 키 백업이 활성화되지 않았습니다. 이 기기에서 키가 아직 백업되지 않았습니다. - 백업이 ID %s의 알 수 없는 기기의 서명이 있습니다. 백업이 이 기기의 올바른 서명이 있습니다. 백업이 확인된 기기 %s의 올바른 서명이 있습니다. @@ -1352,15 +1145,12 @@ 백업이 확인된 기기 %s의 올바르지 않은 서명이 있습니다 백업이 확인되지 않은 기기 %s의 올바르지 않은 서명이 있습니다 백업에 대한 신뢰 정보를 주지 못했습니다 (%s). - 이 기기에서 키 백업을 사용하려면, 지금 암호나 복구 키를 복구하세요. 백업 삭제 중… 백업 삭제에 실패함 (%s) - 백업 상태 확인하기 백업 삭제 서버에서 백업한 암호화 키를 삭제하겠습니까\? 더 이상 복구 키를 사용해 암호화된 메시지 기록을 읽을 수 없습니다. - 새 키 백업 새 보안 메시지 키 백업이 삭제되었습니다. \n @@ -1368,65 +1158,50 @@ 접니다 암호화된 메시지를 잃지 마세요 키 백업 시작 - 암호화된 메시지를 잃지 마세요 키 백업하기 - 새 암호화된 메시지 키 키 백업에서 관리 - 키 백업 중… - 모든 키가 백업됨 %d개의 키를 백업 중… - 버전 알고리즘 서명 - 잘못된 홈서버 검색 응답 자동 완성 서버 설정 ${app_name}이 userId 도메인 \"%1$s\"에 대한 맞춤 서버 설정을 감지했습니다: \n%2$s 설정 사용 - 올바르지 않거나 만료된 자격 때문에 로그아웃되었습니다. - 짧은 문장과 비교하여 확인하세요. 보안을 최대화하려면, 상대방과 직접 대면하거나 신뢰할 수 있는 다른 대화 수단을 사용하는 것이 좋습니다. 확인 시작 수신 확인 요청 이 기기를 확인하여 신뢰할 수 있는 것으로 표시하세요. 종단간 암호화 메시지를 사용하는 경우 상대방의 기기를 신뢰하면 안심할 수 있습니다. 이 기기를 확인하여 신뢰할 수 있는 것으로 표시하세요, 그리고 당신의 기기도 상대방에게 신뢰할 수 있는 것으로 표시하세요. - 다음 이모지가 상대방의 화면에 나타나는 것을 확인하는 것으로 이 기기를 인증합니다 다음 숫자가 상대방의 화면에 나타나는 것을 확인하는 것으로 이 기기를 인증합니다 - 수신 확인 요청을 받았습니다. 요청 보기 상대방이 확인하기를 기다리는 중… - 확인되었습니다! 성공적으로 이 기기를 확인했습니다. 이 사용자 간의 보안 메시지는 종단간 암호화 되며 제 3자가 읽을 수 없습니다. 알겠습니다 - 아무것도 안 나타나나요\? 일부 클라이언트는 아직 대화 식 확인을 지원하지 않습니다. 옛날 확인 방식을 사용하세요. 옛날 확인 방식 사용하기. - 키 확인 요청 취소됨 상대방이 확인을 취소했습니다. \n%s 확인이 취소되었습니다. \n이유: %s - 상호작용 기기 확인 확인 요청 %s님이 당신의 기기를 확인하고 싶습니다 - 사용자가 확인을 취소했습니다 확인 과정 시간이 초과되었습니다 기기는 이 처리에 대해 모릅니다 @@ -1438,16 +1213,12 @@ 키 맞지 않음 사용자 맞지 않음 알 수 없는 오류 - - 편집 답장 - 다시 시도 앱을 시작하면 방에 참가하기. 초대장을 보냈습니다 %1$s 님이 초대했습니다 - 모두 읽었습니다! 더 이상 읽지 않은 메시지가 없습니다 홈에 온 것을 환영합니다! @@ -1456,19 +1227,15 @@ 다이렉트 메시지 대화가 여기에 표시됩니다 방이 여기 표시됩니다 - 리액션 동의 좋아요 리액션 추가 리액션 보기 리액션 - 사용자가 감춘 이벤트 방 관리자가 감춘 이벤트 %1$s님이 %2$s에 마지막으로 편집함 - - 잘못된 이벤트, 표시할 수 없음 새 방 만들기 네트워크 없음. 인터넷 연결 상태를 확인하세요. @@ -1476,13 +1243,10 @@ 네트워크 변경 기다려주세요… 모든 커뮤니티 - 이 방은 미리 볼 수 없습니다 세계가 읽을 수 있는 방의 미리보기는 아직 ${app_name}X에서 지원하지 않습니다 - 다이렉트 메시지 - 새 방 만들기 방 이름 @@ -1490,18 +1254,13 @@ 누구나 이 방에 참가할 수 있습니다 방 목록 이 방을 방 목록에 게시 - 신뢰 정보를 얻는 과정에서 오류가 발생했습니다 키 백업 데이터를 얻는 과정에서 오류가 발생했습니다 - 파일 \"%1$s\"에서 종단간 암호화 키 가져옴. - Matrix SDK 버전 다른 제 3자 고지 이 방을 이미 봤습니다! - 빠른 리액션 - 기본 환경 설정 보안 & 개인 @@ -1509,91 +1268,65 @@ 푸시 규칙 푸시 규칙이 정의되지 않음 등록된 푸시 게이트웨이가 없음 - app_id: push_key: app_display_name: device_name: Url: Format: - 음성 & 영상 도움 & 정보 - - 등록 토큰 - 제안하기 아래에 당신의 제안을 적어주세요. 여기에 당신의 제안을 설명 감사합니다, 제안을 성공적으로 보냈습니다 제안을 보내는 데 실패함 (%s) - 타임라인에서 숨겨진 이벤트 보이기 - 다이렉트 메시지 - 기다리세요… 썸네일 암호화 중… 썸네일 보내는 중 (%1$s / %2$s) 파일 암호화 중… 파일 보내는 중 (%1$s / %2$s) - 파일 %1$s 다운로드하는 중… 파일 %1$s을(를) 다운로드했습니다! - (편집됨) - - 메시지 편집 수정 사항이 없음 - 대화 필터… 원하는 것을 찾을 수 없나요\? 새 방 만들기 새 다이렉트 메시지 보내기 방 목록 보기 - 이름 혹은 ID (#예시:matrix.org) - 타임라인에서 스와이프로 답장 기능 켜기 - 클립보드에 링크 복사 - Matrix ID로 추가 방 만드는 중… 결과가 없습니다, Matrix ID로 추가를 사용하여 서버를 검색하세요. 결과를 얻기 위해 검색 시작 사용자 이름 또는 ID로 필터… - 방에 참가하는 중… - 편집 기록 보기 - 검토 끊기 - 계속 하려면 이 서비스 약관에 동의해야 합니다. - 서비스 약관 조건 검토 다른 사람이 검색할 수 있음 봇, 브릿지, 위젯과 스티커 팩을 사용하세요 - 읽은 시간 - 없음 취소 연결 해제 설정된 ID 서버가 없습니다. - 잘놋 설정된 서버로 인해 전화에 실패함 전화가 정상적으로 작동하도록 TURN 서버를 설정하려면 홈서버 (%1$s)의 관리자에게 연락해주세요. \n \n아니면 %2$s에서 공개 서버를 사용할 수 있습니다, 하지만 신뢰할 수 없고 서버와 IP 주소를 공유하게 됩니다. 설정에서 이것을 관리할 수도 있습니다. %s 사용하기 다시 묻지 않기 - 계정 복구 용 이메일을 설정합니다, 그리고 이후 알고 있는 사람들이 당신을 찾을 수 있는지 여부를 선택할 수 있습니다. 전화를 설정합니다, 그리고 이후 알고 있는 사람들이 당신을 찾을 수 있는지 여부를 선택할 수 있습니다. 계정 복구 용 이메일을 설정합니다. 이메일이나 전화로 이후 알고 있는 사람들이 당신을 찾을 수 있는지 여부를 선택하는데 사용됩니다. @@ -1612,8 +1345,6 @@ 백그라운드 동기화 없음 앱이 백그라운드에 있을 때 수신 메시지의 알림을 받지 않습니다. 설정을 업데이트하는데 실패했습니다. - - 원하는 동기화 간격 %s \n동기화는 자원 (배터리)이나 기기의 상태 (수면)에 따라 지연됩니다. @@ -1623,9 +1354,7 @@ 기기의 공개 이름은 대화하는 사람들에게 보여집니다 ID 서버를 사용하고 있지 않습니다 설정된 ID 서버가 없습니다, 비밀번호를 초기화하려면 ID 서버가 필요합니다. - 다른 홈서버로 연결을 시도합니다. 로그아웃하겠습니까\? - ID 서버 ID 서버 연결 해제 ID 서버 설정 @@ -1639,27 +1368,19 @@ 전화번호로 찾을 수 있음 %s(으)로 확인 이메일을 보냈습니다, 이메일을 확인하고 확인 링크를 클릭하세요 보류 중 - 새 ID 서버를 입력 ID 서버에 연결할 수 없음 ID 서버 URL을 입력해주세요 ID 서버가 서비스 약관이 없습니다 선택한 ID 서버가 서비스 약관이 없습니다. 서비스의 소유자를 신뢰하는 경우에만 계속하세요 %s(으)로 문자 메시지를 보냈습니다. 문자에 있는 확인 코드를 입력해주세요. - 현재 이메일 주소나 전화번호를 ID 서버 %1$s와 공유하고 있습니다. 공유하기를 중지하려면 %2$s(으)로 다시 연결해야 합니다. ID 서버 (%s)의 서비스 약관에 동의하면 다른 사용자가 당신을 이메일 주소나 전화번호로 찾을 수 있게 됩니다. - 상세 로그 켜기. 상세 로그는 분노의 흔들기를 보낼 때 더 많은 로그를 제공해서 개발자에게 도움을 줍니다. 이 설정을 켜도 애플리케이션은 메시지 내용이나 다른 개인 정보를 기록하지 않습니다. - - 홈서버의 이용 약관에 동의한 후 다시 시도해주세요. - 서버의 응답 시간이 지연되고 있습니다. 연결 상태가 좋지 않거나 서버에서 오류가 발생했을지도 모릅니다. 나중에 다시 시도해주세요. - 첨부 파일 보내기 - 내비게이션 서랍 열기 방 만들기 메뉴 열기 방 만들기 메뉴 닫기… @@ -1669,16 +1390,13 @@ 비밀번호 보이기 비밀번호 감추기 맨 아래로 건너뛰기 - %1$s님, %2$s님 그리고 %3$s님이 읽음 %1$s님 그리고 %2$s님이 읽음 %s님이 읽음 %d명이 읽음 - 파일 \'%1$s\' (%2$s)이(가) 업로드하기에 너무 큽니다. 제한은 %3$s입니다. - 첨부 파일을 검색하는 중 오류가 발생했습니다. 파일 연락처 @@ -1687,7 +1405,6 @@ 갤러리 스티커 공유 데이터를 처리할 수 없음 - 스팸 문자입니다 부적절한 문자입니다 맞춤 신고 @@ -1695,7 +1412,6 @@ 이 내용을 신고하는 이유 신고 사용자 출입 금지 - 내용 신고됨 이 내용을 신고했습니다. \n @@ -1708,18 +1424,63 @@ 이 내용을 부적절한 문자로 신고했습니다. \n \n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다 - ${app_name}은 종단간 키를 디스크에 저장하려면 권한이 필요합니다. \n \n키를 수동으로 내보내려면 다음 팝업에서 접근을 허용해주세요. - 현재 네트워크 연결이 없습니다 - 비밀번호가 정확하지 않습니다 라이엇 모바일에서 불가능한 것입니다 인증이 요구됩니다 - - 통합 통합 수락 - + 설명 + 주제 + 주제 추가 + 주제 + 방 주제 (선택) + 주제 변경 + 이 방의 메시지는 종단간 암호화가 적용되었습니다. + 이 방의 메시지는 종단간 암호화가 적용되었습니다. 더보기 & 프로필을 통해 검증. + 이 방의 메시지는 종단간 암호화가 적용됩니다. +\n +\n메시지는 암호화되어 보호되며, 메시지를 복호화할 수 있는 고유 키는 사용자와 수신자만 가지고 있습니다. + 이 방의 메시지는 종단간 암호화가 적용되지 않습니다. + 더보기 + 보안 + 이 계정에 연결된 전화번호가 없습니다 + 전화번호 + 이 계정에 연결된 이메일 주소가 없습니다 + 이메일 주소 + Matrix 계정에 연결된 이메일과 전화번호를 관리합니다 + 이메일과 전화번호 + 메시지 입력란에 이모지 키보드 버튼을 추가합니다. + 이모지 키보드 표시 + 삭제된 메시지를 대화에 표시합니다 + 삭제된 메시지 표시 + 알림과 함께 이메일을 받으려면 Matrix 계정에 이메일을 연결해주세요 + 이메일 알림 + 기타 + SSL 에러. + 새로운 비밀번호 설정하기… + 내 QR코드 공유하기 + QR 코드가 스캔되지 않았습니다! + QR 코드 스캔 + 아니오 + + QR 코드로 추가 + 친구 초대 + 회의는 Jitsi의 보안 및 권한 정책을 사용합니다. 회의가 진행되는 동안 방에 있는 사람들이 참여 버튼을 통해 참가할 수 있습니다. + 전화 회의 시작 + 화상회의 시작 + 회의가 이미 진행 중입니다! + 전화를 걸 수 있는 권한이 없습니다 + 이 방에서 전화를 걸 수 있는 권한이 없습니다 + 전화 회의를 시작할 수 있는 권한이 없습니다 + 이 방에서 전화 회의를 시작할 수 있는 권한이 없습니다 + 권한 없음 + 이 작업을 수행하려면 시스템 설정에서 카메라 권한을 허용해주세요. + 이 작업을 수행할 수 있는 일부 권한이 없습니다. 시스템 설정에서 권한을 허용해주세요. + 일시 정지 + 재생 + 음성 메시지를 보내려면 마이크 권한을 허용해주세요. + \ No newline at end of file From c7fa40fd463ff0c59e95940c5c5128e0725dc733 Mon Sep 17 00:00:00 2001 From: Kiel Date: Tue, 19 Oct 2021 19:45:13 +0000 Subject: [PATCH 055/970] Translated using Weblate (English (United Kingdom)) Currently translated at 0.7% (21 of 2672 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/en_GB/ --- vector/src/main/res/values-en-rGB/strings.xml | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-en-rGB/strings.xml b/vector/src/main/res/values-en-rGB/strings.xml index a6b3daec93..76003bbc69 100644 --- a/vector/src/main/res/values-en-rGB/strings.xml +++ b/vector/src/main/res/values-en-rGB/strings.xml @@ -1,2 +1,24 @@ - \ No newline at end of file + + Extend & customise your experience + Filter favourites + Remove from favourites + Add to favourites + FAVOURITES + Synchronising Self Signing key + Synchronising User key + Synchronising Master key + Initialise CrossSigning + Your email domain is not authorised to register on this server + Unrecognised command: %s + Optimised for real time + Optimised for battery + Background synchronisation + Ignore Optimisation + ${app_name} is not affected by Battery Optimisation. + Battery Optimisation + De-prioritise + Cannot initialise the camera + Unauthorised, missing valid authentication credentials + Initialising service + \ No newline at end of file From 628ccdc328410a6ec6b021fc3642c77e2a47a1e8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Oct 2021 09:16:56 +0200 Subject: [PATCH 056/970] Add English - GB to the list of languages --- vector/src/main/res/values-en-rGB/strings_no_weblate.xml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 vector/src/main/res/values-en-rGB/strings_no_weblate.xml diff --git a/vector/src/main/res/values-en-rGB/strings_no_weblate.xml b/vector/src/main/res/values-en-rGB/strings_no_weblate.xml new file mode 100644 index 0000000000..a57e7ca631 --- /dev/null +++ b/vector/src/main/res/values-en-rGB/strings_no_weblate.xml @@ -0,0 +1,8 @@ + + + + en + GB + Latn + + \ No newline at end of file From 367795ee24aba444d8ad23c5ccf36fc8d6b3d757 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Oct 2021 09:29:15 +0200 Subject: [PATCH 057/970] Fix crash reported by the PlayStore, for release 1.3.4 I did not find a way to reproduce, but this change should add some safety --- .../app/features/home/room/detail/RoomDetailFragment.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 473a993395..7461b89001 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 @@ -641,9 +641,11 @@ class RoomDetailFragment @Inject constructor( } } .setOnEmojiPopupDismissListener { - views.composerLayout.views.composerEmojiButton.apply { - contentDescription = getString(R.string.a11y_open_emoji_picker) - setImageResource(R.drawable.ic_insert_emoji) + if (isAdded) { + views.composerLayout.views.composerEmojiButton.apply { + contentDescription = getString(R.string.a11y_open_emoji_picker) + setImageResource(R.drawable.ic_insert_emoji) + } } } .build(views.composerLayout.views.composerEditText) From e536e1c78510212be7515b2fd0249163dc166ed4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Oct 2021 10:42:12 +0200 Subject: [PATCH 058/970] Run towncrier --- CHANGES.md | 36 ++++++++++++++++++++++++++++++++++++ changelog.d/2909.feature | 1 - changelog.d/3437.bugfix | 1 - changelog.d/3608.bugfix | 1 - changelog.d/3774.bugfix | 1 - changelog.d/3890.misc | 1 - changelog.d/4006.bugfix | 1 - changelog.d/4090.feature | 1 - changelog.d/4106.bugfix | 2 -- changelog.d/4162.bugfix | 1 - changelog.d/4167.bugfix | 1 - changelog.d/4193.bugfix | 1 - changelog.d/4201.bugfix | 1 - changelog.d/4216.misc | 1 - changelog.d/4221.bugfix | 1 - changelog.d/4226.misc | 1 - changelog.d/4234.bugfix | 1 - changelog.d/4247.bugfix | 1 - changelog.d/4250.misc | 1 - changelog.d/4261.bugfix | 1 - changelog.d/4264.misc | 1 - changelog.d/465.misc | 1 - changelog.d/908.bugfix | 1 - 23 files changed, 36 insertions(+), 23 deletions(-) delete mode 100644 changelog.d/2909.feature delete mode 100644 changelog.d/3437.bugfix delete mode 100644 changelog.d/3608.bugfix delete mode 100644 changelog.d/3774.bugfix delete mode 100644 changelog.d/3890.misc delete mode 100644 changelog.d/4006.bugfix delete mode 100644 changelog.d/4090.feature delete mode 100644 changelog.d/4106.bugfix delete mode 100644 changelog.d/4162.bugfix delete mode 100644 changelog.d/4167.bugfix delete mode 100644 changelog.d/4193.bugfix delete mode 100644 changelog.d/4201.bugfix delete mode 100644 changelog.d/4216.misc delete mode 100644 changelog.d/4221.bugfix delete mode 100644 changelog.d/4226.misc delete mode 100644 changelog.d/4234.bugfix delete mode 100644 changelog.d/4247.bugfix delete mode 100644 changelog.d/4250.misc delete mode 100644 changelog.d/4261.bugfix delete mode 100644 changelog.d/4264.misc delete mode 100644 changelog.d/465.misc delete mode 100644 changelog.d/908.bugfix diff --git a/CHANGES.md b/CHANGES.md index c545a70671..8de71eae62 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,39 @@ +Changes in Element v1.3.4 (2021-10-20) +====================================== + +Features ✨ +---------- + - Implement /part command, with or without parameter ([#2909](https://github.com/vector-im/element-android/issues/2909)) + - Handle Presence support, for Direct Message room ([#4090](https://github.com/vector-im/element-android/issues/4090)) + +Bugfixes 🐛 +---------- + - Issue #908 Adding trailing space " " or ": " if the user started a sentence by mentioning someone, ([#908](https://github.com/vector-im/element-android/issues/908)) + - Fixes reappearing notifications when dismissing notifications from slow homeservers or delayed /sync responses ([#3437](https://github.com/vector-im/element-android/issues/3437)) + - Catching event decryption crash and logging when attempting to markOlmSessionForUnwedging fails ([#3608](https://github.com/vector-im/element-android/issues/3608)) + - Fixing notification sounds being triggered for every message, now they only trigger for the first, consistent with the vibrations ([#3774](https://github.com/vector-im/element-android/issues/3774)) + - Voice Message not sendable if recorded while flight mode was on ([#4006](https://github.com/vector-im/element-android/issues/4006)) + - Fixes push notification emails list not refreshing the first time seeing the notifications page. + Also improves the error handling in the email notification toggling by using synchronous flows instead of the WorkManager ([#4106](https://github.com/vector-im/element-android/issues/4106)) + - Make MegolmBackupAuthData.signatures optional for robustness ([#4162](https://github.com/vector-im/element-android/issues/4162)) + - Fixing push notifications starting the looping background sync when the push notification causes the application to be created. ([#4167](https://github.com/vector-im/element-android/issues/4167)) + - Fix random crash when user logs out just after the log in. ([#4193](https://github.com/vector-im/element-android/issues/4193)) + - Make the font size selection dialog scrollable ([#4201](https://github.com/vector-im/element-android/issues/4201)) + - Fix conversation notification for sent messages ([#4221](https://github.com/vector-im/element-android/issues/4221)) + - Fixes the developer sync options being displayed in the home menu when developer mode is disabled ([#4234](https://github.com/vector-im/element-android/issues/4234)) + - Restore support for Android Auto as sent messages are no longer read aloud ([#4247](https://github.com/vector-im/element-android/issues/4247)) + - Fix crash on slash commands Exceptions ([#4261](https://github.com/vector-im/element-android/issues/4261)) + +Other changes +------------- + - Scrub user sensitive data like gps location from images when sending on original quality ([#465](https://github.com/vector-im/element-android/issues/465)) + - Migrate to MvRx2 (Mavericks) ([#3890](https://github.com/vector-im/element-android/issues/3890)) + - Implement a new github action workflow to generate two PRs for emoji and sas string sync ([#4216](https://github.com/vector-im/element-android/issues/4216)) + - Improve wording around rageshakes in the defect issue template. ([#4226](https://github.com/vector-im/element-android/issues/4226)) + - Add automation to move incoming issues and X-Needs-Info into the right places on the issue triage board. ([#4250](https://github.com/vector-im/element-android/issues/4250)) + - Uppon sharing image compression fails, return the original image ([#4264](https://github.com/vector-im/element-android/issues/4264)) + + Changes in Element v1.3.3 (2021-10-11) ====================================== diff --git a/changelog.d/2909.feature b/changelog.d/2909.feature deleted file mode 100644 index 4d72734192..0000000000 --- a/changelog.d/2909.feature +++ /dev/null @@ -1 +0,0 @@ -Implement /part command, with or without parameter \ No newline at end of file diff --git a/changelog.d/3437.bugfix b/changelog.d/3437.bugfix deleted file mode 100644 index 11e493e1ba..0000000000 --- a/changelog.d/3437.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixes reappearing notifications when dismissing notifications from slow homeservers or delayed /sync responses \ No newline at end of file diff --git a/changelog.d/3608.bugfix b/changelog.d/3608.bugfix deleted file mode 100644 index 5f219ab319..0000000000 --- a/changelog.d/3608.bugfix +++ /dev/null @@ -1 +0,0 @@ -Catching event decryption crash and logging when attempting to markOlmSessionForUnwedging fails \ No newline at end of file diff --git a/changelog.d/3774.bugfix b/changelog.d/3774.bugfix deleted file mode 100644 index 9145771bae..0000000000 --- a/changelog.d/3774.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixing notification sounds being triggered for every message, now they only trigger for the first, consistent with the vibrations \ No newline at end of file diff --git a/changelog.d/3890.misc b/changelog.d/3890.misc deleted file mode 100644 index 3bace80fa7..0000000000 --- a/changelog.d/3890.misc +++ /dev/null @@ -1 +0,0 @@ -Migrate to MvRx2 (Mavericks) \ No newline at end of file diff --git a/changelog.d/4006.bugfix b/changelog.d/4006.bugfix deleted file mode 100644 index 61ac98ccb8..0000000000 --- a/changelog.d/4006.bugfix +++ /dev/null @@ -1 +0,0 @@ -Voice Message not sendable if recorded while flight mode was on \ No newline at end of file diff --git a/changelog.d/4090.feature b/changelog.d/4090.feature deleted file mode 100644 index be8aa317a6..0000000000 --- a/changelog.d/4090.feature +++ /dev/null @@ -1 +0,0 @@ -Handle Presence support, for Direct Message room \ No newline at end of file diff --git a/changelog.d/4106.bugfix b/changelog.d/4106.bugfix deleted file mode 100644 index 6ca030f8c4..0000000000 --- a/changelog.d/4106.bugfix +++ /dev/null @@ -1,2 +0,0 @@ -Fixes push notification emails list not refreshing the first time seeing the notifications page. -Also improves the error handling in the email notification toggling by using synchronous flows instead of the WorkManager \ No newline at end of file diff --git a/changelog.d/4162.bugfix b/changelog.d/4162.bugfix deleted file mode 100644 index 833ed2f1b8..0000000000 --- a/changelog.d/4162.bugfix +++ /dev/null @@ -1 +0,0 @@ -Make MegolmBackupAuthData.signatures optional for robustness \ No newline at end of file diff --git a/changelog.d/4167.bugfix b/changelog.d/4167.bugfix deleted file mode 100644 index 8df264d8f6..0000000000 --- a/changelog.d/4167.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixing push notifications starting the looping background sync when the push notification causes the application to be created. diff --git a/changelog.d/4193.bugfix b/changelog.d/4193.bugfix deleted file mode 100644 index a395e70cee..0000000000 --- a/changelog.d/4193.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix random crash when user logs out just after the log in. \ No newline at end of file diff --git a/changelog.d/4201.bugfix b/changelog.d/4201.bugfix deleted file mode 100644 index fa8e506015..0000000000 --- a/changelog.d/4201.bugfix +++ /dev/null @@ -1 +0,0 @@ -Make the font size selection dialog scrollable diff --git a/changelog.d/4216.misc b/changelog.d/4216.misc deleted file mode 100644 index acf5f1dbcb..0000000000 --- a/changelog.d/4216.misc +++ /dev/null @@ -1 +0,0 @@ -Implement a new github action workflow to generate two PRs for emoji and sas string sync diff --git a/changelog.d/4221.bugfix b/changelog.d/4221.bugfix deleted file mode 100644 index 76c66898b1..0000000000 --- a/changelog.d/4221.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix conversation notification for sent messages diff --git a/changelog.d/4226.misc b/changelog.d/4226.misc deleted file mode 100644 index ac7a294f35..0000000000 --- a/changelog.d/4226.misc +++ /dev/null @@ -1 +0,0 @@ -Improve wording around rageshakes in the defect issue template. diff --git a/changelog.d/4234.bugfix b/changelog.d/4234.bugfix deleted file mode 100644 index e7b46a6186..0000000000 --- a/changelog.d/4234.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixes the developer sync options being displayed in the home menu when developer mode is disabled \ No newline at end of file diff --git a/changelog.d/4247.bugfix b/changelog.d/4247.bugfix deleted file mode 100644 index da8ca300b4..0000000000 --- a/changelog.d/4247.bugfix +++ /dev/null @@ -1 +0,0 @@ -Restore support for Android Auto as sent messages are no longer read aloud diff --git a/changelog.d/4250.misc b/changelog.d/4250.misc deleted file mode 100644 index c4d2fcbd6d..0000000000 --- a/changelog.d/4250.misc +++ /dev/null @@ -1 +0,0 @@ -Add automation to move incoming issues and X-Needs-Info into the right places on the issue triage board. diff --git a/changelog.d/4261.bugfix b/changelog.d/4261.bugfix deleted file mode 100644 index 4283335131..0000000000 --- a/changelog.d/4261.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix crash on slash commands Exceptions \ No newline at end of file diff --git a/changelog.d/4264.misc b/changelog.d/4264.misc deleted file mode 100644 index 601abbf792..0000000000 --- a/changelog.d/4264.misc +++ /dev/null @@ -1 +0,0 @@ -Uppon sharing image compression fails, return the original image diff --git a/changelog.d/465.misc b/changelog.d/465.misc deleted file mode 100644 index 709d1f1957..0000000000 --- a/changelog.d/465.misc +++ /dev/null @@ -1 +0,0 @@ -Scrub user sensitive data like gps location from images when sending on original quality diff --git a/changelog.d/908.bugfix b/changelog.d/908.bugfix deleted file mode 100644 index f43b03e892..0000000000 --- a/changelog.d/908.bugfix +++ /dev/null @@ -1 +0,0 @@ -Issue #908 Adding trailing space " " or ": " if the user started a sentence by mentioning someone, From d5f2a6179d8ed66ec5f23f48086ab6018723e21b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Oct 2021 10:44:20 +0200 Subject: [PATCH 059/970] Fastlane change --- fastlane/metadata/android/en-US/changelogs/40103040.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/40103040.txt diff --git a/fastlane/metadata/android/en-US/changelogs/40103040.txt b/fastlane/metadata/android/en-US/changelogs/40103040.txt new file mode 100644 index 0000000000..06b32c8dff --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40103040.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.4 \ No newline at end of file From 7c9c4ecf5fd7665d9f35a006577511a5e1506599 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Oct 2021 10:49:40 +0200 Subject: [PATCH 060/970] 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 b547ae037a..c92d735fac 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.4\"" + buildConfigField "String", "SDK_VERSION", "\"1.3.5\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" resValue "string", "git_sdk_revision", "\"${gitRevision()}\"" diff --git a/vector/build.gradle b/vector/build.gradle index 31a4f1639c..636ae5c884 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 = 4 +ext.versionPatch = 5 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' From 188b4887bacb1c6460b1359428481089bdde3497 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 20 Oct 2021 17:23:40 +0200 Subject: [PATCH 061/970] 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 b3f6b5e14257a841bc5b06755d040839c504946e Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Thu, 21 Oct 2021 01:44:08 +0300 Subject: [PATCH 062/970] Fix Broken EditText when using FromEditTextItem --- changelog.d/4276.bugfix | 1 + .../im/vector/app/features/form/FormEditTextItem.kt | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 changelog.d/4276.bugfix diff --git a/changelog.d/4276.bugfix b/changelog.d/4276.bugfix new file mode 100644 index 0000000000..8cb2ed6977 --- /dev/null +++ b/changelog.d/4276.bugfix @@ -0,0 +1 @@ +Fix Broken EditText when using FromEditTextItem diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt index cda1623c88..c9a640e51a 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt @@ -18,6 +18,7 @@ package im.vector.app.features.form import android.text.Editable import android.text.InputFilter +import android.text.InputType import android.view.View import android.view.inputmethod.EditorInfo import android.widget.TextView @@ -107,8 +108,13 @@ abstract class FormEditTextItem : VectorEpoxyModel() { holder.textInputEditText.isEnabled = enabled inputType?.let { holder.textInputEditText.inputType = it } - holder.textInputEditText.isSingleLine = singleLine - holder.textInputEditText.imeOptions = imeOptions ?: EditorInfo.IME_ACTION_NONE + + if (singleLine) { + holder.textInputEditText.maxLines = 1 + holder.textInputEditText.minLines = 1 + imeOptions ?: run { holder.textInputEditText.imeOptions = EditorInfo.IME_ACTION_NEXT } + inputType ?: run { holder.textInputEditText.setRawInputType(InputType.TYPE_CLASS_TEXT) } + } holder.textInputEditText.addTextChangedListenerOnce(onTextChangeListener) holder.textInputEditText.setOnEditorActionListener(editorActionListener) From 3ea7b37df30ff8ee7093d301d1a20c3f571f29ca Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Thu, 21 Oct 2021 01:54:45 +0300 Subject: [PATCH 063/970] Improve imeOptions --- .../main/java/im/vector/app/features/form/FormEditTextItem.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt index c9a640e51a..328385049b 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt @@ -108,6 +108,7 @@ abstract class FormEditTextItem : VectorEpoxyModel() { holder.textInputEditText.isEnabled = enabled inputType?.let { holder.textInputEditText.inputType = it } + imeOptions?.let { holder.textInputEditText.imeOptions = it } if (singleLine) { holder.textInputEditText.maxLines = 1 From ac1e4e9e9c5c28bc709f79feecb0bafc968f3a02 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 21 Oct 2021 10:10:59 +0200 Subject: [PATCH 064/970] 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 d33daaf799071434613d9a5e6a44497c48641ac4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 21 Oct 2021 11:35:08 +0200 Subject: [PATCH 065/970] Fix voice message record button wrong visibility #4283 --- changelog.d/4283.bugfix | 1 + .../app/features/home/room/detail/RoomDetailFragment.kt | 2 +- .../home/room/detail/composer/TextComposerViewState.kt | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changelog.d/4283.bugfix diff --git a/changelog.d/4283.bugfix b/changelog.d/4283.bugfix new file mode 100644 index 0000000000..030418c405 --- /dev/null +++ b/changelog.d/4283.bugfix @@ -0,0 +1 @@ +Fix voice message record button wrong visibility \ No newline at end of file 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 7461b89001..fa0ca24289 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 @@ -1390,7 +1390,7 @@ class RoomDetailFragment @Inject constructor( lazyLoadedViews.inviteView(false)?.isVisible = false if (mainState.tombstoneEvent == null) { views.composerLayout.isInvisible = !textComposerState.isComposerVisible - views.voiceMessageRecorderView.isVisible = !textComposerState.isSendButtonVisible + views.voiceMessageRecorderView.isVisible = textComposerState.isVoiceMessageRecorderVisible views.composerLayout.views.sendButton.isInvisible = !textComposerState.isSendButtonVisible views.composerLayout.setRoomEncrypted(summary.isEncrypted) // views.composerLayout.alwaysShowSendButton = false diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewState.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewState.kt index 3110aa8dc3..199fb1b82d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewState.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerViewState.kt @@ -49,8 +49,8 @@ data class TextComposerViewState( val sendMode: SendMode = SendMode.REGULAR("", false) ) : MavericksState { - val isComposerVisible: Boolean - get() = canSendMessage && !isVoiceRecording + val isComposerVisible = canSendMessage && !isVoiceRecording + val isVoiceMessageRecorderVisible = canSendMessage && !isSendButtonVisible constructor(args: RoomDetailArgs) : this(roomId = args.roomId) } From dc230f1c300102ac9ad5ead77d694651228ba4e4 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Thu, 21 Oct 2021 14:31:50 +0300 Subject: [PATCH 066/970] Refactor to handle more cases --- .../app/features/form/FormEditTextItem.kt | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt index 328385049b..e23a076485 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt @@ -107,15 +107,9 @@ abstract class FormEditTextItem : VectorEpoxyModel() { } holder.textInputEditText.isEnabled = enabled - inputType?.let { holder.textInputEditText.inputType = it } - imeOptions?.let { holder.textInputEditText.imeOptions = it } - if (singleLine) { - holder.textInputEditText.maxLines = 1 - holder.textInputEditText.minLines = 1 - imeOptions ?: run { holder.textInputEditText.imeOptions = EditorInfo.IME_ACTION_NEXT } - inputType ?: run { holder.textInputEditText.setRawInputType(InputType.TYPE_CLASS_TEXT) } - } + configureInputType(holder) + configureImeOptions(holder) holder.textInputEditText.addTextChangedListenerOnce(onTextChangeListener) holder.textInputEditText.setOnEditorActionListener(editorActionListener) @@ -131,6 +125,32 @@ abstract class FormEditTextItem : VectorEpoxyModel() { } } + /** + * Configure the inputType of the EditText, input type should be always defined + * especially when we want to use a single line, we set the InputType to InputType.TYPE_CLASS_TEXT + * while the default for the EditText is InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE + */ + private fun configureInputType(holder: Holder) = + inputType?.let { + holder.textInputEditText.setRawInputType(it) + } ?: when (singleLine) { + true -> holder.textInputEditText.setRawInputType(InputType.TYPE_CLASS_TEXT) + false -> holder.textInputEditText.setRawInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE) + } + + /** + * Configure the imeOptions of the EditText, when imeOptions are not defined by user + * EditorInfo.IME_ACTION_NEXT will be used for singleLine EditTexts to disable "new line" + * while EditorInfo.IME_ACTION_NONE will be used for all the other cases + */ + private fun configureImeOptions(holder: Holder) = + imeOptions?.let { + holder.textInputEditText.imeOptions = it + } ?: when (singleLine) { + true -> holder.textInputEditText.imeOptions = EditorInfo.IME_ACTION_NEXT + false -> holder.textInputEditText.imeOptions = EditorInfo.IME_ACTION_NONE + } + override fun shouldSaveViewState(): Boolean { return false } From d41ff5009721afdc1c7a9941979a84f24e1013dc Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 21 Oct 2021 16:34:20 +0200 Subject: [PATCH 067/970] Fix crash when clicking on ViewEvent source actions #4279 --- changelog.d/4279.bugfix | 1 + vector/build.gradle | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 changelog.d/4279.bugfix diff --git a/changelog.d/4279.bugfix b/changelog.d/4279.bugfix new file mode 100644 index 0000000000..1b0ea424fa --- /dev/null +++ b/changelog.d/4279.bugfix @@ -0,0 +1 @@ +Fix crash when clicking on ViewEvent source actions \ No newline at end of file diff --git a/vector/build.gradle b/vector/build.gradle index 636ae5c884..254bf3873c 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -470,10 +470,7 @@ dependencies { gplayImplementation 'com.google.android.gms:play-services-oss-licenses:17.0.0' implementation "androidx.emoji:emoji-appcompat:1.1.0" - - implementation ('com.github.BillCarsonFr:JsonViewer:0.6'){ - exclude group: 'com.airbnb.android' - } + implementation ('com.github.BillCarsonFr:JsonViewer:0.7') // WebRTC // org.webrtc:google-webrtc is for development purposes only From beab9ab8f197812eb422f952b9fb7b95feb86149 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Thu, 21 Oct 2021 17:43:01 +0300 Subject: [PATCH 068/970] Refactored for clarity --- .../app/features/form/FormEditTextItem.kt | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt index e23a076485..93973c1bdf 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt @@ -130,26 +130,25 @@ abstract class FormEditTextItem : VectorEpoxyModel() { * especially when we want to use a single line, we set the InputType to InputType.TYPE_CLASS_TEXT * while the default for the EditText is InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE */ - private fun configureInputType(holder: Holder) = - inputType?.let { - holder.textInputEditText.setRawInputType(it) - } ?: when (singleLine) { - true -> holder.textInputEditText.setRawInputType(InputType.TYPE_CLASS_TEXT) - false -> holder.textInputEditText.setRawInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE) + private fun configureInputType(holder: Holder) = holder.textInputEditText.setRawInputType( + inputType ?: when (singleLine) { + true -> InputType.TYPE_CLASS_TEXT + false -> InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE } + ) /** - * Configure the imeOptions of the EditText, when imeOptions are not defined by user + * Configure the imeOptions of the EditText, when imeOptions are not defined by the developer * EditorInfo.IME_ACTION_NEXT will be used for singleLine EditTexts to disable "new line" * while EditorInfo.IME_ACTION_NONE will be used for all the other cases */ - private fun configureImeOptions(holder: Holder) = - imeOptions?.let { - holder.textInputEditText.imeOptions = it - } ?: when (singleLine) { - true -> holder.textInputEditText.imeOptions = EditorInfo.IME_ACTION_NEXT - false -> holder.textInputEditText.imeOptions = EditorInfo.IME_ACTION_NONE - } + private fun configureImeOptions(holder: Holder) { + holder.textInputEditText.imeOptions = + imeOptions ?: when (singleLine) { + true -> EditorInfo.IME_ACTION_NEXT + false -> EditorInfo.IME_ACTION_NONE + } + } override fun shouldSaveViewState(): Boolean { return false From d6d46d1c21b36c4dbe6cab27852ddfaee49f2cc5 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Thu, 21 Oct 2021 19:41:35 +0300 Subject: [PATCH 069/970] Avoid using setRawInputType --- .../app/features/form/FormEditTextItem.kt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt index 93973c1bdf..657c4c1b94 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt @@ -130,12 +130,18 @@ abstract class FormEditTextItem : VectorEpoxyModel() { * especially when we want to use a single line, we set the InputType to InputType.TYPE_CLASS_TEXT * while the default for the EditText is InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE */ - private fun configureInputType(holder: Holder) = holder.textInputEditText.setRawInputType( - inputType ?: when (singleLine) { - true -> InputType.TYPE_CLASS_TEXT - false -> InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE - } - ) + private fun configureInputType(holder: Holder) { + val newInputType = + inputType ?: when (singleLine) { + true -> InputType.TYPE_CLASS_TEXT + false -> InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE + } + + // This is a must in order to avoid extreme lag in some devices, on fast typing + if(holder.textInputEditText.inputType != newInputType){ + holder.textInputEditText.inputType = newInputType + } + } /** * Configure the imeOptions of the EditText, when imeOptions are not defined by the developer From 9d5f84b86aa7c4f528edb5aea8e6f42f104f515e Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Thu, 21 Oct 2021 20:02:21 +0300 Subject: [PATCH 070/970] Linter fixes --- .../main/java/im/vector/app/features/form/FormEditTextItem.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt index 657c4c1b94..7b7896316b 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormEditTextItem.kt @@ -138,7 +138,7 @@ abstract class FormEditTextItem : VectorEpoxyModel() { } // This is a must in order to avoid extreme lag in some devices, on fast typing - if(holder.textInputEditText.inputType != newInputType){ + if (holder.textInputEditText.inputType != newInputType) { holder.textInputEditText.inputType = newInputType } } From d724504662aac3a6320e27d9efa5bbbff70721c4 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 21 Oct 2021 20:17:49 +0200 Subject: [PATCH 071/970] 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 bc137af0e203fde904d01ef6f04523e5a75c5963 Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Wed, 20 Oct 2021 13:06:56 +0000 Subject: [PATCH 072/970] Translated using Weblate (Czech) 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/cs/ --- vector/src/main/res/values-cs/strings.xml | 54 +++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index c6b57e47ff..42e1e3963f 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -335,7 +335,7 @@ Vyřadit Potvrzení Varování - Domů + Úvod Oblíbené Lidé Místnosti @@ -1297,7 +1297,7 @@ Zruší zákaz uživateli s daným id Určit úroveň pokročilosti uživatele Pozve uživatele s daným id do této místnosti - Vstoupí do místnosti s daným aliasem + Vstoupí do místnosti s danou adresou Opustit místnost Určit téma místnosti Nakopne uživatele s daným id @@ -1316,7 +1316,7 @@ Příklad Id komunity příklad - Doma + Úvod Lidé Místnosti Žádní uživatelé @@ -2725,16 +2725,16 @@ Zpráva odeslána Neoznačeno Experimentální, prostor - omezená místnost. - Spaces představují nový způsob seskupování místností a osob. + Prostory představují nový způsob seskupování místností a osob. Založme pro každé místnost. Později můžete přidat i další, včetně již existujících. Na jakých tématech pracujete\? Založíme pro ně místnosti. Můžete přidat další později. Doplňte nějaké podrobnosti, aby jej lidé mohli identifikovat. Můžete je kdykoli změnit. - Spaces jsou nový způsob organizace místností a lidí - Spaces + Prostory jsou nový způsob organizace místností a lidí + Prostory Varování, nutná podpora serveru a experimentální verze místnosti Jste zváni - Vítejte ve Spaces! + Vítejte v prostorech! Přidat existující místnosti a prostor Opustit prostor Přidat místnosti @@ -2764,7 +2764,7 @@ Pozvat lidi Pozvěte do svého prostoru lidi Popis - Zakládám Space… + Vytvářím prostor… Nahodilé Obecné Jaké diskuse si přejete vést v %s\? @@ -2775,15 +2775,15 @@ Privátní Otevřený pro všechny, nejlepší pro komunity Veřejný - Privátní Space pro Vás a Vaše kolegy + Privátní prostor pro Vás a Vaše kolegy Já a kolegové - Privátní Space k organizaci Vašich místností + Privátní prostor k organizaci Vašich místností Jen já Ujistěte se, že ti správní lidé mají přístup do %s. Můžete změnit později. S kým pracujete\? - K vstupu do existujícího Space potřebujete pozvání. + Ke vstupu do existujícího prostoru potřebujete pozvání. Můžete změnit později - Jaký typ Space chcete založit\? + Jaký typ prostoru chcete založit\? Váš privátní prostor Váš veřejný prostor Přidat prostor @@ -2802,7 +2802,7 @@ Dovolit hostům vstoupit Pozvání Doporučené místnosti - Správa místností a Spaces + Správa místností a prostorů Označit za nikoli doporučené Označit za doporučené Doporučeno @@ -2827,9 +2827,9 @@ \nK přidávání místností nemáte oprávnění. Tento prostor nemá žádné místnosti Další informace získáte od správce domovského serveru - Vypadá to, že váš domovský server zatím Spaces nepodporuje + Vypadá to, že váš domovský server zatím Prostory nepodporuje Chcete experimentovat\? -\nDo Spaceu můžete přidat existující Spaces. +\nDo prostoru můžete přidat existující prostory. Přidat místnosti Jste jediným správcem tohoto prostoru. Jeho opuštění bude znamenat, že nad ním nebude mít nikdo kontrolu. Pokud nebudete znovu pozváni, nebudete se moci připojit. @@ -2840,9 +2840,9 @@ Zpětnou vazbu se nepodařilo odeslat (%s) Děkujeme, vaše zpětná vazba byla úspěšně odeslána V případě dalších dotazů se na mě můžete obrátit - Používáte beta verzi Spaces. Váš feedback pomůže při tvorbě dalších verzí. Vaše platforma a uživatelské jméno budou zaznamenány, abychom mohli Váš feedback co nejlépe využít. + Používáte beta verzi prostorů. Vaše zpětná vazba pomůže při tvorbě dalších verzí. Vaše platforma a uživatelské jméno budou zaznamenány, abychom mohli vaši zpětnou vazbu co nejlépe využít. Zpětná vazba - Feedback na Spaces + Zpětná vazba prostorů Omlouváme se, při pokusu o připojení ke konferenci došlo k chybě Nepojmenovaná místnost Soukromý prostor @@ -2860,7 +2860,7 @@ V současné době se lidé nemohou připojit k soukromým místnostem, které jste vytvořili. \n \nV rámci beta verze to zlepšíme, ale jen jsme vás chtěli informovat. - Spaces pro spolupracovníky nejsou ještě zcela připravené, ale přesto je můžete vyzkoušet + Prostory pro spolupracovníky nejsou ještě zcela připravené, ale přesto je můžete vyzkoušet Omlouváme se, došlo k chybě během pokusu o přistoupení: %s Adresa prostoru Prohlédnout a spravovat adresy tohoto prostoru. @@ -2900,17 +2900,17 @@ %d zmeškané hlasové hovory %d zmeškaných hlasových hovorů - Rozhodněte, které Spaces mají přístup do této místnosti. Pokud je vybrán prostor, jeho členové budou moci najít název místnosti a připojit se k ní. - Další Spaces nebo místnosti, které možná neznáte + Rozhodněte, které prostory mají přístup do této místnosti. Pokud je vybrán prostor, jeho členové budou moci najít název místnosti a připojit se k ní. + Další prostory nebo místnosti, které možná neznáte Prostor, o kterém víte, že obsahuje tuto místnost Rozhodněte, kdo může tuto místnost najít a připojit se k ní. - Klepnutím upravíte Spaces - Povolit vyhledání a přístup komukoli v %s. Můžete vybrat i další Spaces. + Klepnutím upravíte prostory + Povolit vyhledání a přístup komukoli v %s. Můžete vybrat i další prostory. Vyžadována aktualizace Každý, kdo se nachází v nadřazeném prostoru, bude moci tuto místnost najít a připojit se k ní - není třeba všechny zvát ručně. Tuto možnost budete moci kdykoli změnit v nastavení místnosti. Kdokoli v %s bude moci tuto místnost najít a připojit se k ní - není třeba všechny zvát ručně. Toto nastavení budete moci kdykoli změnit v nastavení místnosti. Klepnutím na nahrávku ji zastavíte nebo posloucháte - Vybrat Spaces + Vybrat prostory Upozorňujeme, že aktualizací vznikne nová verze místnosti. Všechny aktuální zprávy zůstanou v této archivované místnosti. Hlasová zpráva (%1$s) Nelze odpovídat ani upravovat, když je hlasová zpráva aktivní @@ -2927,7 +2927,7 @@ Posunutím zrušíte Nahrát hlasovou zprávu Hlasová zpráva - Spaces, které mají přístup + Prostory, které mají přístup Umožněte členům prostoru ho najít a zpřístupnit. Členové prostoru %s mohou vyhledávat, prohlížet a připojovat se. Soukromé (pouze pro pozvané) @@ -2952,8 +2952,8 @@ Chcete-li členům prostoru pomoci najít soukromou místnost a připojit se k ní, přejděte do nastavení dané místnosti klepnutím na avatar. Pomozte členům prostoru najít soukromé místnosti Díky tomu mohou místnosti zůstat soukromé a zároveň je mohou lidé v prostoru najít a připojit se k nim. Všechny nové místnosti v prostoru budou mít tuto možnost k dispozici. - Pomozte lidem ve Spaces, aby sami našli soukromé místnosti a připojili se k nim, není třeba všechny zvát ručně. - Novinka: Nechat lidi v Spaces vyhledat a připojit se k soukromým místnostem + Pomozte lidem v prostorech, aby sami našli soukromé místnosti a připojili se k nim, není třeba všechny zvát ručně. + Novinka: Nechat lidi v prostorech vyhledat a připojit se k soukromým místnostem Skupinový hovor zahájen Všechny místnosti, ve kterých se nacházíte, se zobrazí v domovském zobrazení. Zobrazit všechny místnosti v domovském zobrazení @@ -2998,7 +2998,7 @@ Hlasový hovor s %s Videohovor s %s Vyzvánění… - Spaces + Prostory Dozvědět se více Přidejte prostor do jakéhokoli prostoru, který spravujete. Přidat stávající prostory From b83566c1c05c3da4d158c2d5f0381efdfff096da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 20 Oct 2021 14:22:02 +0000 Subject: [PATCH 073/970] Translated using Weblate (Estonian) 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/et/ --- vector/src/main/res/values-et/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index 27c332b605..2585eaa15a 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -1556,7 +1556,7 @@ Määra kasutaja õigused Eemalda antud tunnusega kasutajalt haldusõigused selles jututoas Kutsub nimetatud kasutajatunnusega kasutaja sellesse jututuppa - Liitu antud aadressiga jututoaga + Liitu sellise aadressiga jututoaga Lahku jututoast Määra jututoa teema Müksa selle tunnusega kasutaja jututoast välja From 3993a45825455800b220948fcc40f9cb0ec658a7 Mon Sep 17 00:00:00 2001 From: Glandos Date: Thu, 21 Oct 2021 11:16:30 +0000 Subject: [PATCH 074/970] Translated using Weblate (French) 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/fr/ --- vector/src/main/res/values-fr/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index 483b433ecc..12eca6b823 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -984,7 +984,7 @@ Définit le rang d’un utilisateur Rétrograde l’utilisateur avec l’identifiant fourni Invite l’utilisateur avec l’identifiant fourni dans le salon actuel - Rejoint le salon avec l’alias fourni + Rejoint le salon avec l’adresse fournie Quitte le salon Définit le sujet du salon Expulse l’utilisateur avec l’identifiant fourni @@ -3009,4 +3009,7 @@ L’expulsion des utilisateurs va les supprimer de cet espace \n \nPour les empêcher de revenir, vous devriez les exclure. + Indisponible + Hors ligne + En ligne \ No newline at end of file From 2b0933139a3b42da7176a9025ef5d0382eac0294 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Thu, 21 Oct 2021 18:34:47 +0000 Subject: [PATCH 075/970] Translated using Weblate (Hungarian) 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/hu/ --- vector/src/main/res/values-hu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index 1926a40115..1d9214f926 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -942,7 +942,7 @@ Matrixban az üzenetek láthatósága hasonlít az e-mailre. Az üzenet törlés Felhasználó hozzáférési szintjének meghatározása Meghatározott azonosítójú felhasználó hozzáférési szintjének visszaállítása Megadott azonosítójú felhasználó meghívása a szobába - Megadott becenévvel csatlakozik a szobához + Megadott címmel csatlakozik a szobához Kilépés a szobából A szoba témájának beállítása Megadott azonosítójú felhasználó kirúgása From df5c05fc1f958333653f7efed929b595d9298655 Mon Sep 17 00:00:00 2001 From: Linerly Date: Thu, 21 Oct 2021 02:42:11 +0000 Subject: [PATCH 076/970] Translated using Weblate (Indonesian) 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/id/ --- vector/src/main/res/values-in/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index f899be6bff..8b9016b6c3 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -525,7 +525,7 @@ Ijinkan akses lewat halaman selanjutnya untuk menemukan pengguna ${app_name} yan Cabut larangan pengguna dengan id berikut Tentukan tingkat kuasa seorang pengguna Undang pengguna dengan id berikut bergabung ke ruang ini - Gabung ke ruang dengan alias berikut + Gabung ke ruangan dengan alamat berikut Tinggalkan ruang Tentukan topik ruang Keluarkan pengguna dengan id berikut From 2ddedf49d46b67528a2520378ccaab2d73ebe56e Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Wed, 20 Oct 2021 11:06:14 +0000 Subject: [PATCH 077/970] Translated using Weblate (Portuguese (Brazil)) 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/pt_BR/ --- vector/src/main/res/values-pt-rBR/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index ff824445eb..8ef17a33d9 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -1094,7 +1094,7 @@ Define nível de poder de um/uma usuário(a) Desopa usuária(o) com id dada Convida usuária(o) com id dada para esta sala - Junta-se a sala com alias dado + Junta-se a sala com endereço dado Sair de sala Definir o tópico da sala Expulsa a(o) usuária(o) com id dada From 5a3d1fb7ec4585fc2a2678f2acd77563abe0c6a5 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Wed, 20 Oct 2021 18:43:54 +0000 Subject: [PATCH 078/970] Translated using Weblate (Swedish) 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/sv/ --- vector/src/main/res/values-sv/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 5ff62fa1eb..0ec5b0d820 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -1785,7 +1785,7 @@ Definiera behörighetsnivå för en användare Avoppar användaren med det angivna ID:t Bjuder in användaren med det angivna ID:t till det nuvarande rummet - Går med i rummet med det angivna aliaset + Går med i rummet med den angivna adressen Sätt ett rumsämne Sparkar ut användaren med det angivna ID:t Ändrar ditt visningsnamn From de320e671e5e9f92ac1dd70c8e7d4b7dea7b7d75 Mon Sep 17 00:00:00 2001 From: sr093906 Date: Wed, 20 Oct 2021 13:12:29 +0000 Subject: [PATCH 079/970] Translated using Weblate (Chinese (Simplified)) 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/zh_Hans/ --- vector/src/main/res/values-zh-rCN/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-zh-rCN/strings.xml b/vector/src/main/res/values-zh-rCN/strings.xml index 28d2c8e250..feff737e27 100644 --- a/vector/src/main/res/values-zh-rCN/strings.xml +++ b/vector/src/main/res/values-zh-rCN/strings.xml @@ -948,7 +948,7 @@ 设置用户的权限等级 按照 ID 取消用户管理员权限 按照 ID 邀请用户进入当前聊天室 - 按照别名加入聊天室 + 用给定地址加入聊天室 离开聊天室 设置聊天室主题 按照 ID 踢出用户 From dcda43fc93b6f9311d798609ab4d08124c3de83e Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Thu, 21 Oct 2021 02:14:18 +0000 Subject: [PATCH 080/970] Translated using Weblate (Chinese (Traditional)) 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/zh_Hant/ --- vector/src/main/res/values-zh-rTW/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 66120d9429..df611eceb7 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -988,7 +988,7 @@ 定義使用者的權限等級 取消指定 id 的使用者的管理權 邀請指定 id 的使用者到目前的聊天室 - 加入指定別名的聊天室 + 加入指定地址的聊天室 離開聊天室 設定聊天室主題 踢除指定 id 的使用者 From 7aa860b1fa7048c1c54f64dff22d2e8b228aca44 Mon Sep 17 00:00:00 2001 From: Glandos Date: Thu, 21 Oct 2021 11:15:53 +0000 Subject: [PATCH 081/970] Translated using Weblate (French) Currently translated at 100.0% (34 of 34 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/fr/ --- fastlane/metadata/android/fr-FR/changelogs/40103030.txt | 2 ++ fastlane/metadata/android/fr-FR/full_description.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40103030.txt diff --git a/fastlane/metadata/android/fr-FR/changelogs/40103030.txt b/fastlane/metadata/android/fr-FR/changelogs/40103030.txt new file mode 100644 index 0000000000..0130080ca7 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40103030.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Affiche le(s) politique(s) des serveurs d’identité dans les réglages. Retrait temporaire du support d’Android Auto +Liste de tous les changements : https ://github.com/vector-im/element-android/releases/tag/v1.3.3 diff --git a/fastlane/metadata/android/fr-FR/full_description.txt b/fastlane/metadata/android/fr-FR/full_description.txt index 78fcdf5617..7ffdb6cb9d 100644 --- a/fastlane/metadata/android/fr-FR/full_description.txt +++ b/fastlane/metadata/android/fr-FR/full_description.txt @@ -37,3 +37,6 @@ Messagerie instantannée, appels audio et vidéo, partage de fichier, partage d Reprenez où vous vous êtes arrêté Restez en contact où que vous soyez grâce à l’historique des messages synchronisé entre tous vos appareils et sur le web sur https://app.element.io + +Open source +Element Adroid est un projet libre, hébergé par GitHub. Veuillez signaler tous les problèmes et / ou contribuer à son développement sur https://github.com/vector-im/element-android From b6501ce7b2d032d8039bb4ae0a98728b7739ec57 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Oct 2021 11:30:09 +0200 Subject: [PATCH 082/970] 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 083/970] 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 084/970] 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 a82a5c9b32e0e22d76c7336f041e2d8156194694 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Oct 2021 15:19:39 +0200 Subject: [PATCH 085/970] Fix unread marker not showing #4313 --- changelog.d/4313.bugfix | 1 + .../features/home/room/detail/RoomDetailViewModel.kt | 12 +++++++----- .../workers/signout/ServerBackupStatusViewModel.kt | 11 ++++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 changelog.d/4313.bugfix diff --git a/changelog.d/4313.bugfix b/changelog.d/4313.bugfix new file mode 100644 index 0000000000..da28469ed0 --- /dev/null +++ b/changelog.d/4313.bugfix @@ -0,0 +1 @@ +Fix unread marker not showing \ No newline at end of file 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..f4f2def028 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 @@ -529,9 +529,9 @@ class RoomDetailViewModel @AssistedInject constructor( val isAllowed = action.userJustAccepted || if (widget.type == WidgetType.Jitsi) { widget.senderInfo?.userId == session.myUserId || session.integrationManagerService().isNativeWidgetDomainAllowed( - action.widget.type.preferred, - domain - ) + action.widget.type.preferred, + domain + ) } else false if (isAllowed) { @@ -1092,8 +1092,10 @@ class RoomDetailViewModel @AssistedInject constructor( } override fun onTimelineUpdated(snapshot: List) { - timelineEvents.tryEmit(snapshot) - + viewModelScope.launch { + // tryEmit doesn't work with SharedFlow without cache + timelineEvents.emit(snapshot) + } // PreviewUrl if (vectorPreferences.showUrlPreviews()) { withState { state -> 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..92af25994a 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 @@ -34,6 +34,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.sample +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME @@ -110,7 +111,7 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS if ( crossSigningInfo.getOrNull() == null || (crossSigningInfo.getOrNull()?.isTrusted() == true && - pInfo.getOrNull()?.allKnown().orFalse()) + pInfo.getOrNull()?.allKnown().orFalse()) ) { // So 4S is not setup and we have local secrets, return@combine BannerState.Setup(numberOfKeys = getNumberOfKeysToBackup()) @@ -125,7 +126,9 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS ) } - keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state) + viewModelScope.launch { + keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state) + } } /** @@ -155,7 +158,9 @@ class ServerBackupStatusViewModel @AssistedInject constructor(@Assisted initialS } override fun onStateChange(newState: KeysBackupState) { - keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state) + viewModelScope.launch { + keyBackupFlow.tryEmit(session.cryptoService().keysBackupService().state) + } keysBackupState.value = newState } From c87d276f8ac0d5392333bf9f4b0d46ec1be73297 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 22 Oct 2021 18:09:14 +0200 Subject: [PATCH 086/970] 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 087/970] 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 06b3cc3f4b10cfa80271f2bda22e6d961bd7406a Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 22 Oct 2021 18:29:53 +0100 Subject: [PATCH 088/970] filters the unique notification uris from the link handling - fixes malformed url errors appearing for uri we only create to force uniqueness in the notifications --- .../app/core/extensions/UriExtensions.kt | 25 +++++++++++++++++++ .../notifications/NotificationUtils.kt | 25 ++++++++++--------- .../features/permalink/PermalinkHandler.kt | 25 +++++++++++-------- 3 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/extensions/UriExtensions.kt diff --git a/vector/src/main/java/im/vector/app/core/extensions/UriExtensions.kt b/vector/src/main/java/im/vector/app/core/extensions/UriExtensions.kt new file mode 100644 index 0000000000..ec7a03bdbb --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/extensions/UriExtensions.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.extensions + +import android.net.Uri + +const val IGNORED_SCHEMA = "ignored" + +fun Uri.isIgnored() = scheme == IGNORED_SCHEMA + +fun createIgnoredUri(path: String): Uri = Uri.parse("$IGNORED_SCHEMA://$path") 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 92feb3d038..89db5e7d8f 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 @@ -47,6 +47,7 @@ import androidx.core.graphics.drawable.IconCompat import androidx.fragment.app.Fragment import im.vector.app.BuildConfig import im.vector.app.R +import im.vector.app.core.extensions.createIgnoredUri import im.vector.app.core.resources.StringProvider import im.vector.app.core.services.CallService import im.vector.app.core.utils.startNotificationChannelSettingsIntent @@ -317,7 +318,7 @@ class NotificationUtils @Inject constructor(private val context: Context, mode = VectorCallActivity.INCOMING_RINGING ).apply { flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP - data = Uri.parse("foobar://${call.callId}") + data = createIgnoredUri(call.callId) } val contentPendingIntent = PendingIntent.getActivity(context, System.currentTimeMillis().toInt(), contentIntent, 0) @@ -378,7 +379,7 @@ class NotificationUtils @Inject constructor(private val context: Context, call = call, mode = null).apply { flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP - data = Uri.parse("foobar://$call.callId") + data = createIgnoredUri(call.callId) } val contentPendingIntent = PendingIntent.getActivity(context, System.currentTimeMillis().toInt(), contentIntent, 0) @@ -584,7 +585,7 @@ class NotificationUtils @Inject constructor(private val context: Context, // Mark room as read val markRoomReadIntent = Intent(context, NotificationBroadcastReceiver::class.java) markRoomReadIntent.action = MARK_ROOM_READ_ACTION - markRoomReadIntent.data = Uri.parse("foobar://${roomInfo.roomId}") + markRoomReadIntent.data = createIgnoredUri(roomInfo.roomId) markRoomReadIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomInfo.roomId) val markRoomReadPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), markRoomReadIntent, PendingIntent.FLAG_UPDATE_CURRENT) @@ -652,7 +653,7 @@ class NotificationUtils @Inject constructor(private val context: Context, // offer to type a quick reject button val rejectIntent = Intent(context, NotificationBroadcastReceiver::class.java) rejectIntent.action = REJECT_ACTION - rejectIntent.data = Uri.parse("foobar://$roomId&$matrixId") + rejectIntent.data = createIgnoredUri("$roomId&$matrixId") rejectIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId) val rejectIntentPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), rejectIntent, PendingIntent.FLAG_UPDATE_CURRENT) @@ -665,7 +666,7 @@ class NotificationUtils @Inject constructor(private val context: Context, // offer to type a quick accept button val joinIntent = Intent(context, NotificationBroadcastReceiver::class.java) joinIntent.action = JOIN_ACTION - joinIntent.data = Uri.parse("foobar://$roomId&$matrixId") + joinIntent.data = createIgnoredUri("$roomId&$matrixId") joinIntent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId) val joinIntentPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), joinIntent, PendingIntent.FLAG_UPDATE_CURRENT) @@ -677,7 +678,7 @@ class NotificationUtils @Inject constructor(private val context: Context, val contentIntent = HomeActivity.newIntent(context, inviteNotificationRoomId = inviteNotifiableEvent.roomId) contentIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP // pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that - contentIntent.data = Uri.parse("foobar://" + inviteNotifiableEvent.eventId) + contentIntent.data = createIgnoredUri(inviteNotifiableEvent.eventId) setContentIntent(PendingIntent.getActivity(context, 0, contentIntent, 0)) if (inviteNotifiableEvent.noisy) { @@ -716,7 +717,7 @@ class NotificationUtils @Inject constructor(private val context: Context, val contentIntent = HomeActivity.newIntent(context) contentIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP // pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that - contentIntent.data = Uri.parse("foobar://" + simpleNotifiableEvent.eventId) + contentIntent.data = createIgnoredUri(simpleNotifiableEvent.eventId) setContentIntent(PendingIntent.getActivity(context, 0, contentIntent, 0)) if (simpleNotifiableEvent.noisy) { @@ -738,7 +739,7 @@ class NotificationUtils @Inject constructor(private val context: Context, val roomIntentTap = RoomDetailActivity.newIntent(context, RoomDetailArgs(roomId)) roomIntentTap.action = TAP_TO_VIEW_ACTION // pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that - roomIntentTap.data = Uri.parse("foobar://openRoom?$roomId") + roomIntentTap.data = createIgnoredUri("openRoom?$roomId") // Recreate the back stack return TaskStackBuilder.create(context) @@ -750,7 +751,7 @@ class NotificationUtils @Inject constructor(private val context: Context, private fun buildOpenHomePendingIntentForSummary(): PendingIntent { val intent = HomeActivity.newIntent(context, clearNotification = true) intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP - intent.data = Uri.parse("foobar://tapSummary") + intent.data = createIgnoredUri("tapSummary") return PendingIntent.getActivity(context, Random.nextInt(1000), intent, PendingIntent.FLAG_UPDATE_CURRENT) } @@ -766,7 +767,7 @@ class NotificationUtils @Inject constructor(private val context: Context, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent = Intent(context, NotificationBroadcastReceiver::class.java) intent.action = SMART_REPLY_ACTION - intent.data = Uri.parse("foobar://$roomId") + intent.data = createIgnoredUri(roomId) intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId) return PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT) @@ -781,7 +782,7 @@ class NotificationUtils @Inject constructor(private val context: Context, // the action must be unique else the parameters are ignored quickReplyIntent.action = QUICK_LAUNCH_ACTION - quickReplyIntent.data = Uri.parse("foobar://$roomId") + quickReplyIntent.data = _root_ide_package_.im.vector.app.core.extensions.createIgnoredUri($roomId") return PendingIntent.getActivity(context, 0, quickReplyIntent, 0) } */ @@ -835,7 +836,7 @@ class NotificationUtils @Inject constructor(private val context: Context, private fun getDismissSummaryPendingIntent(): PendingIntent { val intent = Intent(context, NotificationBroadcastReceiver::class.java) intent.action = DISMISS_SUMMARY_ACTION - intent.data = Uri.parse("foobar://deleteSummary") + intent.data = createIgnoredUri("deleteSummary") return PendingIntent.getBroadcast(context.applicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) } 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 a02cfe7517..90bcee3d04 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 @@ -20,6 +20,7 @@ import android.content.Context import android.net.Uri import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.extensions.isIgnored import im.vector.app.core.utils.toast import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData @@ -53,15 +54,19 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti navigationInterceptor: NavigationInterceptor? = null, buildTask: Boolean = false ): Boolean { - if (deepLink == null || !isPermalinkSupported(context, deepLink.toString())) { - return false - } - return tryOrNull { - withContext(Dispatchers.Default) { - val permalinkData = PermalinkParser.parse(deepLink) - handlePermalink(permalinkData, deepLink, context, navigationInterceptor, buildTask) + return when { + deepLink == null -> false + deepLink.isIgnored() -> true + !isPermalinkSupported(context, deepLink.toString()) -> false + else -> { + tryOrNull { + withContext(Dispatchers.Default) { + val permalinkData = PermalinkParser.parse(deepLink) + handlePermalink(permalinkData, deepLink, context, navigationInterceptor, buildTask) + } + } ?: false } - } ?: false + } } private suspend fun handlePermalink( @@ -115,8 +120,8 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti private fun isPermalinkSupported(context: Context, url: String): Boolean { return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE) || context.resources.getStringArray(R.array.permalink_supported_hosts).any { - url.startsWith(it) - } + url.startsWith(it) + } } private suspend fun PermalinkData.RoomLink.getRoomId(): String? { From 9ed8d5b22ed91db8aae6403d21dd98275ff6935b Mon Sep 17 00:00:00 2001 From: Szimszon Date: Fri, 22 Oct 2021 13:59:01 +0000 Subject: [PATCH 089/970] 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 090/970] 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 091/970] 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 092/970] 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 093/970] 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 094/970] 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 095/970] 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 096/970] 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 097/970] 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 325e78106e99212c79921bd0af4dd427d89dd7fb Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 25 Oct 2021 10:51:40 +0100 Subject: [PATCH 098/970] fixing strange ide extract --- .../im/vector/app/features/notifications/NotificationUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 89db5e7d8f..f3b34e1269 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 @@ -782,7 +782,7 @@ class NotificationUtils @Inject constructor(private val context: Context, // the action must be unique else the parameters are ignored quickReplyIntent.action = QUICK_LAUNCH_ACTION - quickReplyIntent.data = _root_ide_package_.im.vector.app.core.extensions.createIgnoredUri($roomId") + quickReplyIntent.data = createIgnoredUri($roomId") return PendingIntent.getActivity(context, 0, quickReplyIntent, 0) } */ From 55c00a09750a062697252f868f2d05e28a47870e Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 25 Oct 2021 10:56:15 +0100 Subject: [PATCH 099/970] adding changelog entry --- changelog.d/4267.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/4267.bugfix diff --git a/changelog.d/4267.bugfix b/changelog.d/4267.bugfix new file mode 100644 index 0000000000..08aabd1e83 --- /dev/null +++ b/changelog.d/4267.bugfix @@ -0,0 +1 @@ +Fixing malformed link pop up when tapping on notifications \ No newline at end of file From b892331e42bda14a3cd1dbe4c59a2dc3bb280af1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 12:35:11 +0200 Subject: [PATCH 100/970] Towncrier --- CHANGES.md | 12 ++++++++++++ changelog.d/4267.bugfix | 1 - changelog.d/4276.bugfix | 1 - changelog.d/4279.bugfix | 1 - changelog.d/4283.bugfix | 1 - changelog.d/4313.bugfix | 1 - 6 files changed, 12 insertions(+), 5 deletions(-) delete mode 100644 changelog.d/4267.bugfix delete mode 100644 changelog.d/4276.bugfix delete mode 100644 changelog.d/4279.bugfix delete mode 100644 changelog.d/4283.bugfix delete mode 100644 changelog.d/4313.bugfix diff --git a/CHANGES.md b/CHANGES.md index 8de71eae62..bf855d66f9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,15 @@ +Changes in Element v1.3.5 (2021-10-25) +====================================== + +Bugfixes 🐛 +---------- + - Fixing malformed link pop up when tapping on notifications ([#4267](https://github.com/vector-im/element-android/issues/4267)) + - Fix Broken EditText when using FromEditTextItem ([#4276](https://github.com/vector-im/element-android/issues/4276)) + - Fix crash when clicking on ViewEvent source actions ([#4279](https://github.com/vector-im/element-android/issues/4279)) + - Fix voice message record button wrong visibility ([#4283](https://github.com/vector-im/element-android/issues/4283)) + - Fix unread marker not showing ([#4313](https://github.com/vector-im/element-android/issues/4313)) + + Changes in Element v1.3.4 (2021-10-20) ====================================== diff --git a/changelog.d/4267.bugfix b/changelog.d/4267.bugfix deleted file mode 100644 index 08aabd1e83..0000000000 --- a/changelog.d/4267.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixing malformed link pop up when tapping on notifications \ No newline at end of file diff --git a/changelog.d/4276.bugfix b/changelog.d/4276.bugfix deleted file mode 100644 index 8cb2ed6977..0000000000 --- a/changelog.d/4276.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix Broken EditText when using FromEditTextItem diff --git a/changelog.d/4279.bugfix b/changelog.d/4279.bugfix deleted file mode 100644 index 1b0ea424fa..0000000000 --- a/changelog.d/4279.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix crash when clicking on ViewEvent source actions \ No newline at end of file diff --git a/changelog.d/4283.bugfix b/changelog.d/4283.bugfix deleted file mode 100644 index 030418c405..0000000000 --- a/changelog.d/4283.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix voice message record button wrong visibility \ No newline at end of file diff --git a/changelog.d/4313.bugfix b/changelog.d/4313.bugfix deleted file mode 100644 index da28469ed0..0000000000 --- a/changelog.d/4313.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix unread marker not showing \ No newline at end of file From 201d558925bb5ed395a8b93555108dd52990f3ad Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 12:37:41 +0200 Subject: [PATCH 101/970] Update previous Changelog (the file was not in the correct folder) --- CHANGES.md | 1 + newsfragment/3313.feature | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 newsfragment/3313.feature diff --git a/CHANGES.md b/CHANGES.md index bf855d66f9..d3bc0cc414 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Features ✨ ---------- - Implement /part command, with or without parameter ([#2909](https://github.com/vector-im/element-android/issues/2909)) - Handle Presence support, for Direct Message room ([#4090](https://github.com/vector-im/element-android/issues/4090)) + - Priority conversations for Android 11+ ([#3313](https://github.com/vector-im/element-android/issues/3313)) Bugfixes 🐛 ---------- diff --git a/newsfragment/3313.feature b/newsfragment/3313.feature deleted file mode 100644 index 3d243fa1ef..0000000000 --- a/newsfragment/3313.feature +++ /dev/null @@ -1 +0,0 @@ -Priority conversations for Android 11+ From f877965550edf2db874555ad23eb0b19519459ce Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 12:38:53 +0200 Subject: [PATCH 102/970] Fastlane files --- fastlane/metadata/android/en-US/changelogs/40103040.txt | 2 +- fastlane/metadata/android/en-US/changelogs/40103050.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/40103050.txt diff --git a/fastlane/metadata/android/en-US/changelogs/40103040.txt b/fastlane/metadata/android/en-US/changelogs/40103040.txt index 06b32c8dff..a6af2efe00 100644 --- a/fastlane/metadata/android/en-US/changelogs/40103040.txt +++ b/fastlane/metadata/android/en-US/changelogs/40103040.txt @@ -1,2 +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. +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.4 \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/40103050.txt b/fastlane/metadata/android/en-US/changelogs/40103050.txt new file mode 100644 index 0000000000..93227f1a6d --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40103050.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.5 \ No newline at end of file From 79d56319b74325f499450f4799973de6eeda906a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 12:40:24 +0200 Subject: [PATCH 103/970] 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 104/970] 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 105/970] 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 106/970] 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 107/970] 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 8f0074911aa6b6147d6ec08a8ecc174a6991d446 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Mon, 25 Oct 2021 19:00:39 +0300 Subject: [PATCH 108/970] Thread awareness, map threads events to replies --- .../network/ThreadToReplyMapInterceptor.kt | 105 +++++++++++++++++ .../sync/handler/room/RoomSyncHandler.kt | 3 + .../handler/room/ThreadsAwarenessHandler.kt | 108 ++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ThreadToReplyMapInterceptor.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ThreadToReplyMapInterceptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ThreadToReplyMapInterceptor.kt new file mode 100644 index 0000000000..519e497e95 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ThreadToReplyMapInterceptor.kt @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.network + +import okhttp3.Interceptor +import okhttp3.Request +import okhttp3.Response +import okhttp3.ResponseBody +import okhttp3.ResponseBody.Companion.toResponseBody +import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.network.ApiInterceptorListener +import org.matrix.android.sdk.api.network.ApiPath +import org.matrix.android.sdk.internal.di.MatrixScope +import timber.log.Timber +import javax.inject.Inject + +/** + * The goal of this interceptor is to map thread events to be handled as replies. + * The interceptor is responsible for mapping a thread event: + * "m.relates_to":{ + * "event_id":"$eventId", + * "rel_type":"io.element.thread" + * } + * to an equivalent reply event: + * m.relates_to":{ + * "m.in_reply_to":{ + * "event_id":"$eventId" + * } + */ +@MatrixScope +internal class ThreadToReplyMapInterceptor @Inject constructor() : Interceptor { + + init { + Timber.d("MapThreadToReplyInterceptor.init") + } + + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + + val response = chain.proceed(request) + + if (isSyncRequest(request)) { + Timber.i(" ------> found SYNC REQUEST") + + return response.body?.let { + val contentType = it.contentType() + val rawBody = it.string() + Timber.i(" ------> $rawBody") + + if(rawBody.contains("\"rel_type\":\"io.element.thread\"")){ + Timber.i(" ------> Thread found") + val start = rawBody.indexOf("\"rel_type\":\"io.element.thread\"") - "\"m.relates_to\":{\"event_id\":\"-GoMTnxkfmZczOPvbjcK43WqNib3wiJVaeO_vRxwHIDA\",\"".length +1 + val end = rawBody.indexOf("\"rel_type\":\"io.element.thread\"") + "\"rel_type\":\"io.element.thread\"".length +2 + val substr = rawBody.subSequence(start,end) + val newRaw = rawBody.replaceRange(start,end,"\"m.relates_to\":{\"m.in_reply_to\":{\"event_id\":\"\$HDddlX2bJQmVS0bN5R9HDzcrGDap18b3cFDDYjTjctc\"}},") + Timber.i(" ------> ${substr}") + Timber.i(" ------> new raw $newRaw") + val newBody = newRaw.toResponseBody(contentType) + response.newBuilder().body(newBody).build() + + }else{ + val newBody = rawBody.toResponseBody(contentType) + response.newBuilder().body(newBody).build() + } + } ?: response + +// response.peekBody(Long.MAX_VALUE).string().let { networkResponse -> +// Timber.i(" ------> ThreadToReplyMapInterceptor $networkResponse") +// } + } + +// val path = request.url.encodedPath +// if(path.contains("/sync/")){ +// Timber.i("-----> SYNC REQUEST --> $responseBody") +// +// +// } + +// val body = ResponseBody.create() +// val newResponse = response.newBuilder().body(body) + return response + } + + /** + * Returns true if the request is a sync request, false otherwise + * Example of a sync request: + * https://matrix-client.matrix.org/_matrix/client/r0/sync?filter=0&set_presence=online&t... + */ + private fun isSyncRequest(request: Request): Boolean = + ApiPath.SYNC.method == request.method && request.url.encodedPath.contains(ApiPath.SYNC.path) +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 8c4af81c99..db4e07a21a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -76,6 +76,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle private val cryptoService: DefaultCryptoService, private val roomMemberEventHandler: RoomMemberEventHandler, private val roomTypingUsersHandler: RoomTypingUsersHandler, + private val threadsAwarenessHandler: ThreadsAwarenessHandler, private val roomChangeMembershipStateDataSource: RoomChangeMembershipStateDataSource, @UserId private val userId: String, private val timelineInput: TimelineInput) { @@ -366,6 +367,8 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle decryptIfNeeded(event, roomId) } + threadsAwarenessHandler.handleIfNeeded(realm, roomId, event, ::decryptIfNeeded) + val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it } val eventEntity = event.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, insertType) if (event.stateKey != null) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt new file mode 100644 index 0000000000..cc01f62448 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt @@ -0,0 +1,108 @@ +/* + * Copyright 2021 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.session.sync.handler.room + +import io.realm.Realm +import org.matrix.android.sdk.api.session.events.model.Content +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.message.MessageFormat +import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent +import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent +import org.matrix.android.sdk.api.session.room.model.tag.RoomTagContent +import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.database.mapper.EventMapper +import org.matrix.android.sdk.internal.database.model.EventEntity +import org.matrix.android.sdk.internal.database.model.EventInsertType +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity +import org.matrix.android.sdk.internal.database.model.RoomTagEntity +import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.database.query.where +import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory +import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory +import timber.log.Timber +import javax.inject.Inject + +/** + * This handler is responsible for a smooth threads migration. It will map all incoming + * threads as replies. So a device without threads enabled/updated will be able to view + * threads response as replies to the orighinal message + */ +internal class ThreadsAwarenessHandler @Inject constructor( + private val permalinkFactory: PermalinkFactory +) { + + fun handleIfNeeded(realm: Realm, + roomId: String, + event: Event, + decryptIfNeeded: (event: Event, roomId: String) -> Unit) { + + if (!isThreadEvent(event)) return + val rootThreadEventId = getRootThreadEventId(event) ?: return + val payload = event.mxDecryptionResult?.payload?.toMutableMap() ?: return + val body = getValueFromPayload(payload, "body") ?: return + val msgType = getValueFromPayload(payload, "msgtype") ?: return + val rootThreadEventEntity = EventEntity.where(realm, eventId = rootThreadEventId).findFirst() ?: return + val rootThreadEvent = EventMapper.map(rootThreadEventEntity) + val rootThreadEventSenderId = rootThreadEvent.senderId ?: return + val rootThreadEventEventId = rootThreadEvent.eventId ?: return + + Timber.i("------> Thread event detected!") + + if (rootThreadEvent.isEncrypted()) { + decryptIfNeeded(rootThreadEvent, roomId) + } + + val rootThreadEventBody = getValueFromPayload(rootThreadEvent.mxDecryptionResult?.payload?.toMutableMap(),"body") + + val permalink = permalinkFactory.createPermalink(roomId, rootThreadEventEventId, false) + val userLink = permalinkFactory.createPermalink(rootThreadEventSenderId, false) ?: "" + + val replyFormatted = LocalEchoEventFactory.REPLY_PATTERN.format( + permalink, + userLink, + rootThreadEventSenderId, + // Remove inner mx_reply tags if any + rootThreadEventBody, + body) + + val messageTextContent = MessageTextContent( + msgType = msgType, + format = MessageFormat.FORMAT_MATRIX_HTML, + body = body, + formattedBody = replyFormatted + ).toContent() + + payload["content"] = messageTextContent + + event.mxDecryptionResult = event.mxDecryptionResult?.copy(payload = payload ) + + } + + private fun isThreadEvent(event: Event): Boolean = + event.content.toModel()?.relatesTo?.type == "io.element.thread" + + private fun getRootThreadEventId(event: Event): String? = + event.content.toModel()?.relatesTo?.eventId + + @Suppress("UNCHECKED_CAST") + private fun getValueFromPayload(payload: JsonDict?, key: String): String? { + val content = payload?.get("content") as? JsonDict + return content?.get(key) as? String + } +} From cb1d5e888d27a1309a5f36c6ddbffdcf5701601f Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 25 Oct 2021 20:14:10 +0300 Subject: [PATCH 109/970] 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 110/970] 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 111/970] 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 112/970] 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 113/970] 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 114/970] 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 115/970] 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 dc5739c11daa4049ca0883fee1375363ac0b3bae Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 18:02:39 +0200 Subject: [PATCH 116/970] Format --- .../main/java/im/vector/app/features/login/LoginViewState.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 { From 9f1efab18d3f461bdcdc62cd9fda86dbf39c95de Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 19:18:14 +0200 Subject: [PATCH 117/970] =?UTF-8?q?Correctly=20handle=20url=20of=20type=20?= =?UTF-8?q?https://mobile.element.io/=3Fhs=5Furl=3D=E2=80=A6&is=5Furl=3D?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skip the choose server screen when such URL are open when Element --- changelog.d/2684.bugfix | 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 ++++++++++++++++--- vector/src/main/res/values/strings.xml | 2 ++ 8 files changed, 60 insertions(+), 17 deletions(-) create mode 100644 changelog.d/2684.bugfix diff --git a/changelog.d/2684.bugfix b/changelog.d/2684.bugfix new file mode 100644 index 0000000000..7d46059936 --- /dev/null +++ b/changelog.d/2684.bugfix @@ -0,0 +1,2 @@ +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 \ 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 f0a1b1f937..a01e02f4e0 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 @@ -103,7 +103,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(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 28a9fa46d1..ca126570ff 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 @@ -19,7 +19,6 @@ 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 @@ -128,6 +127,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) @@ -146,6 +146,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 @@ -744,7 +765,8 @@ class LoginViewModel @AssistedInject constructor( } } - private fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig) { + private fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, + serverTypeOverride: ServerType? = null) { currentHomeServerConnectionConfig = homeServerConnectionConfig currentJob = viewModelScope.launch { @@ -755,7 +777,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 + } ) } @@ -788,7 +814,6 @@ class LoginViewModel @AssistedInject constructor( else -> LoginMode.Unsupported } - // FIXME We should post a view event here normally? setState { copy( asyncHomeServerLoginFlowRequest = Uninitialized, @@ -803,6 +828,7 @@ class LoginViewModel @AssistedInject constructor( // Notify the UI _viewEvents.post(LoginViewEvents.OutdatedHomeserver) } + _viewEvents.post(LoginViewEvents.OnLoginFlowRetrieved) } } 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 f2330903ae735b9cc3c4257c93671b61965d9055 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 25 Oct 2021 22:50:01 +0200 Subject: [PATCH 118/970] Add named parameter for boolean --- .../java/im/vector/app/features/login/LoginSplashFragment.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt index bab39bc374..527f9f99b3 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt @@ -61,7 +61,7 @@ class LoginSplashFragment @Inject constructor( } private fun getStarted() { - loginViewModel.handle(LoginAction.OnGetStarted(false)) + loginViewModel.handle(LoginAction.OnGetStarted(resetLoginConfig = false)) } override fun resetViewModel() { @@ -77,7 +77,7 @@ class LoginSplashFragment @Inject constructor( .setTitle(R.string.dialog_title_error) .setMessage(getString(R.string.login_error_homeserver_from_url_not_found, url)) .setPositiveButton(R.string.login_error_homeserver_from_url_not_found_enter_manual) { _, _ -> - loginViewModel.handle(LoginAction.OnGetStarted(true)) + loginViewModel.handle(LoginAction.OnGetStarted(resetLoginConfig = true)) } .setNegativeButton(R.string.cancel, null) .show() From 093b5c76abfc2b9f00a9c76bb31ac4b5ca9172fb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 26 Oct 2021 16:51:08 +0200 Subject: [PATCH 119/970] towncrier --- CHANGES.md | 9 +++++++++ changelog.d/2684.bugfix | 2 -- 2 files changed, 9 insertions(+), 2 deletions(-) delete mode 100644 changelog.d/2684.bugfix 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/changelog.d/2684.bugfix b/changelog.d/2684.bugfix deleted file mode 100644 index 7d46059936..0000000000 --- a/changelog.d/2684.bugfix +++ /dev/null @@ -1,2 +0,0 @@ -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 \ No newline at end of file From edd29ec4efd2ad6848281f11b96794e6533874a6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 26 Oct 2021 16:51:59 +0200 Subject: [PATCH 120/970] fastlane change --- fastlane/metadata/android/en-US/changelogs/40103060.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/40103060.txt 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 From 792444d1aca7ea731adfc2d9d01431b581e007b5 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Oct 2021 16:23:32 +0100 Subject: [PATCH 121/970] 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 122/970] 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 123/970] 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 d1f3e3f958d827d3d1a6ac0b1cd496757e36a3d4 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Tue, 26 Oct 2021 18:59:01 +0300 Subject: [PATCH 124/970] Thread awareness, map threads events to replies --- .../session/sync/handler/room/RoomSyncHandler.kt | 11 +++++++++-- .../sync/handler/room/ThreadsAwarenessHandler.kt | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index db4e07a21a..543783acac 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -363,11 +363,18 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle } eventIds.add(event.eventId) - if (event.isEncrypted() && insertType != EventInsertType.INITIAL_SYNC) { + val isInitialSync = insertType == EventInsertType.INITIAL_SYNC + + if (event.isEncrypted() && !isInitialSync) { decryptIfNeeded(event, roomId) } - threadsAwarenessHandler.handleIfNeeded(realm, roomId, event, ::decryptIfNeeded) + threadsAwarenessHandler.handleIfNeeded( + realm = realm, + roomId = roomId, + event = event, + isInitialSync = isInitialSync, + ::decryptIfNeeded) val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it } val eventEntity = event.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, insertType) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt index cc01f62448..1c45b16abf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt @@ -41,7 +41,7 @@ import javax.inject.Inject /** * This handler is responsible for a smooth threads migration. It will map all incoming * threads as replies. So a device without threads enabled/updated will be able to view - * threads response as replies to the orighinal message + * threads response as replies to the original message */ internal class ThreadsAwarenessHandler @Inject constructor( private val permalinkFactory: PermalinkFactory @@ -50,6 +50,7 @@ internal class ThreadsAwarenessHandler @Inject constructor( fun handleIfNeeded(realm: Realm, roomId: String, event: Event, + isInitialSync: Boolean, decryptIfNeeded: (event: Event, roomId: String) -> Unit) { if (!isThreadEvent(event)) return @@ -60,9 +61,8 @@ internal class ThreadsAwarenessHandler @Inject constructor( val rootThreadEventEntity = EventEntity.where(realm, eventId = rootThreadEventId).findFirst() ?: return val rootThreadEvent = EventMapper.map(rootThreadEventEntity) val rootThreadEventSenderId = rootThreadEvent.senderId ?: return - val rootThreadEventEventId = rootThreadEvent.eventId ?: return - Timber.i("------> Thread event detected!") + Timber.i("------> Thread event detected! - isInitialSync: $isInitialSync") if (rootThreadEvent.isEncrypted()) { decryptIfNeeded(rootThreadEvent, roomId) @@ -70,7 +70,7 @@ internal class ThreadsAwarenessHandler @Inject constructor( val rootThreadEventBody = getValueFromPayload(rootThreadEvent.mxDecryptionResult?.payload?.toMutableMap(),"body") - val permalink = permalinkFactory.createPermalink(roomId, rootThreadEventEventId, false) + val permalink = permalinkFactory.createPermalink(roomId, rootThreadEventId, false) val userLink = permalinkFactory.createPermalink(rootThreadEventSenderId, false) ?: "" val replyFormatted = LocalEchoEventFactory.REPLY_PATTERN.format( From a9d192fa399c6bddcc6d3bdede485f64f7765a7e Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 26 Oct 2021 18:09:07 +0200 Subject: [PATCH 125/970] 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 126/970] 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 127/970] 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 128/970] 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 129/970] 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 130/970] 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 131/970] 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 132/970] 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 133/970] 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 134/970] 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 135/970] 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 136/970] 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 137/970] 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 138/970] 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 139/970] 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 140/970] 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 141/970] 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 142/970] 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 143/970] 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 144/970] 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 145/970] 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 146/970] 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 147/970] 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 148/970] 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 149/970] 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 150/970] 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 151/970] 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 152/970] 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 153/970] 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 154/970] 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 155/970] 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 156/970] 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 157/970] 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 158/970] 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 159/970] 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 160/970] 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 161/970] 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 162/970] 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 163/970] 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 164/970] 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 165/970] 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 166/970] 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 167/970] 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 168/970] 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 169/970] 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 170/970] 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 171/970] 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 172/970] 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 173/970] 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 174/970] 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 175/970] 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 176/970] 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 177/970] 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 178/970] 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 179/970] 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 180/970] 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 181/970] 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 182/970] 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 183/970] 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 184/970] 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 185/970] 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 186/970] 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 187/970] 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 188/970] 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 189/970] 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 190/970] 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 @@ + + +