From 19e2c104af7c22cede27db604a969031439c2407 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 26 Jun 2023 22:30:12 +0200 Subject: [PATCH] RoomList: update LoadingState and fix a crash --- .../matrix/api/room/RoomSummaryDataSource.kt | 10 ++--- .../libraries/matrix/api/sync/SyncService.kt | 4 +- .../impl/room/RustRoomSummaryDataSource.kt | 41 +++++++++++++++---- .../matrix/impl/sync/RustSyncService.kt | 4 +- .../matrix/test/sync/FakeSyncService.kt | 6 ++- 5 files changed, 45 insertions(+), 20 deletions(-) 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 d1fa6fc454..e0aaecd6a9 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 @@ -20,14 +20,12 @@ import kotlinx.coroutines.flow.StateFlow interface RoomSummaryDataSource { - enum class LoadingState { - NotLoaded, - PreLoaded, - PartiallyLoaded, - FullyLoaded, + sealed class LoadingState { + object NotLoaded : LoadingState() + data class Loaded(val numberOfRooms: Int): LoadingState() } - fun loadingState(): StateFlow + fun allRoomsLoadingState(): StateFlow fun allRooms(): StateFlow> fun inviteRooms(): StateFlow> fun updateRoomListVisibleRange(range: IntRange) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt index b47c463dd8..9ed74c48e6 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/sync/SyncService.kt @@ -22,12 +22,12 @@ interface SyncService { /** * Tries to start the sync. If already syncing it has no effect. */ - fun startSync() + fun startSync(): Result /** * Tries to stop the sync. If service is not syncing it has no effect. */ - fun stopSync() + fun stopSync(): Result /** * Flow of [SyncState]. Will be updated as soon as the current [SyncState] changes. diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt index e7fd3025bd..ed1a060086 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt @@ -20,13 +20,18 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.room.RoomSummary import io.element.android.libraries.matrix.api.room.RoomSummaryDataSource import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import org.matrix.rustcomponents.sdk.RoomList +import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate import org.matrix.rustcomponents.sdk.RoomListException import org.matrix.rustcomponents.sdk.RoomListInput +import org.matrix.rustcomponents.sdk.RoomListLoadingState import org.matrix.rustcomponents.sdk.RoomListRange import org.matrix.rustcomponents.sdk.RoomListService import timber.log.Timber @@ -41,16 +46,20 @@ internal class RustRoomSummaryDataSource( private val allRooms = MutableStateFlow>(emptyList()) private val inviteRooms = MutableStateFlow>(emptyList()) - private val loadingState = MutableStateFlow(RoomSummaryDataSource.LoadingState.NotLoaded) + private val allRoomsLoadingState: MutableStateFlow = MutableStateFlow(RoomSummaryDataSource.LoadingState.NotLoaded) private val allRoomsListProcessor = RoomSummaryListProcessor(allRooms, roomListService, roomSummaryDetailsFactory) init { sessionCoroutineScope.launch(coroutineDispatchers.computation) { - roomListService.allRooms().entriesFlow { roomListEntries -> - allRoomsListProcessor.postEntries(roomListEntries) - }.onEach { update -> - allRoomsListProcessor.postUpdate(update) - }.launchIn(this) + val allRooms = roomListService.allRooms() + allRooms.observeEntriesWithProcessor(allRoomsListProcessor) + .launchIn(this) + + allRooms.loadingStateFlow() + .map { it.toRoomSummaryDataSourceLoadingState() } + .onEach { + allRoomsLoadingState.value = it + }.launchIn(this) } } @@ -62,8 +71,8 @@ internal class RustRoomSummaryDataSource( return inviteRooms } - override fun loadingState(): StateFlow { - return loadingState + override fun allRoomsLoadingState(): StateFlow { + return allRoomsLoadingState } override fun updateRoomListVisibleRange(range: IntRange) { @@ -80,3 +89,19 @@ internal class RustRoomSummaryDataSource( } } } + +private fun RoomListLoadingState.toRoomSummaryDataSourceLoadingState(): RoomSummaryDataSource.LoadingState { + return when (this) { + is RoomListLoadingState.Loaded -> RoomSummaryDataSource.LoadingState.Loaded(maximumNumberOfRooms?.toInt() ?: 0) + is RoomListLoadingState.NotLoaded -> RoomSummaryDataSource.LoadingState.NotLoaded + } +} + +fun RoomList.observeEntriesWithProcessor(processor: RoomSummaryListProcessor): Flow { + return entriesFlow { roomListEntries -> + processor.postEntries(roomListEntries) + }.onEach { update -> + processor.postUpdate(update) + } +} + diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt index 12af4a262e..2103833704 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt @@ -33,13 +33,13 @@ class RustSyncService( sessionCoroutineScope: CoroutineScope ) : SyncService { - override fun startSync() { + override fun startSync() = runCatching { if (!roomListService.isSyncing()) { roomListService.sync() } } - override fun stopSync() { + override fun stopSync() = runCatching { if (roomListService.isSyncing()) { roomListService.stopSync() } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt index cd452ce591..a0e57997d3 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/sync/FakeSyncService.kt @@ -29,12 +29,14 @@ class FakeSyncService : SyncService { syncStateFlow.value = SyncState.InError } - override fun startSync() { + override fun startSync(): Result { syncStateFlow.value = SyncState.Syncing + return Result.success(Unit) } - override fun stopSync() { + override fun stopSync(): Result { syncStateFlow.value = SyncState.Terminated + return Result.success(Unit) } override val syncState: StateFlow = syncStateFlow