Timeline : add a mode to differentiate between live/focused/pinned
This commit is contained in:
@@ -46,6 +46,12 @@ interface Timeline : AutoCloseable {
|
||||
FORWARDS
|
||||
}
|
||||
|
||||
enum class Mode {
|
||||
LIVE,
|
||||
FOCUSED_ON_EVENT,
|
||||
FOCUSED_ON_PINNED_EVENTS
|
||||
}
|
||||
|
||||
val membershipChangeEventReceived: Flow<Unit>
|
||||
suspend fun sendReadReceipt(eventId: EventId, receiptType: ReceiptType): Result<Unit>
|
||||
suspend fun paginate(direction: PaginationDirection): Result<Boolean>
|
||||
|
||||
@@ -153,7 +153,7 @@ class RustMatrixRoom(
|
||||
private val _roomNotificationSettingsStateFlow = MutableStateFlow<MatrixRoomNotificationSettingsState>(MatrixRoomNotificationSettingsState.Unknown)
|
||||
override val roomNotificationSettingsStateFlow: StateFlow<MatrixRoomNotificationSettingsState> = _roomNotificationSettingsStateFlow
|
||||
|
||||
override val liveTimeline = createTimeline(innerTimeline, isLive = true) {
|
||||
override val liveTimeline = createTimeline(innerTimeline, mode = Timeline.Mode.LIVE) {
|
||||
_syncUpdateFlow.value = systemClock.epochMillis()
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ class RustMatrixRoom(
|
||||
numContextEvents = 50u,
|
||||
internalIdPrefix = "focus_$eventId",
|
||||
).let { inner ->
|
||||
createTimeline(inner, isLive = false)
|
||||
createTimeline(inner, mode = Timeline.Mode.FOCUSED_ON_EVENT)
|
||||
}
|
||||
}.mapFailure {
|
||||
it.toFocusEventException()
|
||||
@@ -198,7 +198,7 @@ class RustMatrixRoom(
|
||||
internalIdPrefix = "pinned_events",
|
||||
maxEventsToLoad = 100u,
|
||||
).let { inner ->
|
||||
createTimeline(inner, isLive = false)
|
||||
createTimeline(inner, mode = Timeline.Mode.FOCUSED_ON_PINNED_EVENTS)
|
||||
}
|
||||
}.onFailure {
|
||||
if (it is CancellationException) {
|
||||
@@ -655,13 +655,13 @@ class RustMatrixRoom(
|
||||
|
||||
private fun createTimeline(
|
||||
timeline: InnerTimeline,
|
||||
isLive: Boolean,
|
||||
mode: Timeline.Mode,
|
||||
onNewSyncedEvent: () -> Unit = {},
|
||||
): Timeline {
|
||||
val timelineCoroutineScope = roomCoroutineScope.childScope(coroutineDispatchers.main, "TimelineScope-$roomId-$timeline")
|
||||
return RustTimeline(
|
||||
isKeyBackupEnabled = isKeyBackupEnabled,
|
||||
isLive = isLive,
|
||||
mode = mode,
|
||||
matrixRoom = this,
|
||||
systemClock = systemClock,
|
||||
coroutineScope = timelineCoroutineScope,
|
||||
|
||||
@@ -85,7 +85,7 @@ private const val PAGINATION_SIZE = 50
|
||||
|
||||
class RustTimeline(
|
||||
private val inner: InnerTimeline,
|
||||
private val isLive: Boolean,
|
||||
mode: Timeline.Mode,
|
||||
systemClock: SystemClock,
|
||||
isKeyBackupEnabled: Boolean,
|
||||
private val matrixRoom: MatrixRoom,
|
||||
@@ -131,21 +131,21 @@ class RustTimeline(
|
||||
onNewSyncedEvent = onNewSyncedEvent,
|
||||
)
|
||||
|
||||
private val roomBeginningPostProcessor = RoomBeginningPostProcessor()
|
||||
private val roomBeginningPostProcessor = RoomBeginningPostProcessor(mode)
|
||||
private val loadingIndicatorsPostProcessor = LoadingIndicatorsPostProcessor(systemClock)
|
||||
private val lastForwardIndicatorsPostProcessor = LastForwardIndicatorsPostProcessor(isLive)
|
||||
private val lastForwardIndicatorsPostProcessor = LastForwardIndicatorsPostProcessor(mode)
|
||||
|
||||
private val backPaginationStatus = MutableStateFlow(
|
||||
Timeline.PaginationStatus(isPaginating = false, hasMoreToLoad = true)
|
||||
Timeline.PaginationStatus(isPaginating = false, hasMoreToLoad = mode != Timeline.Mode.FOCUSED_ON_PINNED_EVENTS)
|
||||
)
|
||||
|
||||
private val forwardPaginationStatus = MutableStateFlow(
|
||||
Timeline.PaginationStatus(isPaginating = false, hasMoreToLoad = !isLive)
|
||||
Timeline.PaginationStatus(isPaginating = false, hasMoreToLoad = mode == Timeline.Mode.FOCUSED_ON_EVENT)
|
||||
)
|
||||
|
||||
init {
|
||||
coroutineScope.fetchMembers()
|
||||
if (isLive) {
|
||||
if (mode == Timeline.Mode.LIVE) {
|
||||
// When timeline is live, we need to listen to the back pagination status as
|
||||
// sdk can automatically paginate backwards.
|
||||
coroutineScope.registerBackPaginationStatusListener()
|
||||
|
||||
@@ -17,21 +17,22 @@
|
||||
package io.element.android.libraries.matrix.impl.timeline.postprocessor
|
||||
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
|
||||
|
||||
/**
|
||||
* This post processor is responsible for adding virtual items to indicate all the previous last forward item.
|
||||
*/
|
||||
class LastForwardIndicatorsPostProcessor(
|
||||
private val isTimelineLive: Boolean,
|
||||
private val mode: Timeline.Mode,
|
||||
) {
|
||||
private val lastForwardIdentifiers = LinkedHashSet<String>()
|
||||
|
||||
fun process(
|
||||
items: List<MatrixTimelineItem>,
|
||||
): List<MatrixTimelineItem> {
|
||||
// If the timeline is live, we don't have any last forward indicator to display
|
||||
if (isTimelineLive) {
|
||||
// We don't need to add the last forward indicator if we are not in the FOCUSED_ON_EVENT mode
|
||||
if (mode != Timeline.Mode.FOCUSED_ON_EVENT) {
|
||||
return items
|
||||
} else {
|
||||
return buildList {
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.element.android.libraries.matrix.impl.timeline.postprocessor
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
|
||||
@@ -28,13 +29,14 @@ import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTime
|
||||
* This timeline post-processor removes the room creation event and the self-join event from the timeline for DMs
|
||||
* or add the RoomBeginning item for non DM room.
|
||||
*/
|
||||
class RoomBeginningPostProcessor {
|
||||
class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
|
||||
fun process(
|
||||
items: List<MatrixTimelineItem>,
|
||||
isDm: Boolean,
|
||||
hasMoreToLoadBackwards: Boolean
|
||||
): List<MatrixTimelineItem> {
|
||||
return when {
|
||||
mode == Timeline.Mode.FOCUSED_ON_PINNED_EVENTS -> items
|
||||
hasMoreToLoadBackwards -> items
|
||||
isDm -> processForDM(items)
|
||||
else -> processForRoom(items)
|
||||
|
||||
@@ -36,7 +36,7 @@ class RoomBeginningPostProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processor = RoomBeginningPostProcessor(mode)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEmpty()
|
||||
}
|
||||
@@ -53,7 +53,7 @@ class RoomBeginningPostProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.member_other", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))),
|
||||
MatrixTimelineItem.Event("m.room.message", anEventTimelineItem(content = aMessageContent("hi"))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processor = RoomBeginningPostProcessor(mode)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(expected)
|
||||
}
|
||||
@@ -64,7 +64,7 @@ class RoomBeginningPostProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processor = RoomBeginningPostProcessor(mode)
|
||||
val processedItems = processor.process(timelineItems, isDm = false, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(
|
||||
listOf(processor.createRoomBeginningItem()) + timelineItems
|
||||
@@ -76,7 +76,7 @@ class RoomBeginningPostProcessorTest {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Virtual("EncryptedHistoryBanner", VirtualTimelineItem.EncryptedHistoryBanner),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processor = RoomBeginningPostProcessor(mode)
|
||||
val processedItems = processor.process(timelineItems, isDm = false, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
@@ -87,7 +87,7 @@ class RoomBeginningPostProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processor = RoomBeginningPostProcessor(mode)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
@@ -97,7 +97,7 @@ class RoomBeginningPostProcessorTest {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processor = RoomBeginningPostProcessor(mode)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
@@ -108,7 +108,7 @@ class RoomBeginningPostProcessorTest {
|
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))),
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor()
|
||||
val processor = RoomBeginningPostProcessor(mode)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user