From 647dd4398e1ca942e84de2260c1be4a283c93a03 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Sat, 12 Mar 2022 09:32:25 +0100 Subject: [PATCH] Fix modifying the wrong events in TimelineChunk I was observing cases where builtEvents[modificationIndex] was not having the same eventId as the udpatedEntity in. In particular, I observed both cases that - there was no item in the list yet with the same eventId as the updated one - there was an item with the same eventId already in the list, but at a different position. Whenever this happened, the timeline would render missing, duplicated, or swapped messages in the timeline. Instead of relying on the modificationIndex to be the same for both the change set and builtEvents, look up the proper index by eventId. Change-Id: Ic03bdcc8210ec87b786795848f31e9085096b903 --- .../internal/session/room/timeline/TimelineChunk.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 902e45f871..b1dee12865 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -463,12 +463,13 @@ internal class TimelineChunk(private val chunkEntity: ChunkEntity, for (range in modifications) { for (modificationIndex in (range.startIndex until range.startIndex + range.length)) { val updatedEntity = results[modificationIndex] ?: continue + val displayIndex = builtEventsIndexes.getOrDefault(updatedEntity.eventId, null) + if (displayIndex == null) { + Timber.w("TimelineChunk.handleDatabaseChangeSet: skip modification for ${updatedEntity.eventId} at $modificationIndex, not found in chunk") + continue + } try { - Timber.i("TimelineChunk.handleDatabaseChangeSet: modify ${updatedEntity.eventId} at $modificationIndex (previous: ${builtEvents.getOrNull(modificationIndex)?.eventId})") - if (updatedEntity.eventId != builtEvents.getOrNull(modificationIndex)?.eventId) { - Timber.e("TimelineChunk.handleDatabaseChangeSet: Unexpected modification, bug?!! was using item index $modificationIndex, better could've been ${builtEventsIndexes.getOrDefault(updatedEntity.eventId, null)}") - } - builtEvents[modificationIndex] = updatedEntity.buildAndDecryptIfNeeded() + builtEvents[displayIndex] = updatedEntity.buildAndDecryptIfNeeded() } catch (failure: Throwable) { Timber.v("Fail to update items at index: $modificationIndex") }