Timeline: add some comments and checks
This commit is contained in:
parent
90eeb68d36
commit
7e29665fd0
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue