handling the first sync without any local cache as a loading state rather than showing the empty view

This commit is contained in:
Adam Brown 2022-06-11 23:11:48 +01:00
parent b82397d965
commit 83537b1367
2 changed files with 30 additions and 21 deletions

View File

@ -8,9 +8,7 @@ import app.dapk.st.matrix.message.MessageService
import app.dapk.st.matrix.room.RoomService import app.dapk.st.matrix.room.RoomService
import app.dapk.st.matrix.sync.* import app.dapk.st.matrix.sync.*
import app.dapk.st.matrix.sync.SyncService.SyncEvent.Typing import app.dapk.st.matrix.sync.SyncService.SyncEvent.Typing
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
@JvmInline @JvmInline
value class UnreadCount(val value: Int) value class UnreadCount(val value: Int)
@ -32,23 +30,34 @@ class DirectoryUseCase(
) { ) {
fun state(): Flow<DirectoryState> { fun state(): Flow<DirectoryState> {
return combine( return flow { emit(credentialsStore.credentials()!!.userId) }.flatMapMerge { userId ->
syncService.startSyncing().map { credentialsStore.credentials()!!.userId }, combine(
syncService.overview(), overviewDatasource(),
messageService.localEchos(), messageService.localEchos(),
roomStore.observeUnreadCountById(), roomStore.observeUnreadCountById(),
syncService.events() syncService.events()
) { userId, overviewState, localEchos, unread, events -> ) { overviewState, localEchos, unread, events ->
overviewState.mergeWithLocalEchos(localEchos, userId).map { roomOverview -> overviewState.mergeWithLocalEchos(localEchos, userId).map { roomOverview ->
RoomFoo( RoomFoo(
overview = roomOverview, overview = roomOverview,
unreadCount = UnreadCount(unread[roomOverview.roomId] ?: 0), unreadCount = UnreadCount(unread[roomOverview.roomId] ?: 0),
typing = events.filterIsInstance<Typing>().firstOrNull { it.roomId == roomOverview.roomId } typing = events.filterIsInstance<Typing>().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<RoomId, List<MessageService.LocalEcho>>, userId: UserId): OverviewState { private suspend fun OverviewState.mergeWithLocalEchos(localEchos: Map<RoomId, List<MessageService.LocalEcho>>, userId: UserId): OverviewState {
return when { return when {
localEchos.isEmpty() -> this localEchos.isEmpty() -> this

View File

@ -11,9 +11,7 @@ import app.dapk.st.work.WorkScheduler
import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage import com.google.firebase.messaging.RemoteMessage
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.firstOrNull
private var previousJob: Job? = null private var previousJob: Job? = null
@ -72,7 +70,7 @@ class PushAndroidService : FirebaseMessagingService() {
private suspend fun waitForEvent(timeout: Long, eventId: EventId): EventId? { private suspend fun waitForEvent(timeout: Long, eventId: EventId): EventId? {
return withTimeoutOrNull(timeout) { 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 { .firstOrNull {
it == eventId it == eventId
} }
@ -81,10 +79,12 @@ class PushAndroidService : FirebaseMessagingService() {
private suspend fun waitForUnreadChange(timeout: Long): String? { private suspend fun waitForUnreadChange(timeout: Long): String? {
return withTimeoutOrNull(timeout) { return withTimeoutOrNull(timeout) {
combine(module.syncService().startSyncing(), module.roomStore().observeUnread()) { _, unread -> unread } combine(module.syncService().startSyncing().startInstantly(), module.roomStore().observeUnread()) { _, unread -> unread }
.first() .first()
"ignored" "ignored"
} }
} }
} }
private fun Flow<Unit>.startInstantly() = this.onStart { emit(Unit) }