RoomList: try syncing when network is back and inError state
This commit is contained in:
@@ -22,7 +22,9 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import coil.Coil
|
||||
import com.bumble.appyx.core.composable.Children
|
||||
import com.bumble.appyx.core.lifecycle.subscribe
|
||||
@@ -43,6 +45,8 @@ import io.element.android.appnav.loggedin.LoggedInNode
|
||||
import io.element.android.features.analytics.api.AnalyticsEntryPoint
|
||||
import io.element.android.features.createroom.api.CreateRoomEntryPoint
|
||||
import io.element.android.features.invitelist.api.InviteListEntryPoint
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.features.preferences.api.PreferencesEntryPoint
|
||||
import io.element.android.features.roomlist.api.RoomListEntryPoint
|
||||
import io.element.android.features.verifysession.api.VerifySessionEntryPoint
|
||||
@@ -59,13 +63,17 @@ import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.MAIN_SPACE
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.sync.SyncState
|
||||
import io.element.android.libraries.matrix.ui.di.MatrixUIBindings
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
import io.element.android.services.appnavstate.api.AppNavigationStateService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@ContributesNode(AppScope::class)
|
||||
@@ -81,6 +89,7 @@ class LoggedInFlowNode @AssistedInject constructor(
|
||||
private val inviteListEntryPoint: InviteListEntryPoint,
|
||||
private val analyticsService: AnalyticsService,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val networkMonitor: NetworkMonitor,
|
||||
snackbarDispatcher: SnackbarDispatcher,
|
||||
) : BackstackNode<LoggedInFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
@@ -162,6 +171,27 @@ class LoggedInFlowNode @AssistedInject constructor(
|
||||
loggedInFlowProcessor.stopObserving()
|
||||
}
|
||||
)
|
||||
|
||||
observeSyncStateAndNetworkStatus()
|
||||
}
|
||||
|
||||
private fun observeSyncStateAndNetworkStatus() {
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
combine(
|
||||
syncService.syncState.debounce(100),
|
||||
networkMonitor.connectivity
|
||||
) { syncState, networkStatus ->
|
||||
syncState == SyncState.InError && networkStatus == NetworkStatus.Online
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.collect { restartSync ->
|
||||
if (restartSync) {
|
||||
syncService.startSync()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface NavTarget : Parcelable {
|
||||
|
||||
@@ -37,6 +37,7 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@@ -81,6 +82,7 @@ class NetworkMonitorImpl @Inject constructor(
|
||||
connectivityManager.unregisterNetworkCallback(callback)
|
||||
}
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.debounce(300)
|
||||
.stateIn(appCoroutineScope, SharingStarted.WhileSubscribed(), connectivityManager.activeNetworkStatus())
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ interface SyncService {
|
||||
fun stopSync()
|
||||
|
||||
/**
|
||||
*
|
||||
* Flow of [SyncState]. Will be updated as soon as the current [SyncState] changes.
|
||||
*/
|
||||
fun syncState(): StateFlow<SyncState>
|
||||
val syncState: StateFlow<SyncState>
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ class RustMatrixClient constructor(
|
||||
|
||||
init {
|
||||
client.setDelegate(clientDelegate)
|
||||
syncService.syncState()
|
||||
syncService.syncState
|
||||
.onEach { syncState ->
|
||||
if (syncState == SyncState.Syncing) {
|
||||
onSlidingSyncUpdate()
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.impl.room.roomListStateFlow
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
@@ -46,13 +47,10 @@ class RustSyncService(
|
||||
}
|
||||
}
|
||||
|
||||
override fun syncState(): StateFlow<SyncState> {
|
||||
return roomListService
|
||||
override val syncState: StateFlow<SyncState> =
|
||||
roomListService
|
||||
.roomListStateFlow()
|
||||
.map(RoomListState::toSyncState)
|
||||
.onEach { syncState ->
|
||||
Timber.d("OnSyncState updated = $syncState")
|
||||
}
|
||||
.stateIn(sessionCoroutineScope, SharingStarted.Eagerly, SyncState.Idle)
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.stateIn(sessionCoroutineScope, SharingStarted.WhileSubscribed(), SyncState.Idle)
|
||||
}
|
||||
|
||||
@@ -23,21 +23,19 @@ import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
class FakeSyncService : SyncService {
|
||||
|
||||
private val syncState = MutableStateFlow(SyncState.Idle)
|
||||
private val syncStateFlow = MutableStateFlow(SyncState.Idle)
|
||||
|
||||
fun simulateError() {
|
||||
syncState.value = SyncState.InError
|
||||
syncStateFlow.value = SyncState.InError
|
||||
}
|
||||
|
||||
override fun startSync() {
|
||||
syncState.value = SyncState.Syncing
|
||||
syncStateFlow.value = SyncState.Syncing
|
||||
}
|
||||
|
||||
override fun stopSync() {
|
||||
syncState.value = SyncState.Terminated
|
||||
syncStateFlow.value = SyncState.Terminated
|
||||
}
|
||||
|
||||
override fun syncState(): StateFlow<SyncState> {
|
||||
return syncState
|
||||
}
|
||||
override val syncState: StateFlow<SyncState> = syncStateFlow
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user