mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 03:06:14 +00:00
Merge pull request #7567 from hayaksi1/fix/4099-server-unreachable
Say when the server cannot be reached instead of showing nothing
This commit is contained in:
@@ -105,9 +105,18 @@ class LoggedInPresenter(
|
||||
}
|
||||
val syncIndicator by matrixClient.roomListService.syncIndicator.collectAsState()
|
||||
val isOnline by syncService.isOnline.collectAsState()
|
||||
val showSyncSpinner by remember {
|
||||
val hasNetwork by networkMonitor.connectivity.collectAsState()
|
||||
val syncIndicatorState by remember {
|
||||
derivedStateOf {
|
||||
isOnline && syncIndicator == RoomListService.SyncIndicator.Show
|
||||
when {
|
||||
isOnline -> if (syncIndicator == RoomListService.SyncIndicator.Show) {
|
||||
SyncIndicatorState.Syncing
|
||||
} else {
|
||||
SyncIndicatorState.Hidden
|
||||
}
|
||||
hasNetwork == NetworkStatus.Connected -> SyncIndicatorState.ServerUnreachable
|
||||
else -> SyncIndicatorState.Hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
var forceNativeSlidingSyncMigration by remember { mutableStateOf(false) }
|
||||
@@ -181,7 +190,7 @@ class LoggedInPresenter(
|
||||
}
|
||||
|
||||
return LoggedInState(
|
||||
showSyncSpinner = showSyncSpinner,
|
||||
syncIndicatorState = syncIndicatorState,
|
||||
pusherRegistrationState = pusherRegistrationState.value,
|
||||
ignoreRegistrationError = ignoreRegistrationError,
|
||||
forceNativeSlidingSyncMigration = forceNativeSlidingSyncMigration,
|
||||
|
||||
@@ -11,8 +11,14 @@ package io.element.android.appnav.loggedin
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.permissions.api.localnetwork.LocalNetworkPermissionDialog
|
||||
|
||||
enum class SyncIndicatorState {
|
||||
Hidden,
|
||||
Syncing,
|
||||
ServerUnreachable,
|
||||
}
|
||||
|
||||
data class LoggedInState(
|
||||
val showSyncSpinner: Boolean,
|
||||
val syncIndicatorState: SyncIndicatorState,
|
||||
val pusherRegistrationState: AsyncData<Unit>,
|
||||
val ignoreRegistrationError: Boolean,
|
||||
val forceNativeSlidingSyncMigration: Boolean,
|
||||
|
||||
+4
-3
@@ -17,7 +17,8 @@ open class LoggedInStatePreviewParam : PreviewParameterProvider<LoggedInState> {
|
||||
override val values: Sequence<LoggedInState>
|
||||
get() = sequenceOf(
|
||||
aLoggedInState(),
|
||||
aLoggedInState(showSyncSpinner = true),
|
||||
aLoggedInState(syncIndicatorState = SyncIndicatorState.Syncing),
|
||||
aLoggedInState(syncIndicatorState = SyncIndicatorState.ServerUnreachable),
|
||||
aLoggedInState(pusherRegistrationState = AsyncData.Failure(PusherRegistrationFailure.NoDistributorsAvailable())),
|
||||
aLoggedInState(forceNativeSlidingSyncMigration = true),
|
||||
aLoggedInState(localNetworkPermissionDialog = LocalNetworkPermissionDialog.Rationale),
|
||||
@@ -26,13 +27,13 @@ open class LoggedInStatePreviewParam : PreviewParameterProvider<LoggedInState> {
|
||||
}
|
||||
|
||||
fun aLoggedInState(
|
||||
showSyncSpinner: Boolean = false,
|
||||
syncIndicatorState: SyncIndicatorState = SyncIndicatorState.Hidden,
|
||||
pusherRegistrationState: AsyncData<Unit> = AsyncData.Uninitialized,
|
||||
forceNativeSlidingSyncMigration: Boolean = false,
|
||||
appName: String = "Element X",
|
||||
localNetworkPermissionDialog: LocalNetworkPermissionDialog = LocalNetworkPermissionDialog.None,
|
||||
) = LoggedInState(
|
||||
showSyncSpinner = showSyncSpinner,
|
||||
syncIndicatorState = syncIndicatorState,
|
||||
pusherRegistrationState = pusherRegistrationState,
|
||||
ignoreRegistrationError = false,
|
||||
forceNativeSlidingSyncMigration = forceNativeSlidingSyncMigration,
|
||||
|
||||
@@ -47,7 +47,7 @@ fun LoggedInView(
|
||||
) {
|
||||
SyncStateView(
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
isVisible = state.showSyncSpinner,
|
||||
state = state.syncIndicatorState,
|
||||
)
|
||||
}
|
||||
when (state.pusherRegistrationState) {
|
||||
|
||||
@@ -25,18 +25,23 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun SyncStateView(
|
||||
isVisible: Boolean,
|
||||
state: SyncIndicatorState,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = isVisible,
|
||||
visible = state != SyncIndicatorState.Hidden,
|
||||
modifier = modifier,
|
||||
enter = fadeIn(spring(stiffness = 500F)),
|
||||
exit = fadeOut(spring(stiffness = 500F)),
|
||||
) {
|
||||
AsyncIndicator.Loading(
|
||||
text = stringResource(id = CommonStrings.common_syncing),
|
||||
)
|
||||
when (state) {
|
||||
SyncIndicatorState.ServerUnreachable -> AsyncIndicator.Failure(
|
||||
text = stringResource(id = CommonStrings.common_server_unreachable),
|
||||
)
|
||||
else -> AsyncIndicator.Loading(
|
||||
text = stringResource(id = CommonStrings.common_syncing),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +51,18 @@ internal fun SyncStateViewPreview() = ElementPreview {
|
||||
// Add a box to see the shadow
|
||||
Box(modifier = Modifier.padding(24.dp)) {
|
||||
SyncStateView(
|
||||
isVisible = true
|
||||
state = SyncIndicatorState.Syncing
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun SyncStateViewServerUnreachablePreview() = ElementPreview {
|
||||
// Add a box to see the shadow
|
||||
Box(modifier = Modifier.padding(24.dp)) {
|
||||
SyncStateView(
|
||||
state = SyncIndicatorState.ServerUnreachable
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ class LoggedInPresenterTest {
|
||||
fun `present - initial state`() = runTest {
|
||||
createLoggedInPresenter().test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.showSyncSpinner).isFalse()
|
||||
assertThat(initialState.syncIndicatorState).isEqualTo(SyncIndicatorState.Hidden)
|
||||
assertThat(initialState.pusherRegistrationState.isUninitialized()).isTrue()
|
||||
assertThat(initialState.ignoreRegistrationError).isFalse()
|
||||
}
|
||||
@@ -97,11 +97,33 @@ class LoggedInPresenterTest {
|
||||
matrixClient = FakeMatrixClient(roomListService = roomListService),
|
||||
).test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.showSyncSpinner).isFalse()
|
||||
assertThat(initialState.syncIndicatorState).isEqualTo(SyncIndicatorState.Hidden)
|
||||
roomListService.postSyncIndicator(RoomListService.SyncIndicator.Show)
|
||||
consumeItemsUntilPredicate { it.showSyncSpinner }
|
||||
consumeItemsUntilPredicate { it.syncIndicatorState == SyncIndicatorState.Syncing }
|
||||
roomListService.postSyncIndicator(RoomListService.SyncIndicator.Hide)
|
||||
consumeItemsUntilPredicate { !it.showSyncSpinner }
|
||||
consumeItemsUntilPredicate { it.syncIndicatorState != SyncIndicatorState.Syncing }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - say the server is unreachable when the device has network but the sync is offline`() = runTest {
|
||||
createLoggedInPresenter(
|
||||
syncState = SyncState.Offline,
|
||||
networkMonitor = FakeNetworkMonitor(initialStatus = NetworkStatus.Connected),
|
||||
).test {
|
||||
consumeItemsUntilPredicate { it.syncIndicatorState == SyncIndicatorState.ServerUnreachable }
|
||||
cancelAndConsumeRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - say nothing when the device itself has no network`() = runTest {
|
||||
createLoggedInPresenter(
|
||||
syncState = SyncState.Offline,
|
||||
networkMonitor = FakeNetworkMonitor(initialStatus = NetworkStatus.Disconnected),
|
||||
).test {
|
||||
consumeItemsUntilPredicate { it.syncIndicatorState == SyncIndicatorState.Hidden }
|
||||
cancelAndConsumeRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,7 @@ class KonsistPreviewTest {
|
||||
"SecureBackupSetupViewChangePreview",
|
||||
"SelectedUserCannotRemovePreview",
|
||||
"SpaceMembersViewNoHeroesPreview",
|
||||
"SyncStateViewServerUnreachablePreview",
|
||||
"TextComposerAddCaptionPreview",
|
||||
"TextComposerCaptionPreview",
|
||||
"TextComposerEditCaptionPreview",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
LFS
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user