Let SecureBackupSetupView use UserStoryFlowPage.

This commit is contained in:
Benoit Marty 2023-11-03 10:52:59 +01:00 committed by Benoit Marty
parent 64ca96d502
commit 4bd47c4436

View file

@ -16,10 +16,9 @@
package io.element.android.features.securebackup.impl.setup package io.element.android.features.securebackup.impl.setup
import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@ -28,24 +27,18 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.features.securebackup.impl.R import io.element.android.features.securebackup.impl.R
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyView import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyView
import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
import io.element.android.libraries.androidutils.system.copyToClipboard import io.element.android.libraries.androidutils.system.copyToClipboard
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule import io.element.android.libraries.designsystem.atomic.pages.UserStoryFlowPage
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.IconSource import io.element.android.libraries.designsystem.theme.components.IconSource
import io.element.android.libraries.designsystem.theme.components.OutlinedButton import io.element.android.libraries.designsystem.theme.components.OutlinedButton
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun SecureBackupSetupView( fun SecureBackupSetupView(
state: SecureBackupSetupState, state: SecureBackupSetupState,
@ -53,68 +46,16 @@ fun SecureBackupSetupView(
onBackClicked: () -> Unit, onBackClicked: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val context = LocalContext.current UserStoryFlowPage(
val canGoBack = state.canGoBack()
BackHandler(enabled = canGoBack) {
onBackClicked()
}
HeaderFooterPage(
modifier = modifier, modifier = modifier,
topBar = { canGoBack = state.canGoBack(),
TopAppBar( onBackClicked = onBackClicked,
navigationIcon = { title = title(state),
if (canGoBack) { subTitle = subtitle(state),
BackButton(onClick = onBackClicked) iconResourceId = CommonDrawables.ic_key,
} content = { Content(state) },
}, buttons = { Buttons(state, onDone = onDone) },
title = {}, )
)
},
header = {
HeaderContent(state = state)
},
footer = {
val chooserTitle = stringResource(id = R.string.screen_recovery_key_save_action)
BottomMenu(
state = state,
onSaveClicked = { key ->
context.startSharePlainTextIntent(
activityResultLauncher = null,
chooserTitle = chooserTitle,
text = key,
)
state.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved)
},
onDone = {
if (state.setupState is SetupState.CreatedAndSaved) {
onDone()
} else {
state.eventSink.invoke(SecureBackupSetupEvents.Done)
}
},
)
}
) {
val formattedRecoveryKey = state.recoveryKeyViewState.formattedRecoveryKey
val clickLambda = if (formattedRecoveryKey != null) {
{
context.copyToClipboard(
formattedRecoveryKey,
context.getString(R.string.screen_recovery_key_copied_to_clipboard)
)
state.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved)
}
} else {
if (!state.recoveryKeyViewState.inProgress) {
{
state.eventSink.invoke(SecureBackupSetupEvents.CreateRecoveryKey)
}
} else {
null
}
}
Content(state = state.recoveryKeyViewState, onClick = clickLambda)
}
if (state.showSaveConfirmationDialog) { if (state.showSaveConfirmationDialog) {
ConfirmationDialog( ConfirmationDialog(
@ -134,12 +75,8 @@ private fun SecureBackupSetupState.canGoBack(): Boolean {
} }
@Composable @Composable
private fun HeaderContent( private fun title(state: SecureBackupSetupState): String {
state: SecureBackupSetupState, return when (state.setupState) {
modifier: Modifier = Modifier,
) {
val setupState = state.setupState
val title = when (setupState) {
SetupState.Init, SetupState.Init,
SetupState.Creating -> if (state.isChangeRecoveryKeyUserStory) SetupState.Creating -> if (state.isChangeRecoveryKeyUserStory)
stringResource(id = R.string.screen_recovery_key_change_title) stringResource(id = R.string.screen_recovery_key_change_title)
@ -149,7 +86,11 @@ private fun HeaderContent(
is SetupState.CreatedAndSaved -> is SetupState.CreatedAndSaved ->
stringResource(id = R.string.screen_recovery_key_save_title) stringResource(id = R.string.screen_recovery_key_save_title)
} }
val subTitle = when (setupState) { }
@Composable
private fun subtitle(state: SecureBackupSetupState): String {
return when (state.setupState) {
SetupState.Init, SetupState.Init,
SetupState.Creating -> if (state.isChangeRecoveryKeyUserStory) SetupState.Creating -> if (state.isChangeRecoveryKeyUserStory)
stringResource(id = R.string.screen_recovery_key_change_description) stringResource(id = R.string.screen_recovery_key_change_description)
@ -159,67 +100,87 @@ private fun HeaderContent(
is SetupState.CreatedAndSaved -> is SetupState.CreatedAndSaved ->
stringResource(id = R.string.screen_recovery_key_save_description) stringResource(id = R.string.screen_recovery_key_save_description)
} }
IconTitleSubtitleMolecule(
modifier = modifier.padding(top = 0.dp),
iconResourceId = CommonDrawables.ic_key,
title = title,
subTitle = subTitle,
)
}
@Composable
private fun BottomMenu(
state: SecureBackupSetupState,
onSaveClicked: (String) -> Unit,
onDone: () -> Unit,
) {
val setupState = state.setupState
ButtonColumnMolecule(
modifier = Modifier.padding(bottom = 20.dp)
) {
when (setupState) {
SetupState.Init,
SetupState.Creating -> {
Button(
text = stringResource(id = CommonStrings.action_done),
enabled = false,
modifier = Modifier.fillMaxWidth(),
onClick = onDone
)
}
is SetupState.Created,
is SetupState.CreatedAndSaved -> {
OutlinedButton(
text = stringResource(id = R.string.screen_recovery_key_save_action),
leadingIcon = IconSource.Resource(CommonDrawables.ic_compound_download),
modifier = Modifier.fillMaxWidth(),
onClick = { onSaveClicked(setupState.recoveryKey()!!) },
)
Button(
text = stringResource(id = CommonStrings.action_done),
modifier = Modifier.fillMaxWidth(),
onClick = onDone,
)
}
}
}
} }
@Composable @Composable
private fun Content( private fun Content(
state: RecoveryKeyViewState, state: SecureBackupSetupState,
onClick: (() -> Unit)?,
) { ) {
val modifier = Modifier.padding(top = 52.dp) val context = LocalContext.current
val formattedRecoveryKey = state.recoveryKeyViewState.formattedRecoveryKey
val clickLambda = if (formattedRecoveryKey != null) {
{
context.copyToClipboard(
formattedRecoveryKey,
context.getString(R.string.screen_recovery_key_copied_to_clipboard)
)
state.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved)
}
} else {
if (!state.recoveryKeyViewState.inProgress) {
{
state.eventSink.invoke(SecureBackupSetupEvents.CreateRecoveryKey)
}
} else {
null
}
}
RecoveryKeyView( RecoveryKeyView(
modifier = modifier, modifier = Modifier.padding(top = 52.dp),
state = state, state = state.recoveryKeyViewState,
onClick = onClick, onClick = clickLambda,
onChange = null, onChange = null,
onSubmit = null, onSubmit = null,
) )
} }
@Composable
private fun ColumnScope.Buttons(
state: SecureBackupSetupState,
onDone: () -> Unit,
) {
val context = LocalContext.current
val chooserTitle = stringResource(id = R.string.screen_recovery_key_save_action)
when (state.setupState) {
SetupState.Init,
SetupState.Creating -> {
Button(
text = stringResource(id = CommonStrings.action_done),
enabled = false,
modifier = Modifier.fillMaxWidth(),
onClick = onDone
)
}
is SetupState.Created,
is SetupState.CreatedAndSaved -> {
OutlinedButton(
text = stringResource(id = R.string.screen_recovery_key_save_action),
leadingIcon = IconSource.Resource(CommonDrawables.ic_compound_download),
modifier = Modifier.fillMaxWidth(),
onClick = {
context.startSharePlainTextIntent(
activityResultLauncher = null,
chooserTitle = chooserTitle,
text = state.setupState.recoveryKey()!!,
)
state.eventSink.invoke(SecureBackupSetupEvents.RecoveryKeyHasBeenSaved)
},
)
Button(
text = stringResource(id = CommonStrings.action_done),
modifier = Modifier.fillMaxWidth(),
onClick = {
if (state.setupState is SetupState.CreatedAndSaved) {
onDone()
} else {
state.eventSink.invoke(SecureBackupSetupEvents.Done)
}
},
)
}
}
}
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun SecureBackupSetupViewPreview( internal fun SecureBackupSetupViewPreview(