Timeline merge: wait for both timeline to be ready
This commit is contained in:
parent
99d05d8db3
commit
01d0d1a5ed
|
@ -26,7 +26,12 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.session.room.sender.SenderInfo
|
import org.matrix.android.sdk.api.session.room.sender.SenderInfo
|
||||||
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 kotlin.reflect.KMutableProperty0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be use to merge timeline tiles from 2 different rooms.
|
||||||
|
* Be aware it wont work properly with permalink.
|
||||||
|
*/
|
||||||
class MergedTimelines(
|
class MergedTimelines(
|
||||||
private val coroutineScope: CoroutineScope,
|
private val coroutineScope: CoroutineScope,
|
||||||
private val mainTimeline: Timeline,
|
private val mainTimeline: Timeline,
|
||||||
|
@ -34,10 +39,13 @@ class MergedTimelines(
|
||||||
|
|
||||||
data class SecondaryTimelineParams(
|
data class SecondaryTimelineParams(
|
||||||
val timeline: Timeline,
|
val timeline: Timeline,
|
||||||
|
val disableReadReceipts: Boolean = true,
|
||||||
val shouldFilterTypes: Boolean = false,
|
val shouldFilterTypes: Boolean = false,
|
||||||
val allowedTypes: List<String> = emptyList()
|
val allowedTypes: List<String> = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private var mainIsInit = false
|
||||||
|
private var secondaryIsInit = false
|
||||||
private val secondaryTimeline = secondaryTimelineParams.timeline
|
private val secondaryTimeline = secondaryTimelineParams.timeline
|
||||||
|
|
||||||
private val listenersMapping = HashMap<Timeline.Listener, List<ListenerInterceptor>>()
|
private val listenersMapping = HashMap<Timeline.Listener, List<ListenerInterceptor>>()
|
||||||
|
@ -70,10 +78,10 @@ class MergedTimelines(
|
||||||
|
|
||||||
override fun addListener(listener: Timeline.Listener): Boolean {
|
override fun addListener(listener: Timeline.Listener): Boolean {
|
||||||
val mainTimelineListener = ListenerInterceptor(mainTimeline, listener, false, emptyList()) {
|
val mainTimelineListener = ListenerInterceptor(mainTimeline, listener, false, emptyList()) {
|
||||||
processTimelineUpdates(mainTimelineEvents, it)
|
processTimelineUpdates(::mainIsInit, mainTimelineEvents, it)
|
||||||
}
|
}
|
||||||
val secondaryTimelineListener = ListenerInterceptor(secondaryTimeline, listener, secondaryTimelineParams.shouldFilterTypes, secondaryTimelineParams.allowedTypes) {
|
val secondaryTimelineListener = ListenerInterceptor(secondaryTimeline, listener, secondaryTimelineParams.shouldFilterTypes, secondaryTimelineParams.allowedTypes) {
|
||||||
processTimelineUpdates(secondaryTimelineEvents, it)
|
processTimelineUpdates(::secondaryIsInit, secondaryTimelineEvents, it)
|
||||||
}
|
}
|
||||||
listenersMapping[listener] = listOf(mainTimelineListener, secondaryTimelineListener)
|
listenersMapping[listener] = listOf(mainTimelineListener, secondaryTimelineListener)
|
||||||
return mainTimeline.addListener(mainTimelineListener) && secondaryTimeline.addListener(secondaryTimelineListener)
|
return mainTimeline.addListener(mainTimelineListener) && secondaryTimeline.addListener(secondaryTimelineListener)
|
||||||
|
@ -139,9 +147,10 @@ class MergedTimelines(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processTimelineUpdates(eventsRef: MutableList<TimelineEvent>, newData: List<TimelineEvent>) {
|
private fun processTimelineUpdates(isInit: KMutableProperty0<Boolean>, eventsRef: MutableList<TimelineEvent>, newData: List<TimelineEvent>) {
|
||||||
coroutineScope.launch(Dispatchers.Default) {
|
coroutineScope.launch(Dispatchers.Default) {
|
||||||
processingSemaphore.withPermit {
|
processingSemaphore.withPermit {
|
||||||
|
isInit.set(true)
|
||||||
eventsRef.apply {
|
eventsRef.apply {
|
||||||
clear()
|
clear()
|
||||||
addAll(newData)
|
addAll(newData)
|
||||||
|
@ -157,10 +166,7 @@ class MergedTimelines(
|
||||||
val secondaryItr = secondaryTimelineEvents.toList().listIterator()
|
val secondaryItr = secondaryTimelineEvents.toList().listIterator()
|
||||||
var index = 0
|
var index = 0
|
||||||
var correctedSenderInfo: SenderInfo? = mainTimelineEvents.firstOrNull()?.senderInfo
|
var correctedSenderInfo: SenderInfo? = mainTimelineEvents.firstOrNull()?.senderInfo
|
||||||
if (mainTimelineEvents.isEmpty() && mainTimeline.hasMoreToLoad(Timeline.Direction.BACKWARDS)) {
|
if (!mainIsInit || !secondaryIsInit) {
|
||||||
return
|
|
||||||
}
|
|
||||||
if (secondaryTimelineEvents.isEmpty() && secondaryTimeline.hasMoreToLoad(Timeline.Direction.BACKWARDS)) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
while (merged.size < mainTimelineEvents.size + secondaryTimelineEvents.size) {
|
while (merged.size < mainTimelineEvents.size + secondaryTimelineEvents.size) {
|
||||||
|
@ -203,7 +209,7 @@ class MergedTimelines(
|
||||||
private fun TimelineEvent.correctBeforeMerging(correctedSenderInfo: SenderInfo?): TimelineEvent {
|
private fun TimelineEvent.correctBeforeMerging(correctedSenderInfo: SenderInfo?): TimelineEvent {
|
||||||
return copy(
|
return copy(
|
||||||
senderInfo = correctedSenderInfo ?: senderInfo,
|
senderInfo = correctedSenderInfo ?: senderInfo,
|
||||||
readReceipts = emptyList()
|
readReceipts = if (secondaryTimelineParams.disableReadReceipts) emptyList() else readReceipts
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue