|
|
|
@ -18,9 +18,9 @@ package io.element.android.features.logout.impl
@@ -18,9 +18,9 @@ package io.element.android.features.logout.impl
|
|
|
|
|
|
|
|
|
|
import androidx.compose.foundation.layout.Arrangement |
|
|
|
|
import androidx.compose.foundation.layout.Column |
|
|
|
|
import androidx.compose.foundation.layout.ColumnScope |
|
|
|
|
import androidx.compose.foundation.layout.fillMaxWidth |
|
|
|
|
import androidx.compose.foundation.layout.padding |
|
|
|
|
import androidx.compose.material3.ExperimentalMaterial3Api |
|
|
|
|
import androidx.compose.runtime.Composable |
|
|
|
|
import androidx.compose.runtime.LaunchedEffect |
|
|
|
|
import androidx.compose.ui.Alignment |
|
|
|
@ -29,11 +29,8 @@ import androidx.compose.ui.res.stringResource
@@ -29,11 +29,8 @@ import androidx.compose.ui.res.stringResource
|
|
|
|
|
import androidx.compose.ui.tooling.preview.PreviewParameter |
|
|
|
|
import androidx.compose.ui.unit.dp |
|
|
|
|
import io.element.android.libraries.architecture.Async |
|
|
|
|
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule |
|
|
|
|
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule |
|
|
|
|
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage |
|
|
|
|
import io.element.android.libraries.designsystem.atomic.pages.UserStoryFlowPage |
|
|
|
|
import io.element.android.libraries.designsystem.components.ProgressDialog |
|
|
|
|
import io.element.android.libraries.designsystem.components.button.BackButton |
|
|
|
|
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog |
|
|
|
|
import io.element.android.libraries.designsystem.preview.ElementPreview |
|
|
|
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight |
|
|
|
@ -41,7 +38,6 @@ import io.element.android.libraries.designsystem.theme.components.Button
@@ -41,7 +38,6 @@ import io.element.android.libraries.designsystem.theme.components.Button
|
|
|
|
|
import io.element.android.libraries.designsystem.theme.components.LinearProgressIndicator |
|
|
|
|
import io.element.android.libraries.designsystem.theme.components.OutlinedButton |
|
|
|
|
import io.element.android.libraries.designsystem.theme.components.Text |
|
|
|
|
import io.element.android.libraries.designsystem.theme.components.TopAppBar |
|
|
|
|
import io.element.android.libraries.designsystem.theme.progressIndicatorTrackColor |
|
|
|
|
import io.element.android.libraries.designsystem.utils.CommonDrawables |
|
|
|
|
import io.element.android.libraries.matrix.api.encryption.BackupUploadState |
|
|
|
@ -51,7 +47,6 @@ import io.element.android.libraries.testtags.testTag
@@ -51,7 +47,6 @@ import io.element.android.libraries.testtags.testTag
|
|
|
|
|
import io.element.android.libraries.theme.ElementTheme |
|
|
|
|
import io.element.android.libraries.ui.strings.CommonStrings |
|
|
|
|
|
|
|
|
|
@OptIn(ExperimentalMaterial3Api::class) |
|
|
|
|
@Composable |
|
|
|
|
fun LogoutView( |
|
|
|
|
state: LogoutState, |
|
|
|
@ -62,29 +57,24 @@ fun LogoutView(
@@ -62,29 +57,24 @@ fun LogoutView(
|
|
|
|
|
) { |
|
|
|
|
val eventSink = state.eventSink |
|
|
|
|
|
|
|
|
|
HeaderFooterPage( |
|
|
|
|
UserStoryFlowPage( |
|
|
|
|
canGoBack = true, |
|
|
|
|
onBackClicked = onBackClicked, |
|
|
|
|
title = title(state), |
|
|
|
|
subTitle = subtitle(state), |
|
|
|
|
iconResourceId = CommonDrawables.ic_key, |
|
|
|
|
modifier = modifier, |
|
|
|
|
topBar = { |
|
|
|
|
TopAppBar( |
|
|
|
|
navigationIcon = { BackButton(onClick = onBackClicked) }, |
|
|
|
|
title = {}, |
|
|
|
|
) |
|
|
|
|
}, |
|
|
|
|
header = { |
|
|
|
|
HeaderContent(state = state) |
|
|
|
|
}, |
|
|
|
|
footer = { |
|
|
|
|
BottomMenu( |
|
|
|
|
content = { Content(state) }, |
|
|
|
|
buttons = { |
|
|
|
|
Buttons( |
|
|
|
|
state = state, |
|
|
|
|
onChangeRecoveryKeyClicked = onChangeRecoveryKeyClicked, |
|
|
|
|
onLogoutClicked = { |
|
|
|
|
eventSink(LogoutEvents.Logout(ignoreSdkError = false)) |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
) { |
|
|
|
|
Content(state = state) |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// Log out confirmation dialog |
|
|
|
|
if (state.showConfirmationDialog) { |
|
|
|
@ -92,9 +82,6 @@ fun LogoutView(
@@ -92,9 +82,6 @@ fun LogoutView(
|
|
|
|
|
title = stringResource(id = CommonStrings.action_signout), |
|
|
|
|
content = stringResource(id = R.string.screen_signout_confirmation_dialog_content), |
|
|
|
|
submitText = stringResource(id = CommonStrings.action_signout), |
|
|
|
|
onCancelClicked = { |
|
|
|
|
eventSink(LogoutEvents.CloseDialogs) |
|
|
|
|
}, |
|
|
|
|
onSubmitClicked = { |
|
|
|
|
eventSink(LogoutEvents.Logout(ignoreSdkError = false)) |
|
|
|
|
}, |
|
|
|
@ -112,9 +99,6 @@ fun LogoutView(
@@ -112,9 +99,6 @@ fun LogoutView(
|
|
|
|
|
title = stringResource(id = CommonStrings.dialog_title_error), |
|
|
|
|
content = stringResource(id = CommonStrings.error_unknown), |
|
|
|
|
submitText = stringResource(id = CommonStrings.action_signout_anyway), |
|
|
|
|
onCancelClicked = { |
|
|
|
|
eventSink(LogoutEvents.CloseDialogs) |
|
|
|
|
}, |
|
|
|
|
onSubmitClicked = { |
|
|
|
|
eventSink(LogoutEvents.Logout(ignoreSdkError = true)) |
|
|
|
|
}, |
|
|
|
@ -132,30 +116,23 @@ fun LogoutView(
@@ -132,30 +116,23 @@ fun LogoutView(
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Composable |
|
|
|
|
private fun HeaderContent( |
|
|
|
|
state: LogoutState, |
|
|
|
|
modifier: Modifier = Modifier, |
|
|
|
|
) { |
|
|
|
|
val title = when { |
|
|
|
|
private fun title(state: LogoutState): String { |
|
|
|
|
return when { |
|
|
|
|
state.backupUploadState.isBackingUp() -> stringResource(id = R.string.screen_signout_key_backup_ongoing_title) |
|
|
|
|
state.isLastSession -> stringResource(id = R.string.screen_signout_key_backup_disabled_title) |
|
|
|
|
else -> stringResource(CommonStrings.action_signout) |
|
|
|
|
} |
|
|
|
|
val subtitle = when { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Composable |
|
|
|
|
private fun subtitle(state: LogoutState): String? { |
|
|
|
|
return when { |
|
|
|
|
(state.backupUploadState as? BackupUploadState.SteadyException)?.exception is SteadyStateException.Connection -> |
|
|
|
|
stringResource(id = R.string.screen_signout_key_backup_offline_subtitle) |
|
|
|
|
state.backupUploadState.isBackingUp() -> stringResource(id = R.string.screen_signout_key_backup_ongoing_subtitle) |
|
|
|
|
state.isLastSession -> stringResource(id = R.string.screen_signout_key_backup_disabled_subtitle) |
|
|
|
|
else -> null |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val paddingTop = 0.dp |
|
|
|
|
IconTitleSubtitleMolecule( |
|
|
|
|
modifier = modifier.padding(top = paddingTop), |
|
|
|
|
iconResourceId = CommonDrawables.ic_key, |
|
|
|
|
title = title, |
|
|
|
|
subTitle = subtitle, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun BackupUploadState.isBackingUp(): Boolean { |
|
|
|
@ -171,37 +148,33 @@ private fun BackupUploadState.isBackingUp(): Boolean {
@@ -171,37 +148,33 @@ private fun BackupUploadState.isBackingUp(): Boolean {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Composable |
|
|
|
|
private fun BottomMenu( |
|
|
|
|
private fun ColumnScope.Buttons( |
|
|
|
|
state: LogoutState, |
|
|
|
|
onLogoutClicked: () -> Unit, |
|
|
|
|
onChangeRecoveryKeyClicked: () -> Unit, |
|
|
|
|
) { |
|
|
|
|
val logoutAction = state.logoutAction |
|
|
|
|
ButtonColumnMolecule( |
|
|
|
|
modifier = Modifier.padding(bottom = 20.dp) |
|
|
|
|
) { |
|
|
|
|
if (state.isLastSession) { |
|
|
|
|
OutlinedButton( |
|
|
|
|
text = stringResource(id = CommonStrings.common_settings), |
|
|
|
|
modifier = Modifier.fillMaxWidth(), |
|
|
|
|
onClick = onChangeRecoveryKeyClicked, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
val signOutSubmitRes = when { |
|
|
|
|
logoutAction is Async.Loading -> R.string.screen_signout_in_progress_dialog_content |
|
|
|
|
state.backupUploadState.isBackingUp() -> CommonStrings.action_signout_anyway |
|
|
|
|
else -> CommonStrings.action_signout |
|
|
|
|
} |
|
|
|
|
Button( |
|
|
|
|
text = stringResource(id = signOutSubmitRes), |
|
|
|
|
showProgress = logoutAction is Async.Loading, |
|
|
|
|
destructive = true, |
|
|
|
|
modifier = Modifier |
|
|
|
|
.fillMaxWidth() |
|
|
|
|
.testTag(TestTags.signOut), |
|
|
|
|
onClick = onLogoutClicked, |
|
|
|
|
if (state.isLastSession) { |
|
|
|
|
OutlinedButton( |
|
|
|
|
text = stringResource(id = CommonStrings.common_settings), |
|
|
|
|
modifier = Modifier.fillMaxWidth(), |
|
|
|
|
onClick = onChangeRecoveryKeyClicked, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
val signOutSubmitRes = when { |
|
|
|
|
logoutAction is Async.Loading -> R.string.screen_signout_in_progress_dialog_content |
|
|
|
|
state.backupUploadState.isBackingUp() -> CommonStrings.action_signout_anyway |
|
|
|
|
else -> CommonStrings.action_signout |
|
|
|
|
} |
|
|
|
|
Button( |
|
|
|
|
text = stringResource(id = signOutSubmitRes), |
|
|
|
|
showProgress = logoutAction is Async.Loading, |
|
|
|
|
destructive = true, |
|
|
|
|
modifier = Modifier |
|
|
|
|
.fillMaxWidth() |
|
|
|
|
.testTag(TestTags.signOut), |
|
|
|
|
onClick = onLogoutClicked, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Composable |
|
|
|
|