Fix avatar rendering for DMs, after initial sync (#2693)

Also better handling of previous DMs management
This commit is contained in:
Benoit Marty 2021-03-31 22:53:29 +02:00
parent c0913711d6
commit f998c2f945
5 changed files with 33 additions and 16 deletions

View file

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

View file

@ -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<RoomSummaryEntity> {
internal fun RoomSummaryEntity.Companion.getDirectRooms(realm: Realm,
excludeRoomIds: Set<String>? = null): RealmResults<RoomSummaryEntity> {
return RoomSummaryEntity.where(realm)
.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
.apply {
if (!excludeRoomIds.isNullOrEmpty()) {
not().`in`(RoomSummaryEntityFields.ROOM_ID, excludeRoomIds.toTypedArray())
}
}
.findAll()
}

View file

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

View file

@ -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<DirectMessagesContent>() ?: 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) {

View file

@ -16,4 +16,7 @@
package org.matrix.android.sdk.internal.session.sync.model.accountdata
typealias DirectMessagesContent = Map<String, List<String>>
/**
* Keys are userIds, values are list of roomIds
*/
internal typealias DirectMessagesContent = Map<String, List<String>>