From 83537b13678bf5eec8790ed525bbe796814e198b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Sat, 11 Jun 2022 23:11:48 +0100 Subject: [PATCH] handling the first sync without any local cache as a loading state rather than showing the empty view --- .../app/dapk/st/directory/DirectoryUseCase.kt | 41 +++++++++++-------- .../st/notifications/PushAndroidService.kt | 10 ++--- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/features/directory/src/main/kotlin/app/dapk/st/directory/DirectoryUseCase.kt b/features/directory/src/main/kotlin/app/dapk/st/directory/DirectoryUseCase.kt index 7e327fc..e4f1aa8 100644 --- a/features/directory/src/main/kotlin/app/dapk/st/directory/DirectoryUseCase.kt +++ b/features/directory/src/main/kotlin/app/dapk/st/directory/DirectoryUseCase.kt @@ -8,9 +8,7 @@ import app.dapk.st.matrix.message.MessageService import app.dapk.st.matrix.room.RoomService import app.dapk.st.matrix.sync.* import app.dapk.st.matrix.sync.SyncService.SyncEvent.Typing -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.* @JvmInline value class UnreadCount(val value: Int) @@ -32,23 +30,34 @@ class DirectoryUseCase( ) { fun state(): Flow { - return combine( - syncService.startSyncing().map { credentialsStore.credentials()!!.userId }, - syncService.overview(), - messageService.localEchos(), - roomStore.observeUnreadCountById(), - syncService.events() - ) { userId, overviewState, localEchos, unread, events -> - overviewState.mergeWithLocalEchos(localEchos, userId).map { roomOverview -> - RoomFoo( - overview = roomOverview, - unreadCount = UnreadCount(unread[roomOverview.roomId] ?: 0), - typing = events.filterIsInstance().firstOrNull { it.roomId == roomOverview.roomId } - ) + return flow { emit(credentialsStore.credentials()!!.userId) }.flatMapMerge { userId -> + combine( + overviewDatasource(), + messageService.localEchos(), + roomStore.observeUnreadCountById(), + syncService.events() + ) { overviewState, localEchos, unread, events -> + overviewState.mergeWithLocalEchos(localEchos, userId).map { roomOverview -> + RoomFoo( + overview = roomOverview, + unreadCount = UnreadCount(unread[roomOverview.roomId] ?: 0), + typing = events.filterIsInstance().firstOrNull { it.roomId == roomOverview.roomId } + ) + } } } } + private fun overviewDatasource() = combine( + syncService.startSyncing().map { false }.onStart { emit(true) }, + syncService.overview() + ) { isFirstLoad, overview -> + when { + isFirstLoad && overview.isEmpty() -> null + else -> overview + } + }.filterNotNull() + private suspend fun OverviewState.mergeWithLocalEchos(localEchos: Map>, userId: UserId): OverviewState { return when { localEchos.isEmpty() -> this diff --git a/features/notifications/src/main/kotlin/app/dapk/st/notifications/PushAndroidService.kt b/features/notifications/src/main/kotlin/app/dapk/st/notifications/PushAndroidService.kt index 9f6bf55..cd56aa8 100644 --- a/features/notifications/src/main/kotlin/app/dapk/st/notifications/PushAndroidService.kt +++ b/features/notifications/src/main/kotlin/app/dapk/st/notifications/PushAndroidService.kt @@ -11,9 +11,7 @@ import app.dapk.st.work.WorkScheduler import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import kotlinx.coroutines.* -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.* private var previousJob: Job? = null @@ -72,7 +70,7 @@ class PushAndroidService : FirebaseMessagingService() { private suspend fun waitForEvent(timeout: Long, eventId: EventId): EventId? { return withTimeoutOrNull(timeout) { - combine(module.syncService().startSyncing(), module.syncService().observeEvent(eventId)) { _, event -> event } + combine(module.syncService().startSyncing().startInstantly(), module.syncService().observeEvent(eventId)) { _, event -> event } .firstOrNull { it == eventId } @@ -81,10 +79,12 @@ class PushAndroidService : FirebaseMessagingService() { private suspend fun waitForUnreadChange(timeout: Long): String? { return withTimeoutOrNull(timeout) { - combine(module.syncService().startSyncing(), module.roomStore().observeUnread()) { _, unread -> unread } + combine(module.syncService().startSyncing().startInstantly(), module.roomStore().observeUnread()) { _, unread -> unread } .first() "ignored" } } } + +private fun Flow.startInstantly() = this.onStart { emit(Unit) } \ No newline at end of file