Skip to content

Commit

Permalink
Add new factor success modal
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiupuhalschi-rdx committed Feb 24, 2025
1 parent 260e229 commit 14ac8e8
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,12 @@ fun RadixWalletException.CloudBackupException.toUserFriendlyMessage(): String =
is BackupServiceException.Unknown -> "Unknown error occurred cause: ${cause?.message}"
}

fun RadixWalletException.AddFactorSource.toUserFriendlyMessage(): String = when (this) {
RadixWalletException.AddFactorSource.FactorSourceAlreadyInUse -> "Factor Already in Use" // TODO crowdin
RadixWalletException.AddFactorSource.FactorSourceNotCreated -> "Factor not created" // TODO crowdin
}
fun RadixWalletException.AddFactorSource.toUserFriendlyMessage(context: Context): String = context.getString(
when (this) {
RadixWalletException.AddFactorSource.FactorSourceAlreadyInUse -> R.string.newFactor_error_alreadyInUse
RadixWalletException.AddFactorSource.FactorSourceNotCreated -> R.string.newFactor_error_notCreated
}
)

fun RadixWalletException.toUserFriendlyMessage(context: Context): String {
return when (this) {
Expand All @@ -447,7 +449,7 @@ fun RadixWalletException.toUserFriendlyMessage(context: Context): String {
is RadixWalletException.GatewayException -> toUserFriendlyMessage(context)
is RadixWalletException.LinkConnectionException -> toUserFriendlyMessage(context)
is RadixWalletException.CloudBackupException -> toUserFriendlyMessage()
is RadixWalletException.AddFactorSource -> toUserFriendlyMessage()
is RadixWalletException.AddFactorSource -> toUserFriendlyMessage(context)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import com.babylon.wallet.android.presentation.ui.composables.RadixBottomBar
import com.babylon.wallet.android.presentation.ui.composables.RadixCenteredTopAppBar
import com.babylon.wallet.android.presentation.ui.composables.card.iconRes
import com.babylon.wallet.android.presentation.ui.composables.statusBarsAndBanner
import com.babylon.wallet.android.presentation.ui.composables.utils.HideKeyboardOnFullScroll
import com.babylon.wallet.android.presentation.ui.modifier.keyboardVisiblePadding
import com.radixdlt.sargon.FactorSourceKind
import com.radixdlt.sargon.MnemonicWithPassphrase
Expand Down Expand Up @@ -82,9 +81,6 @@ private fun ConfirmDeviceSeedPhraseContent(
onFillWordsClick: () -> Unit,
onDismiss: () -> Unit
) {
val scrollState = rememberScrollState()
HideKeyboardOnFullScroll(scrollState)

Scaffold(
modifier = modifier,
topBar = {
Expand Down Expand Up @@ -122,7 +118,7 @@ private fun ConfirmDeviceSeedPhraseContent(
padding = padding,
bottom = RadixTheme.dimensions.paddingDefault
)
.verticalScroll(scrollState)
.verticalScroll(rememberScrollState())
.padding(horizontal = RadixTheme.dimensions.paddingSemiLarge),
horizontalAlignment = Alignment.CenterHorizontally
) {
Expand All @@ -136,7 +132,7 @@ private fun ConfirmDeviceSeedPhraseContent(
Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingDefault))

Text(
text = "Confirm Seed Phrase", // TODO crowdin
text = stringResource(id = R.string.newBiometricFactor_confirmSeedPhrase_title),
style = RadixTheme.typography.title,
color = RadixTheme.colors.gray1,
textAlign = TextAlign.Center
Expand All @@ -145,7 +141,7 @@ private fun ConfirmDeviceSeedPhraseContent(
Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingSmall))

Text(
text = "Enter ${state.words.size} words from your seed phrase to confirm you’ve recorded it correctly.", // TODO crowdin
text = stringResource(id = R.string.newBiometricFactor_confirmSeedPhrase_subtitle, state.words.size),
style = RadixTheme.typography.body1Regular,
color = RadixTheme.colors.gray1,
textAlign = TextAlign.Center
Expand All @@ -165,7 +161,13 @@ private fun ConfirmDeviceSeedPhraseContent(
else -> ImeAction.Next
}
),
error = if (word.state == SeedPhraseWord.State.Invalid) "Incorrect. Try again" else null, // TODO crowdin
error = if (word.state == SeedPhraseWord.State.Invalid) {
stringResource(
id = R.string.newBiometricFactor_confirmSeedPhrase_incorrectWord
)
} else {
null
},
errorFixedSize = true,
singleLine = true,
hasInitialFocus = index == 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ private fun DeviceSeedPhraseContent(
) {
Text(
modifier = Modifier.padding(horizontal = RadixTheme.dimensions.paddingXLarge),
text = "Write Down Seed Phrase", // TODO crowdin
text = stringResource(id = R.string.newBiometricFactor_seedPhrase_title),
style = RadixTheme.typography.title,
color = RadixTheme.colors.gray1,
textAlign = TextAlign.Center
Expand All @@ -173,7 +173,7 @@ private fun DeviceSeedPhraseContent(

Text(
modifier = Modifier.padding(horizontal = RadixTheme.dimensions.paddingXLarge),
text = "Write down this BIP39 seed phrase and store safely for future use. Avoid storing electronically so no one can steal it online.", // TODO crowdin
text = stringResource(id = R.string.newBiometricFactor_seedPhrase_subtitle),
style = RadixTheme.typography.body1Regular,
color = RadixTheme.colors.gray1,
textAlign = TextAlign.Center
Expand Down Expand Up @@ -209,7 +209,7 @@ private fun DeviceSeedPhraseContent(

if (!state.isEditingEnabled) {
RadixTextButton(
text = "Clear and enter custom seed phrase", // TODO crowdin
text = stringResource(id = R.string.newBiometricFactor_seedPhrase_enterCustomButton),
onClick = onEnterCustomSeedPhraseClick
)

Expand All @@ -222,7 +222,7 @@ private fun DeviceSeedPhraseContent(
BasicPromptAlertDialog(
finish = { onDismissMessage() },
messageText = error.getMessage(),
confirmText = "Close", // TODO crowdin
confirmText = stringResource(id = R.string.common_close),
dismissText = null
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ private fun FactorSourceKind.addTitle() = when (this) {
FactorSourceKind.PASSWORD -> "Add a New Password"
}

@Suppress("MaxLineLength")
@Composable
private fun FactorSourceKind.addSubtitle() = when (this) {
FactorSourceKind.DEVICE -> "This factor is a seed phrase held by your phone and unlocked by your biometrics/PIN."
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.babylon.wallet.android.presentation.settings.securitycenter.addfactorsource.name

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
Expand All @@ -13,9 +16,11 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
Expand All @@ -24,6 +29,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardCapitalization
Expand All @@ -39,6 +45,8 @@ import com.babylon.wallet.android.designsystem.theme.RadixTheme
import com.babylon.wallet.android.presentation.ui.RadixWalletPreviewTheme
import com.babylon.wallet.android.presentation.ui.composables.BackIconType
import com.babylon.wallet.android.presentation.ui.composables.BasicPromptAlertDialog
import com.babylon.wallet.android.presentation.ui.composables.DSR
import com.babylon.wallet.android.presentation.ui.composables.DefaultModalSheetLayout
import com.babylon.wallet.android.presentation.ui.composables.RadixBottomBar
import com.babylon.wallet.android.presentation.ui.composables.RadixCenteredTopAppBar
import com.babylon.wallet.android.presentation.ui.composables.card.iconRes
Expand All @@ -60,6 +68,7 @@ fun SetFactorSourceNameScreen(
state = state,
onDismiss = onDismiss,
onDismissMessage = viewModel::onDismissMessage,
onDismissSuccessMessage = viewModel::onDismissSuccessMessage,
onNameChange = viewModel::onNameChange,
onSaveClick = viewModel::onSaveClick
)
Expand All @@ -73,12 +82,14 @@ fun SetFactorSourceNameScreen(
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun SetFactorSourceNameContent(
modifier: Modifier = Modifier,
state: SetFactorSourceNameViewModel.State,
onDismiss: () -> Unit,
onDismissMessage: () -> Unit,
onDismissSuccessMessage: () -> Unit,
onNameChange: (String) -> Unit,
onSaveClick: () -> Unit
) {
Expand All @@ -97,18 +108,27 @@ private fun SetFactorSourceNameContent(
RadixBottomBar(
modifier = Modifier.imePadding(),
onClick = onSaveClick,
text = stringResource(id = R.string.common_save),
text = stringResource(id = R.string.newBiometricFactor_name_saveButton),
insets = if (isKeyboardVisible()) WindowInsets.none else WindowInsets.navigationBars,
enabled = state.isButtonEnabled
enabled = state.isButtonEnabled,
isLoading = state.saveInProgress
)
}
) { padding ->
val inputFocusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current

LaunchedEffect(Unit) {
inputFocusRequester.requestFocus()
}

LaunchedEffect(state.saveInProgress) {
if (state.saveInProgress) {
inputFocusRequester.freeFocus()
keyboardController?.hide()
}
}

Column(
modifier = Modifier
.fillMaxSize()
Expand Down Expand Up @@ -150,39 +170,105 @@ private fun SetFactorSourceNameContent(
value = state.name,
singleLine = true,
hintColor = RadixTheme.colors.gray2,
hint = "Enter name", // TODO crowdin
hint = stringResource(id = R.string.newBiometricFactor_name_label),
error = stringResource(id = R.string.renameLabel_factorSource_tooLong).takeIf { state.isNameTooLong }
)

Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingMedium))

Text(
text = "This can be changed any time", // TODO crowdin
text = stringResource(id = R.string.newBiometricFactor_name_note),
style = RadixTheme.typography.body2Regular,
color = RadixTheme.colors.gray2,
)
}
}

val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)

LaunchedEffect(state.showSuccess) {
if (state.showSuccess) {
bottomSheetState.show()
}
}

if (state.showSuccess) {
DefaultModalSheetLayout(
wrapContent = true,
sheetState = bottomSheetState,
sheetContent = {
SuccessSheetContent(
onCloseClick = onDismissSuccessMessage
)
},
onDismissRequest = onDismissSuccessMessage
)
}

state.errorMessage?.let { error ->
BasicPromptAlertDialog(
finish = { onDismissMessage() },
messageText = error.getMessage(),
confirmText = "Close", // TODO crowdin
confirmText = stringResource(id = R.string.common_close),
dismissText = null
)
}
}

@Composable
private fun FactorSourceKind.nameTitle() = when (this) {
FactorSourceKind.DEVICE -> "Name your New Biometrics/PIN Seed Phrase"
FactorSourceKind.LEDGER_HQ_HARDWARE_WALLET -> "Name your New Ledger Nano"
FactorSourceKind.DEVICE -> stringResource(id = R.string.newBiometricFactor_intro_title)
FactorSourceKind.LEDGER_HQ_HARDWARE_WALLET -> "Name your New Ledger Nano" // TODO crowdin
FactorSourceKind.OFF_DEVICE_MNEMONIC -> "Name your New Mnemonic Seed Phrase"
FactorSourceKind.ARCULUS_CARD -> "Name your New Arculus Card"
FactorSourceKind.PASSWORD -> "Name your New Password"
}

@Composable
private fun SuccessSheetContent(
onCloseClick: () -> Unit
) {
Column(
Modifier
.fillMaxWidth()
.background(color = RadixTheme.colors.defaultBackground),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(RadixTheme.dimensions.paddingDefault)
) {
RadixCenteredTopAppBar(
title = "",
backIconType = BackIconType.Close,
onBackClick = onCloseClick
)

Image(
painter = painterResource(DSR.check_circle_outline),
contentDescription = null
)

Text(
modifier = Modifier.padding(horizontal = RadixTheme.dimensions.paddingLarge),
text = stringResource(id = R.string.newFactor_success_title),
style = RadixTheme.typography.title,
color = RadixTheme.colors.gray1,
textAlign = TextAlign.Center
)

Text(
modifier = Modifier.padding(horizontal = RadixTheme.dimensions.paddingLarge),
text = stringResource(id = R.string.newFactor_success_subtitle),
style = RadixTheme.typography.body1Regular,
color = RadixTheme.colors.gray1,
textAlign = TextAlign.Center
)

RadixBottomBar(
onClick = onCloseClick,
text = stringResource(id = R.string.common_close)
)
}
}

@Composable
@Preview
private fun SetFactorSourceNamePreview(
Expand All @@ -193,6 +279,7 @@ private fun SetFactorSourceNamePreview(
state = state,
onDismiss = {},
onDismissMessage = {},
onDismissSuccessMessage = {},
onNameChange = {},
onSaveClick = {}
)
Expand All @@ -206,5 +293,8 @@ class SetFactorSourceNamePreviewProvider : PreviewParameterProvider<SetFactorSou
SetFactorSourceNameViewModel.State(
factorSourceKind = kind
)
}.asSequence()
}.asSequence() + SetFactorSourceNameViewModel.State(
factorSourceKind = FactorSourceKind.DEVICE,
showSuccess = true
)
}
Loading

0 comments on commit 14ac8e8

Please sign in to comment.