Read receipts: fix dummy being overrided

This commit is contained in:
ganfra 2019-08-08 17:49:31 +02:00
parent d98567045c
commit 39f58d048b
5 changed files with 58 additions and 42 deletions

View File

@ -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.TimelineEventEntity
import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields 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.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.database.query.where
import im.vector.matrix.android.internal.extensions.assertIsManaged import im.vector.matrix.android.internal.extensions.assertIsManaged
import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection 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 eventId = event.eventId ?: ""
val senderId = event.senderId ?: "" val senderId = event.senderId ?: ""
val currentReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId).findFirst() val readReceiptsSummaryEntity = ReadReceiptsSummaryEntity.where(realm, eventId).findFirst()
?: ReadReceiptsSummaryEntity(eventId) ?: ReadReceiptsSummaryEntity(eventId)
// Update RR for the sender of a new message // Update RR for the sender of a new message with a dummy one
if (direction == PaginationDirection.FORWARDS && !isUnlinked) {
ReadReceiptEntity.where(realm, roomId = roomId, userId = senderId).findFirst()?.also { if (event.originServerTs != null) {
val previousEventId = it.eventId val timestampOfEvent = event.originServerTs.toDouble()
val previousReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId = previousEventId).findFirst() val readReceiptOfSender = ReadReceiptEntity.getOrCreate(realm, roomId = roomId, userId = senderId)
it.eventId = eventId // If the synced RR is older, update
previousReceiptsSummary?.readReceipts?.remove(it) if (timestampOfEvent > readReceiptOfSender.originServerTs) {
currentReceiptsSummary.readReceipts.add(it) 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 { val eventEntity = TimelineEventEntity(localId).also {
it.root = event.toEntity(roomId).apply { it.root = event.toEntity(roomId).apply {
this.stateIndex = currentStateIndex this.stateIndex = currentStateIndex
@ -162,7 +168,7 @@ internal fun ChunkEntity.add(roomId: String,
it.eventId = eventId it.eventId = eventId
it.roomId = roomId it.roomId = roomId
it.annotations = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() it.annotations = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
it.readReceipts = currentReceiptsSummary it.readReceipts = readReceiptsSummaryEntity
} }
val position = if (direction == PaginationDirection.FORWARDS) 0 else this.timelineEvents.size val position = if (direction == PaginationDirection.FORWARDS) 0 else this.timelineEvents.size
timelineEvents.add(position, eventEntity) timelineEvents.add(position, eventEntity)

View File

@ -26,4 +26,22 @@ internal fun ReadReceiptEntity.Companion.where(realm: Realm, roomId: String, use
return realm.where<ReadReceiptEntity>() return realm.where<ReadReceiptEntity>()
.equalTo(ReadReceiptEntityFields.ROOM_ID, roomId) .equalTo(ReadReceiptEntityFields.ROOM_ID, roomId)
.equalTo(ReadReceiptEntityFields.USER_ID, userId) .equalTo(ReadReceiptEntityFields.USER_ID, userId)
} }
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
}
}

View File

@ -25,4 +25,4 @@ import io.realm.kotlin.where
internal fun ReadReceiptsSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery<ReadReceiptsSummaryEntity> { internal fun ReadReceiptsSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery<ReadReceiptsSummaryEntity> {
return realm.where<ReadReceiptsSummaryEntity>() return realm.where<ReadReceiptsSummaryEntity>()
.equalTo(ReadReceiptsSummaryEntityFields.EVENT_ID, eventId) .equalTo(ReadReceiptsSummaryEntityFields.EVENT_ID, eventId)
} }

View File

@ -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.ReadReceiptEntity
import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntity 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 im.vector.matrix.android.internal.database.query.where
import io.realm.Realm import io.realm.Realm
import timber.log.Timber import timber.log.Timber
@ -64,14 +66,7 @@ internal class ReadReceiptHandler @Inject constructor() {
for ((userId, paramsDict) in userIdsDict) { for ((userId, paramsDict) in userIdsDict) {
val ts = paramsDict[TIMESTAMP_KEY] ?: 0.0 val ts = paramsDict[TIMESTAMP_KEY] ?: 0.0
val primaryKey = "${roomId}_$userId" val receiptEntity = ReadReceiptEntity.createUnmanaged(roomId, eventId, userId, ts)
val receiptEntity = ReadReceiptEntity().apply {
this.primaryKey = primaryKey
this.eventId = eventId
this.roomId = roomId
this.userId = userId
this.originServerTs = ts
}
readReceiptsSummary.readReceipts.add(receiptEntity) readReceiptsSummary.readReceipts.add(receiptEntity)
} }
readReceiptSummaries.add(readReceiptsSummary) readReceiptSummaries.add(readReceiptsSummary)
@ -87,22 +82,19 @@ internal class ReadReceiptHandler @Inject constructor() {
for ((userId, paramsDict) in userIdsDict) { for ((userId, paramsDict) in userIdsDict) {
val ts = paramsDict[TIMESTAMP_KEY] ?: 0.0 val ts = paramsDict[TIMESTAMP_KEY] ?: 0.0
val primaryKey = "${roomId}_$userId" val receiptEntity = ReadReceiptEntity.getOrCreate(realm, roomId, userId)
val receiptEntity = ReadReceiptEntity.where(realm, roomId, userId).findFirst() // ensure new ts is superior to the previous one
?: realm.createObject(ReadReceiptEntity::class.java, primaryKey) if (ts > receiptEntity.originServerTs) {
ReadReceiptsSummaryEntity.where(realm, receiptEntity.eventId).findFirst()?.also {
ReadReceiptsSummaryEntity.where(realm, receiptEntity.eventId).findFirst()?.also { it.readReceipts.remove(receiptEntity)
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)
} }
} }
} }
} }

View File

@ -117,6 +117,14 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
Timber.v("Handle join sync for room $roomId") 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() val roomEntity = RoomEntity.where(realm, roomId).findFirst()
?: realm.createObject(roomId) ?: realm.createObject(roomId)
@ -151,14 +159,6 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
roomEntity.addOrUpdate(chunkEntity) roomEntity.addOrUpdate(chunkEntity)
} }
roomSummaryUpdater.update(realm, roomId, Membership.JOIN, roomSync.summary, roomSync.unreadNotifications) 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 return roomEntity
} }