Loading packages/CredentialManager/res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -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] --> Loading packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt +17 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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), Loading Loading @@ -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) { Loading packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt +17 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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, ) } Loading @@ -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, ) } Loading packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt +19 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 { Loading @@ -216,6 +223,9 @@ fun PrimarySelectionCard( credentialEntryInfo = it.sortedCredentialEntryList.first(), onEntrySelected = onEntrySelected, enforceOneLine = true, onTextLayout = { showMoreForTruncatedEntry.value = it.hasVisualOverflow } ) } authenticationEntryList.forEach { Loading Loading @@ -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 { Loading Loading @@ -438,6 +455,7 @@ fun CredentialEntryRow( credentialEntryInfo: CredentialEntryInfo, onEntrySelected: (BaseEntry) -> Unit, enforceOneLine: Boolean = false, onTextLayout: (TextLayoutResult) -> Unit = {}, ) { Entry( onClick = { onEntrySelected(credentialEntryInfo) }, Loading @@ -463,6 +481,7 @@ fun CredentialEntryRow( ) }, enforceOneLine = enforceOneLine, onTextLayout = onTextLayout, ) } Loading Loading
packages/CredentialManager/res/values/strings.xml +2 −0 Original line number Diff line number Diff line Loading @@ -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] --> Loading
packages/CredentialManager/src/com/android/credentialmanager/common/ui/Entry.kt +17 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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), Loading Loading @@ -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) { Loading
packages/CredentialManager/src/com/android/credentialmanager/common/ui/Texts.kt +17 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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, ) } Loading @@ -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, ) } Loading
packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt +19 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 { Loading @@ -216,6 +223,9 @@ fun PrimarySelectionCard( credentialEntryInfo = it.sortedCredentialEntryList.first(), onEntrySelected = onEntrySelected, enforceOneLine = true, onTextLayout = { showMoreForTruncatedEntry.value = it.hasVisualOverflow } ) } authenticationEntryList.forEach { Loading Loading @@ -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 { Loading Loading @@ -438,6 +455,7 @@ fun CredentialEntryRow( credentialEntryInfo: CredentialEntryInfo, onEntrySelected: (BaseEntry) -> Unit, enforceOneLine: Boolean = false, onTextLayout: (TextLayoutResult) -> Unit = {}, ) { Entry( onClick = { onEntrySelected(credentialEntryInfo) }, Loading @@ -463,6 +481,7 @@ fun CredentialEntryRow( ) }, enforceOneLine = enforceOneLine, onTextLayout = onTextLayout, ) } Loading