forked from GitHub-Mirror/riotX-android
State index management should be ok now
This commit is contained in:
parent
18af7c83f3
commit
40f981e454
@ -1,9 +1,9 @@
|
||||
package im.vector.matrix.android.api.session
|
||||
|
||||
import android.support.annotation.MainThread
|
||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||
import im.vector.matrix.android.api.session.group.GroupService
|
||||
import im.vector.matrix.android.api.session.room.RoomService
|
||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||
|
||||
interface Session : RoomService, GroupService {
|
||||
|
||||
|
@ -3,9 +3,7 @@ package im.vector.matrix.android.internal.database.helper
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.internal.database.mapper.asEntity
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.query.fastContains
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection
|
||||
|
||||
internal fun ChunkEntity.add(event: Event, stateIndex: Int, paginationDirection: PaginationDirection) {
|
||||
@ -16,9 +14,6 @@ internal fun ChunkEntity.add(event: Event, stateIndex: Int, paginationDirection:
|
||||
if (event.eventId == null) {
|
||||
return
|
||||
}
|
||||
if (EventEntity.where(realm, event.eventId).findFirst() != null) {
|
||||
return
|
||||
}
|
||||
|
||||
val eventEntity = event.asEntity()
|
||||
eventEntity.stateIndex = stateIndex
|
||||
|
@ -12,8 +12,6 @@ import io.realm.kotlin.where
|
||||
internal fun ChunkEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<ChunkEntity> {
|
||||
return realm.where<ChunkEntity>()
|
||||
.equalTo("${ChunkEntityFields.ROOM}.${RoomEntityFields.ROOM_ID}", roomId)
|
||||
.notEqualTo(ChunkEntityFields.PREV_TOKEN, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||
.notEqualTo(ChunkEntityFields.NEXT_TOKEN, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.Companion.findWithPrevToken(realm: Realm, roomId: String, prevToken: String?): ChunkEntity? {
|
||||
|
@ -58,7 +58,7 @@ internal class LoadRoomMembersRequest(private val roomAPI: RoomAPI,
|
||||
val roomMembers = RoomMembers(realm, roomId).getLoaded()
|
||||
val eventsToInsert = response.roomMemberEvents.filter { !roomMembers.containsKey(it.stateKey) }
|
||||
|
||||
val chunk = stateEventsChunkHandler.handle(realm, roomId, eventsToInsert, PaginationDirection.BACKWARDS)
|
||||
val chunk = stateEventsChunkHandler.handle(realm, roomId, eventsToInsert)
|
||||
if (!roomEntity.chunks.contains(chunk)) {
|
||||
roomEntity.chunks.add(chunk)
|
||||
}
|
||||
|
@ -2,12 +2,14 @@ package im.vector.matrix.android.internal.session.room.members
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||
import im.vector.matrix.android.internal.database.DBConstants
|
||||
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.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||
import im.vector.matrix.android.internal.database.query.findMostSuitableStateEvent
|
||||
import im.vector.matrix.android.internal.database.query.findWithNextToken
|
||||
import im.vector.matrix.android.internal.database.query.last
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
|
||||
@ -16,25 +18,36 @@ internal class RoomMemberExtractor(private val realm: Realm,
|
||||
|
||||
fun extractFrom(event: EventEntity): RoomMember? {
|
||||
val stateIndex = event.stateIndex
|
||||
val chunkEntity = event.chunk?.firstOrNull()
|
||||
?: throw IllegalStateException("An event should be attached to a chunk")
|
||||
|
||||
// First of all, try to get the most suitable state event coming from a chunk
|
||||
return buildQuery(realm, roomId, event.sender)
|
||||
val roomMember = buildQuery(chunkEntity, event.sender)
|
||||
.findMostSuitableStateEvent(stateIndex = stateIndex)
|
||||
?.asDomain()
|
||||
?.pickContent(stateIndex)
|
||||
?.pickContent<RoomMember>(stateIndex)
|
||||
|
||||
// If the content is null, we try get the last state event, not coming from a chunk
|
||||
?: buildQuery(realm, roomId, event.sender)
|
||||
.last()
|
||||
?.asDomain()
|
||||
?.content()
|
||||
if (roomMember != null) {
|
||||
return roomMember
|
||||
}
|
||||
|
||||
// If the content is null, we try get the last state event coming from a state events chunk
|
||||
val stateChunkEntity = ChunkEntity.findWithNextToken(realm, roomId, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||
?: return null
|
||||
|
||||
return buildQuery(stateChunkEntity, event.sender)
|
||||
.last()
|
||||
?.asDomain()
|
||||
?.content()
|
||||
}
|
||||
|
||||
private fun buildQuery(realm: Realm, roomId: String, sender: String?): RealmQuery<EventEntity> {
|
||||
return EventEntity
|
||||
.where(realm, roomId, EventType.STATE_ROOM_MEMBER)
|
||||
private fun buildQuery(chunk: ChunkEntity,
|
||||
sender: String?): RealmQuery<EventEntity> {
|
||||
return chunk.events
|
||||
.where()
|
||||
.equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_MEMBER)
|
||||
.equalTo(EventEntityFields.STATE_KEY, sender)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,9 +8,12 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import im.vector.matrix.android.internal.database.helper.add
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||
import im.vector.matrix.android.internal.database.query.*
|
||||
import im.vector.matrix.android.internal.database.query.fastContains
|
||||
import im.vector.matrix.android.internal.database.query.findAllIncludingEvents
|
||||
import im.vector.matrix.android.internal.database.query.findWithNextToken
|
||||
import im.vector.matrix.android.internal.database.query.findWithPrevToken
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.legacy.util.FilterUtil
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
@ -62,10 +65,10 @@ internal class PaginationRequest(private val roomAPI: RoomAPI,
|
||||
return monarchy
|
||||
.tryTransactionSync { realm ->
|
||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||
?: throw IllegalStateException("You shouldn't use this method without a room")
|
||||
?: throw IllegalStateException("You shouldn't use this method without a room")
|
||||
|
||||
val currentChunk = ChunkEntity.findWithPrevToken(realm, roomId, receivedChunk.nextToken)
|
||||
?: realm.createObject()
|
||||
?: realm.createObject()
|
||||
|
||||
currentChunk.prevToken = receivedChunk.prevToken
|
||||
|
||||
@ -79,10 +82,10 @@ internal class PaginationRequest(private val roomAPI: RoomAPI,
|
||||
val incrementStateIndex = direction.incrementStateIndex
|
||||
|
||||
receivedChunk.events.forEach { event ->
|
||||
currentChunk.add(event, currentStateIndex, direction)
|
||||
if (EventType.isStateEvent(event.type)) {
|
||||
currentStateIndex += incrementStateIndex
|
||||
}
|
||||
currentChunk.add(event, currentStateIndex, direction)
|
||||
}
|
||||
|
||||
if (prevChunk != null) {
|
||||
@ -110,8 +113,8 @@ internal class PaginationRequest(private val roomAPI: RoomAPI,
|
||||
|
||||
currentChunk.updateStateIndex(currentStateIndex, direction)
|
||||
|
||||
|
||||
val stateEventsChunk = stateEventsChunkHandler.handle(realm, roomId, receivedChunk.stateEvents, direction)
|
||||
// TODO : there is an issue with the pagination sending unwanted room member events
|
||||
val stateEventsChunk = stateEventsChunkHandler.handle(realm, roomId, receivedChunk.stateEvents)
|
||||
if (!roomEntity.chunks.contains(stateEventsChunk)) {
|
||||
roomEntity.chunks.add(stateEventsChunk)
|
||||
}
|
||||
|
@ -12,7 +12,11 @@ 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.room.timeline.PaginationDirection
|
||||
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
|
||||
|
||||
@ -39,9 +43,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)
|
||||
}
|
||||
@ -51,7 +55,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()
|
||||
@ -60,7 +64,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||
roomEntity.membership = MyMembership.JOINED
|
||||
|
||||
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
|
||||
val chunkEntity = stateEventsChunkHandler.handle(realm, roomId, roomSync.state.events, PaginationDirection.FORWARDS)
|
||||
val chunkEntity = stateEventsChunkHandler.handle(realm, roomId, roomSync.state.events)
|
||||
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||
roomEntity.chunks.add(chunkEntity)
|
||||
}
|
||||
@ -113,7 +117,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()
|
||||
@ -150,7 +154,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||
var currentStateIndex = chunkEntity.nextStateIndex
|
||||
eventList.forEach { event ->
|
||||
if (event.isStateEvent()) {
|
||||
currentStateIndex += 1
|
||||
currentStateIndex += PaginationDirection.FORWARDS.incrementStateIndex
|
||||
}
|
||||
chunkEntity.add(event, currentStateIndex, PaginationDirection.FORWARDS)
|
||||
}
|
||||
|
@ -11,19 +11,21 @@ import io.realm.kotlin.createObject
|
||||
|
||||
internal class StateEventsChunkHandler {
|
||||
|
||||
fun handle(realm: Realm, roomId: String, stateEvents: List<Event>, direction: PaginationDirection): ChunkEntity {
|
||||
fun handle(realm: Realm, roomId: String, stateEvents: List<Event>): ChunkEntity {
|
||||
val chunkEntity = ChunkEntity.findWithNextToken(realm, roomId, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||
?: realm.createObject<ChunkEntity>()
|
||||
.apply {
|
||||
prevToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
||||
nextToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
||||
nextStateIndex = Int.MIN_VALUE / 2
|
||||
prevStateIndex = Int.MIN_VALUE / 2
|
||||
}
|
||||
?: realm.createObject<ChunkEntity>()
|
||||
.apply {
|
||||
prevToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
||||
nextToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
||||
nextStateIndex = Int.MIN_VALUE
|
||||
prevStateIndex = Int.MIN_VALUE
|
||||
}
|
||||
|
||||
// We always consider going forwards as data from server are the most recent
|
||||
val direction = PaginationDirection.FORWARDS
|
||||
val stateIndex = chunkEntity.stateIndex(direction) + direction.incrementStateIndex
|
||||
stateEvents.forEach { event ->
|
||||
chunkEntity.add(event, stateIndex, PaginationDirection.FORWARDS)
|
||||
chunkEntity.add(event, stateIndex, direction)
|
||||
}
|
||||
chunkEntity.updateStateIndex(stateIndex, direction)
|
||||
return chunkEntity
|
||||
|
Loading…
Reference in New Issue
Block a user