From e75ec3f6d6154e8b1ce276ba555f3ef0048a8073 Mon Sep 17 00:00:00 2001 From: dritan-x Date: Fri, 22 Nov 2024 18:24:46 -0800 Subject: [PATCH] UI Updates to Document Data Screen - Added warning message text, box, and icon - Showing document data fields according to a specified order defined in the code that matches the slides. Shows remaining fields in an unordered fashion. Tested by: - Manual testing by adding Test eID-Karte Personalausweis - ./gradlew check - ./gradlew connectedCheck Signed-off-by: dritan-x --- .../document/DocumentDetailsScreen.kt | 91 +++++++++++++------ wallet/src/main/res/drawable/warning.xml | 9 ++ wallet/src/main/res/values/strings.xml | 7 +- 3 files changed, 76 insertions(+), 31 deletions(-) create mode 100644 wallet/src/main/res/drawable/warning.xml diff --git a/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/document/DocumentDetailsScreen.kt b/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/document/DocumentDetailsScreen.kt index 46a3beb01..ad56a0664 100644 --- a/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/document/DocumentDetailsScreen.kt +++ b/wallet/src/main/java/com/android/identity_credential/wallet/ui/destination/document/DocumentDetailsScreen.kt @@ -1,6 +1,8 @@ package com.android.identity_credential.wallet.ui.destination.document import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -9,6 +11,9 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -23,12 +28,13 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shadow +import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -48,6 +54,7 @@ import com.android.identity_credential.wallet.ui.KeyValuePairHtml import com.android.identity_credential.wallet.ui.KeyValuePairText import com.android.identity_credential.wallet.ui.ScreenWithAppBarAndBackButton import com.android.identity_credential.wallet.ui.prompt.biometric.showBiometricPrompt +import com.android.identity_credential.wallet.util.inverse import kotlinx.coroutines.launch @@ -156,41 +163,73 @@ private fun DocumentAuthenticationRequired( private fun DocumentDetails( documentInfo: DocumentInfo, ) { - Column() { - Text( - text = stringResource(R.string.document_details_screen_flash_pass_lecture), - textAlign = TextAlign.Center, - fontStyle = FontStyle.Italic, - style = MaterialTheme.typography.bodySmall, - modifier = Modifier.padding(8.dp) - ) - + Column( + modifier = Modifier + .padding(top = 20.dp) + .padding(horizontal = 20.dp) + ) { + Row( + modifier = Modifier + .padding(bottom = 20.dp) + .border( + 1.dp, + SolidColor(MaterialTheme.colorScheme.outline), + RoundedCornerShape(30.dp) + ) + ) { + Icon( + modifier = Modifier + .size(40.dp) + .padding(top = 20.dp, start = 10.dp, end = 10.dp), + painter = painterResource(id = R.drawable.warning), + tint = MaterialTheme.colorScheme.background.inverse(), + contentDescription = stringResource( + R.string.accessibility_artwork_for, + stringResource(id = R.string.document_details_screen_warning_icon_unverified_data) + ) + ) + Text( + modifier = Modifier.padding(top = 20.dp, bottom = 20.dp, end = 16.dp), + text = stringResource(R.string.document_details_screen_flash_pass_lecture), + textAlign = TextAlign.Left, + style = MaterialTheme.typography.bodyLarge + ) + } val topImages = listOf("portrait") val bottomImages = listOf("signature_usual_mark") for (attributeId in topImages) { val attributeDisplayInfo = documentInfo.attributes[attributeId] if (attributeDisplayInfo != null) { val displayInfo = attributeDisplayInfo as AttributeDisplayInfoImage - Row( - horizontalArrangement = Arrangement.Center - ) { - Image( - bitmap = displayInfo.image.asImageBitmap(), - modifier = Modifier - .fillMaxWidth() - .padding(8.dp) - .size(200.dp), - contentDescription = displayInfo.name - ) - } + Image( + bitmap = displayInfo.image.asImageBitmap(), + modifier = Modifier + .width(100.dp) + .background(Color.Green) + .align(Alignment.Start), + contentDescription = displayInfo.name + ) } } - val centerAttributes = documentInfo.attributes.filter { !topImages.contains(it.key) && !bottomImages.contains(it.key) } - for ((attributeId, displayInfo) in centerAttributes) { - when (displayInfo) { + val orderedEntries = listOf( + "issuing_country", + "birth_date", + "expiry_date", + "given_name", + "family_name", + ) + val sortedKeys = centerAttributes.keys.sortedBy { keyValue -> + if (keyValue in orderedEntries) { + orderedEntries.indexOfFirst { it == keyValue } + } else { + Int.MAX_VALUE + } + } + for (sortedKey in sortedKeys) { + when (val displayInfo = centerAttributes[sortedKey]) { is AttributeDisplayInfoPlainText -> { KeyValuePairText(displayInfo.name, displayInfo.value) } @@ -198,7 +237,7 @@ private fun DocumentDetails( KeyValuePairHtml(displayInfo.name, displayInfo.value) } else -> { - throw IllegalArgumentException("Unsupported attribute display info for $attributeId: $displayInfo") + throw IllegalArgumentException("Unsupported attribute display info for $sortedKey: $displayInfo") } } } diff --git a/wallet/src/main/res/drawable/warning.xml b/wallet/src/main/res/drawable/warning.xml new file mode 100644 index 000000000..8cce981ac --- /dev/null +++ b/wallet/src/main/res/drawable/warning.xml @@ -0,0 +1,9 @@ + + + diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml index f7e1eadce..b62862dc0 100644 --- a/wallet/src/main/res/values/strings.xml +++ b/wallet/src/main/res/values/strings.xml @@ -271,13 +271,10 @@ Document Data UNVERIFIED DATA\nDO NOT USE - - Showing this screen is not a secure way of sharing identity data because the verifier - has no way to confirm the authenticity of the data. Use NFC or QR to share identity - data in a secure and privacy-preserving manner. - + Do not share this screen. It is not secure for presenting info directly as authenticity cannot be verified. True False + Warning Icon Credentials