Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5c4bdf5 authored by Helen Qin's avatar Helen Qin
Browse files

When a single entry is truncated on the front page, provide a "View more" button

For a single entry there is no "more option" page.

However, the texts on that entry may be truncated to fit into the one-line requirement for the Credential Selector front page. Therefore, if that happens, render a "view more" that leads to the more option page with the same entry, but fully expanded in text.

Bug: 277272017
Test: manual (see bug for recording)
Change-Id: If5d88453c7d1905a72c7beaebbc2ece8ce212d02
parent 4c6f5787
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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] -->
+17 −3
Original line number Diff line number Diff line
@@ -52,6 +52,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
@@ -80,6 +81,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
@@ -104,7 +106,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),
@@ -142,10 +148,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) {
+17 −4
Original line number Diff line number Diff line
@@ -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

@@ -58,14 +59,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 = MaterialTheme.colorScheme.onSurfaceVariant,
        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,
    )
}

@@ -86,14 +93,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 = MaterialTheme.colorScheme.onSurface,
        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,
    )
}

+19 −0
Original line number Diff line number Diff line
@@ -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,
    )
}