diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/ChunkEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/ChunkEntity.kt index cd84d257..354720df 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/ChunkEntity.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/model/ChunkEntity.kt @@ -6,8 +6,9 @@ import io.realm.RealmResults import io.realm.annotations.LinkingObjects internal open class ChunkEntity(var prevToken: String? = null, - var nextToken: String? = null, - var events: RealmList = RealmList() + var nextToken: String? = null, + var isLast: Boolean = false, + var events: RealmList = RealmList() ) : RealmObject() { @LinkingObjects("chunks") diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ChunkEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ChunkEntityQueries.kt index f6a959c8..ec21f178 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ChunkEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ChunkEntityQueries.kt @@ -38,10 +38,8 @@ internal fun ChunkEntity.Companion.findWithNextToken(realm: Realm, roomId: Strin internal fun ChunkEntity.Companion.findLastLiveChunkFromRoom(realm: Realm, roomId: String): ChunkEntity? { return where(realm, roomId) - .and() - .isNull(ChunkEntityFields.NEXT_TOKEN) - .findAll() - .last(null) + .equalTo(ChunkEntityFields.IS_LAST, true) + .findFirst() } internal fun ChunkEntity.Companion.findAllIncludingEvents(realm: Realm, eventIds: List): RealmResults { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineHolder.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineHolder.kt index 579a9f36..9a317861 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineHolder.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimelineHolder.kt @@ -8,7 +8,8 @@ import im.vector.matrix.android.api.session.events.interceptor.EnrichedEventInte import im.vector.matrix.android.api.session.events.model.EnrichedEvent import im.vector.matrix.android.api.session.room.TimelineHolder 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.ChunkEntityFields +import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntityFields import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.session.events.interceptor.MessageEventInterceptor @@ -17,8 +18,8 @@ import io.realm.Sort private const val PAGE_SIZE = 30 internal class DefaultTimelineHolder(private val roomId: String, - private val monarchy: Monarchy, - private val boundaryCallback: TimelineBoundaryCallback + private val monarchy: Monarchy, + private val boundaryCallback: TimelineBoundaryCallback ) : TimelineHolder { private val eventInterceptors = ArrayList() @@ -30,12 +31,9 @@ internal class DefaultTimelineHolder(private val roomId: String, override fun liveTimeline(): LiveData> { val realmDataSourceFactory = monarchy.createDataSourceFactory { realm -> - ChunkEntity.where(realm, roomId) - .findAll() - .last(null) - ?.let { - it.events.where().sort(EventEntityFields.ORIGIN_SERVER_TS, Sort.DESCENDING) - } + EventEntity.where(realm, roomId = roomId) + .equalTo("${EventEntityFields.CHUNK}.${ChunkEntityFields.IS_LAST}", true) + .sort(EventEntityFields.ORIGIN_SERVER_TS, Sort.DESCENDING) } val domainSourceFactory = realmDataSourceFactory .map { it.asDomain() } 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 bd287f9e..e0826ba9 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 @@ -11,7 +11,11 @@ import im.vector.matrix.android.internal.database.model.RoomSummaryEntity import im.vector.matrix.android.internal.database.query.findAllIncludingEvents import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.session.sync.model.* +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.RoomSyncEphemeral +import im.vector.matrix.android.internal.session.sync.model.RoomSyncSummary +import im.vector.matrix.android.internal.session.sync.model.RoomsSyncResponse import io.realm.Realm import io.realm.kotlin.createObject @@ -38,9 +42,9 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy) { val rooms = when (handlingStrategy) { - is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedRoom(realm, it.key, it.value) } + is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedRoom(realm, it.key, it.value) } is HandlingStrategy.INVITED -> handlingStrategy.data.map { handleInvitedRoom(realm, it.key, it.value) } - is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(it.key, it.value) } + is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(it.key, it.value) } } realm.insertOrUpdate(rooms) } @@ -50,7 +54,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, roomSync: RoomSync): RoomEntity { val roomEntity = RoomEntity.where(realm, roomId).findFirst() - ?: RoomEntity(roomId) + ?: RoomEntity(roomId) if (roomEntity.membership == MyMembership.INVITED) { roomEntity.chunks.deleteAllFromRealm() @@ -111,7 +115,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, roomSummary: RoomSyncSummary) { val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() - ?: RoomSummaryEntity(roomId) + ?: RoomSummaryEntity(roomId) if (roomSummary.heroes.isNotEmpty()) { roomSummaryEntity.heroes.clear() @@ -132,13 +136,17 @@ internal class RoomSyncHandler(private val monarchy: Monarchy, prevToken: String? = null, nextToken: String? = null, isLimited: Boolean = true): ChunkEntity { + + val lastChunk = ChunkEntity.findLastLiveChunkFromRoom(realm, roomId) val chunkEntity = if (!isLimited) { - ChunkEntity.findLastLiveChunkFromRoom(realm, roomId) + lastChunk } else { val eventIds = eventList.filter { it.eventId != null }.map { it.eventId!! } ChunkEntity.findAllIncludingEvents(realm, eventIds).firstOrNull() } ?: realm.createObject().apply { this.prevToken = prevToken } + lastChunk?.isLast = false + chunkEntity.isLast = true chunkEntity.nextToken = nextToken eventList.addManagedToChunk(chunkEntity) return chunkEntity