diff --git a/app/src/main/java/to/bitkit/ui/ContentView.kt b/app/src/main/java/to/bitkit/ui/ContentView.kt index 39bfe1f6b..81ec542c7 100644 --- a/app/src/main/java/to/bitkit/ui/ContentView.kt +++ b/app/src/main/java/to/bitkit/ui/ContentView.kt @@ -81,7 +81,11 @@ import to.bitkit.ui.settings.SecuritySettingsScreen import to.bitkit.ui.settings.SettingsScreen import to.bitkit.ui.settings.backups.BackupWalletScreen import to.bitkit.ui.settings.backups.RestoreWalletScreen +import to.bitkit.ui.settings.pin.ChangePinConfirmScreen +import to.bitkit.ui.settings.pin.ChangePinScreen import to.bitkit.ui.settings.pin.DisablePinScreen +import to.bitkit.ui.settings.pin.ChangePinNewScreen +import to.bitkit.ui.settings.pin.ChangePinResultScreen import to.bitkit.ui.utils.screenScaleIn import to.bitkit.ui.utils.screenScaleOut import to.bitkit.ui.utils.screenSlideIn @@ -234,6 +238,10 @@ fun ContentView( generalSettings(navController) securitySettings(navController) disablePin(navController) + changePin(navController) + changePinNew(navController) + changePinConfirm(navController) + changePinResult(navController) defaultUnitSettings(currencyViewModel, navController) localCurrencySettings(currencyViewModel, navController) backupSettings(navController) @@ -491,6 +499,34 @@ private fun NavGraphBuilder.disablePin(navController: NavHostController) { } } +private fun NavGraphBuilder.changePin(navController: NavHostController) { + composableWithDefaultTransitions { + ChangePinScreen(navController) + } +} + +private fun NavGraphBuilder.changePinNew(navController: NavHostController) { + composableWithDefaultTransitions { + ChangePinNewScreen(navController) + } +} + +private fun NavGraphBuilder.changePinConfirm(navController: NavHostController) { + composableWithDefaultTransitions { navBackEntry -> + val route = navBackEntry.toRoute() + ChangePinConfirmScreen( + newPin = route.newPin, + navController = navController, + ) + } +} + +private fun NavGraphBuilder.changePinResult(navController: NavHostController) { + composableWithDefaultTransitions { + ChangePinResultScreen(navController) + } +} + private fun NavGraphBuilder.defaultUnitSettings( currencyViewModel: CurrencyViewModel, navController: NavHostController, @@ -700,6 +736,22 @@ fun NavController.navigateToDisablePin() = navigate( route = Routes.DisablePin, ) +fun NavController.navigateToChangePin() = navigate( + route = Routes.ChangePin, +) + +fun NavController.navigateToChangePinNew() = navigate( + route = Routes.ChangePinNew, +) + +fun NavController.navigateToChangePinConfirm(newPin: String) = navigate( + route = Routes.ChangePinConfirm(newPin), +) + +fun NavController.navigateToChangePinResult() = navigate( + route = Routes.ChangePinResult, +) + fun NavController.navigateToAuthCheck( showLogoOnPin: Boolean = false, requirePin: Boolean = false, @@ -812,6 +864,18 @@ object Routes { @Serializable data object DisablePin + @Serializable + data object ChangePin + + @Serializable + data object ChangePinNew + + @Serializable + data class ChangePinConfirm(val newPin: String) + + @Serializable + data object ChangePinResult + @Serializable data class AuthCheck( val showLogoOnPin: Boolean = false, diff --git a/app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt b/app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt index 21335201f..53e99d9e6 100644 --- a/app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt +++ b/app/src/main/java/to/bitkit/ui/components/AuthCheckView.kt @@ -29,6 +29,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import to.bitkit.R import to.bitkit.env.Env import to.bitkit.ui.scaffold.AppTopBar +import to.bitkit.ui.shared.util.clickableAlpha import to.bitkit.ui.theme.AppThemeSurface import to.bitkit.ui.theme.Colors import to.bitkit.ui.utils.rememberBiometricAuthSupported @@ -57,6 +58,7 @@ fun AuthCheckView( validatePin = appViewModel::validatePin, onSuccess = onSuccess, onBack = onBack, + onClickForgotPin = { appViewModel.toast(Exception("TODO: Forgot PIN")) }, ) } @@ -71,6 +73,7 @@ private fun AuthCheckViewContent( validatePin: (String) -> Boolean, onSuccess: (() -> Unit)? = null, onBack: (() -> Unit)?, + onClickForgotPin: () -> Unit, ) { var showBio by rememberSaveable { mutableStateOf(isBiometricsEnabled) } @@ -98,6 +101,7 @@ private fun AuthCheckViewContent( onShowBiometrics = { showBio = true }, onSuccess = onSuccess, onBack = onBack, + onClickForgotPin = onClickForgotPin, ) } } @@ -112,6 +116,7 @@ private fun PinPad( onShowBiometrics: () -> Unit, onSuccess: (() -> Unit)?, onBack: (() -> Unit)? = null, + onClickForgotPin: () -> Unit = {}, ) { var pin by remember { mutableStateOf("") } val isLastAttempt = attemptsRemaining == 1 @@ -153,11 +158,11 @@ private fun PinPad( modifier = Modifier.padding(horizontal = 16.dp) ) } else { - // TODO: onClick: show forgotPin sheet BodyS( text = stringResource(R.string.security__pin_attempts).replace("{attemptsRemaining}", "$attemptsRemaining"), color = Colors.Brand, textAlign = TextAlign.Center, + modifier = Modifier.clickableAlpha { onClickForgotPin() } ) } Spacer(modifier = Modifier.height(16.dp)) @@ -213,6 +218,7 @@ private fun PreviewBio() { showLogoOnPin = true, validatePin = { true }, attemptsRemaining = 8, + onClickForgotPin = {}, ) } } @@ -229,6 +235,7 @@ private fun PreviewPin() { showLogoOnPin = true, validatePin = { true }, attemptsRemaining = 8, + onClickForgotPin = {}, ) } } @@ -245,6 +252,7 @@ private fun PreviewPinAttempts() { showLogoOnPin = false, validatePin = { true }, attemptsRemaining = 6, + onClickForgotPin = {}, ) } } @@ -261,6 +269,7 @@ private fun PreviewPinAttemptLast() { showLogoOnPin = true, validatePin = { true }, attemptsRemaining = 1, + onClickForgotPin = {}, ) } } diff --git a/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt index 77bc51629..69da5a180 100644 --- a/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt +++ b/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt @@ -22,6 +22,7 @@ import to.bitkit.ui.components.BodyS import to.bitkit.ui.components.settings.SettingsButtonRow import to.bitkit.ui.components.settings.SettingsSwitchRow import to.bitkit.ui.navigateToAuthCheck +import to.bitkit.ui.navigateToChangePin import to.bitkit.ui.navigateToDisablePin import to.bitkit.ui.navigateToHome import to.bitkit.ui.scaffold.AppTopBar @@ -60,6 +61,9 @@ fun SecuritySettingsScreen( navController.navigateToDisablePin() } }, + onChangePinClick = { + navController.navigateToChangePin() + }, onPinOnLaunchClick = { navController.navigateToAuthCheck( onSuccessActionId = AuthCheckAction.TOGGLE_PIN_ON_LAUNCH, @@ -84,6 +88,7 @@ private fun SecuritySettingsContent( isBiometricEnabled: Boolean, isBiometrySupported: Boolean, onPinClick: () -> Unit = {}, + onChangePinClick: () -> Unit = {}, onPinOnLaunchClick: () -> Unit = {}, onUseBiometricsClick: () -> Unit = {}, onBackClick: () -> Unit = {}, @@ -108,6 +113,10 @@ private fun SecuritySettingsContent( onClick = onPinClick, ) if (isPinEnabled) { + SettingsButtonRow( + title = stringResource(R.string.settings__security__pin_change), + onClick = onChangePinClick, + ) SettingsSwitchRow( title = stringResource(R.string.settings__security__pin_launch), isChecked = isPinOnLaunchEnabled, diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinConfirmScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinConfirmScreen.kt new file mode 100644 index 000000000..9095d3b38 --- /dev/null +++ b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinConfirmScreen.kt @@ -0,0 +1,154 @@ +package to.bitkit.ui.settings.pin + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import kotlinx.coroutines.delay +import to.bitkit.R +import to.bitkit.env.Env +import to.bitkit.ui.appViewModel +import to.bitkit.ui.components.BodyM +import to.bitkit.ui.components.BodyS +import to.bitkit.ui.components.KEY_DELETE +import to.bitkit.ui.components.PinDots +import to.bitkit.ui.components.PinNumberPad +import to.bitkit.ui.navigateToHome +import to.bitkit.ui.navigateToChangePinResult +import to.bitkit.ui.scaffold.AppTopBar +import to.bitkit.ui.scaffold.CloseNavIcon +import to.bitkit.ui.scaffold.ScreenColumn +import to.bitkit.ui.theme.AppThemeSurface +import to.bitkit.ui.theme.Colors + +@Composable +fun ChangePinConfirmScreen( + newPin: String, + navController: NavController, +) { + val app = appViewModel ?: return + var pin by remember { mutableStateOf("") } + var showError by remember { mutableStateOf(false) } + + LaunchedEffect(pin) { + if (pin.length == Env.PIN_LENGTH) { + if (pin == newPin) { + app.editPin(newPin) + navController.navigateToChangePinResult() + } else { + showError = true + delay(500) + pin = "" + } + } + } + + ChangePinConfirmContent( + pin = pin, + showError = showError, + onKeyPress = { key -> + if (key == KEY_DELETE) { + if (pin.isNotEmpty()) { + pin = pin.dropLast(1) + } + } else if (pin.length < Env.PIN_LENGTH) { + pin += key + } + }, + onBackClick = { navController.popBackStack() }, + onCloseClick = { navController.navigateToHome() }, + ) +} + +@Composable +private fun ChangePinConfirmContent( + pin: String, + showError: Boolean, + onKeyPress: (String) -> Unit, + onBackClick: () -> Unit, + onCloseClick: () -> Unit, +) { + ScreenColumn { + AppTopBar( + titleText = stringResource(R.string.security__cp_retype_title), + onBackClick = onBackClick, + actions = { CloseNavIcon(onClick = onCloseClick) }, + ) + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(horizontal = 16.dp) + ) { + BodyM( + text = stringResource(R.string.security__cp_retype_text), + color = Colors.White64, + ) + + Spacer(modifier = Modifier.height(32.dp)) + + AnimatedVisibility(visible = showError) { + BodyS( + text = stringResource(R.string.security__pin_not_match), + textAlign = TextAlign.Center, + color = Colors.Brand, + modifier = Modifier.fillMaxWidth() + ) + } + + PinDots( + pin = pin, + modifier = Modifier.padding(vertical = 16.dp), + ) + + Spacer(modifier = Modifier.weight(1f)) + + PinNumberPad( + modifier = Modifier.height(350.dp), + onPress = onKeyPress, + ) + } + } +} + +@Preview(showBackground = true) +@Composable +private fun Preview() { + AppThemeSurface { + ChangePinConfirmContent( + pin = "12", + showError = false, + onKeyPress = {}, + onBackClick = {}, + onCloseClick = {}, + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun PreviewRetry() { + AppThemeSurface { + ChangePinConfirmContent( + pin = "", + showError = true, + onKeyPress = {}, + onBackClick = {}, + onCloseClick = {}, + ) + } +} diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinNewScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinNewScreen.kt new file mode 100644 index 000000000..24573e559 --- /dev/null +++ b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinNewScreen.kt @@ -0,0 +1,112 @@ +package to.bitkit.ui.settings.pin + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import to.bitkit.R +import to.bitkit.env.Env +import to.bitkit.ui.components.BodyM +import to.bitkit.ui.components.KEY_DELETE +import to.bitkit.ui.components.PinDots +import to.bitkit.ui.components.PinNumberPad +import to.bitkit.ui.navigateToChangePinConfirm +import to.bitkit.ui.navigateToHome +import to.bitkit.ui.scaffold.AppTopBar +import to.bitkit.ui.scaffold.CloseNavIcon +import to.bitkit.ui.scaffold.ScreenColumn +import to.bitkit.ui.theme.AppThemeSurface +import to.bitkit.ui.theme.Colors + +@Composable +fun ChangePinNewScreen( + navController: NavController, +) { + var pin by remember { mutableStateOf("") } + + LaunchedEffect(pin) { + if (pin.length == Env.PIN_LENGTH) { + navController.navigateToChangePinConfirm(pin) + } + } + + ChangePinNewContent( + pin = pin, + onKeyPress = { key -> + if (key == KEY_DELETE) { + if (pin.isNotEmpty()) { + pin = pin.dropLast(1) + } + } else if (pin.length < Env.PIN_LENGTH) { + pin += key + } + }, + onBackClick = { navController.popBackStack() }, + onCloseClick = { navController.navigateToHome() }, + ) +} + +@Composable +private fun ChangePinNewContent( + pin: String, + onKeyPress: (String) -> Unit, + onBackClick: () -> Unit, + onCloseClick: () -> Unit, +) { + ScreenColumn { + AppTopBar( + titleText = stringResource(R.string.security__cp_setnew_title), + onBackClick = onBackClick, + actions = { CloseNavIcon(onClick = onCloseClick) }, + ) + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(horizontal = 16.dp) + ) { + BodyM( + text = stringResource(R.string.security__cp_setnew_text), + color = Colors.White64, + ) + + Spacer(modifier = Modifier.height(32.dp)) + + PinDots( + pin = pin, + modifier = Modifier.padding(vertical = 16.dp), + ) + + Spacer(modifier = Modifier.weight(1f)) + + PinNumberPad( + modifier = Modifier.height(350.dp), + onPress = onKeyPress, + ) + } + } +} + +@Preview(showBackground = true) +@Composable +private fun Preview() { + AppThemeSurface { + ChangePinNewContent( + pin = "12", + onKeyPress = {}, + onBackClick = {}, + onCloseClick = {}, + ) + } +} diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinResultScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinResultScreen.kt new file mode 100644 index 000000000..18b061783 --- /dev/null +++ b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinResultScreen.kt @@ -0,0 +1,84 @@ +package to.bitkit.ui.settings.pin + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import to.bitkit.R +import to.bitkit.ui.Routes +import to.bitkit.ui.components.BodyM +import to.bitkit.ui.components.PrimaryButton +import to.bitkit.ui.scaffold.AppTopBar +import to.bitkit.ui.scaffold.ScreenColumn +import to.bitkit.ui.theme.AppThemeSurface +import to.bitkit.ui.theme.Colors + +@Composable +fun ChangePinResultScreen( + navController: NavController, +) { + ChangePinResultContent( + onOkClick = { + navController.popBackStack(inclusive = false) + }, + ) +} + +@Composable +private fun ChangePinResultContent( + onOkClick: () -> Unit, +) { + ScreenColumn { + AppTopBar(stringResource(R.string.security__cp_changed_title), onBackClick = null) + Column( + modifier = Modifier.padding(horizontal = 16.dp) + ) { + BodyM( + text = stringResource(R.string.security__cp_changed_text), + color = Colors.White64, + ) + + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .fillMaxWidth() + .weight(1f) + ) { + Image( + painter = painterResource(R.drawable.check), + contentDescription = null, + modifier = Modifier.size(256.dp) + ) + } + + PrimaryButton( + text = stringResource(R.string.common__ok), + onClick = onOkClick, + ) + + Spacer(modifier = Modifier.height(16.dp)) + } + } +} + +@Preview(showBackground = true) +@Composable +private fun Preview() { + AppThemeSurface { + ChangePinResultContent( + onOkClick = {}, + ) + } +} diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinScreen.kt new file mode 100644 index 000000000..fe135ae62 --- /dev/null +++ b/app/src/main/java/to/bitkit/ui/settings/pin/ChangePinScreen.kt @@ -0,0 +1,183 @@ +package to.bitkit.ui.settings.pin + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavController +import to.bitkit.R +import to.bitkit.env.Env +import to.bitkit.ui.appViewModel +import to.bitkit.ui.components.BodyM +import to.bitkit.ui.components.BodyS +import to.bitkit.ui.components.KEY_DELETE +import to.bitkit.ui.components.PinDots +import to.bitkit.ui.components.PinNumberPad +import to.bitkit.ui.navigateToChangePinNew +import to.bitkit.ui.navigateToHome +import to.bitkit.ui.scaffold.AppTopBar +import to.bitkit.ui.scaffold.CloseNavIcon +import to.bitkit.ui.scaffold.ScreenColumn +import to.bitkit.ui.shared.util.clickableAlpha +import to.bitkit.ui.theme.AppThemeSurface +import to.bitkit.ui.theme.Colors + +@Composable +fun ChangePinScreen( + navController: NavController, +) { + val app = appViewModel ?: return + val attemptsRemaining by app.pinAttemptsRemaining.collectAsStateWithLifecycle() + var pin by remember { mutableStateOf("") } + + LaunchedEffect(pin) { + if (pin.length == Env.PIN_LENGTH) { + if (app.validatePin(pin)) { + navController.navigateToChangePinNew() + } else { + pin = "" + } + } + } + + ChangePinContent( + pin = pin, + attemptsRemaining = attemptsRemaining, + onKeyPress = { key -> + if (key == KEY_DELETE) { + if (pin.isNotEmpty()) { + pin = pin.dropLast(1) + } + } else if (pin.length < Env.PIN_LENGTH) { + pin += key + } + }, + onBackClick = { navController.popBackStack() }, + onCloseClick = { navController.navigateToHome() }, + onClickForgotPin = { app.toast(Exception("TODO: Forgot PIN")) }, + ) +} + +@Composable +private fun ChangePinContent( + pin: String, + attemptsRemaining: Int, + onKeyPress: (String) -> Unit, + onBackClick: () -> Unit, + onCloseClick: () -> Unit, + onClickForgotPin: () -> Unit, +) { + val isLastAttempt = attemptsRemaining == 1 + + ScreenColumn { + AppTopBar( + titleText = stringResource(R.string.security__cp_title), + onBackClick = onBackClick, + actions = { CloseNavIcon(onClick = onCloseClick) }, + ) + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(horizontal = 16.dp) + ) { + BodyM( + text = stringResource(R.string.security__cp_text), + color = Colors.White64, + ) + + Spacer(modifier = Modifier.height(32.dp)) + + AnimatedVisibility(visible = attemptsRemaining < Env.PIN_ATTEMPTS) { + if (isLastAttempt) { + BodyS( + text = stringResource(R.string.security__pin_last_attempt), + color = Colors.Brand, + textAlign = TextAlign.Center, + ) + } else { + BodyS( + text = stringResource(R.string.security__pin_attempts).replace( + "{attemptsRemaining}", + "$attemptsRemaining" + ), + color = Colors.Brand, + textAlign = TextAlign.Center, + modifier = Modifier.clickableAlpha { onClickForgotPin() } + ) + } + Spacer(modifier = Modifier.height(16.dp)) + } + + PinDots( + pin = pin, + modifier = Modifier.padding(vertical = 16.dp), + ) + + Spacer(modifier = Modifier.weight(1f)) + + PinNumberPad( + modifier = Modifier.height(350.dp), + onPress = onKeyPress, + ) + } + } +} + +@Preview(showBackground = true) +@Composable +private fun Preview() { + AppThemeSurface { + ChangePinContent( + pin = "12", + attemptsRemaining = 8, + onKeyPress = {}, + onBackClick = {}, + onCloseClick = {}, + onClickForgotPin = {}, + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun PreviewAttemptsRemaining() { + AppThemeSurface { + ChangePinContent( + pin = "1234", + attemptsRemaining = 5, + onKeyPress = {}, + onBackClick = {}, + onCloseClick = {}, + onClickForgotPin = {}, + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun PreviewAttemptsLast() { + AppThemeSurface { + ChangePinContent( + pin = "", + attemptsRemaining = 1, + onKeyPress = {}, + onBackClick = {}, + onCloseClick = {}, + onClickForgotPin = {}, + ) + } +} diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ChoosePinScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ChoosePinScreen.kt index 23d08281f..fd78e9b38 100644 --- a/app/src/main/java/to/bitkit/ui/settings/pin/ChoosePinScreen.kt +++ b/app/src/main/java/to/bitkit/ui/settings/pin/ChoosePinScreen.kt @@ -54,10 +54,7 @@ fun ChoosePinScreen( Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.weight(1f)) - PinDots( - pin = pin, - modifier = Modifier.padding(horizontal = 32.dp), - ) + PinDots(pin = pin) Spacer(modifier = Modifier.height(32.dp)) @@ -78,8 +75,6 @@ fun ChoosePinScreen( .height(350.dp) .background(Colors.Black) ) - - Spacer(modifier = Modifier.height(16.dp)) } } diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/ConfirmPinScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/ConfirmPinScreen.kt index ae9907fa6..18695c515 100644 --- a/app/src/main/java/to/bitkit/ui/settings/pin/ConfirmPinScreen.kt +++ b/app/src/main/java/to/bitkit/ui/settings/pin/ConfirmPinScreen.kt @@ -40,7 +40,6 @@ fun ConfirmPinScreen( onBack: () -> Unit, ) { val app = appViewModel ?: return - var pin by remember { mutableStateOf("") } var showError by remember { mutableStateOf(false) } @@ -66,7 +65,7 @@ fun ConfirmPinScreen( pin = pin.dropLast(1) } } else if (pin.length < Env.PIN_LENGTH) { - pin = pin + key + pin += key } }, onBack = onBack, @@ -116,10 +115,7 @@ private fun ConfirmPinContent( Spacer(modifier = Modifier.height(16.dp)) - PinDots( - pin = pin, - modifier = Modifier.padding(horizontal = 32.dp), - ) + PinDots(pin = pin) Spacer(modifier = Modifier.height(32.dp)) @@ -129,8 +125,6 @@ private fun ConfirmPinContent( .height(350.dp) .background(Colors.Black) ) - - Spacer(modifier = Modifier.height(16.dp)) } } diff --git a/app/src/main/java/to/bitkit/ui/settings/pin/DisablePinScreen.kt b/app/src/main/java/to/bitkit/ui/settings/pin/DisablePinScreen.kt index 8d4c842b8..d2e1e8d9c 100644 --- a/app/src/main/java/to/bitkit/ui/settings/pin/DisablePinScreen.kt +++ b/app/src/main/java/to/bitkit/ui/settings/pin/DisablePinScreen.kt @@ -62,7 +62,6 @@ private fun DisablePinContent( Column( modifier = Modifier.padding(horizontal = 16.dp), ) { - BodyM( text = stringResource(R.string.security__pin_disable_text), color = Colors.White64, @@ -85,6 +84,7 @@ private fun DisablePinContent( text = stringResource(R.string.security__pin_disable_button), onClick = onDisableClick, ) + Spacer(modifier = Modifier.height(16.dp)) } } diff --git a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt index 081792bb6..f6d06161e 100644 --- a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt +++ b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt @@ -805,11 +805,13 @@ class AppViewModel @Inject constructor( return false } - fun addPin(pin: String) { + fun addPin(pin: String) = editPin(pin) + + fun editPin(newPin: String) { setIsPinEnabled(true) viewModelScope.launch { - keychain.upsertString(Keychain.Key.PIN.name, pin) + keychain.upsertString(Keychain.Key.PIN.name, newPin) keychain.upsertString(Keychain.Key.PIN_ATTEMPTS_REMAINING.name, Env.PIN_ATTEMPTS.toString()) } }