diff options
4 files changed, 55 insertions, 7 deletions
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml index e9b2e1041c22..3e652517270d 100644 --- a/packages/CredentialManager/res/values/strings.xml +++ b/packages/CredentialManager/res/values/strings.xml @@ -117,6 +117,8 @@ <string name="get_dialog_sign_in_type_username_separator" translatable="false">" • "</string> <!-- This text is followed by a list of one or more options. [CHAR LIMIT=80] --> <string name="get_dialog_title_sign_in_options">Sign-in options</string> + <!-- Button label for viewing the full information about an account. [CHAR LIMIT=80] --> + <string name="button_label_view_more">View more</string> <!-- Column heading for displaying sign-ins for a specific username. [CHAR LIMIT=80] --> <string name="get_dialog_heading_for_username">For <xliff:g id="username" example="becket@gmail.com">%1$s</xliff:g></string> <!-- Column heading for displaying locked (that is, the user needs to first authenticate via pin, fingerprint, faceId, etc.) sign-ins. [CHAR LIMIT=80] --> diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt index 0623ff629812..2dba2ab6777c 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt @@ -51,6 +51,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.LayoutDirection @@ -79,6 +80,7 @@ fun Entry( /** If true, draws a trailing lock icon. */ isLockedAuthEntry: Boolean = false, enforceOneLine: Boolean = false, + onTextLayout: (TextLayoutResult) -> Unit = {}, ) { val iconPadding = Modifier.wrapContentSize().padding( // Horizontal padding should be 16dp, but the suggestion chip itself @@ -103,7 +105,11 @@ fun Entry( ) { // Apply weight so that the trailing icon can always show. Column(modifier = Modifier.wrapContentHeight().fillMaxWidth().weight(1f)) { - SmallTitleText(text = entryHeadlineText, enforceOneLine = enforceOneLine) + SmallTitleText( + text = entryHeadlineText, + enforceOneLine = enforceOneLine, + onTextLayout = onTextLayout, + ) if (passwordValue != null) { Row( modifier = Modifier.fillMaxWidth().padding(top = 4.dp), @@ -141,10 +147,18 @@ fun Entry( ) } } else if (entrySecondLineText != null) { - BodySmallText(text = entrySecondLineText, enforceOneLine = enforceOneLine) + BodySmallText( + text = entrySecondLineText, + enforceOneLine = enforceOneLine, + onTextLayout = onTextLayout, + ) } if (entryThirdLineText != null) { - BodySmallText(text = entryThirdLineText, enforceOneLine = enforceOneLine) + BodySmallText( + text = entryThirdLineText, + enforceOneLine = enforceOneLine, + onTextLayout = onTextLayout, + ) } } if (isLockedAuthEntry) { diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt index 61c03b4041f5..6b46636964e4 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt @@ -22,6 +22,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme @@ -59,14 +60,20 @@ fun BodyMediumText(text: String, modifier: Modifier = Modifier) { * Body-small typography; on-surface-variant color. */ @Composable -fun BodySmallText(text: String, modifier: Modifier = Modifier, enforceOneLine: Boolean = false) { +fun BodySmallText( + text: String, + modifier: Modifier = Modifier, + enforceOneLine: Boolean = false, + onTextLayout: (TextLayoutResult) -> Unit = {}, +) { Text( modifier = modifier.wrapContentSize(), text = text, color = LocalAndroidColorScheme.current.colorOnSurfaceVariant, style = MaterialTheme.typography.bodySmall, overflow = TextOverflow.Ellipsis, - maxLines = if (enforceOneLine) 1 else Int.MAX_VALUE + maxLines = if (enforceOneLine) 1 else Int.MAX_VALUE, + onTextLayout = onTextLayout, ) } @@ -87,14 +94,20 @@ fun LargeTitleText(text: String, modifier: Modifier = Modifier) { * Title-small typography; on-surface color. */ @Composable -fun SmallTitleText(text: String, modifier: Modifier = Modifier, enforceOneLine: Boolean = false) { +fun SmallTitleText( + text: String, + modifier: Modifier = Modifier, + enforceOneLine: Boolean = false, + onTextLayout: (TextLayoutResult) -> Unit = {}, +) { Text( modifier = modifier.wrapContentSize(), text = text, color = LocalAndroidColorScheme.current.colorOnSurface, style = MaterialTheme.typography.titleSmall, overflow = TextOverflow.Ellipsis, - maxLines = if (enforceOneLine) 1 else Int.MAX_VALUE + maxLines = if (enforceOneLine) 1 else Int.MAX_VALUE, + onTextLayout = onTextLayout, ) } diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt index 6d7ecd70eb0b..c1ea1d8d1746 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt @@ -34,11 +34,15 @@ import androidx.compose.material3.Divider import androidx.compose.material3.TextButton 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.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.unit.dp import androidx.core.graphics.drawable.toBitmap import com.android.credentialmanager.CredentialSelectorViewModel @@ -158,6 +162,7 @@ fun PrimarySelectionCard( onMoreOptionSelected: () -> Unit, onLog: @Composable (UiEventEnum) -> Unit, ) { + val showMoreForTruncatedEntry = remember { mutableStateOf(false) } val sortedUserNameToCredentialEntryList = providerDisplayInfo.sortedUserNameToCredentialEntryList val authenticationEntryList = providerDisplayInfo.authenticationEntryList @@ -209,6 +214,8 @@ fun PrimarySelectionCard( Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { val usernameForCredentialSize = sortedUserNameToCredentialEntryList.size val authenticationEntrySize = authenticationEntryList.size + // If true, render a view more button for the single truncated entry on the + // front page. // Show max 4 entries in this primary page if (usernameForCredentialSize + authenticationEntrySize <= 4) { sortedUserNameToCredentialEntryList.forEach { @@ -216,6 +223,9 @@ fun PrimarySelectionCard( credentialEntryInfo = it.sortedCredentialEntryList.first(), onEntrySelected = onEntrySelected, enforceOneLine = true, + onTextLayout = { + showMoreForTruncatedEntry.value = it.hasVisualOverflow + } ) } authenticationEntryList.forEach { @@ -269,6 +279,13 @@ fun PrimarySelectionCard( onMoreOptionSelected ) } + } else if (showMoreForTruncatedEntry.value) { + { + ActionButton( + stringResource(R.string.button_label_view_more), + onMoreOptionSelected + ) + } } else null, rightButton = if (activeEntry != null) { // Only one sign-in options exist { @@ -438,6 +455,7 @@ fun CredentialEntryRow( credentialEntryInfo: CredentialEntryInfo, onEntrySelected: (BaseEntry) -> Unit, enforceOneLine: Boolean = false, + onTextLayout: (TextLayoutResult) -> Unit = {}, ) { Entry( onClick = { onEntrySelected(credentialEntryInfo) }, @@ -463,6 +481,7 @@ fun CredentialEntryRow( ) }, enforceOneLine = enforceOneLine, + onTextLayout = onTextLayout, ) } |