Enable Offline mode of the SyncService, so that the sync starts automatically when the network is back.
Also rely on the sync state to render the "Offline" banner.
This commit is contained in:
parent
f4afda119b
commit
f84aa03605
20 changed files with 91 additions and 74 deletions
|
|
@ -19,8 +19,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||
import androidx.compose.runtime.setValue
|
||||
import im.vector.app.features.analytics.plan.CryptoSessionStateChange
|
||||
import im.vector.app.features.analytics.plan.UserProperties
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.log.logger.LoggerTag
|
||||
|
|
@ -29,6 +27,8 @@ import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
|||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomListService
|
||||
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.isConnected
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||
import io.element.android.libraries.preferences.api.store.EnableNativeSlidingSyncUseCase
|
||||
|
|
@ -46,7 +46,7 @@ private val pusherTag = LoggerTag("Pusher", LoggerTag.PushLoggerTag)
|
|||
|
||||
class LoggedInPresenter @Inject constructor(
|
||||
private val matrixClient: MatrixClient,
|
||||
private val networkMonitor: NetworkMonitor,
|
||||
private val syncService: SyncService,
|
||||
private val pushService: PushService,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
private val analyticsService: AnalyticsService,
|
||||
|
|
@ -76,10 +76,10 @@ class LoggedInPresenter @Inject constructor(
|
|||
.launchIn(this)
|
||||
}
|
||||
val syncIndicator by matrixClient.roomListService.syncIndicator.collectAsState()
|
||||
val networkStatus by networkMonitor.connectivity.collectAsState()
|
||||
val syncState by syncService.syncState.collectAsState()
|
||||
val showSyncSpinner by remember {
|
||||
derivedStateOf {
|
||||
networkStatus == NetworkStatus.Online && syncIndicator == RoomListService.SyncIndicator.Show
|
||||
syncState.isConnected() && syncIndicator == RoomListService.SyncIndicator.Show
|
||||
}
|
||||
}
|
||||
var forceNativeSlidingSyncMigration by remember { mutableStateOf(false) }
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@
|
|||
package io.element.android.appnav.loggedin
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.di.SingleIn
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.SyncState
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
|
@ -27,7 +28,7 @@ const val SEND_QUEUES_RETRY_DELAY_MILLIS = 500L
|
|||
@SingleIn(SessionScope::class)
|
||||
class SendQueues @Inject constructor(
|
||||
private val matrixClient: MatrixClient,
|
||||
private val networkMonitor: NetworkMonitor,
|
||||
private val syncService: SyncService,
|
||||
) {
|
||||
/**
|
||||
* Launches the send queues retry mechanism in the given [coroutineScope].
|
||||
|
|
@ -36,12 +37,12 @@ class SendQueues @Inject constructor(
|
|||
@OptIn(FlowPreview::class)
|
||||
fun launchIn(coroutineScope: CoroutineScope) {
|
||||
combine(
|
||||
networkMonitor.connectivity,
|
||||
syncService.syncState,
|
||||
matrixClient.sendQueueDisabledFlow(),
|
||||
) { networkStatus, _ -> networkStatus }
|
||||
) { syncState, _ -> syncState }
|
||||
.debounce(SEND_QUEUES_RETRY_DELAY_MILLIS)
|
||||
.onEach { networkStatus ->
|
||||
if (networkStatus == NetworkStatus.Online) {
|
||||
.onEach { syncState ->
|
||||
if (syncState == SyncState.Running) {
|
||||
matrixClient.setAllSendQueuesEnabled(enabled = true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
|
|||
import io.element.android.appnav.room.joined.LoadingRoomNodeView
|
||||
import io.element.android.appnav.room.joined.LoadingRoomState
|
||||
import io.element.android.features.joinroom.api.JoinRoomEntryPoint
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.features.roomaliasesolver.api.RoomAliasResolverEntryPoint
|
||||
import io.element.android.features.roomdirectory.api.RoomDescription
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
|
|
@ -50,6 +48,8 @@ import io.element.android.libraries.matrix.api.getRoomInfoFlow
|
|||
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.isConnected
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
|
@ -68,7 +68,7 @@ class RoomFlowNode @AssistedInject constructor(
|
|||
private val client: MatrixClient,
|
||||
private val joinRoomEntryPoint: JoinRoomEntryPoint,
|
||||
private val roomAliasResolverEntryPoint: RoomAliasResolverEntryPoint,
|
||||
private val networkMonitor: NetworkMonitor,
|
||||
private val syncService: SyncService,
|
||||
private val membershipObserver: RoomMembershipObserver,
|
||||
) : BaseFlowNode<RoomFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
|
|
@ -211,10 +211,10 @@ class RoomFlowNode @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun loadingNode(buildContext: BuildContext) = node(buildContext) { modifier ->
|
||||
val networkStatus by networkMonitor.connectivity.collectAsState()
|
||||
val syncState by syncService.syncState.collectAsState()
|
||||
LoadingRoomNodeView(
|
||||
state = LoadingRoomState.Loading,
|
||||
hasNetworkConnection = networkStatus == NetworkStatus.Online,
|
||||
hasNetworkConnection = syncState.isConnected(),
|
||||
onBackClick = { navigateUp() },
|
||||
modifier = modifier,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ import dagger.assisted.Assisted
|
|||
import dagger.assisted.AssistedInject
|
||||
import io.element.android.anvilannotations.ContributesNode
|
||||
import io.element.android.appnav.room.RoomNavigationTarget
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
import io.element.android.libraries.architecture.NodeInputs
|
||||
|
|
@ -37,6 +35,8 @@ import io.element.android.libraries.architecture.createNode
|
|||
import io.element.android.libraries.architecture.inputs
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.isConnected
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
|
@ -48,7 +48,7 @@ class JoinedRoomFlowNode @AssistedInject constructor(
|
|||
@Assisted val buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
loadingRoomStateFlowFactory: LoadingRoomStateFlowFactory,
|
||||
private val networkMonitor: NetworkMonitor,
|
||||
private val syncService: SyncService,
|
||||
) :
|
||||
BaseFlowNode<JoinedRoomFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
|
|
@ -114,10 +114,10 @@ class JoinedRoomFlowNode @AssistedInject constructor(
|
|||
|
||||
private fun loadingNode(buildContext: BuildContext, onBackClick: () -> Unit) = node(buildContext) { modifier ->
|
||||
val loadingRoomState by loadingRoomStateStateFlow.collectAsState()
|
||||
val networkStatus by networkMonitor.connectivity.collectAsState()
|
||||
val syncState by syncService.syncState.collectAsState()
|
||||
LoadingRoomNodeView(
|
||||
state = loadingRoomState,
|
||||
hasNetworkConnection = networkStatus == NetworkStatus.Online,
|
||||
hasNetworkConnection = syncState.isConnected(),
|
||||
modifier = modifier,
|
||||
onBackClick = onBackClick
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,14 +14,13 @@ import app.cash.turbine.test
|
|||
import com.google.common.truth.Truth.assertThat
|
||||
import im.vector.app.features.analytics.plan.CryptoSessionStateChange
|
||||
import im.vector.app.features.analytics.plan.UserProperties
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomListService
|
||||
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
|
||||
import io.element.android.libraries.matrix.api.sync.SyncState
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
|
|
@ -29,6 +28,7 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID
|
|||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
|
||||
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
|
||||
import io.element.android.libraries.matrix.test.sync.FakeSyncService
|
||||
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
|
||||
import io.element.android.libraries.preferences.api.store.EnableNativeSlidingSyncUseCase
|
||||
import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
|
||||
|
|
@ -73,7 +73,7 @@ class LoggedInPresenterTest {
|
|||
@Test
|
||||
fun `present - show sync spinner`() = runTest {
|
||||
val roomListService = FakeRoomListService()
|
||||
val presenter = createLoggedInPresenter(roomListService, NetworkStatus.Online)
|
||||
val presenter = createLoggedInPresenter(roomListService, SyncState.Running)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
|
@ -94,7 +94,7 @@ class LoggedInPresenterTest {
|
|||
val encryptionService = FakeEncryptionService()
|
||||
val presenter = LoggedInPresenter(
|
||||
matrixClient = FakeMatrixClient(roomListService = roomListService, encryptionService = encryptionService),
|
||||
networkMonitor = FakeNetworkMonitor(NetworkStatus.Online),
|
||||
syncService = FakeSyncService(initialSyncState = SyncState.Running),
|
||||
pushService = FakePushService(),
|
||||
sessionVerificationService = verificationService,
|
||||
analyticsService = analyticsService,
|
||||
|
|
@ -574,7 +574,7 @@ class LoggedInPresenterTest {
|
|||
|
||||
private fun TestScope.createLoggedInPresenter(
|
||||
roomListService: RoomListService = FakeRoomListService(),
|
||||
networkStatus: NetworkStatus = NetworkStatus.Offline,
|
||||
syncState: SyncState = SyncState.Running,
|
||||
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
||||
sessionVerificationService: SessionVerificationService = FakeSessionVerificationService(),
|
||||
encryptionService: EncryptionService = FakeEncryptionService(),
|
||||
|
|
@ -584,7 +584,7 @@ class LoggedInPresenterTest {
|
|||
): LoggedInPresenter {
|
||||
return LoggedInPresenter(
|
||||
matrixClient = matrixClient,
|
||||
networkMonitor = FakeNetworkMonitor(networkStatus),
|
||||
syncService = FakeSyncService(initialSyncState = syncState),
|
||||
pushService = pushService,
|
||||
sessionVerificationService = sessionVerificationService,
|
||||
analyticsService = analyticsService,
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
package io.element.android.appnav.loggedin
|
||||
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.sync.SyncState
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||
import io.element.android.libraries.matrix.test.sync.FakeSyncService
|
||||
import io.element.android.tests.testutils.lambda.assert
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
import io.element.android.tests.testutils.lambda.value
|
||||
|
|
@ -25,8 +25,8 @@ import org.junit.Test
|
|||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class SendQueuesTest {
|
||||
private val matrixClient = FakeMatrixClient()
|
||||
private val networkMonitor = FakeNetworkMonitor()
|
||||
private val sut = SendQueues(matrixClient, networkMonitor)
|
||||
private val syncService = FakeSyncService(initialSyncState = SyncState.Running)
|
||||
private val sut = SendQueues(matrixClient, syncService)
|
||||
|
||||
@Test
|
||||
fun `test network status online and sending queue failed`() = runTest {
|
||||
|
|
@ -53,13 +53,13 @@ class SendQueuesTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `test network status offline and sending queue failed`() = runTest {
|
||||
fun `test sync state offline and sending queue failed`() = runTest {
|
||||
val sendQueueDisabledFlow = MutableSharedFlow<RoomId>(replay = 1)
|
||||
|
||||
val setAllSendQueuesEnabledLambda = lambdaRecorder { _: Boolean -> }
|
||||
matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow
|
||||
matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda
|
||||
networkMonitor.connectivity.value = NetworkStatus.Offline
|
||||
syncService.emitSyncState(SyncState.Offline)
|
||||
val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> }
|
||||
val room = FakeMatrixRoom(
|
||||
setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue