Realm-kotlin : continue migrating session db
This commit is contained in:
parent
5d73118c8c
commit
6edea43ab4
@ -16,9 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.database.helper
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.createObject
|
||||
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
@ -32,14 +31,13 @@ import org.matrix.android.sdk.internal.database.model.EventEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.ReadReceiptEntity
|
||||
import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.cleanUp
|
||||
import org.matrix.android.sdk.internal.database.query.find
|
||||
import org.matrix.android.sdk.internal.database.query.findLastForwardChunkOfRoom
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.extensions.realm
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
|
||||
import timber.log.Timber
|
||||
|
||||
@ -63,6 +61,7 @@ internal fun ChunkEntity.addStateEvent(roomId: String, stateEvent: EventEntity,
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.addTimelineEvent(
|
||||
realm: MutableRealm,
|
||||
roomId: String,
|
||||
eventEntity: EventEntity,
|
||||
direction: PaginationDirection,
|
||||
@ -79,32 +78,33 @@ internal fun ChunkEntity.addTimelineEvent(
|
||||
|
||||
// Update RR for the sender of a new message with a dummy one
|
||||
val readReceiptsSummaryEntity = if (!ownedByThreadChunk) handleReadReceipts(realm, roomId, eventEntity, senderId) else null
|
||||
val timelineEventEntity = realm.createObject<TimelineEventEntity>().apply {
|
||||
this.localId = localId
|
||||
this.root = eventEntity
|
||||
this.eventId = eventId
|
||||
this.roomId = roomId
|
||||
this.annotations = EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst()
|
||||
?.also { it.cleanUp(eventEntity.sender) }
|
||||
this.readReceipts = readReceiptsSummaryEntity
|
||||
this.displayIndex = displayIndex
|
||||
this.ownedByThreadChunk = ownedByThreadChunk
|
||||
val roomMemberContent = roomMemberContentsByUser?.get(senderId)
|
||||
this.senderAvatar = roomMemberContent?.avatarUrl
|
||||
this.senderName = roomMemberContent?.displayName
|
||||
isUniqueDisplayName = if (roomMemberContent?.displayName != null) {
|
||||
computeIsUnique(realm, roomId, isLastForward, roomMemberContent, roomMemberContentsByUser)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
// numberOfTimelineEvents++
|
||||
val timelineEventEntity = realm.copyToRealm(
|
||||
TimelineEventEntity().apply {
|
||||
this.localId = localId
|
||||
this.root = eventEntity
|
||||
this.eventId = eventId
|
||||
this.roomId = roomId
|
||||
this.annotations = EventAnnotationsSummaryEntity.where(realm, roomId, eventId).first().find()
|
||||
?.also { realm.cleanUp(it, eventEntity.sender) }
|
||||
this.readReceipts = readReceiptsSummaryEntity
|
||||
this.displayIndex = displayIndex
|
||||
this.ownedByThreadChunk = ownedByThreadChunk
|
||||
val roomMemberContent = roomMemberContentsByUser?.get(senderId)
|
||||
this.senderAvatar = roomMemberContent?.avatarUrl
|
||||
this.senderName = roomMemberContent?.displayName
|
||||
isUniqueDisplayName = if (roomMemberContent?.displayName != null) {
|
||||
computeIsUnique(realm, roomId, isLastForward, roomMemberContent, roomMemberContentsByUser)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
)
|
||||
timelineEvents.add(timelineEventEntity)
|
||||
return timelineEventEntity
|
||||
}
|
||||
|
||||
internal fun computeIsUnique(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
roomId: String,
|
||||
isLastForward: Boolean,
|
||||
senderRoomMemberContent: RoomMemberContent,
|
||||
@ -116,8 +116,8 @@ internal fun computeIsUnique(
|
||||
return if (isLastForward) {
|
||||
val isLiveUnique = RoomMemberSummaryEntity
|
||||
.where(realm, roomId)
|
||||
.equalTo(RoomMemberSummaryEntityFields.DISPLAY_NAME, senderRoomMemberContent.displayName)
|
||||
.findAll()
|
||||
.query("displayName == $0", senderRoomMemberContent.displayName)
|
||||
.find()
|
||||
.none {
|
||||
!roomMemberContentsByUser.containsKey(it.userId)
|
||||
}
|
||||
@ -127,18 +127,19 @@ internal fun computeIsUnique(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleReadReceipts(realm: Realm, roomId: String, eventEntity: EventEntity, senderId: String): ReadReceiptsSummaryEntity {
|
||||
val readReceiptsSummaryEntity = ReadReceiptsSummaryEntity.where(realm, eventEntity.eventId).findFirst()
|
||||
?: realm.createObject<ReadReceiptsSummaryEntity>(eventEntity.eventId).apply {
|
||||
private fun handleReadReceipts(realm: MutableRealm, roomId: String, eventEntity: EventEntity, senderId: String): ReadReceiptsSummaryEntity {
|
||||
val readReceiptsSummaryEntity = ReadReceiptsSummaryEntity.where(realm, eventEntity.eventId).find()
|
||||
?: realm.copyToRealm(ReadReceiptsSummaryEntity().apply {
|
||||
this.eventId = eventEntity.eventId
|
||||
this.roomId = roomId
|
||||
}
|
||||
})
|
||||
val originServerTs = eventEntity.originServerTs
|
||||
if (originServerTs != null) {
|
||||
val timestampOfEvent = originServerTs.toDouble()
|
||||
val readReceiptOfSender = ReadReceiptEntity.getOrCreate(realm, roomId = roomId, userId = senderId)
|
||||
// If the synced RR is older, update
|
||||
if (timestampOfEvent > readReceiptOfSender.originServerTs) {
|
||||
val previousReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId = readReceiptOfSender.eventId).findFirst()
|
||||
val previousReceiptsSummary = ReadReceiptsSummaryEntity.where(realm, eventId = readReceiptOfSender.eventId).find()
|
||||
readReceiptOfSender.eventId = eventEntity.eventId
|
||||
readReceiptOfSender.originServerTs = timestampOfEvent
|
||||
previousReceiptsSummary?.readReceipts?.remove(readReceiptOfSender)
|
||||
|
||||
@ -20,6 +20,8 @@ import com.squareup.moshi.JsonDataException
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.Sort
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import org.matrix.android.sdk.api.session.events.model.UnsignedData
|
||||
import org.matrix.android.sdk.api.session.events.model.isRedacted
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
@ -48,13 +50,13 @@ private typealias Summary = Pair<Int, TimelineEventEntity>?
|
||||
*/
|
||||
internal fun Map<String, EventEntity>.updateThreadSummaryIfNeeded(
|
||||
roomId: String,
|
||||
realm: Realm,
|
||||
realm: MutableRealm,
|
||||
currentUserId: String,
|
||||
chunkEntity: ChunkEntity? = null,
|
||||
shouldUpdateNotifications: Boolean = true
|
||||
) {
|
||||
for ((rootThreadEventId, eventEntity) in this) {
|
||||
eventEntity.threadSummaryInThread(eventEntity.realm, rootThreadEventId, chunkEntity)?.let { threadSummary ->
|
||||
eventEntity.threadSummaryInThread(realm, rootThreadEventId, chunkEntity)?.let { threadSummary ->
|
||||
|
||||
val inThreadMessages = threadSummary.first
|
||||
val latestEventInThread = threadSummary.second
|
||||
@ -105,7 +107,7 @@ internal fun EventEntity.markEventAsRoot(
|
||||
* @param chunkEntity the chunk entity
|
||||
* @return A ThreadSummary containing the counted threads and the latest event message
|
||||
*/
|
||||
internal fun EventEntity.threadSummaryInThread(realm: Realm, rootThreadEventId: String, chunkEntity: ChunkEntity?): Summary {
|
||||
internal fun EventEntity.threadSummaryInThread(realm: TypedRealm, rootThreadEventId: String, chunkEntity: ChunkEntity?): Summary {
|
||||
val inThreadMessages = countInThreadMessages(
|
||||
realm = realm,
|
||||
roomId = roomId,
|
||||
@ -141,12 +143,12 @@ internal fun EventEntity.threadSummaryInThread(realm: Realm, rootThreadEventId:
|
||||
* Counts the number of thread replies in the main timeline thread summary,
|
||||
* with respect to redactions.
|
||||
*/
|
||||
internal fun countInThreadMessages(realm: Realm, roomId: String, rootThreadEventId: String): Int =
|
||||
internal fun countInThreadMessages(realm: TypedRealm, roomId: String, rootThreadEventId: String): Int =
|
||||
TimelineEventEntity
|
||||
.whereRoomId(realm, roomId = roomId)
|
||||
.equalTo(TimelineEventEntityFields.ROOT.ROOT_THREAD_EVENT_ID, rootThreadEventId)
|
||||
.distinct(TimelineEventEntityFields.ROOT.EVENT_ID)
|
||||
.findAll()
|
||||
.query("root.rootThreadEventId == $0", rootThreadEventId)
|
||||
.distinct("root.eventId")
|
||||
.find()
|
||||
.filterNot { timelineEvent ->
|
||||
timelineEvent.root
|
||||
?.unsignedData
|
||||
|
||||
@ -16,10 +16,10 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.database.helper
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.Sort
|
||||
import io.realm.kotlin.createObject
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import io.realm.kotlin.query.Sort
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||
@ -38,27 +38,28 @@ import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.EventInsertType
|
||||
import org.matrix.android.sdk.internal.database.model.RoomEntity
|
||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.cleanUp
|
||||
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntityFields
|
||||
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
import org.matrix.android.sdk.internal.database.query.getOrNull
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.extensions.realm
|
||||
import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.TimelineEventDecryptor
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
|
||||
internal fun ThreadSummaryEntity.updateThreadSummary(
|
||||
realm: TypedRealm,
|
||||
rootThreadEventEntity: EventEntity,
|
||||
numberOfThreads: Int?,
|
||||
latestThreadEventEntity: EventEntity?,
|
||||
isUserParticipating: Boolean,
|
||||
roomMemberContentsByUser: HashMap<String, RoomMemberContent?>
|
||||
) {
|
||||
updateThreadSummaryRootEvent(rootThreadEventEntity, roomMemberContentsByUser)
|
||||
updateThreadSummaryLatestEvent(latestThreadEventEntity, roomMemberContentsByUser)
|
||||
updateThreadSummaryRootEvent(realm, rootThreadEventEntity, roomMemberContentsByUser)
|
||||
updateThreadSummaryLatestEvent(realm, latestThreadEventEntity, roomMemberContentsByUser)
|
||||
this.isUserParticipating = isUserParticipating
|
||||
numberOfThreads?.let {
|
||||
// Update number of threads only when there is an actual value
|
||||
@ -70,6 +71,7 @@ internal fun ThreadSummaryEntity.updateThreadSummary(
|
||||
* Updates the root thread event properties.
|
||||
*/
|
||||
internal fun ThreadSummaryEntity.updateThreadSummaryRootEvent(
|
||||
realm: TypedRealm,
|
||||
rootThreadEventEntity: EventEntity,
|
||||
roomMemberContentsByUser: HashMap<String, RoomMemberContent?>
|
||||
) {
|
||||
@ -89,6 +91,7 @@ internal fun ThreadSummaryEntity.updateThreadSummaryRootEvent(
|
||||
* Updates the latest thread event properties.
|
||||
*/
|
||||
internal fun ThreadSummaryEntity.updateThreadSummaryLatestEvent(
|
||||
realm: TypedRealm,
|
||||
latestThreadEventEntity: EventEntity?,
|
||||
roomMemberContentsByUser: HashMap<String, RoomMemberContent?>
|
||||
) {
|
||||
@ -104,19 +107,19 @@ internal fun ThreadSummaryEntity.updateThreadSummaryLatestEvent(
|
||||
}
|
||||
}
|
||||
|
||||
private fun EventEntity.toTimelineEventEntity(roomMemberContentsByUser: HashMap<String, RoomMemberContent?>): TimelineEventEntity {
|
||||
private fun EventEntity.toTimelineEventEntity(realm: MutableRealm, roomMemberContentsByUser: HashMap<String, RoomMemberContent?>): TimelineEventEntity {
|
||||
val roomId = roomId
|
||||
val eventId = eventId
|
||||
val localId = TimelineEventEntity.nextId(realm)
|
||||
val senderId = sender ?: ""
|
||||
|
||||
val timelineEventEntity = realm.createObject<TimelineEventEntity>().apply {
|
||||
val timelineEventEntity = TimelineEventEntity().apply {
|
||||
this.localId = localId
|
||||
this.root = this@toTimelineEventEntity
|
||||
this.eventId = eventId
|
||||
this.roomId = roomId
|
||||
this.annotations = EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst()
|
||||
?.also { it.cleanUp(sender) }
|
||||
this.annotations = EventAnnotationsSummaryEntity.where(realm, roomId, eventId).first().find()
|
||||
?.also { realm.cleanUp(it, sender) }
|
||||
this.ownedByThreadChunk = true // To skip it from the original event flow
|
||||
val roomMemberContent = roomMemberContentsByUser[senderId]
|
||||
this.senderAvatar = roomMemberContent?.avatarUrl
|
||||
@ -132,7 +135,7 @@ private fun EventEntity.toTimelineEventEntity(roomMemberContentsByUser: HashMap<
|
||||
|
||||
internal fun ThreadSummaryEntity.Companion.createOrUpdate(
|
||||
threadSummaryType: ThreadSummaryUpdateType,
|
||||
realm: Realm,
|
||||
realm: MutableRealm,
|
||||
roomId: String,
|
||||
threadEventEntity: EventEntity? = null,
|
||||
rootThreadEvent: Event? = null,
|
||||
@ -173,6 +176,7 @@ internal fun ThreadSummaryEntity.Companion.createOrUpdate(
|
||||
val isUserParticipating = rootThreadEvent.unsignedData.relations.latestThread.isUserParticipating == true || rootThreadEvent.senderId == userId
|
||||
roomMemberContentsByUser.addSenderState(realm, roomId, rootThreadEvent.senderId)
|
||||
threadSummary.updateThreadSummary(
|
||||
realm = realm,
|
||||
rootThreadEventEntity = rootThreadEventEntity,
|
||||
numberOfThreads = numberOfThreads,
|
||||
latestThreadEventEntity = latestThreadEventEntity,
|
||||
@ -190,7 +194,7 @@ internal fun ThreadSummaryEntity.Companion.createOrUpdate(
|
||||
if (threadSummary != null) {
|
||||
// ThreadSummary exists so lets add the latest event
|
||||
Timber.i("###THREADS ThreadSummaryHelper ADD root eventId:$rootThreadEventId exists, lets update latest thread event.")
|
||||
threadSummary.updateThreadSummaryLatestEvent(threadEventEntity, roomMemberContentsByUser)
|
||||
threadSummary.updateThreadSummaryLatestEvent(realm, threadEventEntity, roomMemberContentsByUser)
|
||||
threadSummary.numberOfThreads++
|
||||
if (threadEventEntity.sender == userId) {
|
||||
threadSummary.isUserParticipating = true
|
||||
@ -202,6 +206,7 @@ internal fun ThreadSummaryEntity.Companion.createOrUpdate(
|
||||
// Root thread event entity exists so lets create a new record
|
||||
ThreadSummaryEntity.getOrCreate(realm, roomId, rootThreadEventEntity.eventId).let {
|
||||
it.updateThreadSummary(
|
||||
realm = realm,
|
||||
rootThreadEventEntity = rootThreadEventEntity,
|
||||
numberOfThreads = 1,
|
||||
latestThreadEventEntity = threadEventEntity,
|
||||
@ -259,7 +264,7 @@ private fun requestDecryption(eventDecryptor: TimelineEventDecryptor?, event: Ev
|
||||
/**
|
||||
* If we don't have any new state on this user, get it from db.
|
||||
*/
|
||||
private fun HashMap<String, RoomMemberContent?>.addSenderState(realm: Realm, roomId: String, senderId: String) {
|
||||
private fun HashMap<String, RoomMemberContent?>.addSenderState(realm: TypedRealm, roomId: String, senderId: String) {
|
||||
getOrPut(senderId) {
|
||||
CurrentStateEventEntity
|
||||
.getOrNull(realm, roomId, senderId, EventType.STATE_ROOM_MEMBER)
|
||||
@ -271,7 +276,7 @@ private fun HashMap<String, RoomMemberContent?>.addSenderState(realm: Realm, roo
|
||||
/**
|
||||
* Create an EventEntity for the root thread event or get an existing one.
|
||||
*/
|
||||
private fun createEventEntity(realm: Realm, roomId: String, event: Event, currentTimeMillis: Long): EventEntity {
|
||||
private fun createEventEntity(realm: MutableRealm, roomId: String, event: Event, currentTimeMillis: Long): EventEntity {
|
||||
val ageLocalTs = currentTimeMillis - (event.unsignedData?.age ?: 0)
|
||||
return event.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, EventInsertType.PAGINATION)
|
||||
}
|
||||
@ -281,7 +286,7 @@ private fun createEventEntity(realm: Realm, roomId: String, event: Event, curren
|
||||
* state
|
||||
*/
|
||||
private fun createLatestEventEntity(
|
||||
realm: Realm,
|
||||
realm: MutableRealm,
|
||||
roomId: String,
|
||||
rootThreadEvent: Event,
|
||||
roomMemberContentsByUser: HashMap<String, RoomMemberContent?>,
|
||||
@ -308,7 +313,7 @@ private fun getLatestEvent(rootThreadEvent: Event): Event? {
|
||||
* @param realm the realm instance
|
||||
* @param roomId The id of the room
|
||||
*/
|
||||
internal fun ThreadSummaryEntity.Companion.findAllThreadsForRoomId(realm: Realm, roomId: String): RealmQuery<ThreadSummaryEntity> =
|
||||
internal fun ThreadSummaryEntity.Companion.findAllThreadsForRoomId(realm: TypedRealm, roomId: String): RealmQuery<ThreadSummaryEntity> =
|
||||
ThreadSummaryEntity
|
||||
.where(realm, roomId = roomId)
|
||||
.sort(ThreadSummaryEntityFields.LATEST_THREAD_EVENT_ENTITY.ORIGIN_SERVER_TS, Sort.DESCENDING)
|
||||
@ -316,24 +321,25 @@ internal fun ThreadSummaryEntity.Companion.findAllThreadsForRoomId(realm: Realm,
|
||||
/**
|
||||
* Enhance each [ThreadSummary] root and latest event with the equivalent decrypted text edition/replacement.
|
||||
*/
|
||||
internal fun List<ThreadSummary>.enhanceWithEditions(realm: Realm, roomId: String): List<ThreadSummary> =
|
||||
internal fun List<ThreadSummary>.enhanceWithEditions(realm: TypedRealm, roomId: String): List<ThreadSummary> =
|
||||
this.map {
|
||||
it.addEditionIfNeeded(realm, roomId, true)
|
||||
it.addEditionIfNeeded(realm, roomId, false)
|
||||
it
|
||||
}
|
||||
|
||||
private fun ThreadSummary.addEditionIfNeeded(realm: Realm, roomId: String, enhanceRoot: Boolean) {
|
||||
private fun ThreadSummary.addEditionIfNeeded(realm: TypedRealm, roomId: String, enhanceRoot: Boolean) {
|
||||
val eventId = if (enhanceRoot) rootEventId else latestEvent?.eventId ?: return
|
||||
EventAnnotationsSummaryEntity
|
||||
.where(realm, roomId, eventId)
|
||||
.findFirst()
|
||||
.first()
|
||||
.find()
|
||||
?.editSummary
|
||||
?.editions
|
||||
?.lastOrNull()
|
||||
?.eventId
|
||||
?.let { editedEventId ->
|
||||
TimelineEventEntity.where(realm, roomId, eventId = editedEventId).findFirst()?.let { editedEvent ->
|
||||
TimelineEventEntity.where(realm, roomId, eventId = editedEventId).first().find()?.let { editedEvent ->
|
||||
if (enhanceRoot) {
|
||||
threadEditions.rootThreadEdition = editedEvent.root?.asDomain()?.getDecryptedTextSummary() ?: "(edited)"
|
||||
} else {
|
||||
|
||||
@ -16,22 +16,22 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.database.mapper
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent
|
||||
import org.matrix.android.sdk.internal.database.RealmObjectMapper
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class LiveLocationShareAggregatedSummaryMapper @Inject constructor() :
|
||||
Monarchy.Mapper<LiveLocationShareAggregatedSummary, LiveLocationShareAggregatedSummaryEntity> {
|
||||
RealmObjectMapper<LiveLocationShareAggregatedSummaryEntity, LiveLocationShareAggregatedSummary> {
|
||||
|
||||
override fun map(entity: LiveLocationShareAggregatedSummaryEntity): LiveLocationShareAggregatedSummary {
|
||||
override fun map(realmObject: LiveLocationShareAggregatedSummaryEntity): LiveLocationShareAggregatedSummary {
|
||||
return LiveLocationShareAggregatedSummary(
|
||||
userId = entity.userId,
|
||||
isActive = entity.isActive,
|
||||
endOfLiveTimestampMillis = entity.endOfLiveTimestampMillis,
|
||||
lastLocationDataContent = ContentMapper.map(entity.lastLocationContent).toModel<MessageBeaconLocationDataContent>()
|
||||
userId = realmObject.userId,
|
||||
isActive = realmObject.isActive,
|
||||
endOfLiveTimestampMillis = realmObject.endOfLiveTimestampMillis,
|
||||
lastLocationDataContent = ContentMapper.map(realmObject.lastLocationContent).toModel<MessageBeaconLocationDataContent>()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,41 +16,30 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.database.mapper
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmList
|
||||
import io.realm.kotlin.isManaged
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
|
||||
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.model.ReadReceiptEntity
|
||||
import org.matrix.android.sdk.internal.database.model.ReadReceiptsSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.extensions.realm
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class ReadReceiptsSummaryMapper @Inject constructor(
|
||||
private val realmSessionProvider: RealmSessionProvider
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
) {
|
||||
|
||||
fun map(readReceiptsSummaryEntity: ReadReceiptsSummaryEntity?): List<ReadReceipt> {
|
||||
if (readReceiptsSummaryEntity == null) {
|
||||
return emptyList()
|
||||
}
|
||||
val readReceipts = readReceiptsSummaryEntity.readReceipts
|
||||
// Avoid opening a new realm if we already have one opened
|
||||
return if (readReceiptsSummaryEntity.isManaged()) {
|
||||
map(readReceipts, readReceiptsSummaryEntity.realm)
|
||||
} else {
|
||||
realmSessionProvider.withRealm { realm ->
|
||||
map(readReceipts, realm)
|
||||
}
|
||||
}
|
||||
val readReceipts = readReceiptsSummaryEntity?.readReceipts.orEmpty()
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return map(readReceipts, realm)
|
||||
}
|
||||
|
||||
private fun map(readReceipts: RealmList<ReadReceiptEntity>, realm: Realm): List<ReadReceipt> {
|
||||
private fun map(readReceipts: List<ReadReceiptEntity>, realm: TypedRealm): List<ReadReceipt> {
|
||||
return readReceipts
|
||||
.mapNotNull {
|
||||
val roomMember = RoomMemberSummaryEntity.where(realm, roomId = it.roomId, userId = it.userId).findFirst()
|
||||
val roomMember = RoomMemberSummaryEntity.where(realm, roomId = it.roomId, userId = it.userId).first().find()
|
||||
?: return@mapNotNull null
|
||||
ReadReceipt(roomMember.asDomain(), it.originServerTs.toLong())
|
||||
}
|
||||
|
||||
@ -15,11 +15,13 @@
|
||||
*/
|
||||
package org.matrix.android.sdk.internal.database.model
|
||||
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.ext.realmListOf
|
||||
import io.realm.kotlin.types.RealmList
|
||||
import io.realm.kotlin.types.RealmObject
|
||||
import io.realm.kotlin.types.annotations.PrimaryKey
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
|
||||
import timber.log.Timber
|
||||
|
||||
internal class EventAnnotationsSummaryEntity : RealmObject {
|
||||
@PrimaryKey
|
||||
@ -52,6 +54,18 @@ internal class EventAnnotationsSummaryEntity : RealmObject {
|
||||
companion object
|
||||
}
|
||||
|
||||
internal fun MutableRealm.cleanUp(entity: EventAnnotationsSummaryEntity, originalEventSenderId: String?) {
|
||||
originalEventSenderId ?: return
|
||||
|
||||
entity.editSummary?.editions?.filter {
|
||||
it.senderId != originalEventSenderId
|
||||
}
|
||||
?.forEach {
|
||||
Timber.w("Deleting an edition from ${it.senderId} of event sent by $originalEventSenderId")
|
||||
delete(it)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
internal fun EventAnnotationsSummaryEntity.deleteOnCascade() {
|
||||
reactionsSummary.deleteAllFromRealm()
|
||||
|
||||
@ -25,6 +25,6 @@ import io.realm.kotlin.types.RealmObject
|
||||
*/
|
||||
internal class UserDraftsEntity : RealmObject {
|
||||
var userDrafts: RealmList<DraftEntity> = realmListOf()
|
||||
|
||||
var roomId: String = ""
|
||||
companion object
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.database.query
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import io.realm.kotlin.types.RealmList
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.internal.database.andIf
|
||||
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||
@ -91,9 +92,7 @@ internal fun EventEntity.Companion.whereTypes(
|
||||
}
|
||||
|
||||
internal fun RealmList<EventEntity>.find(eventId: String): EventEntity? {
|
||||
return this.where()
|
||||
.equalTo(EventEntityFields.EVENT_ID, eventId)
|
||||
.findFirst()
|
||||
return return firstOrNull { it.eventId == eventId }
|
||||
}
|
||||
|
||||
internal fun RealmList<EventEntity>.fastContains(eventId: String): Boolean {
|
||||
|
||||
@ -16,79 +16,80 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.database.query
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.kotlin.where
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntityFields
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.where(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
eventId: String,
|
||||
): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
|
||||
return realm.where<LiveLocationShareAggregatedSummaryEntity>()
|
||||
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, eventId)
|
||||
return realm.query(LiveLocationShareAggregatedSummaryEntity::class)
|
||||
.query("eventId == $0", eventId)
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.where(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
roomId: String,
|
||||
eventId: String,
|
||||
): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
|
||||
return LiveLocationShareAggregatedSummaryEntity
|
||||
.whereRoomId(realm, roomId = roomId)
|
||||
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, eventId)
|
||||
.query("eventId == $0", eventId)
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.whereRoomId(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
roomId: String
|
||||
): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
|
||||
return realm.where<LiveLocationShareAggregatedSummaryEntity>()
|
||||
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, roomId)
|
||||
return realm.query(LiveLocationShareAggregatedSummaryEntity::class)
|
||||
.query("roomId == $0", roomId)
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.create(
|
||||
realm: Realm,
|
||||
realm: MutableRealm,
|
||||
roomId: String,
|
||||
eventId: String,
|
||||
): LiveLocationShareAggregatedSummaryEntity {
|
||||
val obj = realm.createObject(LiveLocationShareAggregatedSummaryEntity::class.java, eventId).apply {
|
||||
this.roomId = roomId
|
||||
}
|
||||
val entity = realm.copyToRealm(
|
||||
LiveLocationShareAggregatedSummaryEntity().apply {
|
||||
this.eventId = eventId
|
||||
this.roomId = roomId
|
||||
}
|
||||
)
|
||||
val annotationSummary = EventAnnotationsSummaryEntity.getOrCreate(realm, roomId = roomId, eventId = eventId)
|
||||
annotationSummary.liveLocationShareAggregatedSummary = obj
|
||||
|
||||
return obj
|
||||
annotationSummary.liveLocationShareAggregatedSummary = entity
|
||||
return entity
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.getOrCreate(
|
||||
realm: Realm,
|
||||
realm: MutableRealm,
|
||||
roomId: String,
|
||||
eventId: String,
|
||||
): LiveLocationShareAggregatedSummaryEntity {
|
||||
return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst()
|
||||
return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).first().find()
|
||||
?: LiveLocationShareAggregatedSummaryEntity.create(realm, roomId, eventId)
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.get(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
roomId: String,
|
||||
eventId: String,
|
||||
): LiveLocationShareAggregatedSummaryEntity? {
|
||||
return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst()
|
||||
return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).first().find()
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.get(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
eventId: String,
|
||||
): LiveLocationShareAggregatedSummaryEntity? {
|
||||
return LiveLocationShareAggregatedSummaryEntity.where(realm, eventId).findFirst()
|
||||
return LiveLocationShareAggregatedSummaryEntity.where(realm, eventId).first().find()
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findActiveLiveInRoomForUser(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
roomId: String,
|
||||
userId: String,
|
||||
ignoredEventId: String,
|
||||
@ -96,11 +97,11 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findActiveLiveIn
|
||||
): List<LiveLocationShareAggregatedSummaryEntity> {
|
||||
return LiveLocationShareAggregatedSummaryEntity
|
||||
.whereRoomId(realm, roomId = roomId)
|
||||
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.USER_ID, userId)
|
||||
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true)
|
||||
.notEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, ignoredEventId)
|
||||
.lessThan(LiveLocationShareAggregatedSummaryEntityFields.START_OF_LIVE_TIMESTAMP_MILLIS, startOfLiveTimestampThreshold)
|
||||
.findAll()
|
||||
.query("userId == $0", userId)
|
||||
.query("isActive == true")
|
||||
.query("eventId != $0", ignoredEventId)
|
||||
.query("startOfLiveTimestampMillis < $0", startOfLiveTimestampThreshold)
|
||||
.find()
|
||||
.toList()
|
||||
}
|
||||
|
||||
@ -108,12 +109,12 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findActiveLiveIn
|
||||
* A live is considered as running when active and with at least a last known location.
|
||||
*/
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findRunningLiveInRoom(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
roomId: String,
|
||||
): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
|
||||
return LiveLocationShareAggregatedSummaryEntity
|
||||
.whereRoomId(realm, roomId = roomId)
|
||||
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true)
|
||||
.isNotEmpty(LiveLocationShareAggregatedSummaryEntityFields.USER_ID)
|
||||
.isNotNull(LiveLocationShareAggregatedSummaryEntityFields.LAST_LOCATION_CONTENT)
|
||||
.query("isActive == true")
|
||||
.query("userId != ''")
|
||||
.query("lastLocationContent != ''")
|
||||
}
|
||||
|
||||
@ -19,10 +19,7 @@ import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import org.matrix.android.sdk.api.session.pushrules.RuleKind
|
||||
import org.matrix.android.sdk.internal.database.andIf
|
||||
import org.matrix.android.sdk.internal.database.model.PushRuleEntity
|
||||
import org.matrix.android.sdk.internal.database.model.PushRuleEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.PushRulesEntity
|
||||
import org.matrix.android.sdk.internal.database.model.PushRulesEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.PusherEntity
|
||||
|
||||
internal fun PusherEntity.Companion.where(
|
||||
@ -45,15 +42,3 @@ internal fun PushRulesEntity.Companion.where(
|
||||
.query("kindStr == $0", kind.name)
|
||||
}
|
||||
|
||||
/*
|
||||
internal fun PushRuleEntity.Companion.where(
|
||||
realm: TypedRealm,
|
||||
scope: String,
|
||||
ruleId: String
|
||||
): RealmQuery<PushRuleEntity> {
|
||||
return realm.query(PushRuleEntity::class)
|
||||
.equalTo(PushRuleEntityFields.PARENT.SCOPE, scope)
|
||||
.equalTo(PushRuleEntityFields.RULE_ID, ruleId)
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@ -133,9 +133,7 @@ internal fun RealmQuery<TimelineEventEntity>.filterTypes(filterTypes: List<Strin
|
||||
}
|
||||
|
||||
internal fun RealmList<TimelineEventEntity>.find(eventId: String): TimelineEventEntity? {
|
||||
return where()
|
||||
.equalTo(TimelineEventEntityFields.EVENT_ID, eventId)
|
||||
.findFirst()
|
||||
return firstOrNull { it.eventId == eventId }
|
||||
}
|
||||
|
||||
internal fun TimelineEventEntity.Companion.findAllInRoomWithSendStates(
|
||||
|
||||
@ -16,16 +16,14 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.database.query
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.kotlin.where
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import org.matrix.android.sdk.internal.database.andIf
|
||||
import org.matrix.android.sdk.internal.database.model.UserDraftsEntity
|
||||
import org.matrix.android.sdk.internal.database.model.UserDraftsEntityFields
|
||||
|
||||
internal fun UserDraftsEntity.Companion.where(realm: Realm, roomId: String? = null): RealmQuery<UserDraftsEntity> {
|
||||
val query = realm.where<UserDraftsEntity>()
|
||||
if (roomId != null) {
|
||||
query.equalTo(UserDraftsEntityFields.ROOM_SUMMARY_ENTITY.ROOM_ID, roomId)
|
||||
}
|
||||
return query
|
||||
internal fun UserDraftsEntity.Companion.where(realm: TypedRealm, roomId: String? = null): RealmQuery<UserDraftsEntity> {
|
||||
return realm.query(UserDraftsEntity::class)
|
||||
.andIf(roomId != null) {
|
||||
query("roomId == $0", roomId!!)
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,8 +16,6 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.room.create
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.RealmConfiguration
|
||||
import kotlinx.coroutines.TimeoutCancellationException
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.failure.MatrixError
|
||||
@ -26,10 +24,9 @@ import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
|
||||
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.awaitNotEmptyResult
|
||||
import org.matrix.android.sdk.internal.database.awaitTransaction
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||
@ -40,7 +37,6 @@ import org.matrix.android.sdk.internal.session.room.read.SetReadMarkersTask
|
||||
import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper
|
||||
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
@ -49,13 +45,11 @@ internal interface CreateRoomTask : Task<CreateRoomParams, String>
|
||||
|
||||
internal class DefaultCreateRoomTask @Inject constructor(
|
||||
private val roomAPI: RoomAPI,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
private val aliasAvailabilityChecker: RoomAliasAvailabilityChecker,
|
||||
private val directChatsHelper: DirectChatsHelper,
|
||||
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
|
||||
private val readMarkersTask: SetReadMarkersTask,
|
||||
@SessionDatabase
|
||||
private val realmConfiguration: RealmConfiguration,
|
||||
private val createRoomBodyBuilder: CreateRoomBodyBuilder,
|
||||
private val globalErrorReceiver: GlobalErrorReceiver,
|
||||
private val clock: Clock,
|
||||
@ -93,17 +87,16 @@ internal class DefaultCreateRoomTask @Inject constructor(
|
||||
val roomId = createRoomResponse.roomId
|
||||
// Wait for room to come back from the sync (but it can maybe be in the DB if the sync response is received before)
|
||||
try {
|
||||
awaitNotEmptyResult(realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
||||
realm.where(RoomSummaryEntity::class.java)
|
||||
.equalTo(RoomSummaryEntityFields.ROOM_ID, roomId)
|
||||
.equalTo(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.JOIN.name)
|
||||
awaitNotEmptyResult(realmInstance, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
||||
RoomSummaryEntity.where(realm, roomId)
|
||||
.query("membershipStr == $0", Membership.JOIN.name)
|
||||
}
|
||||
} catch (exception: TimeoutCancellationException) {
|
||||
throw CreateRoomFailure.CreatedWithTimeout(roomId)
|
||||
}
|
||||
|
||||
awaitTransaction(realmConfiguration) {
|
||||
RoomSummaryEntity.where(it, roomId).findFirst()?.lastActivityTime = clock.epochMillis()
|
||||
realmInstance.write {
|
||||
RoomSummaryEntity.where(this, roomId).first().find()?.lastActivityTime = clock.epochMillis()
|
||||
}
|
||||
|
||||
handleDirectChatCreation(roomId, createRoomBody.getDirectUserId())
|
||||
@ -113,8 +106,8 @@ internal class DefaultCreateRoomTask @Inject constructor(
|
||||
|
||||
private suspend fun handleDirectChatCreation(roomId: String, otherUserId: String?) {
|
||||
otherUserId ?: return // This is not a direct room
|
||||
monarchy.awaitTransaction { realm ->
|
||||
RoomSummaryEntity.where(realm, roomId).findFirst()?.apply {
|
||||
realmInstance.write {
|
||||
RoomSummaryEntity.where(this, roomId).first().find()?.apply {
|
||||
this.directUserId = otherUserId
|
||||
this.isDirect = true
|
||||
}
|
||||
|
||||
@ -17,76 +17,75 @@
|
||||
package org.matrix.android.sdk.internal.session.room.draft
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.createObject
|
||||
import androidx.lifecycle.asLiveData
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import org.matrix.android.sdk.BuildConfig
|
||||
import org.matrix.android.sdk.api.session.room.send.UserDraft
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.clearWith
|
||||
import org.matrix.android.sdk.internal.database.mapper.DraftMapper
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.UserDraftsEntity
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||
import org.matrix.android.sdk.internal.util.mapOptional
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DraftRepository @Inject constructor(
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
private val realmSessionProvider: RealmSessionProvider
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
) {
|
||||
|
||||
suspend fun saveDraft(roomId: String, userDraft: UserDraft) {
|
||||
monarchy.awaitTransaction {
|
||||
saveDraftInDb(it, userDraft, roomId)
|
||||
realmInstance.write {
|
||||
saveDraftInDb(this, userDraft, roomId)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deleteDraft(roomId: String) {
|
||||
monarchy.awaitTransaction {
|
||||
deleteDraftFromDb(it, roomId)
|
||||
realmInstance.write {
|
||||
deleteDraftFromDb(this, roomId)
|
||||
}
|
||||
}
|
||||
|
||||
fun getDraft(roomId: String): UserDraft? {
|
||||
return realmSessionProvider.withRealm { realm ->
|
||||
UserDraftsEntity.where(realm, roomId).findFirst()
|
||||
?.userDrafts
|
||||
?.firstOrNull()
|
||||
?.let {
|
||||
DraftMapper.map(it)
|
||||
}
|
||||
}
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return UserDraftsEntity.where(realm, roomId).first()
|
||||
.find()
|
||||
?.let { mapUserDrafts(it) }
|
||||
}
|
||||
|
||||
fun getDraftsLive(roomId: String): LiveData<Optional<UserDraft>> {
|
||||
val liveData = monarchy.findAllMappedWithChanges(
|
||||
{ UserDraftsEntity.where(it, roomId) },
|
||||
{
|
||||
it.userDrafts.map { draft ->
|
||||
DraftMapper.map(draft)
|
||||
}
|
||||
}
|
||||
)
|
||||
return Transformations.map(liveData) {
|
||||
it.firstOrNull()?.firstOrNull().toOptional()
|
||||
return realmInstance.queryFirst {
|
||||
UserDraftsEntity.where(it, roomId).first()
|
||||
}
|
||||
.mapOptional(::mapUserDrafts)
|
||||
.asLiveData()
|
||||
}
|
||||
|
||||
private fun mapUserDrafts(userDraftsEntity: UserDraftsEntity): UserDraft? {
|
||||
return userDraftsEntity.userDrafts.firstOrNull()?.let { draft ->
|
||||
DraftMapper.map(draft)
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteDraftFromDb(realm: Realm, roomId: String) {
|
||||
UserDraftsEntity.where(realm, roomId).findFirst()?.userDrafts?.clear()
|
||||
private fun deleteDraftFromDb(realm: MutableRealm, roomId: String) {
|
||||
UserDraftsEntity.where(realm, roomId).first().find()?.userDrafts?.clearWith {
|
||||
realm.delete(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveDraftInDb(realm: Realm, draft: UserDraft, roomId: String) {
|
||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
private fun saveDraftInDb(realm: MutableRealm, draft: UserDraft, roomId: String) {
|
||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).first().find()
|
||||
?: realm.copyToRealm(
|
||||
RoomSummaryEntity().apply {
|
||||
this.roomId = roomId
|
||||
}
|
||||
)
|
||||
|
||||
val userDraftsEntity = roomSummaryEntity.userDrafts
|
||||
?: realm.createObject<UserDraftsEntity>().also {
|
||||
?: realm.copyToRealm(UserDraftsEntity()).also {
|
||||
roomSummaryEntity.userDrafts = it
|
||||
}
|
||||
|
||||
|
||||
@ -17,8 +17,7 @@
|
||||
package org.matrix.android.sdk.internal.session.room.location
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import androidx.lifecycle.asLiveData
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
@ -27,16 +26,17 @@ import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareR
|
||||
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
|
||||
import org.matrix.android.sdk.api.util.Cancelable
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.mapper.LiveLocationShareAggregatedSummaryMapper
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.query.findRunningLiveInRoom
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.util.mapOptional
|
||||
|
||||
internal class DefaultLocationSharingService @AssistedInject constructor(
|
||||
@Assisted private val roomId: String,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
private val sendStaticLocationTask: SendStaticLocationTask,
|
||||
private val sendLiveLocationTask: SendLiveLocationTask,
|
||||
private val startLiveLocationShareTask: StartLiveLocationShareTask,
|
||||
@ -113,20 +113,16 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override fun getRunningLiveLocationShareSummaries(): LiveData<List<LiveLocationShareAggregatedSummary>> {
|
||||
return monarchy.findAllMappedWithChanges(
|
||||
{ LiveLocationShareAggregatedSummaryEntity.findRunningLiveInRoom(it, roomId = roomId) },
|
||||
liveLocationShareAggregatedSummaryMapper
|
||||
)
|
||||
return realmInstance.queryList(liveLocationShareAggregatedSummaryMapper) {
|
||||
LiveLocationShareAggregatedSummaryEntity.findRunningLiveInRoom(it, roomId = roomId)
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
override fun getLiveLocationShareSummary(beaconInfoEventId: String): LiveData<Optional<LiveLocationShareAggregatedSummary>> {
|
||||
return Transformations.map(
|
||||
monarchy.findAllMappedWithChanges(
|
||||
{ LiveLocationShareAggregatedSummaryEntity.where(it, roomId = roomId, eventId = beaconInfoEventId) },
|
||||
liveLocationShareAggregatedSummaryMapper
|
||||
)
|
||||
) {
|
||||
it.firstOrNull().toOptional()
|
||||
return realmInstance.queryFirst {
|
||||
LiveLocationShareAggregatedSummaryEntity.where(it, roomId = roomId, eventId = beaconInfoEventId).first()
|
||||
}
|
||||
.mapOptional(liveLocationShareAggregatedSummaryMapper::map)
|
||||
.asLiveData()
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,19 +16,17 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.room.membership
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.kotlin.createObject
|
||||
import kotlinx.coroutines.TimeoutCancellationException
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider
|
||||
import org.matrix.android.sdk.internal.crypto.DeviceListManager
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.awaitNotEmptyResult
|
||||
import org.matrix.android.sdk.internal.database.mapper.toEntity
|
||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.EventInsertType
|
||||
import org.matrix.android.sdk.internal.database.model.RoomEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
|
||||
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
@ -41,7 +39,6 @@ import org.matrix.android.sdk.internal.session.room.RoomDataSource
|
||||
import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater
|
||||
import org.matrix.android.sdk.internal.session.sync.SyncTokenStore
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -57,7 +54,7 @@ internal interface LoadRoomMembersTask : Task<LoadRoomMembersTask.Params, Unit>
|
||||
|
||||
internal class DefaultLoadRoomMembersTask @Inject constructor(
|
||||
private val roomAPI: RoomAPI,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
private val roomDataSource: RoomDataSource,
|
||||
private val syncTokenStore: SyncTokenStore,
|
||||
private val roomSummaryUpdater: RoomSummaryUpdater,
|
||||
@ -78,10 +75,9 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(
|
||||
|
||||
private suspend fun waitPreviousRequestToFinish(params: LoadRoomMembersTask.Params) {
|
||||
try {
|
||||
awaitNotEmptyResult(monarchy.realmConfiguration, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
||||
realm.where(RoomEntity::class.java)
|
||||
.equalTo(RoomEntityFields.ROOM_ID, params.roomId)
|
||||
.equalTo(RoomEntityFields.MEMBERS_LOAD_STATUS_STR, RoomMembersLoadStatusType.LOADED.name)
|
||||
awaitNotEmptyResult(realmInstance, TimeUnit.MINUTES.toMillis(1L)) { realm ->
|
||||
RoomEntity.where(realm, roomId = params.roomId)
|
||||
.query("membersLoadStatusStr == $0", RoomMembersLoadStatusType.LOADED.name)
|
||||
}
|
||||
} catch (exception: TimeoutCancellationException) {
|
||||
// Timeout, do the request anyway (?)
|
||||
@ -109,7 +105,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(
|
||||
private suspend fun insertInDb(response: RoomMembersResponse, roomId: String) {
|
||||
val chunks = response.roomMemberEvents.chunked(500)
|
||||
chunks.forEach { roomMemberEvents ->
|
||||
monarchy.awaitTransaction { realm ->
|
||||
realmInstance.write {
|
||||
Timber.v("Insert ${roomMemberEvents.size} member events in room $roomId")
|
||||
// We ignore all the already known members
|
||||
val now = clock.epochMillis()
|
||||
@ -118,9 +114,9 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(
|
||||
continue
|
||||
}
|
||||
val ageLocalTs = now - (roomMemberEvent.unsignedData?.age ?: 0)
|
||||
val eventEntity = roomMemberEvent.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(realm, EventInsertType.PAGINATION)
|
||||
val eventEntity = roomMemberEvent.toEntity(roomId, SendState.SYNCED, ageLocalTs).copyToRealmOrIgnore(this, EventInsertType.PAGINATION)
|
||||
CurrentStateEventEntity.getOrCreate(
|
||||
realm,
|
||||
this,
|
||||
roomId,
|
||||
roomMemberEvent.stateKey,
|
||||
roomMemberEvent.type
|
||||
@ -128,15 +124,14 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(
|
||||
eventId = roomMemberEvent.eventId
|
||||
root = eventEntity
|
||||
}
|
||||
roomMemberEventHandler.handle(realm, roomId, roomMemberEvent, false)
|
||||
roomMemberEventHandler.handle(this, roomId, roomMemberEvent, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
monarchy.awaitTransaction { realm ->
|
||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
realmInstance.write {
|
||||
val roomEntity = RoomEntity.getOrCreate(this, roomId)
|
||||
roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADED
|
||||
roomSummaryUpdater.update(realm, roomId, updateMembers = true)
|
||||
roomSummaryUpdater.update(this, roomId, updateMembers = true)
|
||||
}
|
||||
if (cryptoSessionInfoProvider.isRoomEncrypted(roomId)) {
|
||||
deviceListManager.onRoomMembersLoadedFor(roomId)
|
||||
@ -144,8 +139,8 @@ internal class DefaultLoadRoomMembersTask @Inject constructor(
|
||||
}
|
||||
|
||||
private suspend fun setRoomMembersLoadStatus(roomId: String, status: RoomMembersLoadStatusType) {
|
||||
monarchy.awaitTransaction { realm ->
|
||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId)
|
||||
realmInstance.write {
|
||||
val roomEntity = RoomEntity.getOrCreate(this, roomId)
|
||||
roomEntity.membersLoadStatus = status
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,22 +17,16 @@
|
||||
package org.matrix.android.sdk.internal.session.room.notification
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import org.matrix.android.sdk.api.session.pushrules.RuleScope
|
||||
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
|
||||
import org.matrix.android.sdk.api.session.room.notification.RoomPushRuleService
|
||||
import org.matrix.android.sdk.internal.database.model.PushRuleEntity
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
|
||||
internal class DefaultRoomPushRuleService @AssistedInject constructor(
|
||||
@Assisted private val roomId: String,
|
||||
private val setRoomNotificationStateTask: SetRoomNotificationStateTask,
|
||||
@SessionDatabase private val monarchy: Monarchy
|
||||
private val roomPushRuleDataSource: RoomPushRuleDataSource,
|
||||
) :
|
||||
RoomPushRuleService {
|
||||
|
||||
@ -42,26 +36,10 @@ internal class DefaultRoomPushRuleService @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override fun getLiveRoomNotificationState(): LiveData<RoomNotificationState> {
|
||||
return Transformations.map(getPushRuleForRoom()) {
|
||||
it?.toRoomNotificationState() ?: RoomNotificationState.ALL_MESSAGES
|
||||
}
|
||||
return roomPushRuleDataSource.getLiveRoomNotificationState(roomId)
|
||||
}
|
||||
|
||||
override suspend fun setRoomNotificationState(roomNotificationState: RoomNotificationState) {
|
||||
setRoomNotificationStateTask.execute(SetRoomNotificationStateTask.Params(roomId, roomNotificationState))
|
||||
}
|
||||
|
||||
private fun getPushRuleForRoom(): LiveData<RoomPushRule?> {
|
||||
val liveData = monarchy.findAllMappedWithChanges(
|
||||
{ realm ->
|
||||
PushRuleEntity.where(realm, scope = RuleScope.GLOBAL, ruleId = roomId)
|
||||
},
|
||||
{ result ->
|
||||
result.toRoomPushRule()
|
||||
}
|
||||
)
|
||||
return Transformations.map(liveData) { results ->
|
||||
results.firstOrNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.room.notification
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.asLiveData
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.query.RealmSingleQuery
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.matrix.android.sdk.api.session.pushrules.RuleScope
|
||||
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.model.PushRulesEntity
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class RoomPushRuleDataSource @Inject constructor(@SessionDatabase private val realmInstance: RealmInstance) {
|
||||
|
||||
suspend fun getCurrentRoomPushRule(roomId: String): RoomPushRule? {
|
||||
val realm = realmInstance.getRealm()
|
||||
return queryPushRulesEntity(realm, roomId)
|
||||
.find()
|
||||
?.toRoomPushRule(ruleId = roomId)
|
||||
}
|
||||
|
||||
fun getLiveRoomNotificationState(roomId: String): LiveData<RoomNotificationState> {
|
||||
return realmInstance.queryFirst {
|
||||
queryPushRulesEntity(it, roomId)
|
||||
}.map {
|
||||
val pushRulesEntity = it.getOrNull()
|
||||
pushRulesEntity
|
||||
?.toRoomPushRule(ruleId = roomId)
|
||||
?.toRoomNotificationState()
|
||||
?: RoomNotificationState.ALL_MESSAGES
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
private fun queryPushRulesEntity(realm: TypedRealm, roomId: String): RealmSingleQuery<PushRulesEntity> {
|
||||
return realm.query(PushRulesEntity::class)
|
||||
.query("scope == $0", RuleScope.GLOBAL)
|
||||
.query("ANY pushRules.ruleId == $0", roomId)
|
||||
.first()
|
||||
}
|
||||
}
|
||||
@ -25,20 +25,20 @@ import org.matrix.android.sdk.api.session.pushrules.rest.PushRule
|
||||
import org.matrix.android.sdk.api.session.pushrules.toJson
|
||||
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
|
||||
import org.matrix.android.sdk.internal.database.mapper.PushRulesMapper
|
||||
import org.matrix.android.sdk.internal.database.model.PushRuleEntity
|
||||
import org.matrix.android.sdk.internal.database.model.PushRulesEntity
|
||||
|
||||
internal fun PushRuleEntity.toRoomPushRule(): RoomPushRule? {
|
||||
val kind = parent?.firstOrNull()?.kind
|
||||
internal fun PushRulesEntity.toRoomPushRule(ruleId: String): RoomPushRule? {
|
||||
val pushRuleEntity = pushRules.firstOrNull { it.ruleId == ruleId } ?: return null
|
||||
val pushRule = when (kind) {
|
||||
RuleSetKey.OVERRIDE -> {
|
||||
PushRulesMapper.map(this)
|
||||
PushRulesMapper.map(pushRuleEntity)
|
||||
}
|
||||
RuleSetKey.ROOM -> {
|
||||
PushRulesMapper.mapRoomRule(this)
|
||||
PushRulesMapper.mapRoomRule(pushRuleEntity)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
return if (pushRule == null || kind == null) {
|
||||
return if (pushRule == null) {
|
||||
null
|
||||
} else {
|
||||
RoomPushRule(kind, pushRule)
|
||||
|
||||
@ -16,13 +16,7 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.room.notification
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.Realm
|
||||
import org.matrix.android.sdk.api.session.pushrules.RuleScope
|
||||
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
|
||||
import org.matrix.android.sdk.internal.database.model.PushRuleEntity
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.session.pushers.AddPushRuleTask
|
||||
import org.matrix.android.sdk.internal.session.pushers.RemovePushRuleTask
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
@ -36,16 +30,14 @@ internal interface SetRoomNotificationStateTask : Task<SetRoomNotificationStateT
|
||||
}
|
||||
|
||||
internal class DefaultSetRoomNotificationStateTask @Inject constructor(
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
private val roomPushRuleDataSource: RoomPushRuleDataSource,
|
||||
private val removePushRuleTask: RemovePushRuleTask,
|
||||
private val addPushRuleTask: AddPushRuleTask
|
||||
) :
|
||||
SetRoomNotificationStateTask {
|
||||
|
||||
override suspend fun execute(params: SetRoomNotificationStateTask.Params) {
|
||||
val currentRoomPushRule = Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
PushRuleEntity.where(it, scope = RuleScope.GLOBAL, ruleId = params.roomId).findFirst()?.toRoomPushRule()
|
||||
}
|
||||
val currentRoomPushRule = roomPushRuleDataSource.getCurrentRoomPushRule(params.roomId)
|
||||
if (currentRoomPushRule != null) {
|
||||
removePushRuleTask.execute(RemovePushRuleTask.Params(currentRoomPushRule.kind, currentRoomPushRule.rule.ruleId))
|
||||
}
|
||||
|
||||
@ -17,15 +17,15 @@
|
||||
package org.matrix.android.sdk.internal.session.room.read
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import androidx.lifecycle.asLiveData
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
|
||||
import org.matrix.android.sdk.api.session.room.read.ReadService
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.mapper.ReadReceiptsSummaryMapper
|
||||
import org.matrix.android.sdk.internal.database.model.ReadMarkerEntity
|
||||
import org.matrix.android.sdk.internal.database.model.ReadReceiptEntity
|
||||
@ -34,10 +34,11 @@ import org.matrix.android.sdk.internal.database.query.isEventRead
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.util.mapOptional
|
||||
|
||||
internal class DefaultReadService @AssistedInject constructor(
|
||||
@Assisted private val roomId: String,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
private val setReadMarkersTask: SetReadMarkersTask,
|
||||
private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper,
|
||||
@UserId private val userId: String
|
||||
@ -68,47 +69,40 @@ internal class DefaultReadService @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override fun isEventRead(eventId: String): Boolean {
|
||||
return isEventRead(monarchy.realmConfiguration, userId, roomId, eventId)
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return isEventRead(realm, userId, roomId, eventId)
|
||||
}
|
||||
|
||||
override fun getReadMarkerLive(): LiveData<Optional<String>> {
|
||||
val liveRealmData = monarchy.findAllMappedWithChanges(
|
||||
{ ReadMarkerEntity.where(it, roomId) },
|
||||
{ it.eventId }
|
||||
)
|
||||
return Transformations.map(liveRealmData) {
|
||||
it.firstOrNull().toOptional()
|
||||
return realmInstance.queryFirst {
|
||||
ReadMarkerEntity.where(it, roomId).first()
|
||||
}
|
||||
.mapOptional { it.eventId }
|
||||
.asLiveData()
|
||||
}
|
||||
|
||||
override fun getMyReadReceiptLive(): LiveData<Optional<String>> {
|
||||
val liveRealmData = monarchy.findAllMappedWithChanges(
|
||||
{ ReadReceiptEntity.where(it, roomId = roomId, userId = userId) },
|
||||
{ it.eventId }
|
||||
)
|
||||
return Transformations.map(liveRealmData) {
|
||||
it.firstOrNull().toOptional()
|
||||
return realmInstance.queryFirst {
|
||||
ReadReceiptEntity.where(it, roomId = roomId, userId = userId).first()
|
||||
}
|
||||
.mapOptional { it.eventId }
|
||||
.asLiveData()
|
||||
}
|
||||
|
||||
override fun getUserReadReceipt(userId: String): String? {
|
||||
var eventId: String? = null
|
||||
monarchy.doWithRealm {
|
||||
eventId = ReadReceiptEntity.where(it, roomId = roomId, userId = userId)
|
||||
.findFirst()
|
||||
?.eventId
|
||||
}
|
||||
return eventId
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return ReadReceiptEntity.where(realm, roomId = roomId, userId = userId)
|
||||
.first()
|
||||
.find()
|
||||
?.eventId
|
||||
}
|
||||
|
||||
override fun getEventReadReceiptsLive(eventId: String): LiveData<List<ReadReceipt>> {
|
||||
val liveRealmData = monarchy.findAllMappedWithChanges(
|
||||
{ ReadReceiptsSummaryEntity.where(it, eventId) },
|
||||
{ readReceiptsSummaryMapper.map(it) }
|
||||
)
|
||||
return Transformations.map(liveRealmData) {
|
||||
it.firstOrNull().orEmpty()
|
||||
}
|
||||
return realmInstance.queryFirst {
|
||||
ReadReceiptsSummaryEntity.where(it, eventId)
|
||||
}.map {
|
||||
readReceiptsSummaryMapper.map(it.getOrNull())
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
private fun ReadService.MarkAsReadParams.forceReadMarker(): Boolean {
|
||||
|
||||
@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.matrix.android.sdk.internal.session.room.relation.threads
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummaryUpdateType
|
||||
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.helper.createOrUpdate
|
||||
import org.matrix.android.sdk.internal.database.model.RoomEntity
|
||||
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntity
|
||||
@ -32,7 +32,6 @@ import org.matrix.android.sdk.internal.session.room.RoomAPI
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationResponse
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||
import org.matrix.android.sdk.internal.util.time.Clock
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@ -53,7 +52,7 @@ internal interface FetchThreadSummariesTask : Task<FetchThreadSummariesTask.Para
|
||||
internal class DefaultFetchThreadSummariesTask @Inject constructor(
|
||||
private val roomAPI: RoomAPI,
|
||||
private val globalErrorReceiver: GlobalErrorReceiver,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
private val cryptoService: DefaultCryptoService,
|
||||
@UserId private val userId: String,
|
||||
private val clock: Clock,
|
||||
@ -82,8 +81,8 @@ internal class DefaultFetchThreadSummariesTask @Inject constructor(
|
||||
params: FetchThreadSummariesTask.Params
|
||||
): Result {
|
||||
val rootThreadList = response.events
|
||||
monarchy.awaitTransaction { realm ->
|
||||
val roomEntity = RoomEntity.where(realm, roomId = params.roomId).findFirst() ?: return@awaitTransaction
|
||||
realmInstance.write {
|
||||
val roomEntity = RoomEntity.where(this, roomId = params.roomId).first().find() ?: return@write
|
||||
|
||||
val roomMemberContentsByUser = HashMap<String, RoomMemberContent?>()
|
||||
for (rootThreadEvent in rootThreadList) {
|
||||
@ -93,7 +92,7 @@ internal class DefaultFetchThreadSummariesTask @Inject constructor(
|
||||
|
||||
ThreadSummaryEntity.createOrUpdate(
|
||||
threadSummaryType = ThreadSummaryUpdateType.REPLACE,
|
||||
realm = realm,
|
||||
realm = this,
|
||||
roomId = params.roomId,
|
||||
rootThreadEvent = rootThreadEvent,
|
||||
roomMemberContentsByUser = roomMemberContentsByUser,
|
||||
|
||||
@ -16,11 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.room.summary
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.createObject
|
||||
import io.realm.kotlin.deleteFromRealm
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
@ -48,7 +45,6 @@ import org.matrix.android.sdk.internal.database.clearWith
|
||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntity
|
||||
@ -60,8 +56,6 @@ import org.matrix.android.sdk.internal.database.query.getOrNull
|
||||
import org.matrix.android.sdk.internal.database.query.isEventRead
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.extensions.clearWith
|
||||
import org.matrix.android.sdk.internal.extensions.realm
|
||||
import org.matrix.android.sdk.internal.query.process
|
||||
import org.matrix.android.sdk.internal.session.room.RoomAvatarResolver
|
||||
import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataDataSource
|
||||
@ -372,17 +366,14 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||
val parent = RoomSummaryEntity.where(realm, entry.key.roomId).first().find()
|
||||
if (parent != null) {
|
||||
val flattenParentsIds = (flattenSpaceParents[parent.roomId] ?: emptyList()) + listOf(parent.roomId)
|
||||
|
||||
entry.value.forEach { child ->
|
||||
RoomSummaryEntity.where(realm, child.roomId).first().find()?.let { childSum ->
|
||||
childSum.directParentNames.add(parent.displayName())
|
||||
|
||||
if (childSum.flattenParentIds == null) {
|
||||
childSum.flattenParentIds = ""
|
||||
parent.displayName()?.also { directParentName ->
|
||||
childSum.directParentNames.add(directParentName)
|
||||
}
|
||||
flattenParentsIds.forEach {
|
||||
if (childSum.flattenParentIds?.contains(it) != true) {
|
||||
childSum.flattenParentIds += "|$it"
|
||||
if (!childSum.flattenParentIds.contains(it)) {
|
||||
childSum.flattenParentIds.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -400,7 +391,7 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||
val relatedSpaces = lookupMap.keys
|
||||
.filter { it.roomType == RoomType.SPACE }
|
||||
.filter {
|
||||
dmRoom.otherMemberIds.toList().intersect(it.otherMemberIds.toList()).isNotEmpty()
|
||||
dmRoom.otherMemberIds.toSet().intersect(it.otherMemberIds.toSet()).isNotEmpty()
|
||||
}
|
||||
.map { it.roomId }
|
||||
.distinct()
|
||||
@ -412,7 +403,7 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||
}.distinct()
|
||||
if (flattenRelated.isNotEmpty()) {
|
||||
// we keep real m.child/m.parent relations and add the one for common memberships
|
||||
dmRoom.flattenParentIds += "|${flattenRelated.joinToString("|")}|"
|
||||
dmRoom.flattenParentIds += flattenRelated
|
||||
}
|
||||
// Timber.v("## SPACES: flatten of ${dmRoom.otherMemberIds.joinToString(",")} is ${dmRoom.flattenParentIds}")
|
||||
}
|
||||
@ -429,7 +420,7 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||
realm.query(RoomSummaryEntity::class)
|
||||
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, listOf(Membership.JOIN))
|
||||
.query("roomType != $0", RoomType.SPACE)
|
||||
.query("flattenParentIds CONTAINS $0", space.roomId)
|
||||
.query("ANY flattenParentIds == $0", space.roomId)
|
||||
.find().forEach {
|
||||
highlightCount += it.highlightCount
|
||||
notificationCount += it.notificationCount
|
||||
|
||||
@ -17,30 +17,26 @@
|
||||
package org.matrix.android.sdk.internal.session.room.threads
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import androidx.lifecycle.asLiveData
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.realm.Realm
|
||||
import org.matrix.android.sdk.api.session.room.threads.ThreadsService
|
||||
import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummary
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.helper.enhanceWithEditions
|
||||
import org.matrix.android.sdk.internal.database.helper.findAllThreadsForRoomId
|
||||
import org.matrix.android.sdk.internal.database.mapper.ThreadSummaryMapper
|
||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
||||
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntity
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadSummariesTask
|
||||
import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask
|
||||
|
||||
internal class DefaultThreadsService @AssistedInject constructor(
|
||||
@Assisted private val roomId: String,
|
||||
@UserId private val userId: String,
|
||||
private val fetchThreadTimelineTask: FetchThreadTimelineTask,
|
||||
private val fetchThreadSummariesTask: FetchThreadSummariesTask,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
private val timelineEventMapper: TimelineEventMapper,
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
private val threadSummaryMapper: ThreadSummaryMapper
|
||||
) : ThreadsService {
|
||||
|
||||
@ -50,25 +46,22 @@ internal class DefaultThreadsService @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override fun getAllThreadSummariesLive(): LiveData<List<ThreadSummary>> {
|
||||
return monarchy.findAllMappedWithChanges(
|
||||
{ ThreadSummaryEntity.findAllThreadsForRoomId(it, roomId = roomId) },
|
||||
{
|
||||
threadSummaryMapper.map(roomId, it)
|
||||
}
|
||||
)
|
||||
return realmInstance.queryList({ threadSummaryMapper.map(roomId, it) }) {
|
||||
ThreadSummaryEntity.findAllThreadsForRoomId(it, roomId = roomId)
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
override fun getAllThreadSummaries(): List<ThreadSummary> {
|
||||
return monarchy.fetchAllMappedSync(
|
||||
{ ThreadSummaryEntity.findAllThreadsForRoomId(it, roomId = roomId) },
|
||||
{ threadSummaryMapper.map(roomId, it) }
|
||||
)
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return ThreadSummaryEntity.findAllThreadsForRoomId(realm, roomId = roomId).find()
|
||||
.map {
|
||||
threadSummaryMapper.map(roomId, it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun enhanceThreadWithEditions(threads: List<ThreadSummary>): List<ThreadSummary> {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
threads.enhanceWithEditions(it, roomId)
|
||||
}
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return threads.enhanceWithEditions(realm, roomId)
|
||||
}
|
||||
|
||||
override suspend fun fetchThreadTimeline(rootThreadEventId: String, from: String, limit: Int) {
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.sync.handler.room
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import org.matrix.android.sdk.internal.database.model.ReadMarkerEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
@ -26,7 +26,7 @@ import javax.inject.Inject
|
||||
|
||||
internal class RoomFullyReadHandler @Inject constructor() {
|
||||
|
||||
fun handle(realm: Realm, roomId: String, content: FullyReadContent?) {
|
||||
fun handle(realm: MutableRealm, roomId: String, content: FullyReadContent?) {
|
||||
if (content == null) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.sync.handler.room
|
||||
|
||||
import dagger.Lazy
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.createObject
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||
@ -40,6 +39,7 @@ import org.matrix.android.sdk.api.session.sync.model.RoomSync
|
||||
import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse
|
||||
import org.matrix.android.sdk.api.settings.LightweightSettingsStorage
|
||||
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
|
||||
import org.matrix.android.sdk.internal.database.clearWith
|
||||
import org.matrix.android.sdk.internal.database.helper.addIfNecessary
|
||||
import org.matrix.android.sdk.internal.database.helper.addTimelineEvent
|
||||
import org.matrix.android.sdk.internal.database.helper.createOrUpdate
|
||||
@ -65,7 +65,6 @@ import org.matrix.android.sdk.internal.database.query.getOrNull
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.extensions.clearWith
|
||||
import org.matrix.android.sdk.internal.session.StreamEventsManager
|
||||
import org.matrix.android.sdk.internal.session.events.getFixedRoomMemberContent
|
||||
import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource
|
||||
@ -233,7 +232,7 @@ internal class RoomSyncHandler @Inject constructor(
|
||||
val roomEntity = RoomEntity.getOrCreate(realm, roomId)
|
||||
|
||||
if (roomEntity.membership == Membership.INVITE) {
|
||||
roomEntity.chunks.deleteAllFromRealm()
|
||||
realm.delete(roomEntity.chunks)
|
||||
}
|
||||
roomEntity.membership = Membership.JOIN
|
||||
|
||||
@ -359,10 +358,10 @@ internal class RoomSyncHandler @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
val leftMember = RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst()
|
||||
val leftMember = RoomMemberSummaryEntity.where(realm, roomId, userId).first().find()
|
||||
val membership = leftMember?.membership ?: Membership.LEAVE
|
||||
roomEntity.membership = membership
|
||||
roomEntity.chunks.clearWith { it.deleteOnCascade(deleteStateEvents = true, canDeleteRoot = true) }
|
||||
roomEntity.chunks.clearWith { realm.deleteOnCascade(it, deleteStateEvents = true, canDeleteRoot = true) }
|
||||
roomTypingUsersHandler.handle(realm, roomId, null)
|
||||
roomChangeMembershipStateDataSource.setMembershipFromSync(roomId, Membership.LEAVE)
|
||||
roomSummaryUpdater.update(realm, roomId, membership, roomSync.summary, roomSync.unreadNotifications)
|
||||
@ -386,12 +385,14 @@ internal class RoomSyncHandler @Inject constructor(
|
||||
} else {
|
||||
// Delete all chunks of the room in case of gap.
|
||||
ChunkEntity.findAll(realm, roomId).forEach {
|
||||
it.deleteOnCascade(deleteStateEvents = false, canDeleteRoot = true)
|
||||
}
|
||||
realm.createObject<ChunkEntity>().apply {
|
||||
this.prevToken = prevToken
|
||||
this.isLastForward = true
|
||||
realm.deleteOnCascade(it, deleteStateEvents = false, canDeleteRoot = true)
|
||||
}
|
||||
realm.copyToRealm(
|
||||
ChunkEntity().apply {
|
||||
this.prevToken = prevToken
|
||||
this.isLastForward = true
|
||||
}
|
||||
)
|
||||
}
|
||||
val eventIds = ArrayList<String>(eventList.size)
|
||||
val roomMemberContentsByUser = HashMap<String, RoomMemberContent?>()
|
||||
@ -444,6 +445,7 @@ internal class RoomSyncHandler @Inject constructor(
|
||||
}
|
||||
|
||||
val timelineEventAdded = chunkEntity.addTimelineEvent(
|
||||
realm = realm,
|
||||
roomId = roomId,
|
||||
eventEntity = eventEntity,
|
||||
direction = PaginationDirection.FORWARDS,
|
||||
@ -491,14 +493,14 @@ internal class RoomSyncHandler @Inject constructor(
|
||||
}
|
||||
}
|
||||
// Finally delete the local echo
|
||||
sendingEventEntity.deleteOnCascade(true)
|
||||
realm.deleteOnCascade(sendingEventEntity, true)
|
||||
} else {
|
||||
Timber.v("Can't find corresponding local echo for tx:$it")
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle deletion of [stuck] local echos if needed
|
||||
deleteLocalEchosIfNeeded(insertType, roomEntity, eventList)
|
||||
deleteLocalEchosIfNeeded(realm, insertType, roomEntity, eventList)
|
||||
if (lightweightSettingsStorage.areThreadMessagesEnabled()) {
|
||||
optimizedThreadSummaryMap.updateThreadSummaryIfNeeded(
|
||||
roomId = roomId,
|
||||
@ -625,7 +627,7 @@ internal class RoomSyncHandler @Inject constructor(
|
||||
* While we cannot know when a specific event arrived from the pagination (no transactionId included), after each room /sync
|
||||
* we clear all SENT events, and we are sure that we will receive it from /sync or pagination
|
||||
*/
|
||||
private fun deleteLocalEchosIfNeeded(insertType: EventInsertType, roomEntity: RoomEntity, eventList: List<Event>) {
|
||||
private fun deleteLocalEchosIfNeeded(realm: MutableRealm, insertType: EventInsertType, roomEntity: RoomEntity, eventList: List<Event>) {
|
||||
// Skip deletion if we are on initial sync
|
||||
if (insertType == EventInsertType.INITIAL_SYNC) return
|
||||
// Skip deletion if there are no timeline events or there is no event received from the current user
|
||||
@ -634,7 +636,7 @@ internal class RoomSyncHandler @Inject constructor(
|
||||
timelineEvent.root?.sendState == SendState.SENT
|
||||
}.forEach {
|
||||
roomEntity.sendingTimelineEvents.remove(it)
|
||||
it.deleteOnCascade(true)
|
||||
realm.deleteOnCascade(it, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,21 +16,19 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.sync.handler.room
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import org.matrix.android.sdk.api.session.room.model.tag.RoomTagContent
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomTagEntity
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class RoomTagHandler @Inject constructor() {
|
||||
|
||||
fun handle(realm: Realm, roomId: String, content: RoomTagContent?) {
|
||||
fun handle(realm: MutableRealm, roomId: String, content: RoomTagContent?) {
|
||||
if (content == null) {
|
||||
return
|
||||
}
|
||||
val tags = content.tags.entries.map { (tagName, params) ->
|
||||
RoomTagEntity(tagName, params["order"] as? Double)
|
||||
Pair(tagName, params["order"] as? Double)
|
||||
}
|
||||
RoomSummaryEntity.getOrCreate(realm, roomId).updateTags(tags)
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.sync.handler.room
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import org.matrix.android.sdk.api.session.room.sender.SenderInfo
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
||||
@ -29,7 +29,7 @@ internal class RoomTypingUsersHandler @Inject constructor(
|
||||
) {
|
||||
|
||||
// TODO This could be handled outside of the Realm transaction. Use the new aggregator?
|
||||
fun handle(realm: Realm, roomId: String, ephemeralResult: RoomSyncHandler.EphemeralResult?) {
|
||||
fun handle(realm: MutableRealm, roomId: String, ephemeralResult: RoomSyncHandler.EphemeralResult?) {
|
||||
val roomMemberHelper = RoomMemberHelper(realm, roomId)
|
||||
val typingIds = ephemeralResult?.typingUserIds?.filter { it != userId }.orEmpty()
|
||||
val senderInfo = typingIds.map { userId ->
|
||||
|
||||
@ -16,8 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.sync.handler.room
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.where
|
||||
import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult
|
||||
import org.matrix.android.sdk.api.session.events.model.Content
|
||||
@ -38,6 +38,7 @@ import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
|
||||
import org.matrix.android.sdk.api.settings.LightweightSettingsStorage
|
||||
import org.matrix.android.sdk.api.util.JsonDict
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
||||
import org.matrix.android.sdk.internal.database.mapper.EventMapper
|
||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||
@ -63,7 +64,7 @@ import javax.inject.Inject
|
||||
*/
|
||||
internal class ThreadsAwarenessHandler @Inject constructor(
|
||||
private val permalinkFactory: PermalinkFactory,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
private val lightweightSettingsStorage: LightweightSettingsStorage,
|
||||
private val getEventTask: GetEventTask,
|
||||
private val clock: Clock,
|
||||
@ -98,21 +99,20 @@ internal class ThreadsAwarenessHandler @Inject constructor(
|
||||
* @param eventList a list with the events to examine
|
||||
*/
|
||||
suspend fun fetchRootThreadEventsIfNeeded(eventList: List<Event>) {
|
||||
if (eventList.isNullOrEmpty()) return
|
||||
if (eventList.isEmpty()) return
|
||||
|
||||
val threadsToFetch = emptyMap<String, String>().toMutableMap()
|
||||
Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
||||
eventList.asSequence()
|
||||
.filter {
|
||||
isThreadEvent(it) && it.roomId != null
|
||||
}.mapNotNull { event ->
|
||||
getRootThreadEventId(event)?.let {
|
||||
Pair(it, event.roomId!!)
|
||||
}
|
||||
}.forEach { (rootThreadEventId, roomId) ->
|
||||
EventEntity.where(realm, rootThreadEventId).findFirst() ?: run { threadsToFetch[rootThreadEventId] = roomId }
|
||||
val realm = realmInstance.getRealm()
|
||||
eventList.asSequence()
|
||||
.filter {
|
||||
isThreadEvent(it) && it.roomId != null
|
||||
}.mapNotNull { event ->
|
||||
getRootThreadEventId(event)?.let {
|
||||
Pair(it, event.roomId!!)
|
||||
}
|
||||
}
|
||||
}.forEach { (rootThreadEventId, roomId) ->
|
||||
EventEntity.where(realm, rootThreadEventId).first().find() ?: run { threadsToFetch[rootThreadEventId] = roomId }
|
||||
}
|
||||
fetchThreadsEvents(threadsToFetch)
|
||||
}
|
||||
|
||||
@ -126,12 +126,12 @@ internal class ThreadsAwarenessHandler @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
if (eventEntityList.isNullOrEmpty()) return
|
||||
if (eventEntityList.isEmpty()) return
|
||||
|
||||
// Transaction should be done on its own thread, like below
|
||||
monarchy.awaitTransaction { realm ->
|
||||
realmInstance.write {
|
||||
eventEntityList.forEach {
|
||||
it.copyToRealmOrIgnore(realm, EventInsertType.INCREMENTAL_SYNC)
|
||||
it.copyToRealmOrIgnore(this, EventInsertType.INCREMENTAL_SYNC)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,7 +159,7 @@ internal class ThreadsAwarenessHandler @Inject constructor(
|
||||
* @return The content to inject in the roomSyncHandler live events
|
||||
*/
|
||||
fun makeEventThreadAware(
|
||||
realm: Realm,
|
||||
realm: MutableRealm,
|
||||
roomId: String?,
|
||||
event: Event?,
|
||||
eventEntity: EventEntity? = null
|
||||
@ -217,7 +217,7 @@ internal class ThreadsAwarenessHandler @Inject constructor(
|
||||
* @return The content to inject in the roomSyncHandler live events
|
||||
*/
|
||||
private fun handleRootThreadEventsIfNeeded(
|
||||
realm: Realm,
|
||||
realm: MutableRealm,
|
||||
roomId: String,
|
||||
eventEntity: EventEntity?,
|
||||
event: Event
|
||||
@ -244,7 +244,7 @@ internal class ThreadsAwarenessHandler @Inject constructor(
|
||||
* @return The content to inject in the roomSyncHandler live events
|
||||
*/
|
||||
private fun handleEventsThatRelatesTo(
|
||||
realm: Realm,
|
||||
realm: MutableRealm,
|
||||
roomId: String,
|
||||
event: Event,
|
||||
eventBody: String,
|
||||
@ -364,7 +364,7 @@ internal class ThreadsAwarenessHandler @Inject constructor(
|
||||
return updateEventEntity(event, eventEntity, eventPayload, messageTextContent)
|
||||
}
|
||||
|
||||
private fun eventThatRelatesTo(realm: Realm, currentEventId: String, rootThreadEventId: String): List<EventEntity>? {
|
||||
private fun eventThatRelatesTo(realm: TypedRealm, currentEventId: String, rootThreadEventId: String): List<EventEntity>? {
|
||||
val threadList = realm.where<EventEntity>()
|
||||
.beginGroup()
|
||||
.equalTo(EventEntityFields.ROOT_THREAD_EVENT_ID, rootThreadEventId)
|
||||
@ -383,8 +383,8 @@ internal class ThreadsAwarenessHandler @Inject constructor(
|
||||
* Try to get the event form the local DB, if the event does not exist null
|
||||
* will be returned.
|
||||
*/
|
||||
private fun getEventFromDB(realm: Realm, eventId: String): Event? {
|
||||
val eventEntity = EventEntity.where(realm, eventId = eventId).findFirst() ?: return null
|
||||
private fun getEventFromDB(realm: TypedRealm, eventId: String): Event? {
|
||||
val eventEntity = EventEntity.where(realm, eventId = eventId).first().find() ?: return null
|
||||
return EventMapper.map(eventEntity)
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
package org.matrix.android.sdk.internal.session.sync.parsing
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes
|
||||
import org.matrix.android.sdk.api.session.room.model.tag.RoomTagContent
|
||||
@ -37,7 +38,7 @@ internal class RoomSyncAccountDataHandler @Inject constructor(
|
||||
private val roomFullyReadHandler: RoomFullyReadHandler
|
||||
) {
|
||||
|
||||
fun handle(realm: Realm, roomId: String, accountData: RoomSyncAccountData) {
|
||||
fun handle(realm: MutableRealm, roomId: String, accountData: RoomSyncAccountData) {
|
||||
if (accountData.events.isNullOrEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user