From 8ce65b4429bb7b99387eab0e2ef10bcb094cf54c Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 22 Jun 2023 12:34:07 +0200 Subject: [PATCH] RoomList: change a bit the api of RoomSummaryDataSource --- .../invitelist/impl/InviteListPresenter.kt | 4 +- .../impl/DefaultInviteStateDataSource.kt | 4 +- .../roomlist/impl/RoomListPresenter.kt | 4 +- .../libraries/matrix/api/MatrixClient.kt | 1 - .../matrix/api/room/RoomSummaryDataSource.kt | 5 +- .../libraries/matrix/impl/RustMatrixClient.kt | 37 +++----- .../matrix/impl/room/RoomListExtensions.kt | 9 +- .../matrix/impl/room/RustMatrixRoom.kt | 2 +- .../impl/room/RustRoomSummaryDataSource.kt | 90 +++++++++---------- .../impl/timeline/MatrixTimelineItemMapper.kt | 4 +- .../impl/timeline/RustMatrixTimeline.kt | 6 +- .../test/room/FakeRoomSummaryDataSource.kt | 4 +- 12 files changed, 78 insertions(+), 92 deletions(-) diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt index db9fec3153..d4b4b23c8f 100644 --- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt +++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt @@ -49,8 +49,8 @@ class InviteListPresenter @Inject constructor( @Composable override fun present(): InviteListState { val invites by client - .invitesDataSource - .roomSummaries() + .roomSummaryDataSource + .inviteList() .collectAsState() var seenInvites by remember { mutableStateOf>(emptySet()) } diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/DefaultInviteStateDataSource.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/DefaultInviteStateDataSource.kt index 74697a5c06..2f387e654b 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/DefaultInviteStateDataSource.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/DefaultInviteStateDataSource.kt @@ -43,8 +43,8 @@ class DefaultInviteStateDataSource @Inject constructor( @Composable override fun inviteState(): InvitesState { val invites by client - .invitesDataSource - .roomSummaries() + .roomSummaryDataSource + .inviteList() .collectAsState() val seenInvites by seenInvitesStore diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt index 9448ff4b1b..30396da74d 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt @@ -77,7 +77,7 @@ class RoomListPresenter @Inject constructor( var filter by rememberSaveable { mutableStateOf("") } val roomSummaries by client .roomSummaryDataSource - .roomSummaries() + .roomList() .collectAsState() val networkConnectionStatus by networkMonitor.connectivity.collectAsState(initial = networkMonitor.currentConnectivityStatus) @@ -177,7 +177,7 @@ class RoomListPresenter @Inject constructor( // Safe to give bigger size than room list val extendedRangeEnd = range.last + midExtendedRangeSize val extendedRange = IntRange(extendedRangeStart, extendedRangeEnd) - client.roomSummaryDataSource.setSlidingSyncRange(extendedRange) + client.roomSummaryDataSource.updateRoomListVisibleRange(extendedRange) } private suspend fun mapRoomSummaries( diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 4a018e18da..485049585c 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -35,7 +35,6 @@ import java.io.Closeable interface MatrixClient : Closeable { val sessionId: SessionId val roomSummaryDataSource: RoomSummaryDataSource - val invitesDataSource: RoomSummaryDataSource val mediaLoader: MatrixMediaLoader fun getRoom(roomId: RoomId): MatrixRoom? fun findDM(userId: UserId): MatrixRoom? diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomSummaryDataSource.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomSummaryDataSource.kt index 6473a45bc7..4315bced9e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomSummaryDataSource.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomSummaryDataSource.kt @@ -28,6 +28,7 @@ interface RoomSummaryDataSource { } fun loadingState(): StateFlow - fun roomSummaries(): StateFlow> - fun setSlidingSyncRange(range: IntRange) + fun roomList(): StateFlow> + fun inviteList(): StateFlow> + fun updateRoomListVisibleRange(range: IntRange) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 54aa60e020..17b36f49a9 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -93,28 +93,18 @@ class RustMatrixClient constructor( } } - private val roomList = client.roomList() + private val roomListService = client.roomList() private val rustRoomSummaryDataSource: RustRoomSummaryDataSource = RustRoomSummaryDataSource( - roomList, - sessionCoroutineScope, - dispatchers, + roomListService = roomListService, + sessionCoroutineScope = sessionCoroutineScope, + coroutineDispatchers = dispatchers, ) override val roomSummaryDataSource: RoomSummaryDataSource get() = rustRoomSummaryDataSource - private val rustInvitesDataSource: RustRoomSummaryDataSource = - RustRoomSummaryDataSource( - roomList, - sessionCoroutineScope, - dispatchers, - ) - - override val invitesDataSource: RoomSummaryDataSource - get() = rustInvitesDataSource - private val rustMediaLoader = RustMediaLoader(baseCacheDirectory, dispatchers, client) override val mediaLoader: MatrixMediaLoader get() = rustMediaLoader @@ -123,17 +113,16 @@ class RustMatrixClient constructor( init { client.setDelegate(clientDelegate) - rustRoomSummaryDataSource.subscribeIfNeeded() - roomList.stateFlow() + rustRoomSummaryDataSource.init() + roomListService.stateFlow() .onEach { Timber.v("onRoomList state change: $it") } .launchIn(sessionCoroutineScope) - //rustInvitesDataSource.init() } override fun getRoom(roomId: RoomId): MatrixRoom? { - val roomListItem = roomList.roomOrNull(roomId.value) ?: return null + val roomListItem = roomListService.roomOrNull(roomId.value) ?: return null val fullRoom = roomListItem.fullRoom() return RustMatrixRoom( sessionId = sessionId, @@ -185,7 +174,7 @@ class RustMatrixClient constructor( // Wait to receive the room back from the sync withTimeout(30_000L) { - roomSummaryDataSource.roomSummaries() + roomSummaryDataSource.roomList() .filter { roomSummaries -> roomSummaries.map { it.identifier() }.contains(roomId.value) }.first() @@ -226,14 +215,14 @@ class RustMatrixClient constructor( override fun notificationService(): NotificationService = notificationService override fun startSync() { - if (!roomList.isSyncing()) { - roomList.sync() + if (!roomListService.isSyncing()) { + roomListService.sync() } } override fun stopSync() { - if (roomList.isSyncing()) { - roomList.stopSync() + if (roomListService.isSyncing()) { + roomListService.stopSync() } } @@ -242,7 +231,7 @@ class RustMatrixClient constructor( sessionCoroutineScope.cancel() client.setDelegate(null) verificationService.destroy() - roomList.destroy() + roomListService.destroy() client.destroy() } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListExtensions.kt index b77bd7fee3..c45d8967b4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListExtensions.kt @@ -7,6 +7,7 @@ import org.matrix.rustcomponents.sdk.RoomList import org.matrix.rustcomponents.sdk.RoomListEntriesListener import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate import org.matrix.rustcomponents.sdk.RoomListEntry +import org.matrix.rustcomponents.sdk.RoomListInterface import org.matrix.rustcomponents.sdk.RoomListItem import org.matrix.rustcomponents.sdk.RoomListState import org.matrix.rustcomponents.sdk.RoomListStateListener @@ -14,7 +15,7 @@ import org.matrix.rustcomponents.sdk.SlidingSyncListLoadingState import org.matrix.rustcomponents.sdk.SlidingSyncListStateObserver import timber.log.Timber -fun RoomList.stateFlow(): Flow = +fun RoomListInterface.stateFlow(): Flow = mxCallbackFlow { val listener = object : RoomListStateListener { override fun onUpdate(state: RoomListState) { @@ -24,7 +25,7 @@ fun RoomList.stateFlow(): Flow = state(listener) } -fun RoomList.loadingStateFlow(): Flow = +fun RoomListInterface.loadingStateFlow(): Flow = mxCallbackFlow { val listener = object : SlidingSyncListStateObserver { override fun didReceiveUpdate(newState: SlidingSyncListLoadingState) { @@ -36,7 +37,7 @@ fun RoomList.loadingStateFlow(): Flow = result.entriesLoadingStateStream } -fun RoomList.roomListEntriesUpdateFlow(onInitialList: suspend (List) -> Unit): Flow = +fun RoomListInterface.roomListEntriesUpdateFlow(onInitialList: suspend (List) -> Unit): Flow = mxCallbackFlow { val listener = object : RoomListEntriesListener { override fun onUpdate(roomEntriesUpdate: RoomListEntriesUpdate) { @@ -48,7 +49,7 @@ fun RoomList.roomListEntriesUpdateFlow(onInitialList: suspend (List>(emptyList()) + private val roomList = MutableStateFlow>(emptyList()) + private val inviteList = MutableStateFlow>(emptyList()) private val loadingState = MutableStateFlow(RoomSummaryDataSource.LoadingState.NotLoaded) - fun subscribeIfNeeded() { - sessionCoroutineScope.launch { - roomList.roomListEntriesUpdateFlow { roomListEntries -> - val summaries = roomListEntries.map(::buildSummaryForRoomListEntry) - updateRoomSummaries { - addAll(summaries) - } - }.onEach { - updateRoomSummaries { - applyUpdate(it) + fun init() { + sessionCoroutineScope.launch(coroutineDispatchers.computation) { + roomListService.roomListEntriesUpdateFlow { roomListEntries -> + roomList.value = roomListEntries.map(::buildSummaryForRoomListEntry) + }.onEach { update -> + roomList.getAndUpdate { + it.applyUpdate(update) } }.launchIn(this) } } - override fun roomSummaries(): StateFlow> { - return roomSummaries + override fun roomList(): StateFlow> { + return roomList + } + + override fun inviteList(): StateFlow> { + return inviteList } override fun loadingState(): StateFlow { return loadingState } - override fun setSlidingSyncRange(range: IntRange) { + override fun updateRoomListVisibleRange(range: IntRange) { Timber.v("setVisibleRange=$range") sessionCoroutineScope.launch { - val ranges = listOf(RoomListRange(range.first.toUInt(), range.last.toUInt())) - roomList.applyInput( - RoomListInput.Viewport(ranges) - ) + try { + val ranges = listOf(RoomListRange(range.first.toUInt(), range.last.toUInt())) + roomListService.applyInput( + RoomListInput.Viewport(ranges) + ) + } catch (exception: RoomListException) { + Timber.e(exception, "Failed updating visible range") + } } } - private fun MutableList.applyUpdate(update: RoomListEntriesUpdate) { - fun MutableList.fillUntil(untilIndex: Int) { - repeat((size - 1 until untilIndex).count()) { - add(buildEmptyRoomSummary()) - } - } + private fun List.applyUpdate(update: RoomListEntriesUpdate): List { + val newList = toMutableList() when (update) { is RoomListEntriesUpdate.Append -> { val roomSummaries = update.values.map { buildSummaryForRoomListEntry(it) } - addAll(roomSummaries) + newList.addAll(roomSummaries) } is RoomListEntriesUpdate.PushBack -> { val roomSummary = buildSummaryForRoomListEntry(update.value) - add(roomSummary) + newList.add(roomSummary) } is RoomListEntriesUpdate.PushFront -> { val roomSummary = buildSummaryForRoomListEntry(update.value) - add(0, roomSummary) + newList.add(0, roomSummary) } is RoomListEntriesUpdate.Set -> { - fillUntil(update.index.toInt()) val roomSummary = buildSummaryForRoomListEntry(update.value) - set(update.index.toInt(), roomSummary) + newList[update.index.toInt()] = roomSummary } is RoomListEntriesUpdate.Insert -> { val roomSummary = buildSummaryForRoomListEntry(update.value) - add(update.index.toInt(), roomSummary) + newList.add(update.index.toInt(), roomSummary) } is RoomListEntriesUpdate.Remove -> { - removeAt(update.index.toInt()) + newList.removeAt(update.index.toInt()) } is RoomListEntriesUpdate.Reset -> { - clear() - addAll(update.values.map { buildSummaryForRoomListEntry(it) }) + newList.clear() + newList.addAll(update.values.map { buildSummaryForRoomListEntry(it) }) } RoomListEntriesUpdate.PopBack -> { - removeFirstOrNull() + newList.removeFirstOrNull() } RoomListEntriesUpdate.PopFront -> { - removeLastOrNull() + newList.removeLastOrNull() } RoomListEntriesUpdate.Clear -> { - clear() + newList.clear() } } + return newList } private fun buildSummaryForRoomListEntry(entry: RoomListEntry): RoomSummary { @@ -139,7 +142,7 @@ internal class RustRoomSummaryDataSource( } private fun buildRoomSummaryForIdentifier(identifier: String): RoomSummary { - val roomListItem = roomList.roomOrNull(identifier) ?: return RoomSummary.Empty(identifier) + val roomListItem = roomListService.roomOrNull(identifier) ?: return RoomSummary.Empty(identifier) return roomListItem.use { roomListItem.fullRoom().use { fullRoom -> RoomSummary.Filled( @@ -148,11 +151,4 @@ internal class RustRoomSummaryDataSource( } } } - - private suspend fun updateRoomSummaries(block: MutableList.() -> Unit) = - withContext(coroutineDispatchers.diffUpdateDispatcher) { - val mutableRoomSummaries = roomSummaries.value.toMutableList() - block(mutableRoomSummaries) - roomSummaries.value = mutableRoomSummaries - } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineItemMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineItemMapper.kt index f7cf728691..f448873ab7 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineItemMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineItemMapper.kt @@ -26,7 +26,7 @@ import org.matrix.rustcomponents.sdk.TimelineItem class MatrixTimelineItemMapper( private val fetchDetailsForEvent: suspend (EventId) -> Result, - private val coroutineScope: CoroutineScope, + private val roomCoroutineScope: CoroutineScope, private val virtualTimelineItemMapper: VirtualTimelineItemMapper = VirtualTimelineItemMapper(), private val eventTimelineItemMapper: EventTimelineItemMapper = EventTimelineItemMapper(), ) { @@ -51,7 +51,7 @@ class MatrixTimelineItemMapper( return MatrixTimelineItem.Other } - private fun fetchEventDetails(eventId: EventId) = coroutineScope.launch { + private fun fetchEventDetails(eventId: EventId) = roomCoroutineScope.launch { fetchDetailsForEvent(eventId) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt index dcb518bf98..906ffa0967 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt @@ -39,7 +39,7 @@ import org.matrix.rustcomponents.sdk.TimelineItem import timber.log.Timber class RustMatrixTimeline( - coroutineScope: CoroutineScope, + roomCoroutineScope: CoroutineScope, private val matrixRoom: MatrixRoom, private val innerRoom: Room, private val coroutineDispatchers: CoroutineDispatchers, @@ -54,7 +54,7 @@ class RustMatrixTimeline( private val timelineItemFactory = MatrixTimelineItemMapper( fetchDetailsForEvent = this::fetchDetailsForEvent, - coroutineScope = coroutineScope, + roomCoroutineScope = roomCoroutineScope, virtualTimelineItemMapper = VirtualTimelineItemMapper(), eventTimelineItemMapper = EventTimelineItemMapper( contentMapper = TimelineEventContentMapper( @@ -66,7 +66,7 @@ class RustMatrixTimeline( private val timelineDiffProcessor = MatrixTimelineDiffProcessor( paginationState = paginationState, timelineItems = timelineItems, - coroutineScope = coroutineScope, + coroutineScope = roomCoroutineScope, diffDispatcher = coroutineDispatchers.diffUpdateDispatcher, timelineItemFactory = timelineItemFactory, ) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeRoomSummaryDataSource.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeRoomSummaryDataSource.kt index 969ad4b413..85f860ea06 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeRoomSummaryDataSource.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeRoomSummaryDataSource.kt @@ -29,14 +29,14 @@ class FakeRoomSummaryDataSource : RoomSummaryDataSource { roomSummariesFlow.emit(roomSummaries) } - override fun roomSummaries(): StateFlow> { + override fun roomList(): StateFlow> { return roomSummariesFlow } var latestSlidingSyncRange: IntRange? = null private set - override fun setSlidingSyncRange(range: IntRange) { + override fun updateRoomListVisibleRange(range: IntRange) { latestSlidingSyncRange = range } }