Skip to content

Commit 1777946

Browse files
authored
Merge pull request #3449 from element-hq/feature/bma/dmRoomBeginning
Fix events blinking at the beginning of DM
2 parents ab5793c + e4d1428 commit 1777946

File tree

11 files changed

+179
-67
lines changed

11 files changed

+179
-67
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ jsoup = "org.jsoup:jsoup:1.18.1"
162162
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
163163
molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0"
164164
timber = "com.jakewharton.timber:timber:5.0.1"
165-
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.43"
165+
matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.44"
166166
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
167167
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
168168
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }

libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@ data class MatrixRoomInfo(
4444
val hasRoomCall: Boolean,
4545
val activeRoomCallParticipants: ImmutableList<String>,
4646
val heroes: ImmutableList<MatrixUser>,
47-
val pinnedEventIds: ImmutableList<EventId>
47+
val pinnedEventIds: ImmutableList<EventId>,
48+
val creator: UserId?,
4849
)

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class MatrixRoomInfoMapper {
2828
fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.let {
2929
return MatrixRoomInfo(
3030
id = RoomId(it.id),
31+
creator = it.creator?.let(::UserId),
3132
name = it.displayName,
3233
rawName = it.rawName,
3334
topic = it.topic,

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class RustTimeline(
8686
onNewSyncedEvent: () -> Unit,
8787
) : Timeline {
8888
private val initLatch = CompletableDeferred<Unit>()
89-
private val isInit = MutableStateFlow(false)
89+
private val isTimelineInitialized = MutableStateFlow(false)
9090

9191
private val _timelineItems: MutableStateFlow<List<MatrixTimelineItem>> =
9292
MutableStateFlow(emptyList())
@@ -110,7 +110,7 @@ class RustTimeline(
110110
timelineCoroutineScope = coroutineScope,
111111
timelineDiffProcessor = timelineDiffProcessor,
112112
initLatch = initLatch,
113-
isInit = isInit,
113+
isTimelineInitialized = isTimelineInitialized,
114114
dispatcher = dispatcher,
115115
onNewSyncedEvent = onNewSyncedEvent,
116116
)
@@ -189,7 +189,7 @@ class RustTimeline(
189189
}
190190

191191
private fun canPaginate(direction: Timeline.PaginationDirection): Boolean {
192-
if (!isInit.value) return false
192+
if (!isTimelineInitialized.value) return false
193193
return when (direction) {
194194
Timeline.PaginationDirection.BACKWARDS -> backPaginationStatus.value.canPaginate
195195
Timeline.PaginationDirection.FORWARDS -> forwardPaginationStatus.value.canPaginate
@@ -207,23 +207,37 @@ class RustTimeline(
207207
_timelineItems,
208208
backPaginationStatus.map { it.hasMoreToLoad }.distinctUntilChanged(),
209209
forwardPaginationStatus.map { it.hasMoreToLoad }.distinctUntilChanged(),
210-
isInit,
211-
) { timelineItems, hasMoreToLoadBackward, hasMoreToLoadForward, isInit ->
210+
matrixRoom.roomInfoFlow.map { it.creator },
211+
isTimelineInitialized,
212+
) { timelineItems,
213+
hasMoreToLoadBackward,
214+
hasMoreToLoadForward,
215+
roomCreator,
216+
isTimelineInitialized ->
212217
withContext(dispatcher) {
213218
timelineItems
214-
.process { items ->
219+
.let { items ->
215220
roomBeginningPostProcessor.process(
216221
items = items,
217222
isDm = matrixRoom.isDm,
218-
hasMoreToLoadBackwards = hasMoreToLoadBackward
223+
roomCreator = roomCreator,
224+
hasMoreToLoadBackwards = hasMoreToLoadBackward,
219225
)
220226
}
221-
.process(predicate = isInit) { items ->
222-
loadingIndicatorsPostProcessor.process(items, hasMoreToLoadBackward, hasMoreToLoadForward)
227+
.let { items ->
228+
loadingIndicatorsPostProcessor.process(
229+
items = items,
230+
isTimelineInitialized = isTimelineInitialized,
231+
hasMoreToLoadBackward = hasMoreToLoadBackward,
232+
hasMoreToLoadForward = hasMoreToLoadForward
233+
)
223234
}
224235
// Keep lastForwardIndicatorsPostProcessor last
225-
.process(predicate = isInit) { items ->
226-
lastForwardIndicatorsPostProcessor.process(items)
236+
.let { items ->
237+
lastForwardIndicatorsPostProcessor.process(
238+
items = items,
239+
isTimelineInitialized = isTimelineInitialized,
240+
)
227241
}
228242
}
229243
}.onStart {
@@ -542,14 +556,3 @@ class RustTimeline(
542556
}
543557
}
544558
}
545-
546-
private suspend fun List<MatrixTimelineItem>.process(
547-
predicate: Boolean = true,
548-
processor: suspend (List<MatrixTimelineItem>) -> List<MatrixTimelineItem>
549-
): List<MatrixTimelineItem> {
550-
return if (predicate) {
551-
processor(this)
552-
} else {
553-
this
554-
}
555-
}

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/TimelineItemsSubscriber.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ internal class TimelineItemsSubscriber(
3838
private val timeline: Timeline,
3939
private val timelineDiffProcessor: MatrixTimelineDiffProcessor,
4040
private val initLatch: CompletableDeferred<Unit>,
41-
private val isInit: MutableStateFlow<Boolean>,
41+
private val isTimelineInitialized: MutableStateFlow<Boolean>,
4242
private val onNewSyncedEvent: () -> Unit,
4343
) {
4444
private var subscriptionCount = 0
@@ -85,13 +85,13 @@ internal class TimelineItemsSubscriber(
8585
ensureActive()
8686
timelineDiffProcessor.postItems(it)
8787
}
88-
isInit.value = true
88+
isTimelineInitialized.value = true
8989
initLatch.complete(Unit)
9090
}
9191

9292
private suspend fun postDiffs(diffs: List<TimelineDiff>) {
9393
val diffsToProcess = diffs.toMutableList()
94-
if (!isInit.value) {
94+
if (!isTimelineInitialized.value) {
9595
val resetDiff = diffsToProcess.firstOrNull { it.change() == TimelineChange.RESET }
9696
if (resetDiff != null) {
9797
// Keep using the postItems logic so we can post the timelineItems asap.

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/LastForwardIndicatorsPostProcessor.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ class LastForwardIndicatorsPostProcessor(
2222

2323
fun process(
2424
items: List<MatrixTimelineItem>,
25+
isTimelineInitialized: Boolean,
2526
): List<MatrixTimelineItem> {
27+
if (!isTimelineInitialized) return items
2628
// We don't need to add the last forward indicator if we are not in the FOCUSED_ON_EVENT mode
2729
if (mode != Timeline.Mode.FOCUSED_ON_EVENT) {
2830
return items

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/LoadingIndicatorsPostProcessor.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import io.element.android.services.toolbox.api.systemclock.SystemClock
1616
class LoadingIndicatorsPostProcessor(private val systemClock: SystemClock) {
1717
fun process(
1818
items: List<MatrixTimelineItem>,
19+
isTimelineInitialized: Boolean,
1920
hasMoreToLoadBackward: Boolean,
2021
hasMoreToLoadForward: Boolean,
2122
): List<MatrixTimelineItem> {
23+
if (!isTimelineInitialized) return items
2224
val shouldAddForwardLoadingIndicator = hasMoreToLoadForward && items.isNotEmpty()
2325
val currentTimestamp = systemClock.epochMillis()
2426
return buildList {

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessor.kt

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package io.element.android.libraries.matrix.impl.timeline.postprocessor
99

1010
import androidx.annotation.VisibleForTesting
1111
import io.element.android.libraries.matrix.api.core.UniqueId
12+
import io.element.android.libraries.matrix.api.core.UserId
1213
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
1314
import io.element.android.libraries.matrix.api.timeline.Timeline
1415
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
@@ -25,12 +26,14 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
2526
fun process(
2627
items: List<MatrixTimelineItem>,
2728
isDm: Boolean,
28-
hasMoreToLoadBackwards: Boolean
29+
roomCreator: UserId?,
30+
hasMoreToLoadBackwards: Boolean,
2931
): List<MatrixTimelineItem> {
3032
return when {
33+
items.isEmpty() -> items
3134
mode == Timeline.Mode.PINNED_EVENTS -> items
35+
isDm -> processForDM(items, roomCreator)
3236
hasMoreToLoadBackwards -> items
33-
isDm -> processForDM(items)
3437
else -> processForRoom(items)
3538
}
3639
}
@@ -40,22 +43,28 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
4043
return listOf(roomBeginningItem) + items
4144
}
4245

43-
private fun processForDM(items: List<MatrixTimelineItem>): List<MatrixTimelineItem> {
44-
// Find room creation event. This is usually index 0
46+
private fun processForDM(items: List<MatrixTimelineItem>, roomCreator: UserId?): List<MatrixTimelineItem> {
47+
// Find room creation event.
48+
// This is usually the first MatrixTimelineItem.Event (so index 1, index 0 is a date)
4549
val roomCreationEventIndex = items.indexOfFirst {
4650
val stateEventContent = (it as? MatrixTimelineItem.Event)?.event?.content as? StateContent
4751
stateEventContent?.content is OtherState.RoomCreate
4852
}
4953

50-
// Find self-join event for room creator. This is usually index 1
51-
val roomCreatorUserId = (items.getOrNull(roomCreationEventIndex) as? MatrixTimelineItem.Event)?.event?.sender
54+
// If the parameter roomCreator is null, the creator is the sender of the RoomCreate Event.
55+
val roomCreatorUserId = roomCreator ?: (items.getOrNull(roomCreationEventIndex) as? MatrixTimelineItem.Event)?.event?.sender
56+
// Find self-join event for the room creator.
57+
// This is usually the second MatrixTimelineItem.Event (so index 2)
5258
val selfUserJoinedEventIndex = roomCreatorUserId?.let { creatorUserId ->
5359
items.indexOfFirst {
5460
val stateEventContent = (it as? MatrixTimelineItem.Event)?.event?.content as? RoomMembershipContent
5561
stateEventContent?.change == MembershipChange.JOINED && stateEventContent.userId == creatorUserId
5662
}
5763
} ?: -1
5864

65+
if (roomCreationEventIndex == -1 && selfUserJoinedEventIndex == -1) {
66+
return items
67+
}
5968
// Remove items at the indices we found
6069
val newItems = items.toMutableList()
6170
if (selfUserJoinedEventIndex in newItems.indices) {

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ package io.element.android.libraries.matrix.impl.roomlist
1010
import com.google.common.truth.Truth.assertThat
1111
import com.sun.jna.Pointer
1212
import io.element.android.libraries.matrix.api.core.RoomId
13+
import io.element.android.libraries.matrix.api.core.UserId
1314
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
1415
import io.element.android.libraries.matrix.test.A_ROOM_ID
1516
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
@@ -215,6 +216,7 @@ private fun aRustRoomInfo(
215216
numUnreadNotifications: ULong = 0uL,
216217
numUnreadMentions: ULong = 0uL,
217218
pinnedEventIds: List<String> = listOf(),
219+
roomCreator: UserId? = null,
218220
) = RoomInfo(
219221
id = id,
220222
displayName = displayName,
@@ -245,6 +247,7 @@ private fun aRustRoomInfo(
245247
numUnreadNotifications = numUnreadNotifications,
246248
numUnreadMentions = numUnreadMentions,
247249
pinnedEventIds = pinnedEventIds,
250+
creator = roomCreator?.value,
248251
)
249252

250253
class FakeRoomListItem(

0 commit comments

Comments
 (0)