BayernMessenger/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/RoomSyncHandler.kt

119 lines
5.0 KiB
Kotlin

package im.vector.matrix.android.internal.events.sync
import im.vector.matrix.android.api.events.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.RoomEntity
import im.vector.matrix.android.internal.database.query.getChunkIncludingEvents
import im.vector.matrix.android.internal.database.query.getForId
import im.vector.matrix.android.internal.database.query.getLastChunkFromRoom
import im.vector.matrix.android.internal.events.sync.data.InvitedRoomSync
import im.vector.matrix.android.internal.events.sync.data.RoomSync
import io.realm.Realm
import io.realm.RealmConfiguration
class RoomSyncHandler(private val realmConfiguration: RealmConfiguration) {
sealed class HandlingStrategy {
data class JOINED(val data: Map<String, RoomSync>) : HandlingStrategy()
data class INVITED(val data: Map<String, InvitedRoomSync>) : HandlingStrategy()
data class LEFT(val data: Map<String, RoomSync>) : HandlingStrategy()
}
fun handleRoomSync(handlingStrategy: HandlingStrategy) {
val realm = Realm.getInstance(realmConfiguration)
realm.executeTransaction { realmInstance ->
val roomEntities = when (handlingStrategy) {
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) }
}
realmInstance.insertOrUpdate(roomEntities)
}
realm.close()
}
// PRIVATE METHODS *****************************************************************************
private fun handleJoinedRoom(realm: Realm,
roomId: String,
roomSync: RoomSync): RoomEntity {
val roomEntity = RoomEntity.getForId(realm, roomId) ?: RoomEntity(roomId)
if (roomEntity.membership == RoomEntity.Membership.INVITED) {
roomEntity.chunks.deleteAllFromRealm()
}
roomEntity.membership = RoomEntity.Membership.JOINED
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
val chunkEntity = eventListToChunk(realm, roomId, roomSync.state.events)
if (!roomEntity.chunks.contains(chunkEntity)) {
roomEntity.chunks.add(chunkEntity)
}
}
if (roomSync.timeline != null && roomSync.timeline.events.isNotEmpty()) {
val chunkEntity = eventListToChunk(realm, roomId, roomSync.timeline.events, roomSync.timeline.prevToken, isLimited = roomSync.timeline.limited)
if (!roomEntity.chunks.contains(chunkEntity)) {
roomEntity.chunks.add(chunkEntity)
}
}
return roomEntity
}
private fun handleInvitedRoom(realm: Realm,
roomId: String,
roomSync:
InvitedRoomSync): RoomEntity {
val roomEntity = RoomEntity()
roomEntity.roomId = roomId
roomEntity.membership = RoomEntity.Membership.INVITED
if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) {
val chunkEntity = eventListToChunk(realm, roomId, roomSync.inviteState.events)
if (!roomEntity.chunks.contains(chunkEntity)) {
roomEntity.chunks.add(chunkEntity)
}
}
return roomEntity
}
// TODO : handle it
private fun handleLeftRoom(roomId: String,
roomSync: RoomSync): RoomEntity {
return RoomEntity().apply {
this.roomId = roomId
this.membership = RoomEntity.Membership.LEFT
}
}
private fun eventListToChunk(realm: Realm,
roomId: String,
eventList: List<Event>,
prevToken: String? = null,
nextToken: String? = null,
isLimited: Boolean = true): ChunkEntity {
val chunkEntity = if (!isLimited) {
ChunkEntity.getLastChunkFromRoom(realm, roomId)
} else {
val eventIds = eventList.filter { it.eventId != null }.map { it.eventId!! }
ChunkEntity.getChunkIncludingEvents(realm, eventIds)
} ?: ChunkEntity().apply { this.prevToken = prevToken }
chunkEntity.nextToken = nextToken
chunkEntity.isLimited = isLimited
eventList.forEach { event ->
val eventEntity = event.asEntity().let {
realm.copyToRealmOrUpdate(it)
}
if (!chunkEntity.events.contains(eventEntity)) {
chunkEntity.events.add(eventEntity)
}
}
return chunkEntity
}
}