mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-29 14:38:45 +03:00
Fix message edition is not rendered in e2e rooms after pagination (#3887)
This commit is contained in:
parent
b4979e0bfb
commit
2e2deba3ac
8 changed files with 37 additions and 31 deletions
1
changelog.d/3887.bugfix
Normal file
1
changelog.d/3887.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Message edition is not rendered in e2e rooms after pagination
|
|
@ -17,6 +17,9 @@
|
||||||
package org.matrix.android.sdk.internal.database
|
package org.matrix.android.sdk.internal.database
|
||||||
|
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
|
import io.realm.RealmResults
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||||
import org.matrix.android.sdk.internal.database.model.EventEntity
|
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.EventInsertEntity
|
import org.matrix.android.sdk.internal.database.model.EventInsertEntity
|
||||||
|
@ -24,20 +27,15 @@ import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
|
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
|
||||||
import io.realm.RealmConfiguration
|
|
||||||
import io.realm.RealmResults
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.matrix.android.sdk.internal.crypto.EventDecryptor
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
|
internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
|
||||||
private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>,
|
private val processors: Set<@JvmSuppressWildcards EventInsertLiveProcessor>)
|
||||||
private val eventDecryptor: EventDecryptor)
|
|
||||||
: RealmLiveEntityObserver<EventInsertEntity>(realmConfiguration) {
|
: RealmLiveEntityObserver<EventInsertEntity>(realmConfiguration) {
|
||||||
|
|
||||||
override val query = Monarchy.Query<EventInsertEntity> {
|
override val query = Monarchy.Query {
|
||||||
it.where(EventInsertEntity::class.java)
|
it.where(EventInsertEntity::class.java).equalTo(EventInsertEntityFields.CAN_BE_PROCESSED, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChange(results: RealmResults<EventInsertEntity>) {
|
override fun onChange(results: RealmResults<EventInsertEntity>) {
|
||||||
|
@ -86,23 +84,6 @@ internal class EventInsertLiveObserver @Inject constructor(@SessionDatabase real
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private fun decryptIfNeeded(event: Event) {
|
|
||||||
// if (event.isEncrypted() && event.mxDecryptionResult == null) {
|
|
||||||
// try {
|
|
||||||
// val result = eventDecryptor.decryptEvent(event, event.roomId ?: "")
|
|
||||||
// event.mxDecryptionResult = OlmDecryptionResult(
|
|
||||||
// payload = result.clearEvent,
|
|
||||||
// senderKey = result.senderCurve25519Key,
|
|
||||||
// keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
|
|
||||||
// forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
|
|
||||||
// )
|
|
||||||
// } catch (e: MXCryptoError) {
|
|
||||||
// Timber.v("Failed to decrypt event")
|
|
||||||
// // TODO -> we should keep track of this and retry, or some processing will never be handled
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun shouldProcess(eventInsertEntity: EventInsertEntity): Boolean {
|
private fun shouldProcess(eventInsertEntity: EventInsertEntity): Boolean {
|
||||||
return processors.any {
|
return processors.any {
|
||||||
it.shouldProcess(eventInsertEntity.eventId, eventInsertEntity.eventType, eventInsertEntity.insertType)
|
it.shouldProcess(eventInsertEntity.eventId, eventInsertEntity.eventType, eventInsertEntity.insertType)
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFie
|
||||||
import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.EditionOfEventFields
|
import org.matrix.android.sdk.internal.database.model.EditionOfEventFields
|
||||||
import org.matrix.android.sdk.internal.database.model.EventEntityFields
|
import org.matrix.android.sdk.internal.database.model.EventEntityFields
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
|
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields
|
import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields
|
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields
|
||||||
|
@ -46,7 +47,7 @@ import timber.log.Timber
|
||||||
|
|
||||||
internal object RealmSessionStoreMigration : RealmMigration {
|
internal object RealmSessionStoreMigration : RealmMigration {
|
||||||
|
|
||||||
const val SESSION_STORE_SCHEMA_VERSION = 16L
|
const val SESSION_STORE_SCHEMA_VERSION = 17L
|
||||||
|
|
||||||
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
|
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
|
||||||
Timber.v("Migrating Realm Session from $oldVersion to $newVersion")
|
Timber.v("Migrating Realm Session from $oldVersion to $newVersion")
|
||||||
|
@ -67,6 +68,7 @@ internal object RealmSessionStoreMigration : RealmMigration {
|
||||||
if (oldVersion <= 13) migrateTo14(realm)
|
if (oldVersion <= 13) migrateTo14(realm)
|
||||||
if (oldVersion <= 14) migrateTo15(realm)
|
if (oldVersion <= 14) migrateTo15(realm)
|
||||||
if (oldVersion <= 15) migrateTo16(realm)
|
if (oldVersion <= 15) migrateTo16(realm)
|
||||||
|
if (oldVersion <= 16) migrateTo17(realm)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun migrateTo1(realm: DynamicRealm) {
|
private fun migrateTo1(realm: DynamicRealm) {
|
||||||
|
@ -330,4 +332,10 @@ internal object RealmSessionStoreMigration : RealmMigration {
|
||||||
obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0)
|
obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun migrateTo17(realm: DynamicRealm) {
|
||||||
|
Timber.d("Step 16 -> 17")
|
||||||
|
realm.schema.get("EventInsertEntity")
|
||||||
|
?.addField(EventInsertEntityFields.CAN_BE_PROCESSED, Boolean::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
|
||||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||||
import io.realm.RealmObject
|
import io.realm.RealmObject
|
||||||
import io.realm.annotations.Index
|
import io.realm.annotations.Index
|
||||||
|
import org.matrix.android.sdk.internal.extensions.assertIsManaged
|
||||||
|
|
||||||
internal open class EventEntity(@Index var eventId: String = "",
|
internal open class EventEntity(@Index var eventId: String = "",
|
||||||
@Index var roomId: String = "",
|
@Index var roomId: String = "",
|
||||||
|
@ -56,15 +57,22 @@ internal open class EventEntity(@Index var eventId: String = "",
|
||||||
companion object
|
companion object
|
||||||
|
|
||||||
fun setDecryptionResult(result: MXEventDecryptionResult) {
|
fun setDecryptionResult(result: MXEventDecryptionResult) {
|
||||||
|
assertIsManaged()
|
||||||
val decryptionResult = OlmDecryptionResult(
|
val decryptionResult = OlmDecryptionResult(
|
||||||
payload = result.clearEvent,
|
payload = result.clearEvent,
|
||||||
senderKey = result.senderCurve25519Key,
|
senderKey = result.senderCurve25519Key,
|
||||||
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
keysClaimed = result.claimedEd25519Key?.let { mapOf("ed25519" to it) },
|
||||||
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
|
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
|
||||||
)
|
)
|
||||||
val adapter = MoshiProvider.providesMoshi().adapter<OlmDecryptionResult>(OlmDecryptionResult::class.java)
|
val adapter = MoshiProvider.providesMoshi().adapter(OlmDecryptionResult::class.java)
|
||||||
decryptionResultJson = adapter.toJson(decryptionResult)
|
decryptionResultJson = adapter.toJson(decryptionResult)
|
||||||
decryptionErrorCode = null
|
decryptionErrorCode = null
|
||||||
decryptionErrorReason = null
|
decryptionErrorReason = null
|
||||||
|
|
||||||
|
// If we have an EventInsertEntity for the eventId we make sures it can be processed now.
|
||||||
|
realm.where(EventInsertEntity::class.java)
|
||||||
|
.equalTo(EventInsertEntityFields.EVENT_ID, eventId)
|
||||||
|
.findFirst()
|
||||||
|
?.canBeProcessed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,12 @@ import io.realm.RealmObject
|
||||||
* in EventEntity table.
|
* in EventEntity table.
|
||||||
*/
|
*/
|
||||||
internal open class EventInsertEntity(var eventId: String = "",
|
internal open class EventInsertEntity(var eventId: String = "",
|
||||||
var eventType: String = ""
|
var eventType: String = "",
|
||||||
|
/**
|
||||||
|
* This flag will be used to filter EventInsertEntity in EventInsertLiveObserver.
|
||||||
|
* Currently it's set to false when the event content is encrypted.
|
||||||
|
*/
|
||||||
|
var canBeProcessed: Boolean = true
|
||||||
) : RealmObject() {
|
) : RealmObject() {
|
||||||
|
|
||||||
private var insertTypeStr: String = EventInsertType.INCREMENTAL_SYNC.name
|
private var insertTypeStr: String = EventInsertType.INCREMENTAL_SYNC.name
|
||||||
|
|
|
@ -24,6 +24,7 @@ import io.realm.Realm
|
||||||
import io.realm.RealmList
|
import io.realm.RealmList
|
||||||
import io.realm.RealmQuery
|
import io.realm.RealmQuery
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
|
||||||
internal fun EventEntity.copyToRealmOrIgnore(realm: Realm, insertType: EventInsertType): EventEntity {
|
internal fun EventEntity.copyToRealmOrIgnore(realm: Realm, insertType: EventInsertType): EventEntity {
|
||||||
val eventEntity = realm.where<EventEntity>()
|
val eventEntity = realm.where<EventEntity>()
|
||||||
|
@ -31,7 +32,8 @@ internal fun EventEntity.copyToRealmOrIgnore(realm: Realm, insertType: EventInse
|
||||||
.equalTo(EventEntityFields.ROOM_ID, roomId)
|
.equalTo(EventEntityFields.ROOM_ID, roomId)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
return if (eventEntity == null) {
|
return if (eventEntity == null) {
|
||||||
val insertEntity = EventInsertEntity(eventId = eventId, eventType = type).apply {
|
val canBeProcessed = type != EventType.ENCRYPTED || decryptionResultJson != null
|
||||||
|
val insertEntity = EventInsertEntity(eventId = eventId, eventType = type, canBeProcessed = canBeProcessed).apply {
|
||||||
this.insertType = insertType
|
this.insertType = insertType
|
||||||
}
|
}
|
||||||
realm.insert(insertEntity)
|
realm.insert(insertEntity)
|
||||||
|
|
|
@ -77,7 +77,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
|
||||||
val timelineEvent = timelineEventMapper.map(timelineEventEntity)
|
val timelineEvent = timelineEventMapper.map(timelineEventEntity)
|
||||||
timelineInput.onLocalEchoCreated(roomId = roomId, timelineEvent = timelineEvent)
|
timelineInput.onLocalEchoCreated(roomId = roomId, timelineEvent = timelineEvent)
|
||||||
taskExecutor.executorScope.asyncTransaction(monarchy) { realm ->
|
taskExecutor.executorScope.asyncTransaction(monarchy) { realm ->
|
||||||
val eventInsertEntity = EventInsertEntity(event.eventId, event.type).apply {
|
val eventInsertEntity = EventInsertEntity(event.eventId, event.type, canBeProcessed = true).apply {
|
||||||
this.insertType = EventInsertType.LOCAL_ECHO
|
this.insertType = EventInsertType.LOCAL_ECHO
|
||||||
}
|
}
|
||||||
realm.insert(eventInsertEntity)
|
realm.insert(eventInsertEntity)
|
||||||
|
|
|
@ -106,7 +106,8 @@ internal class TimelineEventDecryptor @Inject constructor(
|
||||||
val result = cryptoService.decryptEvent(request.event, timelineId)
|
val result = cryptoService.decryptEvent(request.event, timelineId)
|
||||||
Timber.v("Successfully decrypted event ${event.eventId}")
|
Timber.v("Successfully decrypted event ${event.eventId}")
|
||||||
realm.executeTransaction {
|
realm.executeTransaction {
|
||||||
EventEntity.where(it, eventId = event.eventId ?: "")
|
val eventId = event.eventId ?: ""
|
||||||
|
EventEntity.where(it, eventId = eventId)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
?.setDecryptionResult(result)
|
?.setDecryptionResult(result)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue