diff --git a/CHANGES.md b/CHANGES.md index ed549c918f..1601e0ec85 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ Bugfix 🐛: - Fix bad theme change for the MainActivity - Handle encrypted reactions (#2509) - Disable URL preview for some domains (#2995) + - Fix avatar rendering for DMs, after initial sync (#2693) Translations 🗣: - diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomSummaryEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomSummaryEntityQueries.kt index 7430b7822f..2af5dcf0ae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomSummaryEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/RoomSummaryEntityQueries.kt @@ -48,9 +48,15 @@ internal fun RoomSummaryEntity.Companion.getOrCreate(realm: Realm, roomId: Strin return where(realm, roomId).findFirst() ?: realm.createObject(roomId) } -internal fun RoomSummaryEntity.Companion.getDirectRooms(realm: Realm): RealmResults { +internal fun RoomSummaryEntity.Companion.getDirectRooms(realm: Realm, + excludeRoomIds: Set? = null): RealmResults { return RoomSummaryEntity.where(realm) .equalTo(RoomSummaryEntityFields.IS_DIRECT, true) + .apply { + if (!excludeRoomIds.isNullOrEmpty()) { + not().`in`(RoomSummaryEntityFields.ROOM_ID, excludeRoomIds.toTypedArray()) + } + } .findAll() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAvatarResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAvatarResolver.kt index 99f9d3644d..9bcb1eb196 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAvatarResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAvatarResolver.kt @@ -16,18 +16,18 @@ package org.matrix.android.sdk.internal.session.room +import io.realm.Realm 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.RoomAvatarContent import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.getOrNull +import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper -import io.realm.Realm -import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity -import org.matrix.android.sdk.internal.database.query.where import javax.inject.Inject internal class RoomAvatarResolver @Inject constructor(@UserId private val userId: String) { @@ -48,7 +48,7 @@ internal class RoomAvatarResolver @Inject constructor(@UserId private val userId val roomMembers = RoomMemberHelper(realm, roomId) val members = roomMembers.queryActiveRoomMembersEvent().findAll() // detect if it is a room with no more than 2 members (i.e. an alone or a 1:1 chat) - val isDirectRoom = RoomSummaryEntity.where(realm, roomId).findFirst()?.isDirect ?: false + val isDirectRoom = RoomSummaryEntity.where(realm, roomId).findFirst()?.isDirect ?: false if (isDirectRoom) { if (members.size == 1) { res = members.firstOrNull()?.avatarUrl diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt index 449d47abe5..907c1187fe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/UserAccountDataSyncHandler.kt @@ -45,6 +45,7 @@ import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.session.room.RoomAvatarResolver import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper import org.matrix.android.sdk.internal.session.sync.model.InvitedRoomSync import org.matrix.android.sdk.internal.session.sync.model.accountdata.BreadcrumbsContent @@ -60,7 +61,9 @@ internal class UserAccountDataSyncHandler @Inject constructor( @SessionDatabase private val monarchy: Monarchy, @UserId private val userId: String, private val directChatsHelper: DirectChatsHelper, - private val updateUserAccountDataTask: UpdateUserAccountDataTask) { + private val updateUserAccountDataTask: UpdateUserAccountDataTask, + private val roomAvatarResolver: RoomAvatarResolver +) { fun handle(realm: Realm, accountData: UserAccountDataSync?) { accountData?.list?.forEach { event -> @@ -151,23 +154,27 @@ internal class UserAccountDataSyncHandler @Inject constructor( } private fun handleDirectChatRooms(realm: Realm, event: UserAccountDataEvent) { - val oldDirectRooms = RoomSummaryEntity.getDirectRooms(realm) - oldDirectRooms.forEach { - it.isDirect = false - it.directUserId = null - } val content = event.content.toModel() ?: return - content.forEach { - val userId = it.key - it.value.forEach { roomId -> + content.forEach { (userId, roomIds) -> + roomIds.forEach { roomId -> val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() if (roomSummaryEntity != null) { roomSummaryEntity.isDirect = true roomSummaryEntity.directUserId = userId - realm.insertOrUpdate(roomSummaryEntity) + // Also update the avatar, there is a specific treatment for DMs + roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId) } } } + + // Handle previous direct rooms + RoomSummaryEntity.getDirectRooms(realm, excludeRoomIds = content.values.flatten().toSet()) + .forEach { + it.isDirect = false + it.directUserId = null + // Also update the avatar, there was a specific treatment for DMs + it.avatarUrl = roomAvatarResolver.resolve(realm, it.roomId) + } } private fun handleIgnoredUsers(realm: Realm, event: UserAccountDataEvent) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/DirectMessagesContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/DirectMessagesContent.kt index c406f3acf1..41173dea96 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/DirectMessagesContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/model/accountdata/DirectMessagesContent.kt @@ -16,4 +16,7 @@ package org.matrix.android.sdk.internal.session.sync.model.accountdata -typealias DirectMessagesContent = Map> +/** + * Keys are userIds, values are list of roomIds + */ +internal typealias DirectMessagesContent = Map>