Merge pull request #5330 from vector-im/feature/fga/more_realm_fixing

Feature/fga/more realm fixing
This commit is contained in:
Benoit Marty 2022-02-28 21:02:10 +01:00 committed by GitHub
commit 71aac37ec7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 142 additions and 89 deletions

1
changelog.d/5330.misc Normal file
View file

@ -0,0 +1 @@
Continue improving realm usage.

1
changelog.d/5330.sdk Normal file
View file

@ -0,0 +1 @@
Change name of getTimeLineEvent and getTimeLineEventLive methods to getTimelineEvent and getTimelineEventLive.

View file

@ -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()
}
}

View file

@ -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
}
}

View file

@ -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, "") }

View file

@ -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, "") }
}

View file

@ -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.

View file

@ -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
return realmSessionProvider.withRealm { realm ->
readReceipts
.mapNotNull {
val roomMember = RoomMemberSummaryEntity.where(realm, roomId = it.roomId, userId = it.userId).findFirst()
?: return@mapNotNull null
ReadReceipt(roomMember.asDomain(), it.originServerTs.toLong())
}
// 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)
}
}
}
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())
}
}
}

View file

@ -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")
}
}

View file

@ -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()

View file

@ -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)
}
}

View file

@ -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()

View file

@ -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()
}
}
}

View file

@ -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")
}

View file

@ -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)

View file

@ -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)
}
}

View file

@ -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

View file

@ -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!!,

View file

@ -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? {

View 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 -> {

View file

@ -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,

View file

@ -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)
}