Merge "When a single entry is truncated on the front page, provide a "View more" button" into udc-dev

This commit is contained in:
Helen Qin
2023-04-07 20:50:44 +00:00
committed by Android (Google) Code Review
4 changed files with 55 additions and 7 deletions

View File

@@ -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] -->

View File

@@ -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) {

View File

@@ -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,
)
}

View File

@@ -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,
)
}