handling the first sync without any local cache as a loading state rather than showing the empty view
This commit is contained in:
parent
b82397d965
commit
83537b1367
|
@ -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
|
||||||
|
|
|
@ -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) }
|
Loading…
Reference in New Issue