From 39f58d048b61576ce336c359bbd11a416090bc01 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 8 Aug 2019 17:49:31 +0200 Subject: [PATCH] Read receipts: fix dummy being overrided --- .../database/helper/ChunkEntityHelper.kt | 28 +++++++++------ .../query/ReadReceiptEntityQueries.kt | 20 ++++++++++- .../query/ReadReceiptsSummaryEntityQueries.kt | 2 +- .../session/sync/ReadReceiptHandler.kt | 34 +++++++------------ .../internal/session/sync/RoomSyncHandler.kt | 16 ++++----- 5 files changed, 58 insertions(+), 42 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt index 5a76741ede..a541e8cf39 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/helper/ChunkEntityHelper.kt @@ -28,6 +28,7 @@ import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntit import im.vector.matrix.android.internal.database.model.TimelineEventEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields import im.vector.matrix.android.internal.database.query.find +import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.extensions.assertIsManaged import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection @@ -138,20 +139,25 @@ internal fun ChunkEntity.add(roomId: String, val eventId = event.eventId ?: "" val senderId = event.senderId ?: "" - val currentReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId).findFirst() - ?: ReadReceiptsSummaryEntity(eventId) + val readReceiptsSummaryEntity = ReadReceiptsSummaryEntity.where(realm, eventId).findFirst() + ?: ReadReceiptsSummaryEntity(eventId) - // Update RR for the sender of a new message - if (direction == PaginationDirection.FORWARDS && !isUnlinked) { - ReadReceiptEntity.where(realm, roomId = roomId, userId = senderId).findFirst()?.also { - val previousEventId = it.eventId - val previousReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId = previousEventId).findFirst() - it.eventId = eventId - previousReceiptsSummary?.readReceipts?.remove(it) - currentReceiptsSummary.readReceipts.add(it) + // Update RR for the sender of a new message with a dummy one + + if (event.originServerTs != null) { + val timestampOfEvent = event.originServerTs.toDouble() + val readReceiptOfSender = ReadReceiptEntity.getOrCreate(realm, roomId = roomId, userId = senderId) + // If the synced RR is older, update + if (timestampOfEvent > readReceiptOfSender.originServerTs) { + val previousReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId = readReceiptOfSender.eventId).findFirst() + readReceiptOfSender.eventId = eventId + readReceiptOfSender.originServerTs = timestampOfEvent + previousReceiptsSummary?.readReceipts?.remove(readReceiptOfSender) + readReceiptsSummaryEntity.readReceipts.add(readReceiptOfSender) } } + val eventEntity = TimelineEventEntity(localId).also { it.root = event.toEntity(roomId).apply { this.stateIndex = currentStateIndex @@ -162,7 +168,7 @@ internal fun ChunkEntity.add(roomId: String, it.eventId = eventId it.roomId = roomId it.annotations = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() - it.readReceipts = currentReceiptsSummary + it.readReceipts = readReceiptsSummaryEntity } val position = if (direction == PaginationDirection.FORWARDS) 0 else this.timelineEvents.size timelineEvents.add(position, eventEntity) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt index e5a1afb602..acac419946 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptEntityQueries.kt @@ -26,4 +26,22 @@ internal fun ReadReceiptEntity.Companion.where(realm: Realm, roomId: String, use return realm.where() .equalTo(ReadReceiptEntityFields.ROOM_ID, roomId) .equalTo(ReadReceiptEntityFields.USER_ID, userId) -} \ No newline at end of file +} + +internal fun ReadReceiptEntity.Companion.createUnmanaged(roomId: String, eventId: String, userId: String, originServerTs: Double): ReadReceiptEntity { + return ReadReceiptEntity().apply { + this.primaryKey = "${roomId}_$userId" + this.eventId = eventId + this.roomId = roomId + this.userId = userId + this.originServerTs = originServerTs + } +} + +internal fun ReadReceiptEntity.Companion.getOrCreate(realm: Realm, roomId: String, userId: String): ReadReceiptEntity { + return ReadReceiptEntity.where(realm, roomId, userId).findFirst() + ?: realm.createObject(ReadReceiptEntity::class.java, "${roomId}_$userId").apply { + this.roomId = roomId + this.userId = userId + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptsSummaryEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptsSummaryEntityQueries.kt index e6c1e68552..d04ced119c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptsSummaryEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadReceiptsSummaryEntityQueries.kt @@ -25,4 +25,4 @@ import io.realm.kotlin.where internal fun ReadReceiptsSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery { return realm.where() .equalTo(ReadReceiptsSummaryEntityFields.EVENT_ID, eventId) -} \ No newline at end of file +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/ReadReceiptHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/ReadReceiptHandler.kt index 35acb527d5..5098e824f9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/ReadReceiptHandler.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/ReadReceiptHandler.kt @@ -18,6 +18,8 @@ package im.vector.matrix.android.internal.session.sync import im.vector.matrix.android.internal.database.model.ReadReceiptEntity import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntity +import im.vector.matrix.android.internal.database.query.createUnmanaged +import im.vector.matrix.android.internal.database.query.getOrCreate import im.vector.matrix.android.internal.database.query.where import io.realm.Realm import timber.log.Timber @@ -64,14 +66,7 @@ internal class ReadReceiptHandler @Inject constructor() { for ((userId, paramsDict) in userIdsDict) { val ts = paramsDict[TIMESTAMP_KEY] ?: 0.0 - val primaryKey = "${roomId}_$userId" - val receiptEntity = ReadReceiptEntity().apply { - this.primaryKey = primaryKey - this.eventId = eventId - this.roomId = roomId - this.userId = userId - this.originServerTs = ts - } + val receiptEntity = ReadReceiptEntity.createUnmanaged(roomId, eventId, userId, ts) readReceiptsSummary.readReceipts.add(receiptEntity) } readReceiptSummaries.add(readReceiptsSummary) @@ -87,22 +82,19 @@ internal class ReadReceiptHandler @Inject constructor() { for ((userId, paramsDict) in userIdsDict) { val ts = paramsDict[TIMESTAMP_KEY] ?: 0.0 - val primaryKey = "${roomId}_$userId" - val receiptEntity = ReadReceiptEntity.where(realm, roomId, userId).findFirst() - ?: realm.createObject(ReadReceiptEntity::class.java, primaryKey) - - ReadReceiptsSummaryEntity.where(realm, receiptEntity.eventId).findFirst()?.also { - it.readReceipts.remove(receiptEntity) + val receiptEntity = ReadReceiptEntity.getOrCreate(realm, roomId, userId) + // ensure new ts is superior to the previous one + if (ts > receiptEntity.originServerTs) { + ReadReceiptsSummaryEntity.where(realm, receiptEntity.eventId).findFirst()?.also { + it.readReceipts.remove(receiptEntity) + } + receiptEntity.eventId = eventId + receiptEntity.originServerTs = ts + readReceiptsSummary.readReceipts.add(receiptEntity) } - receiptEntity.apply { - this.eventId = eventId - this.roomId = roomId - this.userId = userId - this.originServerTs = ts - } - readReceiptsSummary.readReceipts.add(receiptEntity) } } } + } \ 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 4a243adf42..74b56e774c 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 @@ -117,6 +117,14 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch Timber.v("Handle join sync for room $roomId") + if (roomSync.ephemeral != null && roomSync.ephemeral.events.isNotEmpty()) { + handleEphemeral(realm, roomId, roomSync.ephemeral, isInitalSync) + } + + if (roomSync.accountData != null && roomSync.accountData.events.isNullOrEmpty().not()) { + handleRoomAccountDataEvents(realm, roomId, roomSync.accountData) + } + val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId) @@ -151,14 +159,6 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch roomEntity.addOrUpdate(chunkEntity) } roomSummaryUpdater.update(realm, roomId, Membership.JOIN, roomSync.summary, roomSync.unreadNotifications) - - if (roomSync.ephemeral != null && roomSync.ephemeral.events.isNotEmpty()) { - handleEphemeral(realm, roomId, roomSync.ephemeral, isInitalSync) - } - - if (roomSync.accountData != null && roomSync.accountData.events.isNullOrEmpty().not()) { - handleRoomAccountDataEvents(realm, roomId, roomSync.accountData) - } return roomEntity }