diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 64b60ca82e..13c2e02858 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -162,7 +162,7 @@ jsoup = "org.jsoup:jsoup:1.17.2" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.25" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.27" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt index 8379d30781..4fae22ad57 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt @@ -20,7 +20,6 @@ import androidx.compose.runtime.Immutable import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableMap @@ -41,7 +40,6 @@ data class MatrixRoomInfo( val canonicalAlias: RoomAlias?, val alternativeAliases: ImmutableList, val currentUserMembership: CurrentUserMembership, - val latestEvent: EventTimelineItem?, val inviter: RoomMember?, val activeMembersCount: Long, val invitedMembersCount: Long, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt index 8063c67069..d01a7d1740 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt @@ -23,19 +23,15 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.MatrixRoomInfo import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper -import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toPersistentMap -import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.Membership as RustMembership import org.matrix.rustcomponents.sdk.RoomInfo as RustRoomInfo import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode -class MatrixRoomInfoMapper( - private val timelineItemMapper: EventTimelineItemMapper = EventTimelineItemMapper(), -) { - fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.use { +class MatrixRoomInfoMapper { + fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.let { return MatrixRoomInfo( id = RoomId(it.id), name = it.displayName, @@ -50,7 +46,6 @@ class MatrixRoomInfoMapper( canonicalAlias = it.canonicalAlias?.let(::RoomAlias), alternativeAliases = it.alternativeAliases.toImmutableList(), currentUserMembership = it.membership.map(), - latestEvent = it.latestEvent?.use(timelineItemMapper::map), inviter = it.inviter?.let(RoomMemberMapper::map), activeMembersCount = it.activeMembersCount.toLong(), invitedMembersCount = it.invitedMembersCount.toLong(), diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index f10938cc19..1a14c7a860 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -111,7 +111,7 @@ class RustMatrixRoom( override val roomInfoFlow: Flow = mxCallbackFlow { launch { - val initial = innerRoom.roomInfo().use(matrixRoomInfoMapper::map) + val initial = innerRoom.roomInfo().let(matrixRoomInfoMapper::map) channel.trySend(initial) } innerRoom.subscribeToRoomInfoUpdates(object : RoomInfoListener { @@ -199,7 +199,7 @@ class RustMatrixRoom( } override val displayName: String - get() = runCatching { innerRoom.displayName() }.getOrDefault("") + get() = runCatching { innerRoom.displayName() ?: "" }.getOrDefault("") override val topic: String? get() = runCatching { innerRoom.topic() }.getOrDefault(null) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt index f9c62c2f6a..3ccc071316 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt @@ -23,12 +23,13 @@ import io.element.android.libraries.matrix.impl.notificationsettings.RoomNotific import io.element.android.libraries.matrix.impl.room.map import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory -import org.matrix.rustcomponents.sdk.RoomInfo +import org.matrix.rustcomponents.sdk.RoomListItem import org.matrix.rustcomponents.sdk.use class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory()) { - fun create(roomInfo: RoomInfo): RoomSummaryDetails { - val latestRoomMessage = roomInfo.latestEvent?.use { + suspend fun create(roomListItem: RoomListItem): RoomSummaryDetails { + val roomInfo = roomListItem.roomInfo() + val latestRoomMessage = roomListItem.latestEvent()?.use { roomMessageFactory.create(it) } return RoomSummaryDetails( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt index 35f301c87e..3cfd01f54c 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt @@ -120,11 +120,9 @@ class RoomSummaryListProcessor( private suspend fun buildAndCacheRoomSummaryForIdentifier(identifier: String): RoomSummary { val builtRoomSummary = roomListService.roomOrNull(identifier)?.use { roomListItem -> - roomListItem.roomInfo().use { roomInfo -> - RoomSummary.Filled( - details = roomSummaryDetailsFactory.create(roomInfo) - ) - } + RoomSummary.Filled( + details = roomSummaryDetailsFactory.create(roomListItem) + ) } ?: buildEmptyRoomSummary() roomSummariesByIdentifier[builtRoomSummary.identifier()] = builtRoomSummary return builtRoomSummary diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt index 2ce9d4d435..dc012f67b3 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt @@ -17,7 +17,6 @@ package io.element.android.libraries.matrix.impl.timeline import io.element.android.libraries.matrix.impl.util.cancelAndDestroy -import io.element.android.libraries.matrix.impl.util.destroyAll import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.trySendBlocking @@ -28,7 +27,6 @@ import kotlinx.coroutines.flow.catch import org.matrix.rustcomponents.sdk.PaginationStatusListener import org.matrix.rustcomponents.sdk.Timeline import org.matrix.rustcomponents.sdk.TimelineDiff -import org.matrix.rustcomponents.sdk.TimelineItem import org.matrix.rustcomponents.sdk.TimelineListener import timber.log.Timber import uniffi.matrix_sdk_ui.LiveBackPaginationStatus @@ -47,7 +45,7 @@ internal fun Timeline.liveBackPaginationStatus(): Flow Timber.d(it, "liveBackPaginationStatus() failed") }.buffer(Channel.UNLIMITED) -internal fun Timeline.timelineDiffFlow(onInitialList: suspend (List) -> Unit): Flow> = +internal fun Timeline.timelineDiffFlow(): Flow> = callbackFlow { val listener = object : TimelineListener { override fun onUpdate(diff: List) { @@ -55,16 +53,10 @@ internal fun Timeline.timelineDiffFlow(onInitialList: suspend (List - postItems(initialList) - }.onEach { diffs -> - if (diffs.any { diff -> diff.eventOrigin() == EventItemOrigin.SYNC }) { - onNewSyncedEvent() + inner.timelineDiffFlow() + .onEach { diffs -> + if (diffs.any { diff -> diff.eventOrigin() == EventItemOrigin.SYNC }) { + onNewSyncedEvent() + } + postDiffs(diffs) } - postDiffs(diffs) - }.launchIn(this) + .launchIn(this) launch { fetchMembers() @@ -273,8 +274,19 @@ class RustTimeline( } private suspend fun postDiffs(diffs: List) { + val diffsToProcess = diffs.toMutableList() + if (!isInit.get()) { + val resetDiff = diffsToProcess.firstOrNull { it.change() == TimelineChange.RESET } + if (resetDiff != null) { + // Keep using the postItems logic so we can post the timelineItems asap. + postItems(resetDiff.reset() ?: emptyList()) + diffsToProcess.remove(resetDiff) + } + } initLatch.await() - timelineDiffProcessor.postDiffs(diffs) + if (diffsToProcess.isNotEmpty()) { + timelineDiffProcessor.postDiffs(diffsToProcess) + } } override suspend fun sendMessage(body: String, htmlBody: String?, mentions: List): Result = withContext(dispatcher) { diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index 4ff46c2bc4..6f42553ced 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -170,7 +170,7 @@ class RoomSummaryListProcessorTest { override suspend fun applyInput(input: RoomListInput) = Unit - override suspend fun room(roomId: String): RoomListItem { + override fun room(roomId: String): RoomListItem { return RoomListItem(Pointer.NULL) } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt index d5dddf3b7e..5583f6b11e 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt @@ -45,7 +45,6 @@ import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerL import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.Timeline -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import io.element.android.libraries.matrix.api.widget.MatrixWidgetDriver import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -746,7 +745,6 @@ fun aRoomInfo( canonicalAlias: RoomAlias? = null, alternativeAliases: List = emptyList(), currentUserMembership: CurrentUserMembership = CurrentUserMembership.JOINED, - latestEvent: EventTimelineItem? = null, inviter: RoomMember? = null, activeMembersCount: Long = 1, invitedMembersCount: Long = 0, @@ -771,7 +769,6 @@ fun aRoomInfo( canonicalAlias = canonicalAlias, alternativeAliases = alternativeAliases.toImmutableList(), currentUserMembership = currentUserMembership, - latestEvent = latestEvent, inviter = inviter, activeMembersCount = activeMembersCount, invitedMembersCount = invitedMembersCount,