Skip to content

Commit b7abdb0

Browse files
bmartyElementBot
andauthored
Add a inderminate progress bar when loging out and in Waiting state. (#4538)
* Add a check network connection when the Waiting state last too long. * Update screenshots --------- Co-authored-by: ElementBot <[email protected]>
1 parent f335eb1 commit b7abdb0

File tree

9 files changed

+100
-17
lines changed

9 files changed

+100
-17
lines changed

features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import androidx.compose.runtime.getValue
1515
import androidx.compose.runtime.mutableStateOf
1616
import androidx.compose.runtime.remember
1717
import androidx.compose.runtime.rememberCoroutineScope
18+
import androidx.compose.runtime.setValue
1819
import io.element.android.libraries.architecture.AsyncAction
1920
import io.element.android.libraries.architecture.AsyncData
2021
import io.element.android.libraries.architecture.Presenter
@@ -25,6 +26,7 @@ import io.element.android.libraries.matrix.api.encryption.BackupState
2526
import io.element.android.libraries.matrix.api.encryption.BackupUploadState
2627
import io.element.android.libraries.matrix.api.encryption.EncryptionService
2728
import kotlinx.coroutines.CoroutineScope
29+
import kotlinx.coroutines.delay
2830
import kotlinx.coroutines.launch
2931
import javax.inject.Inject
3032

@@ -44,6 +46,16 @@ class LogoutPresenter @Inject constructor(
4446
}
4547
.collectAsState(initial = BackupUploadState.Unknown)
4648

49+
var waitingForALongTime by remember { mutableStateOf(false) }
50+
LaunchedEffect(backupUploadState) {
51+
if (backupUploadState is BackupUploadState.Waiting) {
52+
delay(2_000)
53+
waitingForALongTime = true
54+
} else {
55+
waitingForALongTime = false
56+
}
57+
}
58+
4759
val isLastDevice by encryptionService.isLastDevice.collectAsState()
4860
val backupState by encryptionService.backupStateStateFlow.collectAsState()
4961
val recoveryState by encryptionService.recoveryStateStateFlow.collectAsState()
@@ -79,6 +91,7 @@ class LogoutPresenter @Inject constructor(
7991
doesBackupExistOnServer = doesBackupExistOnServerAction.value.dataOrNull().orTrue(),
8092
recoveryState = recoveryState,
8193
backupUploadState = backupUploadState,
94+
waitingForALongTime = waitingForALongTime,
8295
logoutAction = logoutAction.value,
8396
eventSink = ::handleEvents
8497
)

features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ data class LogoutState(
1818
val doesBackupExistOnServer: Boolean,
1919
val recoveryState: RecoveryState,
2020
val backupUploadState: BackupUploadState,
21+
val waitingForALongTime: Boolean,
2122
val logoutAction: AsyncAction<Unit>,
2223
val eventSink: (LogoutEvents) -> Unit,
2324
)

features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStateProvider.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ open class LogoutStateProvider : PreviewParameterProvider<LogoutState> {
2929
aLogoutState(isLastDevice = true, recoveryState = RecoveryState.DISABLED),
3030
// Last session no backup
3131
aLogoutState(isLastDevice = true, backupState = BackupState.UNKNOWN, doesBackupExistOnServer = false),
32+
aLogoutState(
33+
isLastDevice = false,
34+
backupUploadState = BackupUploadState.Waiting,
35+
),
36+
aLogoutState(
37+
isLastDevice = false,
38+
backupUploadState = BackupUploadState.Waiting,
39+
waitingForALongTime = true,
40+
),
3241
)
3342
}
3443

@@ -38,6 +47,7 @@ fun aLogoutState(
3847
doesBackupExistOnServer: Boolean = true,
3948
recoveryState: RecoveryState = RecoveryState.ENABLED,
4049
backupUploadState: BackupUploadState = BackupUploadState.Unknown,
50+
waitingForALongTime: Boolean = false,
4151
logoutAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
4252
eventSink: (LogoutEvents) -> Unit = {},
4353
) = LogoutState(
@@ -46,6 +56,7 @@ fun aLogoutState(
4656
doesBackupExistOnServer = doesBackupExistOnServer,
4757
recoveryState = recoveryState,
4858
backupUploadState = backupUploadState,
59+
waitingForALongTime = waitingForALongTime,
4960
logoutAction = logoutAction,
5061
eventSink = eventSink,
5162
)

features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -143,24 +143,41 @@ private fun ColumnScope.Buttons(
143143
@Composable
144144
private fun Content(
145145
state: LogoutState,
146+
modifier: Modifier = Modifier,
146147
) {
147-
if (state.backupUploadState is BackupUploadState.Uploading) {
148-
Column(
149-
modifier = Modifier
150-
.fillMaxWidth()
151-
.padding(top = 60.dp, start = 20.dp, end = 20.dp),
152-
verticalArrangement = Arrangement.spacedBy(8.dp)
153-
) {
154-
LinearProgressIndicator(
155-
modifier = Modifier.fillMaxWidth(),
156-
progress = { state.backupUploadState.backedUpCount.toFloat() / state.backupUploadState.totalCount.toFloat() },
157-
trackColor = ElementTheme.colors.progressIndicatorTrackColor,
158-
)
159-
Text(
160-
modifier = Modifier.align(Alignment.End),
161-
text = "${state.backupUploadState.backedUpCount} / ${state.backupUploadState.totalCount}",
162-
style = ElementTheme.typography.fontBodySmRegular,
163-
)
148+
Column(
149+
modifier = modifier
150+
.fillMaxWidth()
151+
.padding(top = 60.dp, start = 20.dp, end = 20.dp),
152+
verticalArrangement = Arrangement.spacedBy(8.dp)
153+
) {
154+
when (state.backupUploadState) {
155+
is BackupUploadState.Uploading -> {
156+
LinearProgressIndicator(
157+
modifier = Modifier.fillMaxWidth(),
158+
progress = { state.backupUploadState.backedUpCount.toFloat() / state.backupUploadState.totalCount.toFloat() },
159+
trackColor = ElementTheme.colors.progressIndicatorTrackColor,
160+
)
161+
Text(
162+
modifier = Modifier.align(Alignment.End),
163+
text = "${state.backupUploadState.backedUpCount} / ${state.backupUploadState.totalCount}",
164+
style = ElementTheme.typography.fontBodySmRegular,
165+
)
166+
}
167+
BackupUploadState.Waiting -> {
168+
LinearProgressIndicator(
169+
modifier = Modifier.fillMaxWidth(),
170+
trackColor = ElementTheme.colors.progressIndicatorTrackColor,
171+
)
172+
if (state.waitingForALongTime) {
173+
Text(
174+
modifier = Modifier.align(Alignment.CenterHorizontally),
175+
text = stringResource(CommonStrings.common_please_check_internet_connection),
176+
style = ElementTheme.typography.fontBodySmRegular,
177+
)
178+
}
179+
}
180+
else -> Unit
164181
}
165182
}
166183
}

features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class LogoutPresenterTest {
4444
assertThat(initialState.doesBackupExistOnServer).isTrue()
4545
assertThat(initialState.recoveryState).isEqualTo(RecoveryState.UNKNOWN)
4646
assertThat(initialState.backupUploadState).isEqualTo(BackupUploadState.Unknown)
47+
assertThat(initialState.waitingForALongTime).isFalse()
4748
assertThat(initialState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
4849
}
4950
}
@@ -66,6 +67,34 @@ class LogoutPresenterTest {
6667
}
6768
}
6869

70+
@Test
71+
fun `present - initial state - waiting a long time`() = runTest {
72+
val encryptionService = FakeEncryptionService()
73+
encryptionService.givenWaitForBackupUploadSteadyStateFlow(
74+
flow {
75+
emit(BackupUploadState.Waiting)
76+
delay(3_000)
77+
}
78+
)
79+
val presenter = createLogoutPresenter(
80+
encryptionService = encryptionService
81+
)
82+
moleculeFlow(RecompositionMode.Immediate) {
83+
presenter.present()
84+
}.test {
85+
val initialState = awaitItem()
86+
assertThat(initialState.waitingForALongTime).isFalse()
87+
assertThat(initialState.backupUploadState).isEqualTo(BackupUploadState.Unknown)
88+
val waitingState = awaitItem()
89+
assertThat(waitingState.backupUploadState).isEqualTo(BackupUploadState.Waiting)
90+
assertThat(initialState.waitingForALongTime).isFalse()
91+
skipItems(1)
92+
val waitingALongTimeState = awaitItem()
93+
assertThat(waitingALongTimeState.backupUploadState).isEqualTo(BackupUploadState.Waiting)
94+
assertThat(waitingALongTimeState.waitingForALongTime).isTrue()
95+
}
96+
}
97+
6998
@Test
7099
fun `present - initial state - backing up`() = runTest {
71100
val encryptionService = FakeEncryptionService()
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)