Merge "Add ability to show/hide password"
This commit is contained in:
@@ -13,6 +13,10 @@
|
||||
<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 is a label for content description for show password icon button. -->
|
||||
<string name="content_description_show_password">Show password</string>
|
||||
<!-- This is a label for content description for hide password icon button. -->
|
||||
<string name="content_description_hide_password">Hide password</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>
|
||||
<!-- This string highlight passkey benefits related with the password. [CHAR LIMIT=200] -->
|
||||
|
||||
@@ -64,7 +64,7 @@ class CredentialManagerRepo(
|
||||
requestInfo = intent.extras?.getParcelable(
|
||||
RequestInfo.EXTRA_REQUEST_INFO,
|
||||
RequestInfo::class.java
|
||||
) ?: testCreatePasskeyRequestInfo()
|
||||
) ?: testCreatePasswordRequestInfo()
|
||||
|
||||
providerEnabledList = when (requestInfo.type) {
|
||||
RequestInfo.TYPE_CREATE ->
|
||||
|
||||
@@ -16,11 +16,23 @@
|
||||
|
||||
package com.android.credentialmanager.common.ui
|
||||
|
||||
import com.android.credentialmanager.R
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Visibility
|
||||
import androidx.compose.material.icons.outlined.VisibilityOff
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
|
||||
|
||||
@Composable
|
||||
fun ActionButton(text: String, onClick: () -> Unit) {
|
||||
@@ -32,4 +44,27 @@ fun ActionButton(text: String, onClick: () -> Unit) {
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ToggleVisibilityButton(modifier: Modifier = Modifier, onToggle: (Boolean) -> Unit) {
|
||||
// default state is visibility off
|
||||
val toggleState: MutableState<Boolean> = remember { mutableStateOf(false) }
|
||||
|
||||
IconButton(
|
||||
modifier = modifier,
|
||||
onClick = {
|
||||
toggleState.value = !toggleState.value
|
||||
onToggle(toggleState.value)
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = if (toggleState.value)
|
||||
Icons.Outlined.Visibility else Icons.Outlined.VisibilityOff,
|
||||
contentDescription = if (toggleState.value)
|
||||
stringResource(R.string.content_description_show_password) else
|
||||
stringResource(R.string.content_description_hide_password),
|
||||
tint = LocalAndroidColorScheme.current.colorAccentPrimaryVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,15 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.outlined.NewReleases
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -20,18 +26,19 @@ import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.outlined.NewReleases
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
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.Alignment
|
||||
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.AnnotatedString
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
@@ -43,11 +50,13 @@ import com.android.credentialmanager.common.material.ModalBottomSheetValue
|
||||
import com.android.credentialmanager.common.material.rememberModalBottomSheetState
|
||||
import com.android.credentialmanager.common.ui.ActionButton
|
||||
import com.android.credentialmanager.common.ui.ConfirmButton
|
||||
import com.android.credentialmanager.common.ui.ContainerCard
|
||||
import com.android.credentialmanager.common.ui.Entry
|
||||
import com.android.credentialmanager.common.ui.TextOnSurface
|
||||
import com.android.credentialmanager.common.ui.TextSecondary
|
||||
import com.android.credentialmanager.common.ui.TextOnSurfaceVariant
|
||||
import com.android.credentialmanager.common.ui.ContainerCard
|
||||
import com.android.credentialmanager.common.ui.TextSecondary
|
||||
import com.android.credentialmanager.common.ui.ToggleVisibilityButton
|
||||
import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
|
||||
import com.android.credentialmanager.ui.theme.EntryShape
|
||||
import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
|
||||
|
||||
@@ -851,12 +860,38 @@ fun PrimaryCreateOptionRow(
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
modifier = Modifier.padding(top = 16.dp, start = 5.dp),
|
||||
)
|
||||
TextSecondary(
|
||||
Row(modifier = Modifier.fillMaxWidth().padding(top = 4.dp, bottom = 16.dp,
|
||||
start = 5.dp),
|
||||
verticalAlignment = Alignment.CenterVertically) {
|
||||
val visualTransformation = remember { PasswordVisualTransformation() }
|
||||
// This subtitle would never be null for create password
|
||||
text = requestDisplayInfo.subtitle ?: "",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier.padding(bottom = 16.dp, start = 5.dp),
|
||||
)
|
||||
val originalPassword by remember {
|
||||
mutableStateOf(requestDisplayInfo.subtitle ?: "")
|
||||
}
|
||||
val displayedPassword = remember {
|
||||
mutableStateOf(
|
||||
visualTransformation.filter(
|
||||
AnnotatedString(originalPassword)
|
||||
).text.text
|
||||
)
|
||||
}
|
||||
TextSecondary(
|
||||
text = displayedPassword.value,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier.padding(top = 4.dp, bottom = 4.dp),
|
||||
)
|
||||
|
||||
ToggleVisibilityButton(modifier = Modifier.padding(start = 4.dp)
|
||||
.height(24.dp).width(24.dp), onToggle = {
|
||||
if (it) {
|
||||
displayedPassword.value = originalPassword
|
||||
} else {
|
||||
displayedPassword.value = visualTransformation.filter(
|
||||
AnnotatedString(originalPassword)
|
||||
).text.text
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
CredentialType.UNKNOWN -> {
|
||||
if (requestDisplayInfo.subtitle != null) {
|
||||
|
||||
Reference in New Issue
Block a user