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

Commit 9f46cdcb authored by Qinmei Du's avatar Qinmei Du Committed by Android (Google) Code Review
Browse files

Merge "Add the learn more screen for the passkey intro page"

parents e34b8dc6 501b0735
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -11,13 +11,34 @@
  <string name="string_continue">Continue</string>
  <!-- This is a label for a button that links to different places where the user can save their passkeys. [CHAR LIMIT=20] -->
  <string name="string_more_options">More options</string>
  <!-- This is a label for a button that links to additional information about passkeys. [CHAR LIMIT=20] -->
  <string name="string_learn_more">Learn more</string>
  <!-- This string introduces passkeys to the users for the first time they use this method. Tip: to avoid gendered language patterns, this header could be translated as if the original string were "More safety with passkeys". [CHAR LIMIT=200] -->
  <string name="passkey_creation_intro_title">Safer with passkeys</string>
  <!-- These strings highlight passkey benefits. [CHAR LIMIT=200] -->
  <!-- This string highlight passkey benefits related with the password. [CHAR LIMIT=200] -->
  <string name="passkey_creation_intro_body_password">With passkeys, you don’t need to create or remember complex passwords</string>
  <!-- This string highlight passkey benefits related with encrypted. [CHAR LIMIT=200] -->
  <string name="passkey_creation_intro_body_fingerprint">Passkeys are encrypted digital keys you create using your fingerprint, face, or screen lock</string>
  <!-- This string highlight passkey benefits related with signing with other devices. [CHAR LIMIT=200] -->
  <string name="passkey_creation_intro_body_device">They are saved to a password manager, so you can sign in on other devices</string>

  <!-- This string introduces passkeys in more detail to the users for the first time they use this method. [CHAR LIMIT=200] -->
  <string name="more_about_passkeys_title">More about passkeys</string>
  <!-- Title for subsection of "Learn more about passkeys" screen about passwordless technology. [CHAR LIMIT=80] -->
  <string name="passwordless_technology_title">Passwordless technology</string>
  <!-- Detail for subsection of "Learn more about passkeys" screen about passwordless technology. [CHAR LIMIT=500] -->
  <string name="passwordless_technology_detail">Passkeys allow you to sign in without relying on passwords. You just need to use your fingerprint, face recognition, PIN, or swipe pattern to verify your identity and create a passkey.</string>
  <!-- Title for subsection of "Learn more about passkeys" screen about public key cryptography. [CHAR LIMIT=80] -->
  <string name="public_key_cryptography_title">Public key cryptography</string>
  <!-- Detail for subsection of "Learn more about passkeys" screen about public key cryptography. [CHAR LIMIT=500] -->
  <string name="public_key_cryptography_detail">Based on FIDO Alliance (which includes Google, Apple, Microsoft, and more) and W3C standards, passkeys use cryptographic key pairs. Unlike the username and string of characters we use for passwords, a private-public key pair is created for an app or website. The private key is safely stored on your device or password manager and it confirms your identity. The public key is  shared with the app or website server. With corresponding keys, you can instantly register and sign in.</string>
  <!-- Title for subsection of "Learn more about passkeys" screen about improved account security. [CHAR LIMIT=80] -->
  <string name="improved_account_security_title">Improved account security</string>
  <!-- Detail for subsection of "Learn more about passkeys" screen about improved account security. [CHAR LIMIT=500] -->
  <string name="improved_account_security_detail">Each key is exclusively linked with the app or website they were created for, so you can never sign in to a fraudulent app or website by mistake. Plus, with servers only keeping public keys, hacking is a lot harder.</string>
  <!-- Title for subsection of "Learn more about passkeys" screen about seamless transition. [CHAR LIMIT=80] -->
  <string name="seamless_transition_title">Seamless transition</string>
  <!-- Detail for subsection of "Learn more about passkeys" screen about seamless transition. [CHAR LIMIT=500] -->
  <string name="seamless_transition_detail">As we move towards a passwordless future, passwords will still be available alongside passkeys.</string>
  <!-- This appears as the title of the modal bottom sheet which provides all available providers for users to choose. [CHAR LIMIT=200] -->
  <string name="choose_provider_title">Choose where to save your <xliff:g id="createTypes" example="passkeys">%1$s</xliff:g></string>
  <!-- This appears as the description body of the modal bottom sheet which provides all available providers for users to choose. [CHAR LIMIT=200] -->
+96 −13
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ fun CreateCredentialScreen(
                when (uiState.currentScreenState) {
                    CreateScreenState.PASSKEY_INTRO -> ConfirmationCard(
                        onConfirm = viewModel::onConfirmIntro,
                        onCancel = viewModel::onCancel,
                        onLearnMore = viewModel::onLearnMore,
                    )
                    CreateScreenState.PROVIDER_SELECTION -> ProviderSelectionCard(
                        requestDisplayInfo = uiState.requestDisplayInfo,
@@ -115,7 +115,10 @@ fun CreateCredentialScreen(
                        activeRemoteEntry = uiState.activeEntry?.activeEntryInfo!!,
                        onOptionSelected = viewModel::onEntrySelected,
                        onConfirm = viewModel::onConfirmEntrySelected,
                        onCancel = viewModel::onCancel,
                    )
                    CreateScreenState.MORE_ABOUT_PASSKEYS_INTRO -> MoreAboutPasskeysIntroCard(
                        onBackPasskeyIntroButtonSelected =
                        viewModel::onBackPasskeyIntroButtonSelected,
                    )
                }
            } else if (uiState.selectedEntry != null && !uiState.providerActivityPending) {
@@ -136,7 +139,7 @@ fun CreateCredentialScreen(
@Composable
fun ConfirmationCard(
    onConfirm: () -> Unit,
    onCancel: () -> Unit,
    onLearnMore: () -> Unit,
) {
    ContainerCard() {
        Column() {
@@ -223,8 +226,8 @@ fun ConfirmationCard(
                modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
            ) {
                ActionButton(
                    stringResource(R.string.string_cancel),
                    onClick = onCancel
                    stringResource(R.string.string_learn_more),
                    onClick = onLearnMore
                )
                ConfirmButton(
                    stringResource(R.string.string_continue),
@@ -396,8 +399,7 @@ fun MoreOptionsSelectionCard(
                        )
                    }
                },
                colors = TopAppBarDefaults.smallTopAppBarColors
                    (containerColor = Color.Transparent),
                colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
                modifier = Modifier.padding(top = 12.dp)
            )
            Divider(
@@ -634,7 +636,6 @@ fun ExternalOnlySelectionCard(
    activeRemoteEntry: EntryInfo,
    onOptionSelected: (EntryInfo) -> Unit,
    onConfirm: () -> Unit,
    onCancel: () -> Unit,
) {
    ContainerCard() {
        Column() {
@@ -673,13 +674,9 @@ fun ExternalOnlySelectionCard(
                color = Color.Transparent
            )
            Row(
                horizontalArrangement = Arrangement.SpaceBetween,
                horizontalArrangement = Arrangement.End,
                modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
            ) {
                ActionButton(
                    stringResource(R.string.string_cancel),
                    onClick = onCancel
                )
                ConfirmButton(
                    stringResource(R.string.string_continue),
                    onClick = onConfirm
@@ -694,6 +691,92 @@ fun ExternalOnlySelectionCard(
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MoreAboutPasskeysIntroCard(
    onBackPasskeyIntroButtonSelected: () -> Unit,
) {
    ContainerCard() {
        Column() {
            TopAppBar(
                title = {
                    TextOnSurface(
                        text =
                        stringResource(
                            R.string.more_about_passkeys_title),
                        style = MaterialTheme.typography.titleMedium,
                    )
                },
                navigationIcon = {
                    IconButton(
                        onClick = onBackPasskeyIntroButtonSelected
                    ) {
                        Icon(
                            Icons.Filled.ArrowBack,
                            stringResource(R.string.accessibility_back_arrow_button)
                        )
                    }
                },
                colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
                modifier = Modifier.padding(top = 12.dp)
            )
            Column(
                modifier = Modifier.fillMaxWidth().padding(start = 24.dp, end = 68.dp)
            ) {
                TextOnSurfaceVariant(
                    text = stringResource(R.string.passwordless_technology_title),
                    style = MaterialTheme.typography.titleLarge,
                )
                TextSecondary(
                    text = stringResource(R.string.passwordless_technology_detail),
                    style = MaterialTheme.typography.bodyMedium,
                )
                Divider(
                    thickness = 24.dp,
                    color = Color.Transparent
                )
                TextOnSurfaceVariant(
                    text = stringResource(R.string.public_key_cryptography_title),
                    style = MaterialTheme.typography.titleLarge,
                )
                TextSecondary(
                    text = stringResource(R.string.public_key_cryptography_detail),
                    style = MaterialTheme.typography.bodyMedium,
                )
                Divider(
                    thickness = 24.dp,
                    color = Color.Transparent
                )
                TextOnSurfaceVariant(
                    text = stringResource(R.string.improved_account_security_title),
                    style = MaterialTheme.typography.titleLarge,
                )
                TextSecondary(
                    text = stringResource(R.string.improved_account_security_detail),
                    style = MaterialTheme.typography.bodyMedium,
                )
                Divider(
                    thickness = 24.dp,
                    color = Color.Transparent
                )
                TextOnSurfaceVariant(
                    text = stringResource(R.string.seamless_transition_title),
                    style = MaterialTheme.typography.titleLarge,
                )
                TextSecondary(
                    text = stringResource(R.string.seamless_transition_detail),
                    style = MaterialTheme.typography.bodyMedium,
                )
            }
            Divider(
                thickness = 18.dp,
                color = Color.Transparent,
                modifier = Modifier.padding(bottom = 24.dp)
            )
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PrimaryCreateOptionRow(
+12 −0
Original line number Diff line number Diff line
@@ -122,6 +122,12 @@ class CreateCredentialViewModel(
    )
  }

  fun onBackPasskeyIntroButtonSelected() {
    uiState = uiState.copy(
      currentScreenState = CreateScreenState.PASSKEY_INTRO,
    )
  }

  fun onEntrySelectedFromMoreOptionScreen(activeEntry: ActiveEntry) {
    uiState = uiState.copy(
      currentScreenState = if (
@@ -150,6 +156,12 @@ class CreateCredentialViewModel(
    dialogResult.tryEmit(DialogResult(ResultState.NORMAL_CANCELED))
  }

  fun onLearnMore() {
    uiState = uiState.copy(
      currentScreenState = CreateScreenState.MORE_ABOUT_PASSKEYS_INTRO,
    )
  }

  fun onChangeDefaultSelected() {
    uiState = uiState.copy(
      currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ data class ActiveEntry (
/** The name of the current screen. */
enum class CreateScreenState {
  PASSKEY_INTRO,
  MORE_ABOUT_PASSKEYS_INTRO,
  PROVIDER_SELECTION,
  CREATION_OPTION_SELECTION,
  MORE_OPTIONS_SELECTION,