Timeline: add some comments and checks

This commit is contained in:
ganfra 2019-09-20 18:33:57 +02:00
parent 90eeb68d36
commit 7e29665fd0
6 changed files with 619 additions and 572 deletions

View File

@ -44,6 +44,10 @@ interface Timeline {
*/
fun dispose()
/**
* This method restarts the timeline, erases all built events and pagination states.
* It then loads events around the eventId. If eventId is null, it does restart the live timeline.
*/
fun restartWithEventId(eventId: String?)
@ -62,19 +66,39 @@ interface Timeline {
*/
fun paginate(direction: Direction, count: Int)
/**
* Returns the number of sending events
*/
fun pendingEventCount(): Int
/**
* Returns the number of failed sending events.
*/
fun failedToDeliverEventCount(): Int
/**
* Returns the index of a built event or null.
*/
fun getIndexOfEvent(eventId: String?): Int?
/**
* Returns the built [TimelineEvent] at index or null
*/
fun getTimelineEventAtIndex(index: Int): TimelineEvent?
/**
* Returns the built [TimelineEvent] with eventId or null
*/
fun getTimelineEventWithId(eventId: String?): TimelineEvent?
/**
* Returns the first displayable events starting from eventId.
* It does depend on the provided [TimelineSettings].
*/
fun getFirstDisplayableEventId(eventId: String): String?
interface Listener {
interface Listener {
/**
* Call when the timeline has been updated through pagination or sync.
* @param snapshot the most uptodate snapshot

View File

@ -120,6 +120,9 @@ internal class DefaultTimeline(
private val eventDecryptor = TimelineEventDecryptor(realmConfiguration, timelineID, cryptoService)
private val eventsChangeListener = OrderedRealmCollectionChangeListener<RealmResults<TimelineEventEntity>> { results, changeSet ->
if (!results.isLoaded || !results.isValid) {
return@OrderedRealmCollectionChangeListener
}
if (changeSet.state == OrderedCollectionChangeSet.State.INITIAL) {
handleInitialLoad()
} else {

View File

@ -45,6 +45,9 @@ internal class TimelineHiddenReadMarker constructor(private val roomId: String)
private lateinit var delegate: Delegate
private val readMarkerListener = RealmObjectChangeListener<ReadMarkerEntity> { readMarker, _ ->
if (!readMarker.isLoaded || !readMarker.isValid) {
return@RealmObjectChangeListener
}
var hasChange = false
previousDisplayedEventId?.also {
hasChange = delegate.rebuildEvent(it, false)
@ -53,7 +56,7 @@ internal class TimelineHiddenReadMarker constructor(private val roomId: String)
val isEventHidden = liveEvents.where().equalTo(TimelineEventEntityFields.EVENT_ID, readMarker.eventId).findFirst() == null
if (isEventHidden) {
val hiddenEvent = readMarker.timelineEvent?.firstOrNull()
?: return@RealmObjectChangeListener
?: return@RealmObjectChangeListener
val displayIndex = hiddenEvent.root?.displayIndex
if (displayIndex != null) {
// Then we are looking for the first displayable event after the hidden one

View File

@ -53,6 +53,9 @@ internal class TimelineHiddenReadReceipts constructor(private val readReceiptsSu
private lateinit var delegate: Delegate
private val hiddenReadReceiptsListener = OrderedRealmCollectionChangeListener<RealmResults<ReadReceiptsSummaryEntity>> { collection, changeSet ->
if (!collection.isLoaded || !collection.isValid) {
return@OrderedRealmCollectionChangeListener
}
var hasChange = false
// Deletion here means we don't have any readReceipts for the given hidden events
changeSet.deletions.forEach {

View File

@ -20,9 +20,15 @@ import androidx.recyclerview.widget.LinearLayoutManager
import im.vector.matrix.android.api.session.room.timeline.Timeline
import im.vector.riotx.core.platform.DefaultListUpdateCallback
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.concurrent.atomic.AtomicReference
/**
* This handles scrolling to an event which wasn't yet loaded when scheduled.
*/
class ScrollOnHighlightedEventCallback(private val layoutManager: LinearLayoutManager,
private val timelineEventController: TimelineEventController) : DefaultListUpdateCallback {
@ -30,7 +36,15 @@ class ScrollOnHighlightedEventCallback(private val layoutManager: LinearLayoutMa
var timeline: Timeline? = null
override fun onInserted(position: Int, count: Int) {
scrollIfNeeded()
}
override fun onChanged(position: Int, count: Int, tag: Any?) {
scrollIfNeeded()
}
private fun scrollIfNeeded() {
val eventId = scheduledEventId.get() ?: return
val nonNullTimeline = timeline ?: return
val correctedEventId = nonNullTimeline.getFirstDisplayableEventId(eventId)