From d46ce8245da8661e09ca2df09f9d22f1b4bea44d Mon Sep 17 00:00:00 2001
From: ganfra <francoisg@matrix.org>
Date: Tue, 13 Nov 2018 10:50:53 +0100
Subject: [PATCH] Add a param "isLast" in chunk as we want live results in
 timeline... not sure it's the right way to do it.

---
 .../internal/database/model/ChunkEntity.kt    |  5 +++--
 .../database/query/ChunkEntityQueries.kt      |  6 ++----
 .../room/timeline/DefaultTimelineHolder.kt    | 16 +++++++--------
 .../internal/session/sync/RoomSyncHandler.kt  | 20 +++++++++++++------
 4 files changed, 26 insertions(+), 21 deletions(-)

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 cd84d257d0..354720df84 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<EventEntity> = RealmList()
+                                var nextToken: String? = null,
+                                var isLast: Boolean = false,
+                                var events: RealmList<EventEntity> = 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 f6a959c862..ec21f17871 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<String>): RealmResults<ChunkEntity> {
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 579a9f3687..9a317861ec 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<EnrichedEventInterceptor>()
@@ -30,12 +31,9 @@ internal class DefaultTimelineHolder(private val roomId: String,
 
     override fun liveTimeline(): LiveData<PagedList<EnrichedEvent>> {
         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 bd287f9e89..e0826ba98a 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<ChunkEntity>().apply { this.prevToken = prevToken }
 
+        lastChunk?.isLast = false
+        chunkEntity.isLast = true
         chunkEntity.nextToken = nextToken
         eventList.addManagedToChunk(chunkEntity)
         return chunkEntity