diff --git a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/myeid/pinandcertificate/MyEidPinScreen.kt b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/myeid/pinandcertificate/MyEidPinScreen.kt index 43b9a6b0..044a0c2c 100644 --- a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/myeid/pinandcertificate/MyEidPinScreen.kt +++ b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/myeid/pinandcertificate/MyEidPinScreen.kt @@ -29,7 +29,6 @@ import androidx.compose.foundation.focusable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -37,7 +36,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface @@ -90,7 +88,6 @@ import ee.ria.DigiDoc.ui.theme.Dimensions.MPadding import ee.ria.DigiDoc.ui.theme.Dimensions.SPadding import ee.ria.DigiDoc.ui.theme.Dimensions.XSPadding import ee.ria.DigiDoc.ui.theme.Dimensions.iconSizeM -import ee.ria.DigiDoc.ui.theme.Dimensions.iconSizeXXS import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.getAccessibilityEventType import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.isTalkBackEnabled import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.sendAccessibilityEvent @@ -139,9 +136,6 @@ fun MyEidPinScreen( val actionContinue = stringResource(R.string.action_continue) - val clearButtonText = stringResource(R.string.clear_text) - val buttonName = stringResource(id = R.string.button_name) - val codeType = content?.codeType ?: CodeType.PIN1 val isForgottenPin = content?.isForgottenPin == true val title = stringResource(content?.title ?: R.string.myeid_pin_change_title, codeType.name) @@ -622,72 +616,33 @@ fun MyEidPinScreen( color = MaterialTheme.colorScheme.onSurfaceVariant, style = MaterialTheme.typography.titleLarge, ) - Row( + SecurePinTextField( modifier = modifier .fillMaxWidth() - .padding(top = MPadding), - horizontalArrangement = Arrangement.Start, - verticalAlignment = Alignment.CenterVertically, - ) { - SecurePinTextField( - modifier = - modifier - .weight(1f) - .zIndex(3f) - .semantics { - traversalIndex = 3f - testTagsAsResourceId = true - }.testTag("myEidCurrentPinTextField"), - pin = currentPinState, - label = pinCodeLabel, - focusRequester = currentPinFocusRequester, - pinCodeTextEdited = null, - isError = !isCurrentPinValid, - keyboardImeAction = ImeAction.Next, - onDone = { - if (isCurrentPinValid) { - showCurrentPinField.value = false - showNewRepeatPinField.value = false - showNewPinField.value = true - } else { - focusManager.clearFocus() - } - }, - ) - if (isTalkBackEnabled(context) && currentPinState.value.isNotEmpty()) { - IconButton( - modifier = - modifier - .zIndex(4f) - .align(Alignment.CenterVertically) - .semantics { - traversalIndex = 4f - testTagsAsResourceId = true - }.testTag("myEidCurrentPinRemoveButton"), - onClick = { - currentPinState.value = byteArrayOf() - scope.launch(Main) { - currentPinFocusRequester.requestFocus() - focusManager.clearFocus() - delay(200) - currentPinFocusRequester.requestFocus() - } - }, - ) { - Icon( - modifier = - modifier - .size(iconSizeXXS) - .semantics { - testTagsAsResourceId = true - }.testTag("idCardCurrentPinRemoveIconButton"), - imageVector = ImageVector.vectorResource(R.drawable.ic_icon_remove), - contentDescription = "$clearButtonText $buttonName", - ) + .padding(top = MPadding) + .zIndex(3f) + .semantics { + traversalIndex = 3f + testTagsAsResourceId = true + }.testTag("myEidCurrentPinTextField"), + pin = currentPinState, + label = pinCodeLabel, + focusRequester = currentPinFocusRequester, + pinCodeTextEdited = null, + isError = !isCurrentPinValid, + keyboardImeAction = ImeAction.Next, + removeIconTestTag = "myEidCurrentPinRemoveButton", + onDone = { + if (isCurrentPinValid) { + showCurrentPinField.value = false + showNewRepeatPinField.value = false + showNewPinField.value = true + } else { + focusManager.clearFocus() } - } - } + }, + ) Text( modifier = modifier @@ -723,72 +678,33 @@ fun MyEidPinScreen( color = MaterialTheme.colorScheme.onSurfaceVariant, style = MaterialTheme.typography.titleLarge, ) - Row( + SecurePinTextField( modifier = modifier .fillMaxWidth() - .padding(top = MPadding), - horizontalArrangement = Arrangement.Start, - verticalAlignment = Alignment.CenterVertically, - ) { - SecurePinTextField( - modifier = - modifier - .weight(1f) - .zIndex(7f) - .semantics { - traversalIndex = 7f - testTagsAsResourceId = true - }.testTag("myEidNewPinTextField"), - pin = newPinState, - label = pinCodeLabel, - focusRequester = newPinFocusRequester, - pinCodeTextEdited = null, - isError = !isNewPinValid, - keyboardImeAction = ImeAction.Next, - onDone = { - if (isNewPinValid) { - showCurrentPinField.value = false - showNewPinField.value = false - showNewRepeatPinField.value = true - } else { - focusManager.clearFocus() - } - }, - ) - if (isTalkBackEnabled(context) && newPinState.value.isNotEmpty()) { - IconButton( - modifier = - modifier - .zIndex(8f) - .align(Alignment.CenterVertically) - .semantics { - traversalIndex = 8f - testTagsAsResourceId = true - }.testTag("myEidNewPinRemoveButton"), - onClick = { - newPinState.value = byteArrayOf() - scope.launch(Main) { - newPinFocusRequester.requestFocus() - focusManager.clearFocus() - delay(200) - newPinFocusRequester.requestFocus() - } - }, - ) { - Icon( - modifier = - modifier - .size(iconSizeXXS) - .semantics { - testTagsAsResourceId = true - }.testTag("idCardNewPinRemoveIconButton"), - imageVector = ImageVector.vectorResource(R.drawable.ic_icon_remove), - contentDescription = "$clearButtonText $buttonName", - ) + .padding(top = MPadding) + .zIndex(7f) + .semantics { + traversalIndex = 7f + testTagsAsResourceId = true + }.testTag("myEidNewPinTextField"), + pin = newPinState, + label = pinCodeLabel, + focusRequester = newPinFocusRequester, + pinCodeTextEdited = null, + isError = !isNewPinValid, + keyboardImeAction = ImeAction.Next, + removeIconTestTag = "myEidNewPinRemoveButton", + onDone = { + if (isNewPinValid) { + showCurrentPinField.value = false + showNewPinField.value = false + showNewRepeatPinField.value = true + } else { + focusManager.clearFocus() } - } - } + }, + ) Text( modifier = modifier @@ -853,62 +769,23 @@ fun MyEidPinScreen( color = MaterialTheme.colorScheme.onSurfaceVariant, style = MaterialTheme.typography.titleLarge, ) - Row( + SecurePinTextField( modifier = modifier .fillMaxWidth() - .padding(top = MPadding), - horizontalArrangement = Arrangement.Start, - verticalAlignment = Alignment.CenterVertically, - ) { - SecurePinTextField( - modifier = - modifier - .weight(1f) - .zIndex(11f) - .semantics { - traversalIndex = 11f - testTagsAsResourceId = true - }.testTag("myEidNewPinRepeatedTextField"), - pin = newPinRepeatedState, - label = pinCodeLabel, - focusRequester = newPinRepeatedFocusRequester, - pinCodeTextEdited = null, - isError = !isNewRepeatedPinValid, - ) - if (isTalkBackEnabled(context) && newPinRepeatedState.value.isNotEmpty()) { - IconButton( - modifier = - modifier - .zIndex(12f) - .align(Alignment.CenterVertically) - .semantics { - traversalIndex = 12f - testTagsAsResourceId = true - }.testTag("myEidNewPinRepeatedRemoveButton"), - onClick = { - newPinRepeatedState.value = byteArrayOf() - scope.launch(Main) { - newPinRepeatedFocusRequester.requestFocus() - focusManager.clearFocus() - delay(200) - newPinRepeatedFocusRequester.requestFocus() - } - }, - ) { - Icon( - modifier = - modifier - .size(iconSizeXXS) - .semantics { - testTagsAsResourceId = true - }.testTag("idCardNewPinRepeatedRemoveIconButton"), - imageVector = ImageVector.vectorResource(R.drawable.ic_icon_remove), - contentDescription = "$clearButtonText $buttonName", - ) - } - } - } + .padding(top = MPadding) + .zIndex(11f) + .semantics { + traversalIndex = 11f + testTagsAsResourceId = true + }.testTag("myEidNewPinRepeatedTextField"), + pin = newPinRepeatedState, + label = pinCodeLabel, + focusRequester = newPinRepeatedFocusRequester, + pinCodeTextEdited = null, + isError = !isNewRepeatedPinValid, + removeIconTestTag = "myEidNewPinRepeatedRemoveButton", + ) Text( modifier = modifier diff --git a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/shared/PrimaryTextField.kt b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/shared/PrimaryTextField.kt index d966c433..d352f166 100644 --- a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/shared/PrimaryTextField.kt +++ b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/shared/PrimaryTextField.kt @@ -69,6 +69,7 @@ import androidx.compose.ui.text.style.TextAlign import ee.ria.DigiDoc.R import ee.ria.DigiDoc.ui.theme.Dimensions.MSPadding import ee.ria.DigiDoc.ui.theme.Dimensions.XSPadding +import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.addInvisibleElement import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.isTalkBackEnabled import ee.ria.DigiDoc.utils.extensions.notAccessible import kotlinx.coroutines.Dispatchers.Main @@ -267,3 +268,11 @@ fun PrimaryTextField( } } } + +fun talkBackTextFieldValue(text: String): TextFieldValue { + val withInvisibleElements = addInvisibleElement(text) + return TextFieldValue( + text = withInvisibleElements, + selection = TextRange(withInvisibleElements.length), + ) +} diff --git a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/MobileIdView.kt b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/MobileIdView.kt index 6fc7d61d..ac3b6081 100644 --- a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/MobileIdView.kt +++ b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/MobileIdView.kt @@ -78,13 +78,13 @@ import ee.ria.DigiDoc.ui.component.shared.HrefMessageDialog import ee.ria.DigiDoc.ui.component.shared.InvisibleElement import ee.ria.DigiDoc.ui.component.shared.PrimaryTextField import ee.ria.DigiDoc.ui.component.shared.RoleDataView +import ee.ria.DigiDoc.ui.component.shared.talkBackTextFieldValue import ee.ria.DigiDoc.ui.component.support.textFieldValueSaver import ee.ria.DigiDoc.ui.theme.Dimensions.MSPadding import ee.ria.DigiDoc.ui.theme.Dimensions.SPadding import ee.ria.DigiDoc.ui.theme.Dimensions.XSPadding import ee.ria.DigiDoc.ui.theme.RIADigiDocTheme import ee.ria.DigiDoc.ui.theme.buttonRoundCornerShape -import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.addInvisibleElement import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.isTalkBackEnabled import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.removeInvisibleElement import ee.ria.DigiDoc.utils.snackbar.SnackBarManager.showMessage @@ -190,8 +190,8 @@ fun MobileIdView( val phoneNumberFocusRequester = remember { FocusRequester() } val personalCodeFocusRequester = remember { FocusRequester() } - val phoneNumberWithInvisibleSpaces = TextFieldValue(addInvisibleElement(countryCodeAndPhone.text)) - val personalCodeWithInvisibleSpaces = TextFieldValue(addInvisibleElement(personalCode.text)) + val phoneNumberWithInvisibleSpaces = talkBackTextFieldValue(countryCodeAndPhone.text) + val personalCodeWithInvisibleSpaces = talkBackTextFieldValue(personalCode.text) BackHandler { if (isSigning) { diff --git a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/NFCView.kt b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/NFCView.kt index 063a4a7c..4b5175ed 100644 --- a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/NFCView.kt +++ b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/NFCView.kt @@ -95,13 +95,13 @@ import ee.ria.DigiDoc.ui.component.shared.InvisibleElement import ee.ria.DigiDoc.ui.component.shared.PrimaryTextField import ee.ria.DigiDoc.ui.component.shared.RoleDataView import ee.ria.DigiDoc.ui.component.shared.SecurePinTextField +import ee.ria.DigiDoc.ui.component.shared.talkBackTextFieldValue import ee.ria.DigiDoc.ui.component.support.textFieldValueSaver import ee.ria.DigiDoc.ui.theme.Dimensions.MSPadding import ee.ria.DigiDoc.ui.theme.Dimensions.SPadding import ee.ria.DigiDoc.ui.theme.Dimensions.XSPadding import ee.ria.DigiDoc.ui.theme.RIADigiDocTheme import ee.ria.DigiDoc.ui.theme.buttonRoundCornerShape -import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.addInvisibleElement import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.isTalkBackEnabled import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.removeInvisibleElement import ee.ria.DigiDoc.utils.extensions.notAccessible @@ -216,7 +216,7 @@ fun NFCView( val canNumberFocusRequester = remember { FocusRequester() } val pinNumberFocusRequester = remember { FocusRequester() } - val canNumberWithInvisibleSpaces = TextFieldValue(addInvisibleElement(canNumber.text)) + val canNumberWithInvisibleSpaces = talkBackTextFieldValue(canNumber.text) val pinCode = remember { mutableStateOf(byteArrayOf()) } diff --git a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/SmartIdView.kt b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/SmartIdView.kt index 8e34c42d..6d3faa3c 100644 --- a/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/SmartIdView.kt +++ b/app/src/main/kotlin/ee/ria/DigiDoc/ui/component/signing/SmartIdView.kt @@ -91,13 +91,13 @@ import ee.ria.DigiDoc.ui.component.shared.InvisibleElement import ee.ria.DigiDoc.ui.component.shared.PrimaryTextField import ee.ria.DigiDoc.ui.component.shared.RoleDataView import ee.ria.DigiDoc.ui.component.shared.dialog.OptionChooserDialog +import ee.ria.DigiDoc.ui.component.shared.talkBackTextFieldValue import ee.ria.DigiDoc.ui.component.support.textFieldValueSaver import ee.ria.DigiDoc.ui.theme.Dimensions.MSPadding import ee.ria.DigiDoc.ui.theme.Dimensions.SPadding import ee.ria.DigiDoc.ui.theme.Dimensions.XSPadding import ee.ria.DigiDoc.ui.theme.RIADigiDocTheme import ee.ria.DigiDoc.ui.theme.buttonRoundCornerShape -import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.addInvisibleElement import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.isTalkBackEnabled import ee.ria.DigiDoc.utils.accessibility.AccessibilityUtil.Companion.removeInvisibleElement import ee.ria.DigiDoc.utils.snackbar.SnackBarManager.showMessage @@ -184,7 +184,7 @@ fun SmartIdView( val clearButtonText = stringResource(R.string.clear_text) val buttonName = stringResource(id = R.string.button_name) - val personalCodeWithInvisibleSpaces = TextFieldValue(addInvisibleElement(personalCode.text)) + val personalCodeWithInvisibleSpaces = talkBackTextFieldValue(personalCode.text) val smartIdChallengeNotificationId = Constant.SmartIdConstants.NOTIFICATION_PERMISSION_CODE