Timeline\Read marker: continue fixing potential issues
This commit is contained in:
parent
5d6d0202a9
commit
69fb7bdf95
|
@ -27,15 +27,33 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineSettings
|
||||||
import im.vector.matrix.android.api.util.CancelableBag
|
import im.vector.matrix.android.api.util.CancelableBag
|
||||||
import im.vector.matrix.android.internal.database.mapper.TimelineEventMapper
|
import im.vector.matrix.android.internal.database.mapper.TimelineEventMapper
|
||||||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
import im.vector.matrix.android.internal.database.model.*
|
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.query.*
|
import im.vector.matrix.android.internal.database.model.ChunkEntityFields
|
||||||
|
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||||
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.TimelineEventEntityFields
|
||||||
|
import im.vector.matrix.android.internal.database.query.FilterContent
|
||||||
|
import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates
|
||||||
|
import im.vector.matrix.android.internal.database.query.findIncludingEvent
|
||||||
|
import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom
|
||||||
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
|
import im.vector.matrix.android.internal.database.query.whereInRoom
|
||||||
import im.vector.matrix.android.internal.task.TaskConstraints
|
import im.vector.matrix.android.internal.task.TaskConstraints
|
||||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||||
import im.vector.matrix.android.internal.task.configureWith
|
import im.vector.matrix.android.internal.task.configureWith
|
||||||
import im.vector.matrix.android.internal.util.Debouncer
|
import im.vector.matrix.android.internal.util.Debouncer
|
||||||
import im.vector.matrix.android.internal.util.createBackgroundHandler
|
import im.vector.matrix.android.internal.util.createBackgroundHandler
|
||||||
import im.vector.matrix.android.internal.util.createUIHandler
|
import im.vector.matrix.android.internal.util.createUIHandler
|
||||||
import io.realm.*
|
import io.realm.OrderedCollectionChangeSet
|
||||||
|
import io.realm.OrderedRealmCollectionChangeListener
|
||||||
|
import io.realm.Realm
|
||||||
|
import io.realm.RealmConfiguration
|
||||||
|
import io.realm.RealmQuery
|
||||||
|
import io.realm.RealmResults
|
||||||
|
import io.realm.Sort
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
@ -221,11 +239,11 @@ internal class DefaultTimeline(
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
if (isStarted.compareAndSet(true, false)) {
|
if (isStarted.compareAndSet(true, false)) {
|
||||||
eventDecryptor.destroy()
|
isReady.set(false)
|
||||||
Timber.v("Dispose timeline for roomId: $roomId and eventId: $initialEventId")
|
Timber.v("Dispose timeline for roomId: $roomId and eventId: $initialEventId")
|
||||||
|
cancelableBag.cancel()
|
||||||
BACKGROUND_HANDLER.removeCallbacksAndMessages(null)
|
BACKGROUND_HANDLER.removeCallbacksAndMessages(null)
|
||||||
BACKGROUND_HANDLER.post {
|
BACKGROUND_HANDLER.post {
|
||||||
cancelableBag.cancel()
|
|
||||||
roomEntity?.sendingTimelineEvents?.removeAllChangeListeners()
|
roomEntity?.sendingTimelineEvents?.removeAllChangeListeners()
|
||||||
eventRelations.removeAllChangeListeners()
|
eventRelations.removeAllChangeListeners()
|
||||||
liveEvents.removeAllChangeListeners()
|
liveEvents.removeAllChangeListeners()
|
||||||
|
@ -238,6 +256,7 @@ internal class DefaultTimeline(
|
||||||
it.close()
|
it.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
eventDecryptor.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +324,7 @@ internal class DefaultTimeline(
|
||||||
private fun hasMoreInCache(direction: Timeline.Direction): Boolean {
|
private fun hasMoreInCache(direction: Timeline.Direction): Boolean {
|
||||||
return Realm.getInstance(realmConfiguration).use { localRealm ->
|
return Realm.getInstance(realmConfiguration).use { localRealm ->
|
||||||
val timelineEventEntity = buildEventQuery(localRealm).findFirst(direction)
|
val timelineEventEntity = buildEventQuery(localRealm).findFirst(direction)
|
||||||
?: return false
|
?: return false
|
||||||
if (direction == Timeline.Direction.FORWARDS) {
|
if (direction == Timeline.Direction.FORWARDS) {
|
||||||
val firstEvent = builtEvents.firstOrNull() ?: return true
|
val firstEvent = builtEvents.firstOrNull() ?: return true
|
||||||
firstEvent.displayIndex < timelineEventEntity.root!!.displayIndex
|
firstEvent.displayIndex < timelineEventEntity.root!!.displayIndex
|
||||||
|
@ -426,11 +445,15 @@ internal class DefaultTimeline(
|
||||||
* This has to be called on TimelineThread as it access realm live results
|
* This has to be called on TimelineThread as it access realm live results
|
||||||
*/
|
*/
|
||||||
private fun executePaginationTask(direction: Timeline.Direction, limit: Int) {
|
private fun executePaginationTask(direction: Timeline.Direction, limit: Int) {
|
||||||
val token = getTokenLive(direction) ?: return
|
val token = getTokenLive(direction)
|
||||||
|
if (token == null) {
|
||||||
|
updatePaginationState(direction) { it.copy(isPaginating = false, requestedCount = 0) }
|
||||||
|
return
|
||||||
|
}
|
||||||
val params = PaginationTask.Params(roomId = roomId,
|
val params = PaginationTask.Params(roomId = roomId,
|
||||||
from = token,
|
from = token,
|
||||||
direction = direction.toPaginationDirection(),
|
direction = direction.toPaginationDirection(),
|
||||||
limit = limit)
|
limit = limit)
|
||||||
|
|
||||||
Timber.v("Should fetch $limit items $direction")
|
Timber.v("Should fetch $limit items $direction")
|
||||||
cancelableBag += paginationTask
|
cancelableBag += paginationTask
|
||||||
|
@ -501,7 +524,7 @@ internal class DefaultTimeline(
|
||||||
val timelineEvent = buildTimelineEvent(eventEntity)
|
val timelineEvent = buildTimelineEvent(eventEntity)
|
||||||
|
|
||||||
if (timelineEvent.isEncrypted()
|
if (timelineEvent.isEncrypted()
|
||||||
&& timelineEvent.root.mxDecryptionResult == null) {
|
&& timelineEvent.root.mxDecryptionResult == null) {
|
||||||
timelineEvent.root.eventId?.let { eventDecryptor.requestDecryption(it) }
|
timelineEvent.root.eventId?.let { eventDecryptor.requestDecryption(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,11 +607,14 @@ internal class DefaultTimeline(
|
||||||
|
|
||||||
private fun fetchEvent(eventId: String) {
|
private fun fetchEvent(eventId: String) {
|
||||||
val params = GetContextOfEventTask.Params(roomId, eventId)
|
val params = GetContextOfEventTask.Params(roomId, eventId)
|
||||||
contextOfEventTask.configureWith(params).executeBy(taskExecutor)
|
cancelableBag += contextOfEventTask.configureWith(params).executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postSnapshot() {
|
private fun postSnapshot() {
|
||||||
BACKGROUND_HANDLER.post {
|
BACKGROUND_HANDLER.post {
|
||||||
|
if (isReady.get().not()) {
|
||||||
|
return@post
|
||||||
|
}
|
||||||
val snapshot = createSnapshot()
|
val snapshot = createSnapshot()
|
||||||
val runnable = Runnable { listener?.onUpdated(snapshot) }
|
val runnable = Runnable { listener?.onUpdated(snapshot) }
|
||||||
debouncer.debounce("post_snapshot", runnable, 50)
|
debouncer.debounce("post_snapshot", runnable, 50)
|
||||||
|
|
|
@ -56,7 +56,7 @@ internal class TimelineHiddenReadReceipts constructor(private val readReceiptsSu
|
||||||
var hasChange = false
|
var hasChange = false
|
||||||
// Deletion here means we don't have any readReceipts for the given hidden events
|
// Deletion here means we don't have any readReceipts for the given hidden events
|
||||||
changeSet.deletions.forEach {
|
changeSet.deletions.forEach {
|
||||||
val eventId = correctedReadReceiptsEventByIndex[it]
|
val eventId = correctedReadReceiptsEventByIndex.get(it, "")
|
||||||
val timelineEvent = liveEvents.where()
|
val timelineEvent = liveEvents.where()
|
||||||
.equalTo(TimelineEventEntityFields.EVENT_ID, eventId)
|
.equalTo(TimelineEventEntityFields.EVENT_ID, eventId)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
|
|
|
@ -643,11 +643,10 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
||||||
if (readMarkerId == null || isReadMarkerViewVisible || !timeline.isLive) {
|
if (readMarkerId == null || isReadMarkerViewVisible || !timeline.isLive) {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
val readMarkerPosition = timeline.getIndexOfEvent(readMarkerId)
|
val readMarkerPosition = timeline.getTimelineEventWithId(readMarkerId)?.displayIndex
|
||||||
?: Int.MAX_VALUE
|
?: Int.MIN_VALUE
|
||||||
val currentVisibleEventPosition = timeline.getIndexOfEvent(currentVisibleEvent.event.root.eventId)
|
val currentVisibleEventPosition = currentVisibleEvent.event.displayIndex
|
||||||
?: Int.MAX_VALUE
|
readMarkerPosition < currentVisibleEventPosition
|
||||||
readMarkerPosition > currentVisibleEventPosition
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue