From 581c0ffcb0c3989c133dc81e108e41e93ac10e01 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Wed, 16 Mar 2022 13:39:19 +0100 Subject: [PATCH] Fix endless loading timeline due to conflicting chunks Change-Id: I46918ed17b0bd5b2ac6797bfd2a9e3ffa42f14b8 --- .../database/query/ChunkEntityQueries.kt | 11 ++++++++++ .../room/timeline/TokenChunkEventPersistor.kt | 22 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt index 156a8dd767..109bda010e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/ChunkEntityQueries.kt @@ -40,6 +40,17 @@ internal fun ChunkEntity.Companion.find(realm: Realm, roomId: String, prevToken: return query.findFirst() } +internal fun ChunkEntity.Companion.findAll(realm: Realm, roomId: String, prevToken: String? = null, nextToken: String? = null): RealmResults? { + val query = where(realm, roomId) + if (prevToken != null) { + query.equalTo(ChunkEntityFields.PREV_TOKEN, prevToken) + } + if (nextToken != null) { + query.equalTo(ChunkEntityFields.NEXT_TOKEN, nextToken) + } + return query.findAll() +} + internal fun ChunkEntity.Companion.findLastForwardChunkOfRoom(realm: Realm, roomId: String): ChunkEntity? { return where(realm, roomId) .equalTo(ChunkEntityFields.IS_LAST_FORWARD, true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt index c97547c55b..30791138eb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt @@ -37,6 +37,7 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntity import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore import org.matrix.android.sdk.internal.database.query.create import org.matrix.android.sdk.internal.database.query.find +import org.matrix.android.sdk.internal.database.query.findAll 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 @@ -79,7 +80,26 @@ internal class TokenChunkEventPersistor @Inject constructor( val existingChunk = ChunkEntity.find(realm, roomId, prevToken = prevToken, nextToken = nextToken) if (existingChunk != null) { - Timber.v("This chunk is already in the db, returns") + Timber.v("This chunk is already in the db, checking if this might be caused by broken links") + if (direction == PaginationDirection.FORWARDS) { + val prevChunks = ChunkEntity.findAll(realm, roomId, nextToken = prevToken) + Timber.v("Found ${prevChunks?.size} prevChunks") + prevChunks?.forEach { + if (it.nextChunk != existingChunk) { + Timber.i("Set nextChunk for ${it.identifier()} from ${it.nextChunk?.identifier()} to ${existingChunk.identifier()}") + it.nextChunk = existingChunk + } + } + } else { + val nextChunks = ChunkEntity.findAll(realm, roomId, prevToken = nextToken) + Timber.v("Found ${nextChunks?.size} nextChunks") + nextChunks?.forEach { + if (it.prevChunk != existingChunk) { + Timber.i("Set prevChunk for ${it.identifier()} from ${it.prevChunk?.identifier()} to ${existingChunk.identifier()}") + it.prevChunk = existingChunk + } + } + } return@awaitTransaction } val prevChunk = ChunkEntity.find(realm, roomId, nextToken = prevToken)