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

118 lines
5.0 KiB
Kotlin
Raw Normal View History

2018-10-17 16:21:09 +00:00
package im.vector.matrix.android.internal.session.sync
2018-10-18 09:16:02 +00:00
import com.zhuinden.monarchy.Monarchy
2018-10-17 16:21:09 +00:00
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.internal.database.DBConstants
import im.vector.matrix.android.internal.database.mapper.asEntity
2018-10-12 17:26:22 +00:00
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.findAllIncludingEvents
import im.vector.matrix.android.internal.database.query.findLastFromRoom
import im.vector.matrix.android.internal.database.query.where
2018-10-17 16:21:09 +00:00
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
import im.vector.matrix.android.internal.session.sync.model.RoomSync
2018-10-15 17:42:13 +00:00
import io.realm.Realm
2018-10-18 09:16:02 +00:00
class RoomSyncHandler(private val monarchy: Monarchy) {
2018-10-15 17:42:13 +00:00
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()
}
2018-10-15 17:42:13 +00:00
fun handleRoomSync(handlingStrategy: HandlingStrategy) {
monarchy.runTransactionSync { realm ->
2018-10-15 17:42:13 +00:00
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) }
}
2018-10-18 09:16:02 +00:00
realm.insertOrUpdate(roomEntities)
2018-10-12 17:26:22 +00:00
}
}
2018-10-15 17:42:13 +00:00
// PRIVATE METHODS *****************************************************************************
private fun handleJoinedRoom(realm: Realm,
roomId: String,
roomSync: RoomSync): RoomEntity {
val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: RoomEntity(roomId)
2018-10-15 17:42:13 +00:00
2018-10-12 17:26:22 +00:00
if (roomEntity.membership == RoomEntity.Membership.INVITED) {
2018-10-15 17:42:13 +00:00
roomEntity.chunks.deleteAllFromRealm()
2018-10-12 17:26:22 +00:00
}
2018-10-15 17:42:13 +00:00
2018-10-12 17:26:22 +00:00
roomEntity.membership = RoomEntity.Membership.JOINED
2018-10-15 17:42:13 +00:00
if (roomSync.state != null && roomSync.state.events.isNotEmpty()) {
val chunkEntity = eventListToChunk(realm, roomId, roomSync.state.events, DBConstants.STATE_EVENTS_CHUNK_TOKEN, DBConstants.STATE_EVENTS_CHUNK_TOKEN)
2018-10-15 17:42:13 +00:00
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)
}
2018-10-12 17:26:22 +00:00
}
2018-10-15 17:42:13 +00:00
return roomEntity
}
2018-10-12 17:26:22 +00:00
2018-10-15 17:42:13 +00:00
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)
}
2018-10-12 17:26:22 +00:00
}
return roomEntity
}
2018-10-15 17:42:13 +00:00
// 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>,
2018-10-13 09:18:49 +00:00
prevToken: String? = null,
2018-10-15 17:42:13 +00:00
nextToken: String? = null,
isLimited: Boolean = true): ChunkEntity {
val chunkEntity = if (!isLimited) {
ChunkEntity.findLastFromRoom(realm, roomId)
2018-10-15 17:42:13 +00:00
} else {
val eventIds = eventList.filter { it.eventId != null }.map { it.eventId!! }
ChunkEntity.findAllIncludingEvents(realm, eventIds).firstOrNull()
} ?: ChunkEntity().apply { this.prevToken = prevToken }
2018-10-15 17:42:13 +00:00
2018-10-13 09:18:49 +00:00
chunkEntity.nextToken = nextToken
2018-10-15 17:42:13 +00:00
chunkEntity.isLimited = isLimited
2018-10-17 11:59:21 +00:00
2018-10-15 17:42:13 +00:00
eventList.forEach { event ->
val eventEntity = event.asEntity().let {
2018-10-15 17:42:13 +00:00
realm.copyToRealmOrUpdate(it)
}
if (!chunkEntity.events.contains(eventEntity)) {
chunkEntity.events.add(eventEntity)
}
}
2018-10-13 09:18:49 +00:00
return chunkEntity
}
}