mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-22 16:49:19 +03:00
State index management should be ok now
This commit is contained in:
parent
18af7c83f3
commit
40f981e454
8 changed files with 58 additions and 43 deletions
matrix-sdk-android/src/main/java/im/vector/matrix/android
api/session
internal
database
session
|
@ -1,9 +1,9 @@
|
||||||
package im.vector.matrix.android.api.session
|
package im.vector.matrix.android.api.session
|
||||||
|
|
||||||
import android.support.annotation.MainThread
|
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.group.GroupService
|
||||||
import im.vector.matrix.android.api.session.room.RoomService
|
import im.vector.matrix.android.api.session.room.RoomService
|
||||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
|
||||||
|
|
||||||
interface Session : RoomService, GroupService {
|
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.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.internal.database.mapper.asEntity
|
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.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.fastContains
|
||||||
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.room.timeline.PaginationDirection
|
||||||
|
|
||||||
internal fun ChunkEntity.add(event: Event, stateIndex: Int, paginationDirection: 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) {
|
if (event.eventId == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (EventEntity.where(realm, event.eventId).findFirst() != null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val eventEntity = event.asEntity()
|
val eventEntity = event.asEntity()
|
||||||
eventEntity.stateIndex = stateIndex
|
eventEntity.stateIndex = stateIndex
|
||||||
|
|
|
@ -12,8 +12,6 @@ import io.realm.kotlin.where
|
||||||
internal fun ChunkEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<ChunkEntity> {
|
internal fun ChunkEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<ChunkEntity> {
|
||||||
return realm.where<ChunkEntity>()
|
return realm.where<ChunkEntity>()
|
||||||
.equalTo("${ChunkEntityFields.ROOM}.${RoomEntityFields.ROOM_ID}", roomId)
|
.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? {
|
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 roomMembers = RoomMembers(realm, roomId).getLoaded()
|
||||||
val eventsToInsert = response.roomMemberEvents.filter { !roomMembers.containsKey(it.stateKey) }
|
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)) {
|
if (!roomEntity.chunks.contains(chunk)) {
|
||||||
roomEntity.chunks.add(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.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
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.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.EventEntity
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
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.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.last
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.RealmQuery
|
import io.realm.RealmQuery
|
||||||
|
|
||||||
|
@ -16,25 +18,36 @@ internal class RoomMemberExtractor(private val realm: Realm,
|
||||||
|
|
||||||
fun extractFrom(event: EventEntity): RoomMember? {
|
fun extractFrom(event: EventEntity): RoomMember? {
|
||||||
val stateIndex = event.stateIndex
|
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
|
// 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)
|
.findMostSuitableStateEvent(stateIndex = stateIndex)
|
||||||
?.asDomain()
|
?.asDomain()
|
||||||
?.pickContent(stateIndex)
|
?.pickContent<RoomMember>(stateIndex)
|
||||||
|
|
||||||
// If the content is null, we try get the last state event, not coming from a chunk
|
if (roomMember != null) {
|
||||||
?: buildQuery(realm, roomId, event.sender)
|
return roomMember
|
||||||
.last()
|
}
|
||||||
?.asDomain()
|
|
||||||
?.content()
|
|
||||||
|
|
||||||
|
// 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> {
|
private fun buildQuery(chunk: ChunkEntity,
|
||||||
return EventEntity
|
sender: String?): RealmQuery<EventEntity> {
|
||||||
.where(realm, roomId, EventType.STATE_ROOM_MEMBER)
|
return chunk.events
|
||||||
|
.where()
|
||||||
|
.equalTo(EventEntityFields.TYPE, EventType.STATE_ROOM_MEMBER)
|
||||||
.equalTo(EventEntityFields.STATE_KEY, sender)
|
.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.api.util.Cancelable
|
||||||
import im.vector.matrix.android.internal.database.helper.add
|
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.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.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.legacy.util.FilterUtil
|
||||||
import im.vector.matrix.android.internal.network.executeRequest
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||||
|
@ -62,10 +65,10 @@ internal class PaginationRequest(private val roomAPI: RoomAPI,
|
||||||
return monarchy
|
return monarchy
|
||||||
.tryTransactionSync { realm ->
|
.tryTransactionSync { realm ->
|
||||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
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)
|
val currentChunk = ChunkEntity.findWithPrevToken(realm, roomId, receivedChunk.nextToken)
|
||||||
?: realm.createObject()
|
?: realm.createObject()
|
||||||
|
|
||||||
currentChunk.prevToken = receivedChunk.prevToken
|
currentChunk.prevToken = receivedChunk.prevToken
|
||||||
|
|
||||||
|
@ -79,10 +82,10 @@ internal class PaginationRequest(private val roomAPI: RoomAPI,
|
||||||
val incrementStateIndex = direction.incrementStateIndex
|
val incrementStateIndex = direction.incrementStateIndex
|
||||||
|
|
||||||
receivedChunk.events.forEach { event ->
|
receivedChunk.events.forEach { event ->
|
||||||
currentChunk.add(event, currentStateIndex, direction)
|
|
||||||
if (EventType.isStateEvent(event.type)) {
|
if (EventType.isStateEvent(event.type)) {
|
||||||
currentStateIndex += incrementStateIndex
|
currentStateIndex += incrementStateIndex
|
||||||
}
|
}
|
||||||
|
currentChunk.add(event, currentStateIndex, direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevChunk != null) {
|
if (prevChunk != null) {
|
||||||
|
@ -110,8 +113,8 @@ internal class PaginationRequest(private val roomAPI: RoomAPI,
|
||||||
|
|
||||||
currentChunk.updateStateIndex(currentStateIndex, direction)
|
currentChunk.updateStateIndex(currentStateIndex, direction)
|
||||||
|
|
||||||
|
// TODO : there is an issue with the pagination sending unwanted room member events
|
||||||
val stateEventsChunk = stateEventsChunkHandler.handle(realm, roomId, receivedChunk.stateEvents, direction)
|
val stateEventsChunk = stateEventsChunkHandler.handle(realm, roomId, receivedChunk.stateEvents)
|
||||||
if (!roomEntity.chunks.contains(stateEventsChunk)) {
|
if (!roomEntity.chunks.contains(stateEventsChunk)) {
|
||||||
roomEntity.chunks.add(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.findLastLiveChunkFromRoom
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
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.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.Realm
|
||||||
import io.realm.kotlin.createObject
|
import io.realm.kotlin.createObject
|
||||||
|
|
||||||
|
@ -39,9 +43,9 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||||
|
|
||||||
private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy) {
|
private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy) {
|
||||||
val rooms = when (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.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)
|
realm.insertOrUpdate(rooms)
|
||||||
}
|
}
|
||||||
|
@ -51,7 +55,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||||
roomSync: RoomSync): RoomEntity {
|
roomSync: RoomSync): RoomEntity {
|
||||||
|
|
||||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||||
?: RoomEntity(roomId)
|
?: RoomEntity(roomId)
|
||||||
|
|
||||||
if (roomEntity.membership == MyMembership.INVITED) {
|
if (roomEntity.membership == MyMembership.INVITED) {
|
||||||
roomEntity.chunks.deleteAllFromRealm()
|
roomEntity.chunks.deleteAllFromRealm()
|
||||||
|
@ -60,7 +64,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||||
roomEntity.membership = MyMembership.JOINED
|
roomEntity.membership = MyMembership.JOINED
|
||||||
|
|
||||||
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
|
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)) {
|
if (!roomEntity.chunks.contains(chunkEntity)) {
|
||||||
roomEntity.chunks.add(chunkEntity)
|
roomEntity.chunks.add(chunkEntity)
|
||||||
}
|
}
|
||||||
|
@ -113,7 +117,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||||
roomSummary: RoomSyncSummary) {
|
roomSummary: RoomSyncSummary) {
|
||||||
|
|
||||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||||
?: RoomSummaryEntity(roomId)
|
?: RoomSummaryEntity(roomId)
|
||||||
|
|
||||||
if (roomSummary.heroes.isNotEmpty()) {
|
if (roomSummary.heroes.isNotEmpty()) {
|
||||||
roomSummaryEntity.heroes.clear()
|
roomSummaryEntity.heroes.clear()
|
||||||
|
@ -150,7 +154,7 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
|
||||||
var currentStateIndex = chunkEntity.nextStateIndex
|
var currentStateIndex = chunkEntity.nextStateIndex
|
||||||
eventList.forEach { event ->
|
eventList.forEach { event ->
|
||||||
if (event.isStateEvent()) {
|
if (event.isStateEvent()) {
|
||||||
currentStateIndex += 1
|
currentStateIndex += PaginationDirection.FORWARDS.incrementStateIndex
|
||||||
}
|
}
|
||||||
chunkEntity.add(event, currentStateIndex, PaginationDirection.FORWARDS)
|
chunkEntity.add(event, currentStateIndex, PaginationDirection.FORWARDS)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,21 @@ import io.realm.kotlin.createObject
|
||||||
|
|
||||||
internal class StateEventsChunkHandler {
|
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)
|
val chunkEntity = ChunkEntity.findWithNextToken(realm, roomId, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
|
||||||
?: realm.createObject<ChunkEntity>()
|
?: realm.createObject<ChunkEntity>()
|
||||||
.apply {
|
.apply {
|
||||||
prevToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
prevToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
||||||
nextToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
nextToken = DBConstants.STATE_EVENTS_CHUNK_TOKEN
|
||||||
nextStateIndex = Int.MIN_VALUE / 2
|
nextStateIndex = Int.MIN_VALUE
|
||||||
prevStateIndex = Int.MIN_VALUE / 2
|
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
|
val stateIndex = chunkEntity.stateIndex(direction) + direction.incrementStateIndex
|
||||||
stateEvents.forEach { event ->
|
stateEvents.forEach { event ->
|
||||||
chunkEntity.add(event, stateIndex, PaginationDirection.FORWARDS)
|
chunkEntity.add(event, stateIndex, direction)
|
||||||
}
|
}
|
||||||
chunkEntity.updateStateIndex(stateIndex, direction)
|
chunkEntity.updateStateIndex(stateIndex, direction)
|
||||||
return chunkEntity
|
return chunkEntity
|
||||||
|
|
Loading…
Add table
Reference in a new issue