mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Rename getTimeLine to getTimeline to align naming. Also create TimelineEventDataSource.
This commit is contained in:
parent
924a4f8c94
commit
fb2ed9a7ac
@ -58,9 +58,9 @@ class FlowRoom(private val room: Room) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun liveTimelineEvent(eventId: String): Flow<Optional<TimelineEvent>> {
|
fun liveTimelineEvent(eventId: String): Flow<Optional<TimelineEvent>> {
|
||||||
return room.getTimeLineEventLive(eventId).asFlow()
|
return room.getTimelineEventLive(eventId).asFlow()
|
||||||
.startWith(room.coroutineDispatchers.io) {
|
.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")
|
assertEquals(megolmSessionId, sentEvent.root.content.toModel<EncryptedEventContent>()?.sessionId, "Unexpected megolm session")
|
||||||
testHelper.waitWithLatch { latch ->
|
testHelper.waitWithLatch { latch ->
|
||||||
testHelper.retryPeriodicallyWithLatch(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 roomSecondSessionPOV = aliceSession2.getRoom(roomId)
|
||||||
|
|
||||||
val receivedEvent = roomSecondSessionPOV?.getTimeLineEvent(sentEventId)
|
val receivedEvent = roomSecondSessionPOV?.getTimelineEvent(sentEventId)
|
||||||
assertNotNull(receivedEvent)
|
assertNotNull(receivedEvent)
|
||||||
assert(receivedEvent!!.isEncrypted())
|
assert(receivedEvent!!.isEncrypted())
|
||||||
|
|
||||||
@ -382,7 +382,7 @@ class KeyShareTests : InstrumentedTest {
|
|||||||
commonTestHelper.sendTextMessage(roomAlicePov, "After", 1)
|
commonTestHelper.sendTextMessage(roomAlicePov, "After", 1)
|
||||||
|
|
||||||
val roomRoomBobPov = aliceSession.getRoom(roomId)
|
val roomRoomBobPov = aliceSession.getRoom(roomId)
|
||||||
val beforeJoin = roomRoomBobPov!!.getTimeLineEvent(secondEventId)
|
val beforeJoin = roomRoomBobPov!!.getTimelineEvent(secondEventId)
|
||||||
|
|
||||||
var dRes = tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin!!.root, "") }
|
var dRes = tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin!!.root, "") }
|
||||||
|
|
||||||
|
@ -80,11 +80,11 @@ class WithHeldTests : InstrumentedTest {
|
|||||||
// await for bob unverified session to get the message
|
// await for bob unverified session to get the message
|
||||||
testHelper.waitWithLatch { latch ->
|
testHelper.waitWithLatch { latch ->
|
||||||
testHelper.retryPeriodicallyWithLatch(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
|
// ASSERT
|
||||||
@ -109,7 +109,7 @@ class WithHeldTests : InstrumentedTest {
|
|||||||
|
|
||||||
testHelper.waitWithLatch { latch ->
|
testHelper.waitWithLatch { latch ->
|
||||||
testHelper.retryPeriodicallyWithLatch(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
|
// wait until it's decrypted
|
||||||
ev?.root?.getClearType() == EventType.MESSAGE
|
ev?.root?.getClearType() == EventType.MESSAGE
|
||||||
}
|
}
|
||||||
@ -157,12 +157,12 @@ class WithHeldTests : InstrumentedTest {
|
|||||||
// await for bob session to get the message
|
// await for bob session to get the message
|
||||||
testHelper.waitWithLatch { latch ->
|
testHelper.waitWithLatch { latch ->
|
||||||
testHelper.retryPeriodicallyWithLatch(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)
|
// 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 {
|
try {
|
||||||
// .. might need to wait a bit for stability?
|
// .. might need to wait a bit for stability?
|
||||||
bobSession.cryptoService().decryptEvent(eventBobPOV!!.root, "")
|
bobSession.cryptoService().decryptEvent(eventBobPOV!!.root, "")
|
||||||
@ -190,7 +190,7 @@ class WithHeldTests : InstrumentedTest {
|
|||||||
// await for bob SecondSession session to get the message
|
// await for bob SecondSession session to get the message
|
||||||
testHelper.waitWithLatch { latch ->
|
testHelper.waitWithLatch { latch ->
|
||||||
testHelper.retryPeriodicallyWithLatch(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
|
// await for bob SecondSession session to get the message
|
||||||
testHelper.waitWithLatch { latch ->
|
testHelper.waitWithLatch { latch ->
|
||||||
testHelper.retryPeriodicallyWithLatch(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
|
// try to decrypt and force key request
|
||||||
tryOrNull { bobSecondSession.cryptoService().decryptEvent(it.root, "") }
|
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.
|
* 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
|
* @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.
|
* 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.
|
* 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
|
* @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.
|
* Returns a snapshot list of TimelineEvent with EventType.MESSAGE and MessageType.MSGTYPE_IMAGE or MessageType.MSGTYPE_VIDEO.
|
||||||
|
@ -513,7 +513,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
|||||||
|
|
||||||
private fun getPollEvent(roomId: String, eventId: String): TimelineEvent? {
|
private fun getPollEvent(roomId: String, eventId: String): TimelineEvent? {
|
||||||
val session = sessionManager.getSessionComponent(sessionId)?.session()
|
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")
|
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.NoOpCancellable
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.toOptional
|
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.mapper.asDomain
|
||||||
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
|
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.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask
|
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.LocalEchoEventFactory
|
||||||
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
|
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 org.matrix.android.sdk.internal.util.fetchCopyMap
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||||||
private val findReactionEventForUndoTask: FindReactionEventForUndoTask,
|
private val findReactionEventForUndoTask: FindReactionEventForUndoTask,
|
||||||
private val fetchEditHistoryTask: FetchEditHistoryTask,
|
private val fetchEditHistoryTask: FetchEditHistoryTask,
|
||||||
private val fetchThreadTimelineTask: FetchThreadTimelineTask,
|
private val fetchThreadTimelineTask: FetchThreadTimelineTask,
|
||||||
private val timelineEventMapper: TimelineEventMapper,
|
private val timelineEventDataSource: TimelineEventDataSource,
|
||||||
@SessionDatabase private val monarchy: Monarchy
|
@SessionDatabase private val monarchy: Monarchy
|
||||||
) : RelationService {
|
) : RelationService {
|
||||||
|
|
||||||
@ -60,14 +59,8 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun sendReaction(targetEventId: String, reaction: String): Cancelable {
|
override fun sendReaction(targetEventId: String, reaction: String): Cancelable {
|
||||||
return if (monarchy
|
val targetTimelineEvent = timelineEventDataSource.getTimelineEvent(roomId, targetEventId)
|
||||||
.fetchCopyMap(
|
return if (targetTimelineEvent
|
||||||
{ realm ->
|
|
||||||
TimelineEventEntity.where(realm, roomId, targetEventId).findFirst()
|
|
||||||
},
|
|
||||||
{ entity, _ ->
|
|
||||||
timelineEventMapper.map(entity)
|
|
||||||
})
|
|
||||||
?.annotations
|
?.annotations
|
||||||
?.reactionsSummary
|
?.reactionsSummary
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
@ -21,36 +21,23 @@ import com.zhuinden.monarchy.Monarchy
|
|||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
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.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.Timeline
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
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.TimelineService
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
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.lightweight.LightweightSettingsStorage
|
||||||
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
|
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.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.room.membership.LoadRoomMembersTask
|
||||||
import org.matrix.android.sdk.internal.session.sync.handler.room.ReadReceiptHandler
|
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.session.sync.handler.room.ThreadsAwarenessHandler
|
||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
|
||||||
|
|
||||||
internal class DefaultTimelineService @AssistedInject constructor(
|
internal class DefaultTimelineService @AssistedInject constructor(
|
||||||
@Assisted private val roomId: String,
|
@Assisted private val roomId: String,
|
||||||
@UserId private val userId: String,
|
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
private val realmSessionProvider: RealmSessionProvider,
|
|
||||||
private val timelineInput: TimelineInput,
|
private val timelineInput: TimelineInput,
|
||||||
private val taskExecutor: TaskExecutor,
|
|
||||||
private val contextOfEventTask: GetContextOfEventTask,
|
private val contextOfEventTask: GetContextOfEventTask,
|
||||||
private val eventDecryptor: TimelineEventDecryptor,
|
private val eventDecryptor: TimelineEventDecryptor,
|
||||||
private val paginationTask: PaginationTask,
|
private val paginationTask: PaginationTask,
|
||||||
@ -60,7 +47,8 @@ internal class DefaultTimelineService @AssistedInject constructor(
|
|||||||
private val threadsAwarenessHandler: ThreadsAwarenessHandler,
|
private val threadsAwarenessHandler: ThreadsAwarenessHandler,
|
||||||
private val lightweightSettingsStorage: LightweightSettingsStorage,
|
private val lightweightSettingsStorage: LightweightSettingsStorage,
|
||||||
private val readReceiptHandler: ReadReceiptHandler,
|
private val readReceiptHandler: ReadReceiptHandler,
|
||||||
private val coroutineDispatchers: MatrixCoroutineDispatchers
|
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||||
|
private val timelineEventDataSource: TimelineEventDataSource
|
||||||
) : TimelineService {
|
) : TimelineService {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
@ -88,27 +76,15 @@ internal class DefaultTimelineService @AssistedInject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimeLineEvent(eventId: String): TimelineEvent? {
|
override fun getTimelineEvent(eventId: String): TimelineEvent? {
|
||||||
return realmSessionProvider.withRealm { realm ->
|
return timelineEventDataSource.getTimelineEvent(roomId, eventId)
|
||||||
TimelineEventEntity.where(realm, roomId = roomId, eventId = eventId).findFirst()?.let {
|
|
||||||
timelineEventMapper.map(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
|
override fun getTimelineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
|
||||||
return LiveTimelineEvent(monarchy, taskExecutor.executorScope, timelineEventMapper, roomId, eventId)
|
return timelineEventDataSource.getTimelineEventLive(roomId, eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttachmentMessages(): List<TimelineEvent> {
|
override fun getAttachmentMessages(): List<TimelineEvent> {
|
||||||
// TODO pretty bad query.. maybe we should denormalize clear type in base?
|
return timelineEventDataSource.getAttachmentMessages(roomId)
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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 {
|
try {
|
||||||
val session = activeSessionHolder.getSafeActiveSession() ?: return false
|
val session = activeSessionHolder.getSafeActiveSession() ?: return false
|
||||||
val room = session.getRoom(roomId) ?: return false
|
val room = session.getRoom(roomId) ?: return false
|
||||||
return room.getTimeLineEvent(eventId) != null
|
return room.getTimelineEvent(eventId) != null
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.tag(loggerTag.value).e(e, "## isEventAlreadyKnown() : failed to check if the event was already defined")
|
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) {
|
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)
|
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)
|
// We need to update this with the related m.replace also (to move read receipt)
|
||||||
action.event.annotations?.editSummary?.sourceEvents?.forEach {
|
action.event.annotations?.editSummary?.sourceEvents?.forEach {
|
||||||
room.getTimeLineEvent(it)?.let { event ->
|
room.getTimelineEvent(it)?.let { event ->
|
||||||
visibleEventsSource.post(RoomDetailAction.TimelineEventTurnsVisible(event))
|
visibleEventsSource.post(RoomDetailAction.TimelineEventTurnsVisible(event))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -886,7 +886,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
private fun handleResendEvent(action: RoomDetailAction.ResendMessage) {
|
private fun handleResendEvent(action: RoomDetailAction.ResendMessage) {
|
||||||
val targetEventId = action.eventId
|
val targetEventId = action.eventId
|
||||||
room.getTimeLineEvent(targetEventId)?.let {
|
room.getTimelineEvent(targetEventId)?.let {
|
||||||
// State must be UNDELIVERED or Failed
|
// State must be UNDELIVERED or Failed
|
||||||
if (!it.root.sendState.hasFailed()) {
|
if (!it.root.sendState.hasFailed()) {
|
||||||
Timber.e("Cannot resend message, it is not failed, Cancel first")
|
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) {
|
private fun handleRemove(action: RoomDetailAction.RemoveFailedEcho) {
|
||||||
val targetEventId = action.eventId
|
val targetEventId = action.eventId
|
||||||
room.getTimeLineEvent(targetEventId)?.let {
|
room.getTimelineEvent(targetEventId)?.let {
|
||||||
// State must be UNDELIVERED or Failed
|
// State must be UNDELIVERED or Failed
|
||||||
if (!it.root.sendState.hasFailed()) {
|
if (!it.root.sendState.hasFailed()) {
|
||||||
Timber.e("Cannot resend message, it is not failed, Cancel first")
|
Timber.e("Cannot resend message, it is not failed, Cancel first")
|
||||||
@ -920,7 +920,7 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val targetEventId = action.eventId
|
val targetEventId = action.eventId
|
||||||
room.getTimeLineEvent(targetEventId)?.let {
|
room.getTimelineEvent(targetEventId)?.let {
|
||||||
// State must be in one of the sending states
|
// State must be in one of the sending states
|
||||||
if (!it.root.sendState.isSending()) {
|
if (!it.root.sendState.isSending()) {
|
||||||
Timber.e("Cannot cancel message, it is not sending")
|
Timber.e("Cannot cancel message, it is not sending")
|
||||||
@ -1046,14 +1046,14 @@ class TimelineViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
private fun handleReRequestKeys(action: RoomDetailAction.ReRequestKeys) {
|
private fun handleReRequestKeys(action: RoomDetailAction.ReRequestKeys) {
|
||||||
// Check if this request is still active and handled by me
|
// 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)
|
session.cryptoService().reRequestRoomKeyForEvent(it.root)
|
||||||
_viewEvents.post(RoomDetailViewEvents.ShowMessage(stringProvider.getString(R.string.e2e_re_request_encryption_key_dialog_content)))
|
_viewEvents.post(RoomDetailViewEvents.ShowMessage(stringProvider.getString(R.string.e2e_re_request_encryption_key_dialog_content)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleTapOnFailedToDecrypt(action: RoomDetailAction.TapOnFailedToDecrypt) {
|
private fun handleTapOnFailedToDecrypt(action: RoomDetailAction.TapOnFailedToDecrypt) {
|
||||||
room.getTimeLineEvent(action.eventId)?.let {
|
room.getTimelineEvent(action.eventId)?.let {
|
||||||
val code = when (it.root.mCryptoError) {
|
val code = when (it.root.mCryptoError) {
|
||||||
MXCryptoError.ErrorType.KEYS_WITHHELD -> {
|
MXCryptoError.ErrorType.KEYS_WITHHELD -> {
|
||||||
WithHeldCode.fromCode(it.root.mCryptoErrorReason)
|
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
|
// Do not allow to vote unsent local echo of the poll event
|
||||||
if (LocalEcho.isLocalEchoId(action.eventId)) return
|
if (LocalEcho.isLocalEchoId(action.eventId)) return
|
||||||
// Do not allow to vote the same option twice
|
// 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
|
val currentVote = pollTimelineEvent.annotations?.pollResponseSummary?.aggregatedContent?.myVote
|
||||||
if (currentVote != action.optionKey) {
|
if (currentVote != action.optionKey) {
|
||||||
room.voteToPoll(action.eventId, action.optionKey)
|
room.voteToPoll(action.eventId, action.optionKey)
|
||||||
|
@ -143,7 +143,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEnterEditMode(action: MessageComposerAction.EnterEditMode) {
|
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())) }
|
setState { copy(sendMode = SendMode.Edit(timelineEvent, timelineEvent.getTextEditableContent())) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,13 +175,13 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEnterQuoteMode(action: MessageComposerAction.EnterQuoteMode) {
|
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)) }
|
setState { copy(sendMode = SendMode.Quote(timelineEvent, action.text)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEnterReplyMode(action: MessageComposerAction.EnterReplyMode) {
|
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)) }
|
setState { copy(sendMode = SendMode.Reply(timelineEvent, action.text)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -479,7 +479,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||||||
|
|
||||||
if (inReplyTo != null) {
|
if (inReplyTo != null) {
|
||||||
// TODO check if same content?
|
// TODO check if same content?
|
||||||
room.getTimeLineEvent(inReplyTo)?.let {
|
room.getTimelineEvent(inReplyTo)?.let {
|
||||||
room.editReply(state.sendMode.timelineEvent, it, action.text.toString())
|
room.editReply(state.sendMode.timelineEvent, it, action.text.toString())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -555,17 +555,17 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||||||
sendMode = when (currentDraft) {
|
sendMode = when (currentDraft) {
|
||||||
is UserDraft.Regular -> SendMode.Regular(currentDraft.content, false)
|
is UserDraft.Regular -> SendMode.Regular(currentDraft.content, false)
|
||||||
is UserDraft.Quote -> {
|
is UserDraft.Quote -> {
|
||||||
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
room.getTimelineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||||
SendMode.Quote(timelineEvent, currentDraft.content)
|
SendMode.Quote(timelineEvent, currentDraft.content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is UserDraft.Reply -> {
|
is UserDraft.Reply -> {
|
||||||
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
room.getTimelineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||||
SendMode.Reply(timelineEvent, currentDraft.content)
|
SendMode.Reply(timelineEvent, currentDraft.content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is UserDraft.Edit -> {
|
is UserDraft.Edit -> {
|
||||||
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
room.getTimelineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||||
SendMode.Edit(timelineEvent, currentDraft.content)
|
SendMode.Edit(timelineEvent, currentDraft.content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ class VerificationItemFactory @Inject constructor(
|
|||||||
?: return ignoredConclusion(params)
|
?: return ignoredConclusion(params)
|
||||||
|
|
||||||
// If we cannot find the referenced request we do not display the done event
|
// 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)
|
?: return ignoredConclusion(params)
|
||||||
|
|
||||||
// If it's not a request ignore this event
|
// If it's not a request ignore this event
|
||||||
|
@ -86,7 +86,7 @@ class ViewReactionsViewModel @AssistedInject constructor(@Assisted
|
|||||||
annotationsSummary.reactionsSummary
|
annotationsSummary.reactionsSummary
|
||||||
.flatMap { reactionsSummary ->
|
.flatMap { reactionsSummary ->
|
||||||
reactionsSummary.sourceEvents.map {
|
reactionsSummary.sourceEvents.map {
|
||||||
val event = room.getTimeLineEvent(it)
|
val event = room.getTimelineEvent(it)
|
||||||
?: throw RuntimeException("Your eventId is not valid")
|
?: throw RuntimeException("Your eventId is not valid")
|
||||||
ReactionInfo(
|
ReactionInfo(
|
||||||
event.root.eventId!!,
|
event.root.eventId!!,
|
||||||
|
@ -81,7 +81,7 @@ class DataAttachmentRoomProvider(
|
|||||||
|
|
||||||
override fun getTimelineEventAtPosition(position: Int): TimelineEvent? {
|
override fun getTimelineEventAtPosition(position: Int): TimelineEvent? {
|
||||||
val item = getItem(position)
|
val item = getItem(position)
|
||||||
return room?.getTimeLineEvent(item.eventId)
|
return room?.getTimelineEvent(item.eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getFileForSharing(position: Int): File? {
|
override suspend fun getFileForSharing(position: Int): File? {
|
||||||
|
@ -65,7 +65,7 @@ class NotifiableEventResolver @Inject constructor(
|
|||||||
if (event.getClearType() == EventType.STATE_ROOM_MEMBER) {
|
if (event.getClearType() == EventType.STATE_ROOM_MEMBER) {
|
||||||
return resolveStateRoomEvent(event, session, canBeReplaced = false, isNoisy = isNoisy)
|
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()) {
|
return when (event.getClearType()) {
|
||||||
EventType.MESSAGE,
|
EventType.MESSAGE,
|
||||||
EventType.ENCRYPTED -> {
|
EventType.ENCRYPTED -> {
|
||||||
|
@ -89,7 +89,7 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
|
|||||||
|
|
||||||
val rootThreadEventId = permalinkData.eventId?.let { eventId ->
|
val rootThreadEventId = permalinkData.eventId?.let { eventId ->
|
||||||
val room = roomId?.let { session?.getRoom(it) }
|
val room = roomId?.let { session?.getRoom(it) }
|
||||||
room?.getTimeLineEvent(eventId)?.root?.getRootThreadEventId()
|
room?.getTimelineEvent(eventId)?.root?.getRootThreadEventId()
|
||||||
}
|
}
|
||||||
openRoom(
|
openRoom(
|
||||||
navigationInterceptor,
|
navigationInterceptor,
|
||||||
|
@ -68,7 +68,7 @@ class CreatePollViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeEditedPoll(eventId: String) {
|
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 content = event.getLastMessageContent() as? MessagePollContent ?: return
|
||||||
|
|
||||||
val pollType = content.pollCreationInfo?.kind ?: PollType.DISCLOSED
|
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>) {
|
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)
|
room.editPoll(editedEvent, pollType, question, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user