Load RR when opening a timeline
This commit is contained in:
parent
3777b00ad7
commit
fe39c92e25
|
@ -44,6 +44,7 @@ import org.matrix.android.sdk.internal.database.query.findAllInRoomWithSendState
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.database.query.whereRoomId
|
import org.matrix.android.sdk.internal.database.query.whereRoomId
|
||||||
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.ReadReceiptHandler
|
||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||||
import org.matrix.android.sdk.internal.task.configureWith
|
import org.matrix.android.sdk.internal.task.configureWith
|
||||||
import org.matrix.android.sdk.internal.util.Debouncer
|
import org.matrix.android.sdk.internal.util.Debouncer
|
||||||
|
@ -73,7 +74,8 @@ internal class DefaultTimeline(
|
||||||
private val timelineInput: TimelineInput,
|
private val timelineInput: TimelineInput,
|
||||||
private val eventDecryptor: TimelineEventDecryptor,
|
private val eventDecryptor: TimelineEventDecryptor,
|
||||||
private val realmSessionProvider: RealmSessionProvider,
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
private val loadRoomMembersTask: LoadRoomMembersTask
|
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||||
|
private val readReceiptHandler: ReadReceiptHandler
|
||||||
) : Timeline,
|
) : Timeline,
|
||||||
TimelineHiddenReadReceipts.Delegate,
|
TimelineHiddenReadReceipts.Delegate,
|
||||||
TimelineInput.Listener,
|
TimelineInput.Listener,
|
||||||
|
@ -182,11 +184,26 @@ internal class DefaultTimeline(
|
||||||
}
|
}
|
||||||
.executeBy(taskExecutor)
|
.executeBy(taskExecutor)
|
||||||
|
|
||||||
|
// Ensure ReadReceipt from init sync are loaded
|
||||||
|
ensureReadReceiptAreLoaded(realm)
|
||||||
|
|
||||||
isReady.set(true)
|
isReady.set(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ensureReadReceiptAreLoaded(realm: Realm) {
|
||||||
|
readReceiptHandler.getContentFromInitSync(roomId)
|
||||||
|
?.also {
|
||||||
|
Timber.w("INIT_SYNC Insert when opening timeline RR for room $roomId")
|
||||||
|
}
|
||||||
|
?.let { readReceiptContent ->
|
||||||
|
realm.executeTransactionAsync {
|
||||||
|
readReceiptHandler.handle(it, roomId, readReceiptContent, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun TimelineSettings.shouldHandleHiddenReadReceipts(): Boolean {
|
private fun TimelineSettings.shouldHandleHiddenReadReceipts(): Boolean {
|
||||||
return buildReadReceipts && (filters.filterEdits || filters.filterTypes)
|
return buildReadReceipts && (filters.filterEdits || filters.filterTypes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,10 @@
|
||||||
package org.matrix.android.sdk.internal.session.room.timeline
|
package org.matrix.android.sdk.internal.session.room.timeline
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import dagger.assisted.Assisted
|
|
||||||
import dagger.assisted.AssistedInject
|
|
||||||
import dagger.assisted.AssistedFactory
|
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
import io.realm.Sort
|
import io.realm.Sort
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
||||||
|
@ -38,20 +38,23 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
||||||
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.membership.LoadRoomMembersTask
|
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
||||||
|
import org.matrix.android.sdk.internal.session.sync.ReadReceiptHandler
|
||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||||
|
|
||||||
internal class DefaultTimelineService @AssistedInject constructor(@Assisted private val roomId: String,
|
internal class DefaultTimelineService @AssistedInject constructor(
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@Assisted private val roomId: String,
|
||||||
private val realmSessionProvider: RealmSessionProvider,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
private val timelineInput: TimelineInput,
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
private val taskExecutor: TaskExecutor,
|
private val timelineInput: TimelineInput,
|
||||||
private val contextOfEventTask: GetContextOfEventTask,
|
private val taskExecutor: TaskExecutor,
|
||||||
private val eventDecryptor: TimelineEventDecryptor,
|
private val contextOfEventTask: GetContextOfEventTask,
|
||||||
private val paginationTask: PaginationTask,
|
private val eventDecryptor: TimelineEventDecryptor,
|
||||||
private val fetchTokenAndPaginateTask: FetchTokenAndPaginateTask,
|
private val paginationTask: PaginationTask,
|
||||||
private val timelineEventMapper: TimelineEventMapper,
|
private val fetchTokenAndPaginateTask: FetchTokenAndPaginateTask,
|
||||||
private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper,
|
private val timelineEventMapper: TimelineEventMapper,
|
||||||
private val loadRoomMembersTask: LoadRoomMembersTask
|
private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper,
|
||||||
|
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||||
|
private val readReceiptHandler: ReadReceiptHandler
|
||||||
) : TimelineService {
|
) : TimelineService {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -74,7 +77,8 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv
|
||||||
eventDecryptor = eventDecryptor,
|
eventDecryptor = eventDecryptor,
|
||||||
fetchTokenAndPaginateTask = fetchTokenAndPaginateTask,
|
fetchTokenAndPaginateTask = fetchTokenAndPaginateTask,
|
||||||
realmSessionProvider = realmSessionProvider,
|
realmSessionProvider = realmSessionProvider,
|
||||||
loadRoomMembersTask = loadRoomMembersTask
|
loadRoomMembersTask = loadRoomMembersTask,
|
||||||
|
readReceiptHandler = readReceiptHandler
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,55 +90,11 @@ internal class ReadReceiptHandler @Inject constructor(
|
||||||
realm.insertOrUpdate(readReceiptSummaries)
|
realm.insertOrUpdate(readReceiptSummaries)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Example of content:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* "type": "m.receipt",
|
|
||||||
* "content": {
|
|
||||||
* "$ofZhdeinmEReG_X-agD3J2TIhosEPkuvl62HJ8pVMMs": {
|
|
||||||
* "m.read": {
|
|
||||||
* "@benoit.marty:matrix.org": {
|
|
||||||
* "ts": 1610468193999
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* },
|
|
||||||
* "$ZMa_qwE_w_ZOj_vAxv7JuJeHCQfYzuQblmIZxkYmNMs": {
|
|
||||||
* "m.read": {
|
|
||||||
* "@benoitx:matrix.org": {
|
|
||||||
* "ts": 1610468049579
|
|
||||||
* },
|
|
||||||
* "@benoit.marty:matrix.org": {
|
|
||||||
* "ts": 1609156029466
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
private fun incrementalSyncStrategy(realm: Realm, roomId: String, content: ReadReceiptContent) {
|
private fun incrementalSyncStrategy(realm: Realm, roomId: String, content: ReadReceiptContent) {
|
||||||
// First check if we have data from init sync to handle
|
// First check if we have data from init sync to handle
|
||||||
// TODO Rename contentFromInitSync
|
getContentFromInitSync(roomId)?.let {
|
||||||
val initSyncContent = roomSyncEphemeralTemporaryStore.read(roomId)
|
Timber.w("INIT_SYNC Insert during incremental sync RR for room $roomId")
|
||||||
?.events
|
|
||||||
?.firstOrNull { it.type == EventType.RECEIPT }
|
|
||||||
?.let {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
it.content as? ReadReceiptContent
|
|
||||||
}
|
|
||||||
?.also {
|
|
||||||
Timber.w("INIT_SYNC Copy RR for room $roomId")
|
|
||||||
}
|
|
||||||
|
|
||||||
initSyncContent?.let {
|
|
||||||
Timber.w("BOOK Copy RR for room $roomId")
|
|
||||||
|
|
||||||
// TODO Merge with data we just received
|
|
||||||
// TODO Store that when we enter the timeline
|
|
||||||
initialSyncStrategy(realm, roomId, it)
|
initialSyncStrategy(realm, roomId, it)
|
||||||
roomSyncEphemeralTemporaryStore.delete(roomId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ((eventId, receiptDict) in content) {
|
for ((eventId, receiptDict) in content) {
|
||||||
|
@ -163,4 +119,17 @@ internal class ReadReceiptHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getContentFromInitSync(roomId: String): ReadReceiptContent? {
|
||||||
|
return roomSyncEphemeralTemporaryStore.read(roomId)
|
||||||
|
?.events
|
||||||
|
?.firstOrNull { it.type == EventType.RECEIPT }
|
||||||
|
?.let {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
it.content as? ReadReceiptContent
|
||||||
|
}
|
||||||
|
?.also {
|
||||||
|
roomSyncEphemeralTemporaryStore.delete(roomId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ internal class RoomSyncEphemeralTemporaryStoreFile @Inject constructor(
|
||||||
* Write RoomSyncEphemeral to a file
|
* Write RoomSyncEphemeral to a file
|
||||||
*/
|
*/
|
||||||
override fun write(roomId: String, roomSyncEphemeralJson: String) {
|
override fun write(roomId: String, roomSyncEphemeralJson: String) {
|
||||||
Timber.w("INIT_SYNC Store RR for room $roomId")
|
Timber.w("INIT_SYNC Store ephemeral events for room $roomId")
|
||||||
getFile(roomId).writeText(roomSyncEphemeralJson)
|
getFile(roomId).writeText(roomSyncEphemeralJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue