Start handling prune events. WIP

This commit is contained in:
ganfra 2018-11-07 20:36:19 +01:00
parent cd25232572
commit be8b1287c7
14 changed files with 184 additions and 129 deletions

View file

@ -26,7 +26,7 @@ class MessageItemFactory(private val timelineDateFormatter: TimelineDateFormatte
avatarUrl = roomMember.avatarUrl, avatarUrl = roomMember.avatarUrl,
showInformation = showInformation, showInformation = showInformation,
time = timelineDateFormatter.formatMessageHour(date), time = timelineDateFormatter.formatMessageHour(date),
memberName = roomMember.displayName memberName = roomMember.displayName ?: event.root.sender
) )
} }

View file

@ -31,7 +31,7 @@ class TimelineEventController(private val roomId: String,
} }
} }
var snapshotList: List<EnrichedEvent>? = emptyList() private var snapshotList: List<EnrichedEvent>? = emptyList()
var timeline: PagedList<EnrichedEvent>? = null var timeline: PagedList<EnrichedEvent>? = null
set(value) { set(value) {
field?.removeWeakCallback(pagedListCallback) field?.removeWeakCallback(pagedListCallback)

View file

@ -4,7 +4,7 @@
<item android:state_selected="true"> <item android:state_selected="true">
<shape android:shape="oval"> <shape android:shape="oval">
<solid android:color="@android:color/transparent" /> <solid android:color="@android:color/transparent" />
<stroke android:width="2dp" android:color="@color/pale_teal" /> <stroke android:width="3dp" android:color="@color/pale_teal" />
</shape> </shape>
</item> </item>

View file

@ -16,7 +16,9 @@ data class Event(
@Json(name = "sender") val sender: String? = null, @Json(name = "sender") val sender: String? = null,
@Json(name = "state_key") val stateKey: String? = null, @Json(name = "state_key") val stateKey: String? = null,
@Json(name = "room_id") var roomId: String? = null, @Json(name = "room_id") var roomId: String? = null,
@Json(name = "unsigned") val unsignedData: UnsignedData? = null @Json(name = "unsigned") val unsignedData: UnsignedData? = null,
@Json(name = "redacts") val redacts: String? = null
) { ) {
val contentAsJsonObject: JsonObject? by lazy { val contentAsJsonObject: JsonObject? by lazy {

View file

@ -0,0 +1,48 @@
package im.vector.matrix.android.internal.database
import android.arch.lifecycle.LiveData
import android.arch.lifecycle.Observer
import com.zhuinden.monarchy.Monarchy
import io.realm.RealmObject
import io.realm.RealmResults
import java.util.concurrent.atomic.AtomicBoolean
internal interface LiveEntityObserver {
fun start()
fun dispose()
}
internal abstract class RealmLiveEntityObserver<T : RealmObject>(protected val monarchy: Monarchy)
: Observer<Monarchy.ManagedChangeSet<T>>, LiveEntityObserver {
protected abstract val query: Monarchy.Query<T>
private val isStarted = AtomicBoolean(false)
private val liveResults: LiveData<Monarchy.ManagedChangeSet<T>> by lazy {
monarchy.findAllManagedWithChanges(query)
}
override fun start() {
if (isStarted.compareAndSet(false, true)) {
liveResults.observeForever(this)
}
}
override fun dispose() {
if (isStarted.compareAndSet(true, false)) {
liveResults.removeObserver(this)
}
}
// PRIVATE
override fun onChanged(changeSet: Monarchy.ManagedChangeSet<T>?) {
if (changeSet == null) {
return
}
val indexes = changeSet.orderedCollectionChangeSet.changes + changeSet.orderedCollectionChangeSet.insertions
process(changeSet.realmResults, indexes)
}
abstract fun process(results: RealmResults<T>, indexes: IntArray)
}

View file

@ -1,10 +1,10 @@
package im.vector.matrix.android.internal.database.mapper package im.vector.matrix.android.internal.database.mapper
import com.squareup.moshi.Types import com.squareup.moshi.Types
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.UnsignedData import im.vector.matrix.android.api.session.events.model.UnsignedData
import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.di.MoshiProvider
import im.vector.matrix.android.api.session.events.model.Event
object EventMapper { object EventMapper {
@ -22,21 +22,23 @@ object EventMapper {
eventEntity.type = event.type eventEntity.type = event.type
eventEntity.sender = event.sender eventEntity.sender = event.sender
eventEntity.originServerTs = event.originServerTs eventEntity.originServerTs = event.originServerTs
eventEntity.redacts = event.redacts
eventEntity.age = event.unsignedData?.age ?: event.originServerTs eventEntity.age = event.unsignedData?.age ?: event.originServerTs
return eventEntity return eventEntity
} }
internal fun map(eventEntity: EventEntity): Event { internal fun map(eventEntity: EventEntity): Event {
return Event( return Event(
eventEntity.type, type = eventEntity.type,
eventEntity.eventId, eventId = eventEntity.eventId,
adapter.fromJson(eventEntity.content), content = adapter.fromJson(eventEntity.content),
adapter.fromJson(eventEntity.prevContent ?: ""), prevContent = adapter.fromJson(eventEntity.prevContent ?: ""),
eventEntity.originServerTs, originServerTs = eventEntity.originServerTs,
eventEntity.sender, sender = eventEntity.sender,
eventEntity.stateKey, stateKey = eventEntity.stateKey,
null, roomId = null,
UnsignedData(eventEntity.age) unsignedData = UnsignedData(eventEntity.age),
redacts = eventEntity.redacts
) )
} }
} }

View file

@ -2,17 +2,18 @@ package im.vector.matrix.android.internal.database.model
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.RealmResults import io.realm.RealmResults
import io.realm.annotations.Index
import io.realm.annotations.LinkingObjects import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey
open class EventEntity(@Index var eventId: String = "", open class EventEntity(@PrimaryKey var eventId: String = "",
var type: String = "", var type: String = "",
var content: String = "", var content: String = "",
var prevContent: String? = null, var prevContent: String? = null,
var stateKey: String? = null, var stateKey: String? = null,
var originServerTs: Long? = null, var originServerTs: Long? = null,
var sender: String? = null, var sender: String? = null,
var age: Long? = 0 var age: Long? = 0,
var redacts: String? = null
) : RealmObject() { ) : RealmObject() {
companion object companion object

View file

@ -15,9 +15,11 @@ fun EventEntity.Companion.where(realm: Realm, eventId: String): RealmQuery<Event
.equalTo(EventEntityFields.EVENT_ID, eventId) .equalTo(EventEntityFields.EVENT_ID, eventId)
} }
fun EventEntity.Companion.where(realm: Realm, roomId: String, type: String? = null): RealmQuery<EventEntity> { fun EventEntity.Companion.where(realm: Realm, roomId: String? = null, type: String? = null): RealmQuery<EventEntity> {
val query = realm.where<EventEntity>() val query = realm.where<EventEntity>()
.equalTo("${EventEntityFields.CHUNK}.${ChunkEntityFields.ROOM}.${RoomEntityFields.ROOM_ID}", roomId) if (roomId != null) {
query.equalTo("${EventEntityFields.CHUNK}.${ChunkEntityFields.ROOM}.${RoomEntityFields.ROOM_ID}", roomId)
}
if (type != null) { if (type != null) {
query.equalTo(EventEntityFields.TYPE, type) query.equalTo(EventEntityFields.TYPE, type)
} }
@ -32,7 +34,7 @@ fun EventEntity.Companion.stateEvents(realm: Realm, roomId: String): RealmQuery<
fun RealmQuery<EventEntity>.last(from: Long? = null): EventEntity? { fun RealmQuery<EventEntity>.last(from: Long? = null): EventEntity? {
if (from != null) { if (from != null) {
this.lessThanOrEqualTo(EventEntityFields.ORIGIN_SERVER_TS, from) this.lessThan(EventEntityFields.ORIGIN_SERVER_TS, from)
} }
return this return this
.sort(EventEntityFields.ORIGIN_SERVER_TS, Sort.DESCENDING) .sort(EventEntityFields.ORIGIN_SERVER_TS, Sort.DESCENDING)

View file

@ -11,10 +11,9 @@ import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.RoomService import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.internal.auth.data.SessionParams import im.vector.matrix.android.internal.auth.data.SessionParams
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.session.group.GroupModule import im.vector.matrix.android.internal.session.group.GroupModule
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
import im.vector.matrix.android.internal.session.room.RoomModule import im.vector.matrix.android.internal.session.room.RoomModule
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.sync.SyncModule import im.vector.matrix.android.internal.session.sync.SyncModule
import im.vector.matrix.android.internal.session.sync.job.SyncThread import im.vector.matrix.android.internal.session.sync.job.SyncThread
import org.koin.core.scope.Scope import org.koin.core.scope.Scope
@ -32,8 +31,7 @@ class DefaultSession(override val sessionParams: SessionParams) : Session, KoinC
private lateinit var scope: Scope private lateinit var scope: Scope
private val roomSummaryObserver by inject<RoomSummaryUpdater>() private val liveEntityUpdaters by inject<List<LiveEntityObserver>>()
private val groupSummaryUpdater by inject<GroupSummaryUpdater>()
private val roomService by inject<RoomService>() private val roomService by inject<RoomService>()
private val groupService by inject<GroupService>() private val groupService by inject<GroupService>()
private val syncThread by inject<SyncThread>() private val syncThread by inject<SyncThread>()
@ -50,8 +48,7 @@ class DefaultSession(override val sessionParams: SessionParams) : Session, KoinC
val groupModule = GroupModule() val groupModule = GroupModule()
StandAloneContext.loadKoinModules(listOf(sessionModule, syncModule, roomModule, groupModule)) StandAloneContext.loadKoinModules(listOf(sessionModule, syncModule, roomModule, groupModule))
scope = getKoin().getOrCreateScope(SCOPE) scope = getKoin().getOrCreateScope(SCOPE)
roomSummaryObserver.start() liveEntityUpdaters.forEach { it.start() }
groupSummaryUpdater.start()
syncThread.start() syncThread.start()
} }
@ -61,8 +58,7 @@ class DefaultSession(override val sessionParams: SessionParams) : Session, KoinC
checkIsMainThread() checkIsMainThread()
assert(isOpen) assert(isOpen)
syncThread.kill() syncThread.kill()
groupSummaryUpdater.dispose() liveEntityUpdaters.forEach { it.dispose() }
roomSummaryObserver.dispose()
scope.close() scope.close()
isOpen = false isOpen = false
} }

View file

@ -4,6 +4,8 @@ import com.zhuinden.monarchy.Monarchy
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.internal.auth.data.SessionParams import im.vector.matrix.android.internal.auth.data.SessionParams
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.session.events.prune.EventsPruner
import im.vector.matrix.android.internal.session.group.DefaultGroupService import im.vector.matrix.android.internal.session.group.DefaultGroupService
import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
import im.vector.matrix.android.internal.session.room.DefaultRoomService import im.vector.matrix.android.internal.session.room.DefaultRoomService
@ -53,22 +55,23 @@ class SessionModule(private val sessionParams: SessionParams) : Module {
RoomAvatarResolver(get(), sessionParams.credentials) RoomAvatarResolver(get(), sessionParams.credentials)
} }
scope(DefaultSession.SCOPE) {
RoomSummaryUpdater(get(), get(), get(), get(), sessionParams.credentials)
}
scope(DefaultSession.SCOPE) { scope(DefaultSession.SCOPE) {
DefaultRoomService(get()) as RoomService DefaultRoomService(get()) as RoomService
} }
scope(DefaultSession.SCOPE) {
GroupSummaryUpdater(get(), get())
}
scope(DefaultSession.SCOPE) { scope(DefaultSession.SCOPE) {
DefaultGroupService(get()) as GroupService DefaultGroupService(get()) as GroupService
} }
scope(DefaultSession.SCOPE) {
val roomSummaryUpdater = RoomSummaryUpdater(get(), get(), get(), get(), sessionParams.credentials)
val groupSummaryUpdater = GroupSummaryUpdater(get(), get())
val eventsPruner = EventsPruner(get())
listOf<LiveEntityObserver>(roomSummaryUpdater, groupSummaryUpdater, eventsPruner)
}
}.invoke() }.invoke()

View file

@ -0,0 +1,68 @@
package im.vector.matrix.android.internal.session.events.prune
import arrow.core.Option
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.mapper.asEntity
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.where
import io.realm.Realm
import io.realm.RealmResults
internal class EventsPruner(monarchy: Monarchy) :
RealmLiveEntityObserver<EventEntity>(monarchy) {
override val query = Monarchy.Query<EventEntity> { EventEntity.where(it, type = EventType.REDACTION) }
override fun process(results: RealmResults<EventEntity>, indexes: IntArray) {
val redactionEvents = results.map { it.asDomain() }
monarchy.writeAsync { realm ->
indexes.forEach { index ->
val data = redactionEvents[index]
pruneEvent(realm, data)
}
}
}
private fun pruneEvent(realm: Realm, redactionEvent: Event?) {
if (redactionEvent == null || redactionEvent.redacts.isNullOrEmpty()) {
return
}
val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst()?.asDomain()
?: return
val allowedKeys = computeAllowedKeys(eventToPrune.type)
val prunedContent = allowedKeys.fold(
{ eventToPrune.content },
{ eventToPrune.content?.filterKeys { key -> it.contains(key) } }
)
val eventToPruneEntity = eventToPrune.copy(content = prunedContent).asEntity()
realm.insertOrUpdate(eventToPruneEntity)
}
private fun computeAllowedKeys(type: String): Option<List<String>> {
// Add filtered content, allowed keys in content depends on the event type
val result = when (type) {
EventType.STATE_ROOM_MEMBER -> listOf("membership")
EventType.STATE_ROOM_CREATE -> listOf("creator")
EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule")
EventType.STATE_ROOM_POWER_LEVELS -> listOf("users",
"users_default",
"events",
"events_default",
"state_default",
"ban",
"kick",
"redact",
"invite")
EventType.STATE_ROOM_ALIASES -> listOf("aliases")
EventType.STATE_CANONICAL_ALIAS -> listOf("alias")
EventType.FEEDBACK -> listOf("type", "target_event_id")
else -> null
}
return Option.fromNullable(result)
}
}

View file

@ -1,62 +1,30 @@
package im.vector.matrix.android.internal.session.group package im.vector.matrix.android.internal.session.group
import android.arch.lifecycle.Observer
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.group.Group import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.GroupEntity import im.vector.matrix.android.internal.database.model.GroupEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import timber.log.Timber import io.realm.RealmResults
import java.util.concurrent.atomic.AtomicBoolean
internal class GroupSummaryUpdater(private val monarchy: Monarchy, internal class GroupSummaryUpdater(monarchy: Monarchy,
private val getGroupDataRequest: GetGroupDataRequest private val getGroupDataRequest: GetGroupDataRequest
) : Observer<Monarchy.ManagedChangeSet<GroupEntity>> { ) : RealmLiveEntityObserver<GroupEntity>(monarchy) {
private var isStarted = AtomicBoolean(false) override val query = Monarchy.Query<GroupEntity> { GroupEntity.where(it) }
private val liveResults = monarchy.findAllManagedWithChanges { GroupEntity.where(it) }
fun start() { override fun process(results: RealmResults<GroupEntity>, indexes: IntArray) {
if (isStarted.compareAndSet(false, true)) { indexes.forEach { index ->
liveResults.observeForever(this) val data = results[index]
fetchGroupData(data)
} }
} }
fun dispose() { private fun fetchGroupData(data: GroupEntity?) {
if (isStarted.compareAndSet(true, false)) { if (data == null) {
liveResults.removeObserver(this)
}
}
// PRIVATE
override fun onChanged(changeSet: Monarchy.ManagedChangeSet<GroupEntity>?) {
if (changeSet == null) {
return return
} }
val groups = changeSet.realmResults.map { it.asDomain() } getGroupDataRequest.execute(data.groupId, object : MatrixCallback<Boolean> {})
val indexesToUpdate = changeSet.orderedCollectionChangeSet.changes + changeSet.orderedCollectionChangeSet.insertions
updateGroupList(groups, indexesToUpdate)
}
private fun updateGroupList(groups: List<Group>, indexes: IntArray) {
indexes.forEach {
val group = groups[it]
try {
updateGroup(group)
} catch (e: Exception) {
Timber.e(e, "An error occured when updating room summaries")
}
}
}
private fun updateGroup(group: Group?) {
if (group == null) {
return
}
getGroupDataRequest.execute(group.groupId, object : MatrixCallback<Boolean> {})
} }
} }

View file

@ -1,12 +1,12 @@
package im.vector.matrix.android.internal.session.room package im.vector.matrix.android.internal.session.room
import android.arch.lifecycle.Observer
import android.content.Context import android.content.Context
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
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.Room import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.model.RoomTopicContent import im.vector.matrix.android.api.session.room.model.RoomTopicContent
import im.vector.matrix.android.internal.auth.data.Credentials import im.vector.matrix.android.internal.auth.data.Credentials
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
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.EventEntity 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
@ -16,53 +16,24 @@ import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver import im.vector.matrix.android.internal.session.room.members.RoomDisplayNameResolver
import im.vector.matrix.android.internal.session.room.members.RoomMembers import im.vector.matrix.android.internal.session.room.members.RoomMembers
import io.realm.Realm import io.realm.Realm
import io.realm.RealmResults
import io.realm.kotlin.createObject import io.realm.kotlin.createObject
import timber.log.Timber
import java.util.concurrent.atomic.AtomicBoolean
internal class RoomSummaryUpdater(private val monarchy: Monarchy, internal class RoomSummaryUpdater(monarchy: Monarchy,
private val roomDisplayNameResolver: RoomDisplayNameResolver, private val roomDisplayNameResolver: RoomDisplayNameResolver,
private val roomAvatarResolver: RoomAvatarResolver, private val roomAvatarResolver: RoomAvatarResolver,
private val context: Context, private val context: Context,
private val credentials: Credentials private val credentials: Credentials
) : Observer<Monarchy.ManagedChangeSet<RoomEntity>> { ) : RealmLiveEntityObserver<RoomEntity>(monarchy) {
private var isStarted = AtomicBoolean(false) override val query = Monarchy.Query<RoomEntity> { RoomEntity.where(it) }
private val liveResults = monarchy.findAllManagedWithChanges { RoomEntity.where(it) }
fun start() { override fun process(results: RealmResults<RoomEntity>, indexes: IntArray) {
if (isStarted.compareAndSet(false, true)) { val rooms = results.map { it.asDomain() }
liveResults.observeForever(this)
}
}
fun dispose() {
if (isStarted.compareAndSet(true, false)) {
liveResults.removeObserver(this)
}
}
// PRIVATE
override fun onChanged(changeSet: Monarchy.ManagedChangeSet<RoomEntity>?) {
if (changeSet == null) {
return
}
val rooms = changeSet.realmResults.map { it.asDomain() }
val indexesToUpdate = changeSet.orderedCollectionChangeSet.changes + changeSet.orderedCollectionChangeSet.insertions
monarchy.writeAsync { realm -> monarchy.writeAsync { realm ->
updateRoomList(realm, rooms, indexesToUpdate) indexes.forEach { index ->
} val data = rooms[index]
} updateRoom(realm, data)
private fun updateRoomList(realm: Realm, rooms: List<Room>, indexes: IntArray) {
indexes.forEach {
val room = rooms[it]
try {
updateRoom(realm, room)
} catch (e: Exception) {
Timber.e(e, "An error occured when updating room summaries")
} }
} }
} }

View file

@ -11,11 +11,7 @@ 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.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.sync.model.InvitedRoomSync import im.vector.matrix.android.internal.session.sync.model.*
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
@ -42,9 +38,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)
} }
@ -54,7 +50,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()
@ -115,7 +111,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()
@ -136,7 +132,6 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
prevToken: String? = null, prevToken: String? = null,
nextToken: String? = null, nextToken: String? = null,
isLimited: Boolean = true): ChunkEntity { isLimited: Boolean = true): ChunkEntity {
val chunkEntity = if (!isLimited) { val chunkEntity = if (!isLimited) {
ChunkEntity.findLastLiveChunkFromRoom(realm, roomId) ChunkEntity.findLastLiveChunkFromRoom(realm, roomId)
} else { } else {
@ -157,5 +152,4 @@ internal class RoomSyncHandler(private val monarchy: Monarchy,
.map { it.content<ReadReceiptContent>() } .map { it.content<ReadReceiptContent>() }
.flatMap { readReceiptHandler.handle(realm, roomId, it) } .flatMap { readReceiptHandler.handle(realm, roomId, it) }
} }
} }