mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Merge pull request #5330 from vector-im/feature/fga/more_realm_fixing
Feature/fga/more realm fixing
This commit is contained in:
commit
71aac37ec7
22 changed files with 142 additions and 89 deletions
1
changelog.d/5330.misc
Normal file
1
changelog.d/5330.misc
Normal file
|
@ -0,0 +1 @@
|
|||
Continue improving realm usage.
|
1
changelog.d/5330.sdk
Normal file
1
changelog.d/5330.sdk
Normal file
|
@ -0,0 +1 @@
|
|||
Change name of getTimeLineEvent and getTimeLineEventLive methods to getTimelineEvent and getTimelineEventLive.
|
|
@ -58,9 +58,9 @@ class FlowRoom(private val room: Room) {
|
|||
}
|
||||
|
||||
fun liveTimelineEvent(eventId: String): Flow<Optional<TimelineEvent>> {
|
||||
return room.getTimeLineEventLive(eventId).asFlow()
|
||||
return room.getTimelineEventLive(eventId).asFlow()
|
||||
.startWith(room.coroutineDispatchers.io) {
|
||||
room.getTimeLineEvent(eventId).toOptional()
|
||||
room.getTimelineEvent(eventId).toOptional()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ class PreShareKeysTest : InstrumentedTest {
|
|||
assertEquals(megolmSessionId, sentEvent.root.content.toModel<EncryptedEventContent>()?.sessionId, "Unexpected megolm session")
|
||||
testHelper.waitWithLatch { latch ->
|
||||
testHelper.retryPeriodicallyWithLatch(latch) {
|
||||
bobSession.getRoom(e2eRoomID)?.getTimeLineEvent(sentEvent.eventId)?.root?.getClearType() == EventType.MESSAGE
|
||||
bobSession.getRoom(e2eRoomID)?.getTimelineEvent(sentEvent.eventId)?.root?.getClearType() == EventType.MESSAGE
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class KeyShareTests : InstrumentedTest {
|
|||
|
||||
val roomSecondSessionPOV = aliceSession2.getRoom(roomId)
|
||||
|
||||
val receivedEvent = roomSecondSessionPOV?.getTimeLineEvent(sentEventId)
|
||||
val receivedEvent = roomSecondSessionPOV?.getTimelineEvent(sentEventId)
|
||||
assertNotNull(receivedEvent)
|
||||
assert(receivedEvent!!.isEncrypted())
|
||||
|
||||
|
@ -382,7 +382,7 @@ class KeyShareTests : InstrumentedTest {
|
|||
commonTestHelper.sendTextMessage(roomAlicePov, "After", 1)
|
||||
|
||||
val roomRoomBobPov = aliceSession.getRoom(roomId)
|
||||
val beforeJoin = roomRoomBobPov!!.getTimeLineEvent(secondEventId)
|
||||
val beforeJoin = roomRoomBobPov!!.getTimelineEvent(secondEventId)
|
||||
|
||||
var dRes = tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin!!.root, "") }
|
||||
|
||||
|
|
|
@ -80,11 +80,11 @@ class WithHeldTests : InstrumentedTest {
|
|||
// await for bob unverified session to get the message
|
||||
testHelper.waitWithLatch { latch ->
|
||||
testHelper.retryPeriodicallyWithLatch(latch) {
|
||||
bobUnverifiedSession.getRoom(roomId)?.getTimeLineEvent(timelineEvent.eventId) != null
|
||||
bobUnverifiedSession.getRoom(roomId)?.getTimelineEvent(timelineEvent.eventId) != null
|
||||
}
|
||||
}
|
||||
|
||||
val eventBobPOV = bobUnverifiedSession.getRoom(roomId)?.getTimeLineEvent(timelineEvent.eventId)!!
|
||||
val eventBobPOV = bobUnverifiedSession.getRoom(roomId)?.getTimelineEvent(timelineEvent.eventId)!!
|
||||
|
||||
// =============================
|
||||
// ASSERT
|
||||
|
@ -109,7 +109,7 @@ class WithHeldTests : InstrumentedTest {
|
|||
|
||||
testHelper.waitWithLatch { latch ->
|
||||
testHelper.retryPeriodicallyWithLatch(latch) {
|
||||
val ev = bobUnverifiedSession.getRoom(roomId)?.getTimeLineEvent(secondEvent.eventId)
|
||||
val ev = bobUnverifiedSession.getRoom(roomId)?.getTimelineEvent(secondEvent.eventId)
|
||||
// wait until it's decrypted
|
||||
ev?.root?.getClearType() == EventType.MESSAGE
|
||||
}
|
||||
|
@ -157,12 +157,12 @@ class WithHeldTests : InstrumentedTest {
|
|||
// await for bob session to get the message
|
||||
testHelper.waitWithLatch { latch ->
|
||||
testHelper.retryPeriodicallyWithLatch(latch) {
|
||||
bobSession.getRoom(testData.roomId)?.getTimeLineEvent(eventId) != null
|
||||
bobSession.getRoom(testData.roomId)?.getTimelineEvent(eventId) != null
|
||||
}
|
||||
}
|
||||
|
||||
// Previous message should still be undecryptable (partially withheld session)
|
||||
val eventBobPOV = bobSession.getRoom(testData.roomId)?.getTimeLineEvent(eventId)
|
||||
val eventBobPOV = bobSession.getRoom(testData.roomId)?.getTimelineEvent(eventId)
|
||||
try {
|
||||
// .. might need to wait a bit for stability?
|
||||
bobSession.cryptoService().decryptEvent(eventBobPOV!!.root, "")
|
||||
|
@ -190,7 +190,7 @@ class WithHeldTests : InstrumentedTest {
|
|||
// await for bob SecondSession session to get the message
|
||||
testHelper.waitWithLatch { latch ->
|
||||
testHelper.retryPeriodicallyWithLatch(latch) {
|
||||
bobSecondSession.getRoom(testData.roomId)?.getTimeLineEvent(secondMessageId) != null
|
||||
bobSecondSession.getRoom(testData.roomId)?.getTimelineEvent(secondMessageId) != null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ class WithHeldTests : InstrumentedTest {
|
|||
// await for bob SecondSession session to get the message
|
||||
testHelper.waitWithLatch { latch ->
|
||||
testHelper.retryPeriodicallyWithLatch(latch) {
|
||||
val timeLineEvent = bobSecondSession.getRoom(testData.roomId)?.getTimeLineEvent(eventId)?.also {
|
||||
val timeLineEvent = bobSecondSession.getRoom(testData.roomId)?.getTimelineEvent(eventId)?.also {
|
||||
// try to decrypt and force key request
|
||||
tryOrNull { bobSecondSession.cryptoService().decryptEvent(it.root, "") }
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ interface TimelineService {
|
|||
* At the opposite of getTimeLineEventLive which will be updated when local echo event is synced, it will return null in this case.
|
||||
* @param eventId the eventId to get the TimelineEvent
|
||||
*/
|
||||
fun getTimeLineEvent(eventId: String): TimelineEvent?
|
||||
fun getTimelineEvent(eventId: String): TimelineEvent?
|
||||
|
||||
/**
|
||||
* Creates a LiveData of Optional TimelineEvent event with eventId.
|
||||
|
@ -49,7 +49,7 @@ interface TimelineService {
|
|||
* In this case, makes sure to use the new synced eventId from the TimelineEvent class if you want to interact, as the local echo is removed from the SDK.
|
||||
* @param eventId the eventId to listen for TimelineEvent
|
||||
*/
|
||||
fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>>
|
||||
fun getTimelineEventLive(eventId: String): LiveData<Optional<TimelineEvent>>
|
||||
|
||||
/**
|
||||
* Returns a snapshot list of TimelineEvent with EventType.MESSAGE and MessageType.MSGTYPE_IMAGE or MessageType.MSGTYPE_VIDEO.
|
||||
|
|
|
@ -16,8 +16,11 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.database.mapper
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmList
|
||||
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.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
|
||||
|
@ -32,14 +35,22 @@ internal class ReadReceiptsSummaryMapper @Inject constructor(
|
|||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return realmSessionProvider.withRealm { realm ->
|
||||
readReceipts
|
||||
private fun map(readReceipts: RealmList<ReadReceiptEntity>, realm: Realm): List<ReadReceipt> {
|
||||
return readReceipts
|
||||
.mapNotNull {
|
||||
val roomMember = RoomMemberSummaryEntity.where(realm, roomId = it.roomId, userId = it.userId).findFirst()
|
||||
?: return@mapNotNull null
|
||||
ReadReceipt(roomMember.asDomain(), it.originServerTs.toLong())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -513,7 +513,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
|||
|
||||
private fun getPollEvent(roomId: String, eventId: String): TimelineEvent? {
|
||||
val session = sessionManager.getSessionComponent(sessionId)?.session()
|
||||
return session?.getRoom(roomId)?.getTimeLineEvent(eventId) ?: return null.also {
|
||||
return session?.getRoom(roomId)?.getTimelineEvent(eventId) ?: return null.also {
|
||||
Timber.v("## POLL target poll event $eventId not found in room $roomId")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,15 +30,14 @@ import org.matrix.android.sdk.api.util.Cancelable
|
|||
import org.matrix.android.sdk.api.util.NoOpCancellable
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask
|
||||
import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
|
||||
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.TimelineEventDataSource
|
||||
import org.matrix.android.sdk.internal.util.fetchCopyMap
|
||||
import timber.log.Timber
|
||||
|
||||
|
@ -50,7 +49,7 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
private val findReactionEventForUndoTask: FindReactionEventForUndoTask,
|
||||
private val fetchEditHistoryTask: FetchEditHistoryTask,
|
||||
private val fetchThreadTimelineTask: FetchThreadTimelineTask,
|
||||
private val timelineEventMapper: TimelineEventMapper,
|
||||
private val timelineEventDataSource: TimelineEventDataSource,
|
||||
@SessionDatabase private val monarchy: Monarchy
|
||||
) : RelationService {
|
||||
|
||||
|
@ -60,14 +59,8 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
}
|
||||
|
||||
override fun sendReaction(targetEventId: String, reaction: String): Cancelable {
|
||||
return if (monarchy
|
||||
.fetchCopyMap(
|
||||
{ realm ->
|
||||
TimelineEventEntity.where(realm, roomId, targetEventId).findFirst()
|
||||
},
|
||||
{ entity, _ ->
|
||||
timelineEventMapper.map(entity)
|
||||
})
|
||||
val targetTimelineEvent = timelineEventDataSource.getTimelineEvent(roomId, targetEventId)
|
||||
return if (targetTimelineEvent
|
||||
?.annotations
|
||||
?.reactionsSummary
|
||||
.orEmpty()
|
||||
|
|
|
@ -21,36 +21,23 @@ import com.zhuinden.monarchy.Monarchy
|
|||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.realm.Sort
|
||||
import io.realm.kotlin.where
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
||||
import org.matrix.android.sdk.api.session.events.model.isVideoMessage
|
||||
import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineService
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||
import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage
|
||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
||||
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.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
||||
import org.matrix.android.sdk.internal.session.sync.handler.room.ReadReceiptHandler
|
||||
import org.matrix.android.sdk.internal.session.sync.handler.room.ThreadsAwarenessHandler
|
||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||
|
||||
internal class DefaultTimelineService @AssistedInject constructor(
|
||||
@Assisted private val roomId: String,
|
||||
@UserId private val userId: String,
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
private val realmSessionProvider: RealmSessionProvider,
|
||||
private val timelineInput: TimelineInput,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val contextOfEventTask: GetContextOfEventTask,
|
||||
private val eventDecryptor: TimelineEventDecryptor,
|
||||
private val paginationTask: PaginationTask,
|
||||
|
@ -60,7 +47,8 @@ internal class DefaultTimelineService @AssistedInject constructor(
|
|||
private val threadsAwarenessHandler: ThreadsAwarenessHandler,
|
||||
private val lightweightSettingsStorage: LightweightSettingsStorage,
|
||||
private val readReceiptHandler: ReadReceiptHandler,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val timelineEventDataSource: TimelineEventDataSource
|
||||
) : TimelineService {
|
||||
|
||||
@AssistedFactory
|
||||
|
@ -88,27 +76,15 @@ internal class DefaultTimelineService @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
override fun getTimeLineEvent(eventId: String): TimelineEvent? {
|
||||
return realmSessionProvider.withRealm { realm ->
|
||||
TimelineEventEntity.where(realm, roomId = roomId, eventId = eventId).findFirst()?.let {
|
||||
timelineEventMapper.map(it)
|
||||
}
|
||||
}
|
||||
override fun getTimelineEvent(eventId: String): TimelineEvent? {
|
||||
return timelineEventDataSource.getTimelineEvent(roomId, eventId)
|
||||
}
|
||||
|
||||
override fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
|
||||
return LiveTimelineEvent(monarchy, taskExecutor.executorScope, timelineEventMapper, roomId, eventId)
|
||||
override fun getTimelineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
|
||||
return timelineEventDataSource.getTimelineEventLive(roomId, eventId)
|
||||
}
|
||||
|
||||
override fun getAttachmentMessages(): List<TimelineEvent> {
|
||||
// TODO pretty bad query.. maybe we should denormalize clear type in base?
|
||||
return realmSessionProvider.withRealm { realm ->
|
||||
realm.where<TimelineEventEntity>()
|
||||
.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
||||
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.ASCENDING)
|
||||
.findAll()
|
||||
?.mapNotNull { timelineEventMapper.map(it).takeIf { it.root.isImageMessage() || it.root.isVideoMessage() } }
|
||||
.orEmpty()
|
||||
}
|
||||
return timelineEventDataSource.getAttachmentMessages(roomId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ internal class RealmSendingEventsDataSource(
|
|||
|
||||
private val sendingTimelineEventsListener = RealmChangeListener<RealmList<TimelineEventEntity>> { events ->
|
||||
uiEchoManager.onSentEventsInDatabase(events.map { it.eventId })
|
||||
frozenSendingTimelineEvents = sendingTimelineEvents?.freeze()
|
||||
updateFrozenResults(events)
|
||||
onEventsUpdated(false)
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,17 @@ internal class RealmSendingEventsDataSource(
|
|||
|
||||
override fun stop() {
|
||||
sendingTimelineEvents?.removeChangeListener(sendingTimelineEventsListener)
|
||||
updateFrozenResults(null)
|
||||
sendingTimelineEvents = null
|
||||
roomEntity = null
|
||||
}
|
||||
|
||||
private fun updateFrozenResults(sendingEvents: RealmList<TimelineEventEntity>?) {
|
||||
// Makes sure to close the previous frozen realm
|
||||
frozenSendingTimelineEvents?.realm?.close()
|
||||
frozenSendingTimelineEvents = sendingEvents?.freeze()
|
||||
}
|
||||
|
||||
override fun buildSendingEvents(): List<TimelineEvent> {
|
||||
val builtSendingEvents = mutableListOf<TimelineEvent>()
|
||||
uiEchoManager.getInMemorySendingEvents()
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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.timeline
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.Sort
|
||||
import io.realm.kotlin.where
|
||||
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
||||
import org.matrix.android.sdk.api.session.events.model.isVideoMessage
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.internal.database.RealmSessionProvider
|
||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
||||
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.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class TimelineEventDataSource @Inject constructor(private val realmSessionProvider: RealmSessionProvider,
|
||||
private val timelineEventMapper: TimelineEventMapper,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
@SessionDatabase private val monarchy: Monarchy) {
|
||||
|
||||
fun getTimelineEvent(roomId: String, eventId: String): TimelineEvent? {
|
||||
return realmSessionProvider.withRealm { realm ->
|
||||
TimelineEventEntity.where(realm, roomId = roomId, eventId = eventId).findFirst()?.let {
|
||||
timelineEventMapper.map(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getTimelineEventLive(roomId: String, eventId: String): LiveData<Optional<TimelineEvent>> {
|
||||
return LiveTimelineEvent(monarchy, taskExecutor.executorScope, timelineEventMapper, roomId, eventId)
|
||||
}
|
||||
|
||||
fun getAttachmentMessages(roomId: String): List<TimelineEvent> {
|
||||
// TODO pretty bad query.. maybe we should denormalize clear type in base?
|
||||
return realmSessionProvider.withRealm { realm ->
|
||||
realm.where<TimelineEventEntity>()
|
||||
.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
||||
.sort(TimelineEventEntityFields.DISPLAY_INDEX, Sort.ASCENDING)
|
||||
.findAll()
|
||||
?.mapNotNull { timelineEventMapper.map(it).takeIf { it.root.isImageMessage() || it.root.isVideoMessage() } }
|
||||
.orEmpty()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -213,7 +213,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
|
|||
try {
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return false
|
||||
val room = session.getRoom(roomId) ?: return false
|
||||
return room.getTimeLineEvent(eventId) != null
|
||||
return room.getTimelineEvent(eventId) != null
|
||||
} catch (e: Exception) {
|
||||
Timber.tag(loggerTag.value).e(e, "## isEventAlreadyKnown() : failed to check if the event was already defined")
|
||||
}
|
||||
|
|
|
@ -742,7 +742,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun handleRedactEvent(action: RoomDetailAction.RedactAction) {
|
||||
val event = room.getTimeLineEvent(action.targetEventId) ?: return
|
||||
val event = room.getTimelineEvent(action.targetEventId) ?: return
|
||||
room.redactEvent(event.root, action.reason)
|
||||
}
|
||||
|
||||
|
@ -782,7 +782,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||
}
|
||||
// We need to update this with the related m.replace also (to move read receipt)
|
||||
action.event.annotations?.editSummary?.sourceEvents?.forEach {
|
||||
room.getTimeLineEvent(it)?.let { event ->
|
||||
room.getTimelineEvent(it)?.let { event ->
|
||||
visibleEventsSource.post(RoomDetailAction.TimelineEventTurnsVisible(event))
|
||||
}
|
||||
}
|
||||
|
@ -886,7 +886,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||
|
||||
private fun handleResendEvent(action: RoomDetailAction.ResendMessage) {
|
||||
val targetEventId = action.eventId
|
||||
room.getTimeLineEvent(targetEventId)?.let {
|
||||
room.getTimelineEvent(targetEventId)?.let {
|
||||
// State must be UNDELIVERED or Failed
|
||||
if (!it.root.sendState.hasFailed()) {
|
||||
Timber.e("Cannot resend message, it is not failed, Cancel first")
|
||||
|
@ -904,7 +904,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||
|
||||
private fun handleRemove(action: RoomDetailAction.RemoveFailedEcho) {
|
||||
val targetEventId = action.eventId
|
||||
room.getTimeLineEvent(targetEventId)?.let {
|
||||
room.getTimelineEvent(targetEventId)?.let {
|
||||
// State must be UNDELIVERED or Failed
|
||||
if (!it.root.sendState.hasFailed()) {
|
||||
Timber.e("Cannot resend message, it is not failed, Cancel first")
|
||||
|
@ -920,7 +920,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||
return
|
||||
}
|
||||
val targetEventId = action.eventId
|
||||
room.getTimeLineEvent(targetEventId)?.let {
|
||||
room.getTimelineEvent(targetEventId)?.let {
|
||||
// State must be in one of the sending states
|
||||
if (!it.root.sendState.isSending()) {
|
||||
Timber.e("Cannot cancel message, it is not sending")
|
||||
|
@ -1046,14 +1046,14 @@ class TimelineViewModel @AssistedInject constructor(
|
|||
|
||||
private fun handleReRequestKeys(action: RoomDetailAction.ReRequestKeys) {
|
||||
// Check if this request is still active and handled by me
|
||||
room.getTimeLineEvent(action.eventId)?.let {
|
||||
room.getTimelineEvent(action.eventId)?.let {
|
||||
session.cryptoService().reRequestRoomKeyForEvent(it.root)
|
||||
_viewEvents.post(RoomDetailViewEvents.ShowMessage(stringProvider.getString(R.string.e2e_re_request_encryption_key_dialog_content)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleTapOnFailedToDecrypt(action: RoomDetailAction.TapOnFailedToDecrypt) {
|
||||
room.getTimeLineEvent(action.eventId)?.let {
|
||||
room.getTimelineEvent(action.eventId)?.let {
|
||||
val code = when (it.root.mCryptoError) {
|
||||
MXCryptoError.ErrorType.KEYS_WITHHELD -> {
|
||||
WithHeldCode.fromCode(it.root.mCryptoErrorReason)
|
||||
|
@ -1069,7 +1069,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||
// Do not allow to vote unsent local echo of the poll event
|
||||
if (LocalEcho.isLocalEchoId(action.eventId)) return
|
||||
// Do not allow to vote the same option twice
|
||||
room.getTimeLineEvent(action.eventId)?.let { pollTimelineEvent ->
|
||||
room.getTimelineEvent(action.eventId)?.let { pollTimelineEvent ->
|
||||
val currentVote = pollTimelineEvent.annotations?.pollResponseSummary?.aggregatedContent?.myVote
|
||||
if (currentVote != action.optionKey) {
|
||||
room.voteToPoll(action.eventId, action.optionKey)
|
||||
|
|
|
@ -143,7 +143,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun handleEnterEditMode(action: MessageComposerAction.EnterEditMode) {
|
||||
room.getTimeLineEvent(action.eventId)?.let { timelineEvent ->
|
||||
room.getTimelineEvent(action.eventId)?.let { timelineEvent ->
|
||||
setState { copy(sendMode = SendMode.Edit(timelineEvent, timelineEvent.getTextEditableContent())) }
|
||||
}
|
||||
}
|
||||
|
@ -175,13 +175,13 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun handleEnterQuoteMode(action: MessageComposerAction.EnterQuoteMode) {
|
||||
room.getTimeLineEvent(action.eventId)?.let { timelineEvent ->
|
||||
room.getTimelineEvent(action.eventId)?.let { timelineEvent ->
|
||||
setState { copy(sendMode = SendMode.Quote(timelineEvent, action.text)) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleEnterReplyMode(action: MessageComposerAction.EnterReplyMode) {
|
||||
room.getTimeLineEvent(action.eventId)?.let { timelineEvent ->
|
||||
room.getTimelineEvent(action.eventId)?.let { timelineEvent ->
|
||||
setState { copy(sendMode = SendMode.Reply(timelineEvent, action.text)) }
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +479,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||
|
||||
if (inReplyTo != null) {
|
||||
// TODO check if same content?
|
||||
room.getTimeLineEvent(inReplyTo)?.let {
|
||||
room.getTimelineEvent(inReplyTo)?.let {
|
||||
room.editReply(state.sendMode.timelineEvent, it, action.text.toString())
|
||||
}
|
||||
} else {
|
||||
|
@ -555,17 +555,17 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||
sendMode = when (currentDraft) {
|
||||
is UserDraft.Regular -> SendMode.Regular(currentDraft.content, false)
|
||||
is UserDraft.Quote -> {
|
||||
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||
room.getTimelineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||
SendMode.Quote(timelineEvent, currentDraft.content)
|
||||
}
|
||||
}
|
||||
is UserDraft.Reply -> {
|
||||
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||
room.getTimelineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||
SendMode.Reply(timelineEvent, currentDraft.content)
|
||||
}
|
||||
}
|
||||
is UserDraft.Edit -> {
|
||||
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||
room.getTimelineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||
SendMode.Edit(timelineEvent, currentDraft.content)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class VerificationItemFactory @Inject constructor(
|
|||
?: return ignoredConclusion(params)
|
||||
|
||||
// If we cannot find the referenced request we do not display the done event
|
||||
val refEvent = session.getRoom(event.root.roomId ?: "")?.getTimeLineEvent(refEventId)
|
||||
val refEvent = session.getRoom(event.root.roomId ?: "")?.getTimelineEvent(refEventId)
|
||||
?: return ignoredConclusion(params)
|
||||
|
||||
// If it's not a request ignore this event
|
||||
|
|
|
@ -86,7 +86,7 @@ class ViewReactionsViewModel @AssistedInject constructor(@Assisted
|
|||
annotationsSummary.reactionsSummary
|
||||
.flatMap { reactionsSummary ->
|
||||
reactionsSummary.sourceEvents.map {
|
||||
val event = room.getTimeLineEvent(it)
|
||||
val event = room.getTimelineEvent(it)
|
||||
?: throw RuntimeException("Your eventId is not valid")
|
||||
ReactionInfo(
|
||||
event.root.eventId!!,
|
||||
|
|
|
@ -81,7 +81,7 @@ class DataAttachmentRoomProvider(
|
|||
|
||||
override fun getTimelineEventAtPosition(position: Int): TimelineEvent? {
|
||||
val item = getItem(position)
|
||||
return room?.getTimeLineEvent(item.eventId)
|
||||
return room?.getTimelineEvent(item.eventId)
|
||||
}
|
||||
|
||||
override suspend fun getFileForSharing(position: Int): File? {
|
||||
|
|
|
@ -65,7 +65,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||
if (event.getClearType() == EventType.STATE_ROOM_MEMBER) {
|
||||
return resolveStateRoomEvent(event, session, canBeReplaced = false, isNoisy = isNoisy)
|
||||
}
|
||||
val timelineEvent = session.getRoom(roomID)?.getTimeLineEvent(eventId) ?: return null
|
||||
val timelineEvent = session.getRoom(roomID)?.getTimelineEvent(eventId) ?: return null
|
||||
return when (event.getClearType()) {
|
||||
EventType.MESSAGE,
|
||||
EventType.ENCRYPTED -> {
|
||||
|
|
|
@ -89,7 +89,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
|
|||
|
||||
val rootThreadEventId = permalinkData.eventId?.let { eventId ->
|
||||
val room = roomId?.let { session?.getRoom(it) }
|
||||
room?.getTimeLineEvent(eventId)?.root?.getRootThreadEventId()
|
||||
room?.getTimelineEvent(eventId)?.root?.getRootThreadEventId()
|
||||
}
|
||||
openRoom(
|
||||
navigationInterceptor,
|
||||
|
|
|
@ -68,7 +68,7 @@ class CreatePollViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun initializeEditedPoll(eventId: String) {
|
||||
val event = room.getTimeLineEvent(eventId) ?: return
|
||||
val event = room.getTimelineEvent(eventId) ?: return
|
||||
val content = event.getLastMessageContent() as? MessagePollContent ?: return
|
||||
|
||||
val pollType = content.pollCreationInfo?.kind ?: PollType.DISCLOSED
|
||||
|
@ -115,7 +115,7 @@ class CreatePollViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun sendEditedPoll(editedEventId: String, pollType: PollType, question: String, options: List<String>) {
|
||||
val editedEvent = room.getTimeLineEvent(editedEventId) ?: return
|
||||
val editedEvent = room.getTimelineEvent(editedEventId) ?: return
|
||||
room.editPoll(editedEvent, pollType, question, options)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue