Invite sync: assign eventId and remove the primaryKey constraint

This commit is contained in:
ganfra 2020-02-21 13:56:15 +01:00 committed by Benoit Marty
parent 3e8a0f7252
commit 981c9ac4ac
12 changed files with 48 additions and 34 deletions

View file

@ -45,7 +45,8 @@ data class RoomSummary constructor(
val versioningState: VersioningState = VersioningState.NONE,
val readMarkerId: String? = null,
val userDrafts: List<UserDraft> = emptyList(),
var isEncrypted: Boolean,
val isEncrypted: Boolean,
val inviterId: String? = null,
val typingRoomMemberIds: List<String> = emptyList(),
val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
// TODO Plug it
@ -62,3 +63,5 @@ data class RoomSummary constructor(
const val NOT_IN_BREADCRUMBS = -1
}
}

View file

@ -32,7 +32,8 @@ internal object EventMapper {
val uds = if (event.unsignedData == null) null
else MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(event.unsignedData)
val eventEntity = EventEntity()
eventEntity.eventId = event.eventId ?: ""
//TODO change this as we shouldn't use event everywhere
eventEntity.eventId = event.eventId ?: "$roomId-${System.currentTimeMillis()}-${event.hashCode()}"
eventEntity.roomId = event.roomId ?: roomId
eventEntity.content = ContentMapper.map(event.content)
val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent

View file

@ -77,7 +77,8 @@ internal class RoomSummaryMapper @Inject constructor(
isEncrypted = roomSummaryEntity.isEncrypted,
typingRoomMemberIds = roomSummaryEntity.typingUserIds.toList(),
breadcrumbsIndex = roomSummaryEntity.breadcrumbsIndex,
roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel
roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel,
inviterId = roomSummaryEntity.inviterId
)
}
}

View file

@ -24,7 +24,7 @@ import io.realm.RealmObject
import io.realm.annotations.Index
import io.realm.annotations.PrimaryKey
internal open class EventEntity(@PrimaryKey var eventId: String = "",
internal open class EventEntity(@Index var eventId: String = "",
@Index var roomId: String = "",
@Index var type: String = "",
var content: String? = null,

View file

@ -49,7 +49,8 @@ internal open class RoomSummaryEntity(
var flatAliases: String = "",
var isEncrypted: Boolean = false,
var typingUserIds: RealmList<String> = RealmList(),
var roomEncryptionTrustLevelStr: String? = null
var roomEncryptionTrustLevelStr: String? = null,
var inviterId: String? = null
) : RealmObject() {
private var membershipStr: String = Membership.NONE.name

View file

@ -23,6 +23,13 @@ import io.realm.RealmList
import io.realm.RealmQuery
import io.realm.kotlin.where
internal fun EventEntity.copyToRealmOrIgnore(realm: Realm): EventEntity {
return realm.where<EventEntity>()
.equalTo(EventEntityFields.EVENT_ID, eventId)
.equalTo(EventEntityFields.ROOM_ID, roomId)
.findFirst() ?: realm.copyToRealm(this)
}
internal fun EventEntity.Companion.where(realm: Realm, eventId: String): RealmQuery<EventEntity> {
return realm.where<EventEntity>()
.equalTo(EventEntityFields.EVENT_ID, eventId)

View file

@ -81,7 +81,8 @@ internal class RoomSummaryUpdater @Inject constructor(
roomSummary: RoomSyncSummary? = null,
unreadNotifications: RoomSyncUnreadNotifications? = null,
updateMembers: Boolean = false,
ephemeralResult: RoomSyncHandler.EphemeralResult? = null) {
ephemeralResult: RoomSyncHandler.EphemeralResult? = null,
inviterId: String? = null) {
val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId)
if (roomSummary != null) {
if (roomSummary.heroes.isNotEmpty()) {
@ -133,6 +134,7 @@ internal class RoomSummaryUpdater @Inject constructor(
roomSummaryEntity.isEncrypted = encryptionEvent != null
roomSummaryEntity.typingUserIds.clear()
roomSummaryEntity.typingUserIds.addAll(ephemeralResult?.typingUserIds.orEmpty())
roomSummaryEntity.inviterId = inviterId
if (updateMembers) {
val otherRoomMembers = RoomMemberHelper(realm, roomId)

View file

@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.matrix.android.internal.database.mapper.toEntity
import im.vector.matrix.android.internal.database.model.CurrentStateEventEntity
import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.query.copyToRealmOrIgnore
import im.vector.matrix.android.internal.database.query.getOrCreate
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.network.executeRequest
@ -73,9 +74,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(
if (roomMemberEvent.eventId == null || roomMemberEvent.stateKey == null) {
continue
}
val eventEntity = roomMemberEvent.toEntity(roomId, SendState.SYNCED).let {
realm.copyToRealmOrUpdate(it)
}
val eventEntity = roomMemberEvent.toEntity(roomId, SendState.SYNCED).copyToRealmOrIgnore(realm)
CurrentStateEventEntity.getOrCreate(realm, roomId, roomMemberEvent.stateKey, roomMemberEvent.type).apply {
eventId = roomMemberEvent.eventId
root = eventEntity

View file

@ -31,6 +31,7 @@ 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.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.copyToRealmOrIgnore
import im.vector.matrix.android.internal.database.query.create
import im.vector.matrix.android.internal.database.query.find
import im.vector.matrix.android.internal.database.query.findAllIncludingEvents
@ -199,9 +200,7 @@ internal class TokenChunkEventPersistor @Inject constructor(private val monarchy
val stateEvents = receivedChunk.stateEvents
for (stateEvent in stateEvents) {
val stateEventEntity = stateEvent.toEntity(roomId, SendState.SYNCED).let {
realm.copyToRealmOrUpdate(it)
}
val stateEventEntity = stateEvent.toEntity(roomId, SendState.SYNCED).copyToRealmOrIgnore(realm)
currentChunk.addStateEvent(roomId, stateEventEntity, direction)
if (stateEvent.type == EventType.STATE_ROOM_MEMBER && stateEvent.stateKey != null) {
roomMemberContentsByUser[stateEvent.stateKey] = stateEvent.content.toModel<RoomMemberContent>()
@ -213,9 +212,7 @@ internal class TokenChunkEventPersistor @Inject constructor(private val monarchy
continue
}
eventIds.add(event.eventId)
val eventEntity = event.toEntity(roomId, SendState.SYNCED).let {
realm.copyToRealmOrUpdate(it)
}
val eventEntity = event.toEntity(roomId, SendState.SYNCED).copyToRealmOrIgnore(realm)
if (event.type == EventType.STATE_ROOM_MEMBER && event.stateKey != null) {
val contentToUse = if (direction == PaginationDirection.BACKWARDS) {
event.prevContent

View file

@ -32,6 +32,7 @@ import im.vector.matrix.android.internal.database.mapper.toEntity
import im.vector.matrix.android.internal.database.model.ChunkEntity
import im.vector.matrix.android.internal.database.model.CurrentStateEventEntity
import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.query.copyToRealmOrIgnore
import im.vector.matrix.android.internal.database.query.find
import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom
import im.vector.matrix.android.internal.database.query.getOrCreate
@ -93,7 +94,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
}
is HandlingStrategy.INVITED ->
handlingStrategy.data.mapWithProgress(reporter, R.string.initial_sync_start_importing_account_invited_rooms, 0.1f) {
handleInvitedRoom(realm, it.key, it.value, syncLocalTimeStampMillis)
handleInvitedRoom(realm, it.key, it.value)
}
is HandlingStrategy.LEFT -> {
@ -134,9 +135,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
if (event.eventId == null || event.stateKey == null) {
continue
}
val eventEntity = event.toEntity(roomId, SendState.SYNCED).let {
realm.copyToRealmOrUpdate(it)
}
val eventEntity = event.toEntity(roomId, SendState.SYNCED).copyToRealmOrIgnore(realm)
CurrentStateEventEntity.getOrCreate(realm, roomId, event.stateKey, event.type).apply {
eventId = event.eventId
root = eventEntity
@ -177,19 +176,26 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
private fun handleInvitedRoom(realm: Realm,
roomId: String,
roomSync: InvitedRoomSync,
syncLocalTimestampMillis: Long): RoomEntity {
roomSync: InvitedRoomSync): RoomEntity {
Timber.v("Handle invited sync for room $roomId")
val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId)
roomEntity.membership = Membership.INVITE
if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) {
val chunkEntity = handleTimelineEvents(realm, roomId, roomEntity, roomSync.inviteState.events, syncLocalTimestampMillis = syncLocalTimestampMillis)
roomEntity.addOrUpdate(chunkEntity)
roomSync.inviteState.events.forEach {
if (it.stateKey == null) {
return@forEach
}
val eventEntity = it.toEntity(roomId, SendState.SYNCED).copyToRealmOrIgnore(realm)
CurrentStateEventEntity.getOrCreate(realm, roomId, it.stateKey, it.type).apply {
eventId = eventEntity.eventId
root = eventEntity
}
}
}
val hasRoomMember = roomSync.inviteState?.events?.firstOrNull {
val inviterEvent = roomSync.inviteState?.events?.lastOrNull {
it.type == EventType.STATE_ROOM_MEMBER
} != null
roomSummaryUpdater.update(realm, roomId, Membership.INVITE, updateMembers = hasRoomMember)
}
roomSummaryUpdater.update(realm, roomId, Membership.INVITE, updateMembers = true, inviterId = inviterEvent?.senderId)
return roomEntity
}
@ -197,7 +203,6 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
roomId: String,
roomSync: RoomSync): RoomEntity {
val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId)
roomEntity.membership = Membership.LEAVE
roomEntity.chunks.deleteAllFromRealm()
roomSummaryUpdater.update(realm, roomId, Membership.LEAVE, roomSync.summary, roomSync.unreadNotifications)
@ -229,9 +234,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
}
eventIds.add(event.eventId)
val ageLocalTs = event.unsignedData?.age?.let { syncLocalTimestampMillis - it }
val eventEntity = event.toEntity(roomId, SendState.SYNCED, ageLocalTs).let {
realm.copyToRealmOrUpdate(it)
}
val eventEntity = event.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm)
if (event.isStateEvent() && event.stateKey != null) {
CurrentStateEventEntity.getOrCreate(realm, roomId, event.stateKey, event.type).apply {
eventId = event.eventId

View file

@ -950,8 +950,8 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
private fun observeSummaryState() {
asyncSubscribe(RoomDetailViewState::asyncRoomSummary) { summary ->
if (summary.membership == Membership.INVITE) {
summary.latestPreviewableEvent?.root?.senderId?.let { senderId ->
session.getUser(senderId)
summary.inviterId?.let { inviterId ->
session.getUser(inviterId)
}?.also {
setState { copy(asyncInviter = Success(it)) }
}

View file

@ -60,9 +60,9 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
rejectingErrorRoomsIds: Set<String>,
listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> {
val secondLine = if (roomSummary.isDirect) {
roomSummary.latestPreviewableEvent?.root?.senderId
roomSummary.inviterId
} else {
roomSummary.latestPreviewableEvent?.root?.senderId?.let {
roomSummary.inviterId?.let {
stringProvider.getString(R.string.invited_by, it)
}
}