Update the first time create flow(change the logic when there's no createOptions, delete the textButton on creation screen, add the remote textButton on provider selection screen)

screencast: https://screencast.googleplex.com/cast/NjM5Njc4NzMwOTkzNjY0MHw3YzcwMmQ4YS0zNQ

Test: deployed locally

Bug: 253157231
Change-Id: I28ca4d6756d1d980f48015f6de7f2398240714e2
This commit is contained in:
Qinmei Du
2022-11-23 03:02:23 +00:00
parent 626f905f4b
commit 91fddc7003
4 changed files with 78 additions and 49 deletions

View File

@@ -7,6 +7,7 @@
<string name="string_create_in_another_place">Create in another place</string>
<string name="string_save_to_another_place">Save to another place</string>
<string name="string_use_another_device">Use another device</string>
<string name="string_save_to_another_device">Save to another device</string>
<string name="string_no_thanks">No thanks</string>
<string name="passkey_creation_intro_title">A simple way to sign in safely</string>
<string name="passkey_creation_intro_body">Use your fingerprint, face or screen lock to sign in with a unique passkey that can’t be forgotten or stolen. Learn more</string>

View File

@@ -172,6 +172,7 @@ class CredentialManagerRepo(
{CreateScreenState.PASSKEY_INTRO} else {CreateScreenState.PROVIDER_SELECTION}
} else {CreateScreenState.CREATION_OPTION_SELECTION},
requestDisplayInfo,
false,
if (hasDefault) {
ActiveEntry(defaultProvider, defaultProvider.createOptions.first())
} else null

View File

@@ -80,14 +80,16 @@ fun CreateCredentialScreen(
enabledProviderList = uiState.enabledProviders,
disabledProviderList = uiState.disabledProviders,
onCancel = viewModel::onCancel,
onOptionSelected = viewModel::onMoreOptionsRowSelectedForFirstUse,
onOptionSelected = viewModel::onEntrySelectedFromFirstUseScreen,
onDisabledPasswordManagerSelected = viewModel::onDisabledPasswordManagerSelected,
onRemoteEntrySelected = selectEntryCallback,
)
CreateScreenState.CREATION_OPTION_SELECTION -> CreationSelectionCard(
requestDisplayInfo = uiState.requestDisplayInfo,
enabledProviderList = uiState.enabledProviders,
providerInfo = uiState.activeEntry?.activeProvider!!,
createOptionInfo = uiState.activeEntry.activeEntryInfo as CreateOptionInfo,
showActiveEntryOnly = uiState.showActiveEntryOnly,
onOptionSelected = selectEntryCallback,
onConfirm = confirmEntryCallback,
onCancel = viewModel::onCancel,
@@ -98,7 +100,7 @@ fun CreateCredentialScreen(
enabledProviderList = uiState.enabledProviders,
disabledProviderList = uiState.disabledProviders,
onBackButtonSelected = viewModel::onBackButtonSelected,
onOptionSelected = viewModel::onMoreOptionsRowSelected,
onOptionSelected = viewModel::onEntrySelectedFromMoreOptionScreen,
onDisabledPasswordManagerSelected = viewModel::onDisabledPasswordManagerSelected,
onRemoteEntrySelected = selectEntryCallback,
)
@@ -184,7 +186,8 @@ fun ProviderSelectionCard(
disabledProviderList: List<DisabledProviderInfo>?,
onOptionSelected: (ActiveEntry) -> Unit,
onDisabledPasswordManagerSelected: () -> Unit,
onCancel: () -> Unit
onCancel: () -> Unit,
onRemoteEntrySelected: (EntryInfo) -> Unit,
) {
Card() {
Column() {
@@ -254,10 +257,23 @@ fun ProviderSelectionCard(
}
}
}
Divider(
thickness = 24.dp,
color = Color.Transparent
)
// TODO: handle the error situation that if multiple remoteInfos exists
enabledProviderList.forEach { enabledProvider ->
if (enabledProvider.remoteEntry != null) {
TextButton(
onClick = {
onRemoteEntrySelected(enabledProvider.remoteEntry!!) },
modifier = Modifier
.padding(horizontal = 24.dp)
.align(alignment = Alignment.CenterHorizontally)
) {
Text(
text = stringResource(R.string.string_save_to_another_device),
textAlign = TextAlign.Center,
)
}
}
}
Row(
horizontalArrangement = Arrangement.Start,
modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
@@ -416,6 +432,7 @@ fun CreationSelectionCard(
enabledProviderList: List<EnabledProviderInfo>,
providerInfo: EnabledProviderInfo,
createOptionInfo: CreateOptionInfo,
showActiveEntryOnly: Boolean,
onOptionSelected: (EntryInfo) -> Unit,
onConfirm: () -> Unit,
onCancel: () -> Unit,
@@ -473,41 +490,43 @@ fun CreationSelectionCard(
onOptionSelected = onOptionSelected
)
}
var createOptionsSize = 0
enabledProviderList.forEach{
enabledProvider -> createOptionsSize += enabledProvider.createOptions.size}
if (createOptionsSize > 1) {
TextButton(
onClick = onMoreOptionsSelected,
modifier = Modifier
.padding(horizontal = 24.dp)
.align(alignment = Alignment.CenterHorizontally)){
Text(
text =
when (requestDisplayInfo.type) {
TYPE_PUBLIC_KEY_CREDENTIAL ->
stringResource(R.string.string_create_in_another_place)
else -> stringResource(R.string.string_save_to_another_place)},
textAlign = TextAlign.Center,
)
}
} else if (
requestDisplayInfo.type == TYPE_PUBLIC_KEY_CREDENTIAL
) {
// TODO: handle the error situation that if multiple remoteInfos exists
enabledProviderList.forEach { enabledProvider ->
if (enabledProvider.remoteEntry != null) {
TextButton(
onClick = {
onOptionSelected(enabledProvider.remoteEntry!!) },
modifier = Modifier
.padding(horizontal = 24.dp)
.align(alignment = Alignment.CenterHorizontally)
) {
Text(
text = stringResource(R.string.string_use_another_device),
textAlign = TextAlign.Center,
)
if (!showActiveEntryOnly) {
var createOptionsSize = 0
enabledProviderList.forEach{
enabledProvider -> createOptionsSize += enabledProvider.createOptions.size}
if (createOptionsSize > 1) {
TextButton(
onClick = onMoreOptionsSelected,
modifier = Modifier
.padding(horizontal = 24.dp)
.align(alignment = Alignment.CenterHorizontally)){
Text(
text =
when (requestDisplayInfo.type) {
TYPE_PUBLIC_KEY_CREDENTIAL ->
stringResource(R.string.string_create_in_another_place)
else -> stringResource(R.string.string_save_to_another_place)},
textAlign = TextAlign.Center,
)
}
} else if (
requestDisplayInfo.type == TYPE_PUBLIC_KEY_CREDENTIAL
) {
// TODO: handle the error situation that if multiple remoteInfos exists
enabledProviderList.forEach { enabledProvider ->
if (enabledProvider.remoteEntry != null) {
TextButton(
onClick = {
onOptionSelected(enabledProvider.remoteEntry!!) },
modifier = Modifier
.padding(horizontal = 24.dp)
.align(alignment = Alignment.CenterHorizontally)
) {
Text(
text = stringResource(R.string.string_use_another_device),
textAlign = TextAlign.Center,
)
}
}
}
}

View File

@@ -36,6 +36,7 @@ data class CreateCredentialUiState(
val disabledProviders: List<DisabledProviderInfo>? = null,
val currentScreenState: CreateScreenState,
val requestDisplayInfo: RequestDisplayInfo,
val showActiveEntryOnly: Boolean,
val activeEntry: ActiveEntry? = null,
val selectedEntry: EntryInfo? = null,
)
@@ -56,13 +57,18 @@ class CreateCredentialViewModel(
}
fun onConfirmIntro() {
if (uiState.enabledProviders.size > 1) {
uiState = uiState.copy(
currentScreenState = CreateScreenState.PROVIDER_SELECTION
var createOptionSize = 0
uiState.enabledProviders.forEach {
enabledProvider -> createOptionSize += enabledProvider.createOptions.size}
uiState = if (createOptionSize > 1) {
uiState.copy(
currentScreenState = CreateScreenState.PROVIDER_SELECTION,
showActiveEntryOnly = true
)
} else if (uiState.enabledProviders.size == 1){
uiState = uiState.copy(
} else if (createOptionSize == 1){
uiState.copy(
currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
showActiveEntryOnly = false,
activeEntry = ActiveEntry(uiState.enabledProviders.first(),
uiState.enabledProviders.first().createOptions.first()
)
@@ -90,16 +96,18 @@ class CreateCredentialViewModel(
)
}
fun onMoreOptionsRowSelected(activeEntry: ActiveEntry) {
fun onEntrySelectedFromMoreOptionScreen(activeEntry: ActiveEntry) {
uiState = uiState.copy(
currentScreenState = CreateScreenState.MORE_OPTIONS_ROW_INTRO,
showActiveEntryOnly = false,
activeEntry = activeEntry
)
}
fun onMoreOptionsRowSelectedForFirstUse(activeEntry: ActiveEntry) {
fun onEntrySelectedFromFirstUseScreen(activeEntry: ActiveEntry) {
uiState = uiState.copy(
currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
showActiveEntryOnly = true,
activeEntry = activeEntry
)
}