From 94db36d6c4185021b9c913b76f058a87b82428cf Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 29 Mar 2019 11:15:27 +0100 Subject: [PATCH] Fix room summary not being updated when room members are loaded --- .../android/internal/session/SessionModule.kt | 5 ++ .../internal/session/room/RoomModule.kt | 10 +-- .../session/room/RoomSummaryUpdater.kt | 79 +++++++++++++++++++ .../room/members/LoadRoomMembersTask.kt | 16 ++-- .../internal/session/sync/RoomSyncHandler.kt | 79 ++----------------- .../internal/session/sync/SyncModule.kt | 2 +- 6 files changed, 103 insertions(+), 88 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt index 510325fa..85dcdb03 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt @@ -29,6 +29,7 @@ import im.vector.matrix.android.internal.session.group.DefaultGroupService import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater import im.vector.matrix.android.internal.session.room.DefaultRoomService import im.vector.matrix.android.internal.session.room.RoomAvatarResolver +import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver import im.vector.matrix.android.internal.session.room.members.RoomMemberDisplayNameResolver import im.vector.matrix.android.internal.session.room.prune.EventsPruner @@ -89,6 +90,10 @@ internal class SessionModule(private val sessionParams: SessionParams) { RoomAvatarResolver(get(), sessionParams.credentials) } + scope(DefaultSession.SCOPE) { + RoomSummaryUpdater(get(), get(), get()) + } + scope(DefaultSession.SCOPE) { DefaultRoomService(get(), get()) as RoomService } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt index 716fd155..c506cb0d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt @@ -22,11 +22,7 @@ import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersTas import im.vector.matrix.android.internal.session.room.read.DefaultSetReadMarkersTask import im.vector.matrix.android.internal.session.room.read.SetReadMarkersTask import im.vector.matrix.android.internal.session.room.send.EventFactory -import im.vector.matrix.android.internal.session.room.timeline.DefaultGetContextOfEventTask -import im.vector.matrix.android.internal.session.room.timeline.DefaultPaginationTask -import im.vector.matrix.android.internal.session.room.timeline.GetContextOfEventTask -import im.vector.matrix.android.internal.session.room.timeline.PaginationTask -import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor +import im.vector.matrix.android.internal.session.room.timeline.* import org.koin.dsl.module.module import retrofit2.Retrofit @@ -41,7 +37,7 @@ class RoomModule { } scope(DefaultSession.SCOPE) { - DefaultLoadRoomMembersTask(get(), get(), get()) as LoadRoomMembersTask + DefaultLoadRoomMembersTask(get(), get(), get(), get()) as LoadRoomMembersTask } scope(DefaultSession.SCOPE) { @@ -57,7 +53,7 @@ class RoomModule { } scope(DefaultSession.SCOPE) { - DefaultSetReadMarkersTask(get(), get(),get()) as SetReadMarkersTask + DefaultSetReadMarkersTask(get(), get(), get()) as SetReadMarkersTask } scope(DefaultSession.SCOPE) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt new file mode 100644 index 00000000..c8ed0ee9 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomSummaryUpdater.kt @@ -0,0 +1,79 @@ +/* + * + * * 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.matrix.android.internal.session.room + +import im.vector.matrix.android.api.auth.data.Credentials +import im.vector.matrix.android.api.session.events.model.EventType +import im.vector.matrix.android.api.session.events.model.toModel +import im.vector.matrix.android.api.session.room.model.RoomTopicContent +import im.vector.matrix.android.internal.database.mapper.asDomain +import im.vector.matrix.android.internal.database.model.EventEntity +import im.vector.matrix.android.internal.database.model.RoomSummaryEntity +import im.vector.matrix.android.internal.database.query.latestEvent +import im.vector.matrix.android.internal.database.query.prev +import im.vector.matrix.android.internal.database.query.where +import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver +import im.vector.matrix.android.internal.session.room.members.RoomMembers +import im.vector.matrix.android.internal.session.sync.model.RoomSyncSummary +import im.vector.matrix.android.internal.session.sync.model.RoomSyncUnreadNotifications +import io.realm.Realm +import io.realm.kotlin.createObject + +internal class RoomSummaryUpdater(private val credentials: Credentials, + private val roomDisplayNameResolver: RoomDisplayNameResolver, + private val roomAvatarResolver: RoomAvatarResolver) { + + fun update(realm: Realm, + roomId: String, + roomSummary: RoomSyncSummary? = null, + unreadNotifications: RoomSyncUnreadNotifications? = null) { + + val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() + ?: realm.createObject(roomId) + + if (roomSummary != null) { + if (roomSummary.heroes.isNotEmpty()) { + roomSummaryEntity.heroes.clear() + roomSummaryEntity.heroes.addAll(roomSummary.heroes) + } + if (roomSummary.invitedMembersCount != null) { + roomSummaryEntity.invitedMembersCount = roomSummary.invitedMembersCount + } + if (roomSummary.joinedMembersCount != null) { + roomSummaryEntity.joinedMembersCount = roomSummary.joinedMembersCount + } + } + if (unreadNotifications?.highlightCount != null) { + roomSummaryEntity.highlightCount = unreadNotifications.highlightCount + } + if (unreadNotifications?.notificationCount != null) { + roomSummaryEntity.notificationCount = unreadNotifications.notificationCount + } + + val lastEvent = EventEntity.latestEvent(realm, roomId, includedTypes = listOf(EventType.MESSAGE)) + val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev()?.asDomain() + val otherRoomMembers = RoomMembers(realm, roomId).getLoaded().filterKeys { it != credentials.userId } + roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString() + roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(roomId) + roomSummaryEntity.topic = lastTopicEvent?.content.toModel()?.topic + roomSummaryEntity.lastMessage = lastEvent + roomSummaryEntity.otherMemberIds.clear() + roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers.keys) + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/LoadRoomMembersTask.kt index 788bb1c1..7cd8bbaf 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/members/LoadRoomMembersTask.kt @@ -24,6 +24,7 @@ import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.session.room.RoomAPI +import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.session.sync.SyncTokenStore import im.vector.matrix.android.internal.task.Task import im.vector.matrix.android.internal.util.tryTransactionSync @@ -39,7 +40,8 @@ internal interface LoadRoomMembersTask : Task { @@ -49,7 +51,7 @@ internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI, //TODO use this token val lastToken = syncTokenStore.getLastToken() executeRequest { - apiCall = roomAPI.getMembers(params.roomId, null, null, params.excludeMembership?.value) + apiCall = roomAPI.getMembers(params.roomId, lastToken, null, params.excludeMembership?.value) }.flatMap { response -> insertInDb(response, params.roomId) }.map { true } @@ -61,22 +63,24 @@ internal class DefaultLoadRoomMembersTask(private val roomAPI: RoomAPI, .tryTransactionSync { realm -> // We ignore all the already known members val roomEntity = RoomEntity.where(realm, roomId).findFirst() - ?: realm.createObject(roomId) + ?: realm.createObject(roomId) val roomMembers = RoomMembers(realm, roomId).getLoaded() val eventsToInsert = response.roomMemberEvents.filter { !roomMembers.containsKey(it.stateKey) } roomEntity.addStateEvents(eventsToInsert) roomEntity.areAllMembersLoaded = true + + roomSummaryUpdater.update(realm, roomId) } .map { response } } private fun areAllMembersAlreadyLoaded(roomId: String): Boolean { return monarchy - .fetchAllCopiedSync { RoomEntity.where(it, roomId) } - .firstOrNull() - ?.areAllMembersLoaded ?: false + .fetchAllCopiedSync { RoomEntity.where(it, roomId) } + .firstOrNull() + ?.areAllMembersLoaded ?: false } } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt index cc29f99e..70848eea 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/RoomSyncHandler.kt @@ -17,45 +17,28 @@ package im.vector.matrix.android.internal.session.sync import com.zhuinden.monarchy.Monarchy -import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.room.model.MyMembership -import im.vector.matrix.android.api.session.room.model.RoomTopicContent import im.vector.matrix.android.api.session.room.model.tag.RoomTagContent import im.vector.matrix.android.internal.database.helper.addAll import im.vector.matrix.android.internal.database.helper.addOrUpdate import im.vector.matrix.android.internal.database.helper.addStateEvents import im.vector.matrix.android.internal.database.helper.lastStateIndex -import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.ChunkEntity -import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.RoomEntity -import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom -import im.vector.matrix.android.internal.database.query.latestEvent -import im.vector.matrix.android.internal.database.query.prev import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.session.room.RoomAvatarResolver -import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver -import im.vector.matrix.android.internal.session.room.members.RoomMembers +import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection -import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync -import im.vector.matrix.android.internal.session.sync.model.RoomSync -import im.vector.matrix.android.internal.session.sync.model.RoomSyncAccountData -import im.vector.matrix.android.internal.session.sync.model.RoomSyncEphemeral -import im.vector.matrix.android.internal.session.sync.model.RoomSyncSummary -import im.vector.matrix.android.internal.session.sync.model.RoomSyncUnreadNotifications -import im.vector.matrix.android.internal.session.sync.model.RoomsSyncResponse +import im.vector.matrix.android.internal.session.sync.model.* import io.realm.Realm import io.realm.kotlin.createObject internal class RoomSyncHandler(private val monarchy: Monarchy, private val readReceiptHandler: ReadReceiptHandler, - private val roomDisplayNameResolver: RoomDisplayNameResolver, - private val roomAvatarResolver: RoomAvatarResolver, - private val credentials: Credentials, + private val roomSummaryUpdater: RoomSummaryUpdater, private val roomTagHandler: RoomTagHandler) { sealed class HandlingStrategy { @@ -88,7 +71,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, roomSync: RoomSync): RoomEntity { val roomEntity = RoomEntity.where(realm, roomId).findFirst() - ?: realm.createObject(roomId) + ?: realm.createObject(roomId) if (roomEntity.membership == MyMembership.INVITED) { roomEntity.chunks.deleteAllFromRealm() @@ -119,12 +102,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, ) roomEntity.addOrUpdate(chunkEntity) } - - handleRoomSummary(realm, roomId, roomSync.summary) - - if (roomSync.unreadNotifications != null) { - handleUnreadNotifications(realm, roomId, roomSync.unreadNotifications) - } + roomSummaryUpdater.update(realm, roomId, roomSync.summary, roomSync.unreadNotifications) if (roomSync.ephemeral != null && roomSync.ephemeral.events.isNotEmpty()) { handleEphemeral(realm, roomId, roomSync.ephemeral) @@ -180,39 +158,6 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, return chunkEntity } - private fun handleRoomSummary(realm: Realm, - roomId: String, - roomSummary: RoomSyncSummary?) { - - val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() - ?: RoomSummaryEntity(roomId) - - val lastEvent = EventEntity.latestEvent(realm, roomId, includedTypes = listOf(EventType.MESSAGE)) - val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev()?.asDomain() - - val otherRoomMembers = RoomMembers(realm, roomId).getLoaded().filterKeys { it != credentials.userId } - roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString() - roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(roomId) - roomSummaryEntity.topic = lastTopicEvent?.content.toModel()?.topic - roomSummaryEntity.lastMessage = lastEvent - roomSummaryEntity.otherMemberIds.clear() - roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers.keys) - - if (roomSummary != null) { - if (roomSummary.heroes.isNotEmpty()) { - roomSummaryEntity.heroes.clear() - roomSummaryEntity.heroes.addAll(roomSummary.heroes) - } - if (roomSummary.invitedMembersCount != null) { - roomSummaryEntity.invitedMembersCount = roomSummary.invitedMembersCount - } - if (roomSummary.joinedMembersCount != null) { - roomSummaryEntity.joinedMembersCount = roomSummary.joinedMembersCount - } - } - realm.insertOrUpdate(roomSummaryEntity) - } - private fun handleEphemeral(realm: Realm, roomId: String, ephemeral: RoomSyncEphemeral) { @@ -222,20 +167,6 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, .flatMap { readReceiptHandler.handle(realm, roomId, it) } } - private fun handleUnreadNotifications(realm: Realm, roomId: String, unreadNotifications: RoomSyncUnreadNotifications) { - val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() - ?: RoomSummaryEntity(roomId) - - if (unreadNotifications.highlightCount != null) { - roomSummaryEntity.highlightCount = unreadNotifications.highlightCount - } - if (unreadNotifications.notificationCount != null) { - roomSummaryEntity.notificationCount = unreadNotifications.notificationCount - } - realm.insertOrUpdate(roomSummaryEntity) - - } - private fun handleRoomAccountDataEvents(realm: Realm, roomId: String, accountData: RoomSyncAccountData) { accountData.events .filter { it.type == EventType.TAG } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt index b1926486..7995fff1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncModule.kt @@ -40,7 +40,7 @@ internal class SyncModule { } scope(DefaultSession.SCOPE) { - RoomSyncHandler(get(), get(), get(),get(),get(),get()) + RoomSyncHandler(get(), get(), get(), get()) } scope(DefaultSession.SCOPE) {