From 9bf868b76981dcda12ce3399ad8a7dbba75acff3 Mon Sep 17 00:00:00 2001 From: Xinto Date: Thu, 16 Mar 2023 23:50:44 +0400 Subject: [PATCH] improve account screen forms --- .../account/DefaultAccountRepository.kt | 14 ++-- .../domain/account/model/DomainAccountInfo.kt | 12 ++-- .../mauth/domain/otp/DefaultOtpRepository.kt | 6 +- .../mauth/ui/screen/account/AccountScreen.kt | 16 +++-- .../account/state/AccountScreenSuccess.kt | 64 +++++++++++++------ app/src/main/res/values/strings.xml | 1 + 6 files changed, 73 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/com/xinto/mauth/domain/account/DefaultAccountRepository.kt b/app/src/main/java/com/xinto/mauth/domain/account/DefaultAccountRepository.kt index f30548a..53b7e88 100644 --- a/app/src/main/java/com/xinto/mauth/domain/account/DefaultAccountRepository.kt +++ b/app/src/main/java/com/xinto/mauth/domain/account/DefaultAccountRepository.kt @@ -37,8 +37,8 @@ class DefaultAccountRepository( override suspend fun putAccount(domainAccountInfo: DomainAccountInfo) { val entityAccount = domainAccountInfo.toEntityAccount() - rtdataDao.insertCountData(EntityCountData(entityAccount.id, domainAccountInfo.counter)) - accountsDao.insert(entityAccount) + rtdataDao.upsertCountData(EntityCountData(entityAccount.id, domainAccountInfo.counter.toInt())) + accountsDao.upsert(entityAccount) } override suspend fun incrementAccountCounter(id: UUID) { @@ -86,9 +86,9 @@ class DefaultAccountRepository( secret = secret, algorithm = algorithm, type = type, - digits = digits, - period = period, - counter = counter + digits = digits.toString(), + period = period.toString(), + counter = counter.toString() ) } @@ -101,8 +101,8 @@ class DefaultAccountRepository( issuer = issuer, algorithm = algorithm, type = type, - digits = digits, - period = period + digits = digits.toInt(), + period = period.toInt() ) } diff --git a/app/src/main/java/com/xinto/mauth/domain/account/model/DomainAccountInfo.kt b/app/src/main/java/com/xinto/mauth/domain/account/model/DomainAccountInfo.kt index bf19f2d..87440d5 100644 --- a/app/src/main/java/com/xinto/mauth/domain/account/model/DomainAccountInfo.kt +++ b/app/src/main/java/com/xinto/mauth/domain/account/model/DomainAccountInfo.kt @@ -18,9 +18,9 @@ data class DomainAccountInfo( val secret: String, val algorithm: OtpDigest, val type: OtpType, - val digits: Int, - val counter: Int, - val period: Int, + val digits: String, + val counter: String, + val period: String, ) : Parcelable { companion object { @@ -32,9 +32,9 @@ data class DomainAccountInfo( secret = "", algorithm = OtpDigest.Sha1, type = OtpType.Totp, - digits = 6, - counter = 0, - period = 30 + digits = "6", + counter = "0", + period = "30" ) } diff --git a/app/src/main/java/com/xinto/mauth/domain/otp/DefaultOtpRepository.kt b/app/src/main/java/com/xinto/mauth/domain/otp/DefaultOtpRepository.kt index 338570c..6d90f9c 100644 --- a/app/src/main/java/com/xinto/mauth/domain/otp/DefaultOtpRepository.kt +++ b/app/src/main/java/com/xinto/mauth/domain/otp/DefaultOtpRepository.kt @@ -82,9 +82,9 @@ class DefaultOtpRepository( secret = parseResult.data.secret, algorithm = parseResult.data.algorithm, type = parseResult.data.type, - digits = parseResult.data.digits, - counter = parseResult.data.counter ?: DomainAccountInfo.DEFAULT.counter, - period = parseResult.data.period ?: DomainAccountInfo.DEFAULT.period, + digits = parseResult.data.digits.toString(), + counter = parseResult.data.counter?.toString() ?: DomainAccountInfo.DEFAULT.counter, + period = parseResult.data.period?.toString() ?: DomainAccountInfo.DEFAULT.period, ) } is OtpUriParserResult.Failure -> null diff --git a/app/src/main/java/com/xinto/mauth/ui/screen/account/AccountScreen.kt b/app/src/main/java/com/xinto/mauth/ui/screen/account/AccountScreen.kt index f592809..2731e02 100644 --- a/app/src/main/java/com/xinto/mauth/ui/screen/account/AccountScreen.kt +++ b/app/src/main/java/com/xinto/mauth/ui/screen/account/AccountScreen.kt @@ -88,11 +88,19 @@ fun AccountScreen( topBar = { TopAppBar( actions = { + val enabled by remember(accountInfo) { + derivedStateOf { + accountInfo != null && + accountInfo!!.label.isNotEmpty() && + accountInfo!!.secret.isNotEmpty() && + accountInfo!!.digits.toIntOrNull() != null && + accountInfo!!.counter.toIntOrNull() != null && + accountInfo!!.period.toIntOrNull() != null + } + } TextButton( - onClick = { - onSave(accountInfo!!) - }, - enabled = accountInfo != null + onClick = { onSave(accountInfo!!) }, + enabled = enabled ) { Text(stringResource(R.string.account_actions_save)) } diff --git a/app/src/main/java/com/xinto/mauth/ui/screen/account/state/AccountScreenSuccess.kt b/app/src/main/java/com/xinto/mauth/ui/screen/account/state/AccountScreenSuccess.kt index fffe859..0cb2be7 100644 --- a/app/src/main/java/com/xinto/mauth/ui/screen/account/state/AccountScreenSuccess.kt +++ b/app/src/main/java/com/xinto/mauth/ui/screen/account/state/AccountScreenSuccess.kt @@ -45,12 +45,12 @@ fun AccountScreenSuccess( onTypeChange: (OtpType) -> Unit, digest: OtpDigest, onDigestChange: (OtpDigest) -> Unit, - digits: Int, - onDigitsChange: (Int) -> Unit, - counter: Int, - onCounterChange: (Int) -> Unit, - period: Int, - onPeriodChange: (Int) -> Unit, + digits: String, + onDigitsChange: (String) -> Unit, + counter: String, + onCounterChange: (String) -> Unit, + period: String, + onPeriodChange: (String) -> Unit, ) { LazyVerticalGrid( modifier = Modifier.fillMaxSize(), @@ -100,10 +100,9 @@ fun AccountScreenSuccess( } } singleItem { - OutlinedTextField( + DataField( value = label, onValueChange = onLabelChange, - singleLine = true, label = { Text(stringResource(R.string.account_data_label)) }, @@ -113,13 +112,13 @@ fun AccountScreenSuccess( contentDescription = null ) }, + required = true ) } singleItem { - OutlinedTextField( + DataField( value = issuer, onValueChange = onIssuerChange, - singleLine = true, label = { Text(stringResource(R.string.account_data_issuer)) }, @@ -133,10 +132,9 @@ fun AccountScreenSuccess( } singleItem { var secretShown by remember { mutableStateOf(false) } - OutlinedTextField( + DataField( value = secret, onValueChange = onSecretChange, - singleLine = true, label = { Text(stringResource(R.string.account_data_secret)) }, @@ -161,7 +159,8 @@ fun AccountScreenSuccess( PasswordVisualTransformation() } }, - keyboardOptions = remember { KeyboardOptions(keyboardType = KeyboardType.Password) } + keyboardOptions = remember { KeyboardOptions(keyboardType = KeyboardType.Password) }, + required = true ) } item { @@ -245,22 +244,47 @@ private fun SlideAnimatable( } } +@Composable +private fun DataField( + value: String, + onValueChange: (String) -> Unit, + required: Boolean = false, + label: (@Composable () -> Unit)? = null, + leadingIcon: (@Composable () -> Unit)? = null, + trailingIcon: (@Composable () -> Unit)? = null, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, +) { + OutlinedTextField( + value = value, + onValueChange = onValueChange, + singleLine = true, + label = label, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + supportingText = if (required) { -> + Text(stringResource(R.string.account_data_status_required)) + } else null, + visualTransformation = visualTransformation, + keyboardOptions = keyboardOptions, + ) +} + @Composable private fun NumberField( - value: Int, - onValueChange: (Int) -> Unit, + value: String, + onValueChange: (String) -> Unit, label: (@Composable () -> Unit)? = null, ) { OutlinedTextField( - value = value.toString(), - onValueChange = { newValue -> - onValueChange(newValue.filter { it.isDigit() }.toInt()) - }, + value = value, + onValueChange = onValueChange, singleLine = true, keyboardOptions = remember { KeyboardOptions(keyboardType = KeyboardType.Number) }, - label = label + label = label, + isError = value.toIntOrNull() == null ) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a655530..8ad1057 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -41,6 +41,7 @@ Discard Cancel An error occurred while loading the account + required Settings Secure mode