Merge "[CredManUI] Make all bottom sheet pages scrollable." into udc-dev
This commit is contained in:
@@ -16,11 +16,13 @@
|
|||||||
|
|
||||||
package com.android.credentialmanager.common.ui
|
package com.android.credentialmanager.common.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.LazyListScope
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@@ -40,7 +42,8 @@ import androidx.compose.ui.unit.dp
|
|||||||
fun SheetContainerCard(
|
fun SheetContainerCard(
|
||||||
topAppBar: (@Composable () -> Unit)? = null,
|
topAppBar: (@Composable () -> Unit)? = null,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
content: @Composable ColumnScope.() -> Unit,
|
contentVerticalArrangement: Arrangement.Vertical = Arrangement.Top,
|
||||||
|
content: LazyListScope.() -> Unit,
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = modifier.fillMaxWidth().wrapContentHeight(),
|
modifier = modifier.fillMaxWidth().wrapContentHeight(),
|
||||||
@@ -54,7 +57,7 @@ fun SheetContainerCard(
|
|||||||
if (topAppBar != null) {
|
if (topAppBar != null) {
|
||||||
topAppBar()
|
topAppBar()
|
||||||
}
|
}
|
||||||
Column(
|
LazyColumn(
|
||||||
modifier = Modifier.padding(
|
modifier = Modifier.padding(
|
||||||
start = 24.dp,
|
start = 24.dp,
|
||||||
end = 24.dp,
|
end = 24.dp,
|
||||||
@@ -63,6 +66,7 @@ fun SheetContainerCard(
|
|||||||
).fillMaxWidth().wrapContentHeight(),
|
).fillMaxWidth().wrapContentHeight(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
content = content,
|
content = content,
|
||||||
|
verticalArrangement = contentVerticalArrangement,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2023 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.credentialmanager.common.ui
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.LazyListScope
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun EntryListColumn(content: LazyListScope.() -> Unit) {
|
|
||||||
LazyColumn(
|
|
||||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
|
||||||
content = content,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -8,11 +8,12 @@ import androidx.activity.result.IntentSenderRequest
|
|||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
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.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.material3.Divider
|
import androidx.compose.material3.Divider
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
@@ -23,7 +24,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
@@ -43,7 +43,6 @@ import com.android.credentialmanager.common.ui.ConfirmButton
|
|||||||
import com.android.credentialmanager.common.ui.CredentialContainerCard
|
import com.android.credentialmanager.common.ui.CredentialContainerCard
|
||||||
import com.android.credentialmanager.common.ui.CtaButtonRow
|
import com.android.credentialmanager.common.ui.CtaButtonRow
|
||||||
import com.android.credentialmanager.common.ui.Entry
|
import com.android.credentialmanager.common.ui.Entry
|
||||||
import com.android.credentialmanager.common.ui.EntryListColumn
|
|
||||||
import com.android.credentialmanager.common.ui.HeadlineIcon
|
import com.android.credentialmanager.common.ui.HeadlineIcon
|
||||||
import com.android.credentialmanager.common.ui.LargeLabelTextOnSurfaceVariant
|
import com.android.credentialmanager.common.ui.LargeLabelTextOnSurfaceVariant
|
||||||
import com.android.credentialmanager.common.ui.ModalBottomSheet
|
import com.android.credentialmanager.common.ui.ModalBottomSheet
|
||||||
@@ -157,6 +156,7 @@ fun PasskeyIntroCard(
|
|||||||
onLearnMore: () -> Unit,
|
onLearnMore: () -> Unit,
|
||||||
) {
|
) {
|
||||||
SheetContainerCard {
|
SheetContainerCard {
|
||||||
|
item {
|
||||||
val onboardingImageResource = remember {
|
val onboardingImageResource = remember {
|
||||||
mutableStateOf(R.drawable.ic_passkeys_onboarding)
|
mutableStateOf(R.drawable.ic_passkeys_onboarding)
|
||||||
}
|
}
|
||||||
@@ -165,31 +165,43 @@ fun PasskeyIntroCard(
|
|||||||
} else {
|
} else {
|
||||||
onboardingImageResource.value = R.drawable.ic_passkeys_onboarding
|
onboardingImageResource.value = R.drawable.ic_passkeys_onboarding
|
||||||
}
|
}
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.wrapContentHeight().fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
) {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(onboardingImageResource.value),
|
painter = painterResource(onboardingImageResource.value),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier
|
modifier = Modifier.size(316.dp, 168.dp)
|
||||||
.align(alignment = Alignment.CenterHorizontally).size(316.dp, 168.dp)
|
|
||||||
)
|
)
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
}
|
||||||
HeadlineText(text = stringResource(R.string.passkey_creation_intro_title))
|
}
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
|
item { HeadlineText(text = stringResource(R.string.passkey_creation_intro_title)) }
|
||||||
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
PasskeyBenefitRow(
|
PasskeyBenefitRow(
|
||||||
leadingIconPainter = painterResource(R.drawable.ic_passkeys_onboarding_password),
|
leadingIconPainter = painterResource(R.drawable.ic_passkeys_onboarding_password),
|
||||||
text = stringResource(R.string.passkey_creation_intro_body_password),
|
text = stringResource(R.string.passkey_creation_intro_body_password),
|
||||||
)
|
)
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
PasskeyBenefitRow(
|
PasskeyBenefitRow(
|
||||||
leadingIconPainter = painterResource(R.drawable.ic_passkeys_onboarding_fingerprint),
|
leadingIconPainter = painterResource(R.drawable.ic_passkeys_onboarding_fingerprint),
|
||||||
text = stringResource(R.string.passkey_creation_intro_body_fingerprint),
|
text = stringResource(R.string.passkey_creation_intro_body_fingerprint),
|
||||||
)
|
)
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
PasskeyBenefitRow(
|
PasskeyBenefitRow(
|
||||||
leadingIconPainter = painterResource(R.drawable.ic_passkeys_onboarding_device),
|
leadingIconPainter = painterResource(R.drawable.ic_passkeys_onboarding_device),
|
||||||
text = stringResource(R.string.passkey_creation_intro_body_device),
|
text = stringResource(R.string.passkey_creation_intro_body_device),
|
||||||
)
|
)
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
|
|
||||||
|
item {
|
||||||
CtaButtonRow(
|
CtaButtonRow(
|
||||||
leftButton = {
|
leftButton = {
|
||||||
ActionButton(
|
ActionButton(
|
||||||
@@ -205,6 +217,7 @@ fun PasskeyIntroCard(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -218,8 +231,9 @@ fun ProviderSelectionCard(
|
|||||||
onMoreOptionsSelected: () -> Unit,
|
onMoreOptionsSelected: () -> Unit,
|
||||||
) {
|
) {
|
||||||
SheetContainerCard {
|
SheetContainerCard {
|
||||||
HeadlineIcon(bitmap = requestDisplayInfo.typeIcon.toBitmap().asImageBitmap())
|
item { HeadlineIcon(bitmap = requestDisplayInfo.typeIcon.toBitmap().asImageBitmap()) }
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
HeadlineText(
|
HeadlineText(
|
||||||
text = stringResource(
|
text = stringResource(
|
||||||
R.string.choose_provider_title,
|
R.string.choose_provider_title,
|
||||||
@@ -232,16 +246,17 @@ fun ProviderSelectionCard(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
|
|
||||||
BodyMediumText(text = stringResource(R.string.choose_provider_body))
|
item { BodyMediumText(text = stringResource(R.string.choose_provider_body)) }
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
CredentialContainerCard {
|
CredentialContainerCard {
|
||||||
LazyColumn(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(2.dp)
|
verticalArrangement = Arrangement.spacedBy(2.dp)
|
||||||
) {
|
) {
|
||||||
sortedCreateOptionsPairs.forEach { entry ->
|
sortedCreateOptionsPairs.forEach { entry ->
|
||||||
item {
|
|
||||||
MoreOptionsInfoRow(
|
MoreOptionsInfoRow(
|
||||||
requestDisplayInfo = requestDisplayInfo,
|
requestDisplayInfo = requestDisplayInfo,
|
||||||
providerInfo = entry.second,
|
providerInfo = entry.second,
|
||||||
@@ -256,8 +271,6 @@ fun ProviderSelectionCard(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
item {
|
|
||||||
MoreOptionsDisabledProvidersRow(
|
MoreOptionsDisabledProvidersRow(
|
||||||
disabledProviders = disabledProviderList,
|
disabledProviders = disabledProviderList,
|
||||||
onDisabledProvidersSelected = onDisabledProvidersSelected,
|
onDisabledProvidersSelected = onDisabledProvidersSelected,
|
||||||
@@ -266,7 +279,8 @@ fun ProviderSelectionCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasRemoteEntry) {
|
if (hasRemoteEntry) {
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
CtaButtonRow(
|
CtaButtonRow(
|
||||||
leftButton = {
|
leftButton = {
|
||||||
ActionButton(
|
ActionButton(
|
||||||
@@ -277,6 +291,7 @@ fun ProviderSelectionCard(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -310,14 +325,14 @@ fun MoreOptionsSelectionCard(
|
|||||||
else onBackCreationSelectionButtonSelected,
|
else onBackCreationSelectionButtonSelected,
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
CredentialContainerCard {
|
CredentialContainerCard {
|
||||||
EntryListColumn {
|
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||||
// Only in the flows with default provider(not first time use) we can show the
|
// Only in the flows with default provider(not first time use) we can show the
|
||||||
// createOptions here, or they will be shown on ProviderSelectionCard
|
// createOptions here, or they will be shown on ProviderSelectionCard
|
||||||
if (hasDefaultProvider) {
|
if (hasDefaultProvider) {
|
||||||
sortedCreateOptionsPairs.forEach { entry ->
|
sortedCreateOptionsPairs.forEach { entry ->
|
||||||
item {
|
|
||||||
MoreOptionsInfoRow(
|
MoreOptionsInfoRow(
|
||||||
requestDisplayInfo = requestDisplayInfo,
|
requestDisplayInfo = requestDisplayInfo,
|
||||||
providerInfo = entry.second,
|
providerInfo = entry.second,
|
||||||
@@ -329,31 +344,28 @@ fun MoreOptionsSelectionCard(
|
|||||||
entry.first
|
entry.first
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
item {
|
|
||||||
MoreOptionsDisabledProvidersRow(
|
MoreOptionsDisabledProvidersRow(
|
||||||
disabledProviders = disabledProviderList,
|
disabledProviders = disabledProviderList,
|
||||||
onDisabledProvidersSelected =
|
onDisabledProvidersSelected =
|
||||||
onDisabledProvidersSelected,
|
onDisabledProvidersSelected,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
enabledProviderList.forEach {
|
enabledProviderList.forEach {
|
||||||
if (it.remoteEntry != null) {
|
if (it.remoteEntry != null) {
|
||||||
item {
|
|
||||||
RemoteEntryRow(
|
RemoteEntryRow(
|
||||||
remoteInfo = it.remoteEntry!!,
|
remoteInfo = it.remoteEntry!!,
|
||||||
onRemoteEntrySelected = onRemoteEntrySelected,
|
onRemoteEntrySelected = onRemoteEntrySelected,
|
||||||
)
|
)
|
||||||
}
|
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -363,16 +375,19 @@ fun MoreOptionsRowIntroCard(
|
|||||||
onUseOnceSelected: () -> Unit,
|
onUseOnceSelected: () -> Unit,
|
||||||
) {
|
) {
|
||||||
SheetContainerCard {
|
SheetContainerCard {
|
||||||
HeadlineIcon(imageVector = Icons.Outlined.NewReleases)
|
item { HeadlineIcon(imageVector = Icons.Outlined.NewReleases) }
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
HeadlineText(
|
HeadlineText(
|
||||||
text = stringResource(
|
text = stringResource(
|
||||||
R.string.use_provider_for_all_title,
|
R.string.use_provider_for_all_title,
|
||||||
providerInfo.displayName
|
providerInfo.displayName
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
}
|
||||||
BodyMediumText(text = stringResource(R.string.use_provider_for_all_description))
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
|
item { BodyMediumText(text = stringResource(R.string.use_provider_for_all_description)) }
|
||||||
|
item {
|
||||||
CtaButtonRow(
|
CtaButtonRow(
|
||||||
leftButton = {
|
leftButton = {
|
||||||
ActionButton(
|
ActionButton(
|
||||||
@@ -388,6 +403,7 @@ fun MoreOptionsRowIntroCard(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -402,13 +418,16 @@ fun CreationSelectionCard(
|
|||||||
hasDefaultProvider: Boolean,
|
hasDefaultProvider: Boolean,
|
||||||
) {
|
) {
|
||||||
SheetContainerCard {
|
SheetContainerCard {
|
||||||
|
item {
|
||||||
HeadlineIcon(
|
HeadlineIcon(
|
||||||
bitmap = providerInfo.icon.toBitmap().asImageBitmap(),
|
bitmap = providerInfo.icon.toBitmap().asImageBitmap(),
|
||||||
tint = Color.Unspecified,
|
tint = Color.Unspecified,
|
||||||
)
|
)
|
||||||
Divider(thickness = 4.dp, color = Color.Transparent)
|
}
|
||||||
LargeLabelTextOnSurfaceVariant(text = providerInfo.displayName)
|
item { Divider(thickness = 4.dp, color = Color.Transparent) }
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
item { LargeLabelTextOnSurfaceVariant(text = providerInfo.displayName) }
|
||||||
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
HeadlineText(
|
HeadlineText(
|
||||||
text = when (requestDisplayInfo.type) {
|
text = when (requestDisplayInfo.type) {
|
||||||
CredentialType.PASSKEY -> stringResource(
|
CredentialType.PASSKEY -> stringResource(
|
||||||
@@ -425,7 +444,9 @@ fun CreationSelectionCard(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
CredentialContainerCard {
|
CredentialContainerCard {
|
||||||
PrimaryCreateOptionRow(
|
PrimaryCreateOptionRow(
|
||||||
requestDisplayInfo = requestDisplayInfo,
|
requestDisplayInfo = requestDisplayInfo,
|
||||||
@@ -433,7 +454,8 @@ fun CreationSelectionCard(
|
|||||||
onOptionSelected = onOptionSelected
|
onOptionSelected = onOptionSelected
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
var createOptionsSize = 0
|
var createOptionsSize = 0
|
||||||
var remoteEntry: RemoteInfo? = null
|
var remoteEntry: RemoteInfo? = null
|
||||||
enabledProviderList.forEach { enabledProvider ->
|
enabledProviderList.forEach { enabledProvider ->
|
||||||
@@ -450,6 +472,7 @@ fun CreationSelectionCard(
|
|||||||
} else {
|
} else {
|
||||||
createOptionsSize > 1 || remoteEntry != null
|
createOptionsSize > 1 || remoteEntry != null
|
||||||
}
|
}
|
||||||
|
item {
|
||||||
CtaButtonRow(
|
CtaButtonRow(
|
||||||
leftButton = if (shouldShowMoreOptionsButton) {
|
leftButton = if (shouldShowMoreOptionsButton) {
|
||||||
{
|
{
|
||||||
@@ -466,13 +489,16 @@ fun CreationSelectionCard(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
}
|
||||||
if (createOptionInfo.footerDescription != null) {
|
if (createOptionInfo.footerDescription != null) {
|
||||||
|
item {
|
||||||
Divider(
|
Divider(
|
||||||
thickness = 1.dp,
|
thickness = 1.dp,
|
||||||
color = MaterialTheme.colorScheme.outlineVariant,
|
color = MaterialTheme.colorScheme.outlineVariant,
|
||||||
modifier = Modifier.padding(vertical = 16.dp)
|
modifier = Modifier.padding(vertical = 16.dp)
|
||||||
)
|
)
|
||||||
BodySmallText(text = createOptionInfo.footerDescription)
|
}
|
||||||
|
item { BodySmallText(text = createOptionInfo.footerDescription) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -485,13 +511,11 @@ fun ExternalOnlySelectionCard(
|
|||||||
onConfirm: () -> Unit,
|
onConfirm: () -> Unit,
|
||||||
) {
|
) {
|
||||||
SheetContainerCard {
|
SheetContainerCard {
|
||||||
HeadlineIcon(painter = painterResource(R.drawable.ic_other_devices))
|
item { HeadlineIcon(painter = painterResource(R.drawable.ic_other_devices)) }
|
||||||
Divider(thickness = 16.dp, color = Color.Transparent)
|
item { Divider(thickness = 16.dp, color = Color.Transparent) }
|
||||||
HeadlineText(text = stringResource(R.string.create_passkey_in_other_device_title))
|
item { HeadlineText(text = stringResource(R.string.create_passkey_in_other_device_title)) }
|
||||||
Divider(
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
thickness = 24.dp,
|
item {
|
||||||
color = Color.Transparent
|
|
||||||
)
|
|
||||||
CredentialContainerCard {
|
CredentialContainerCard {
|
||||||
PrimaryCreateOptionRow(
|
PrimaryCreateOptionRow(
|
||||||
requestDisplayInfo = requestDisplayInfo,
|
requestDisplayInfo = requestDisplayInfo,
|
||||||
@@ -499,7 +523,9 @@ fun ExternalOnlySelectionCard(
|
|||||||
onOptionSelected = onOptionSelected
|
onOptionSelected = onOptionSelected
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
CtaButtonRow(
|
CtaButtonRow(
|
||||||
rightButton = {
|
rightButton = {
|
||||||
ConfirmButton(
|
ConfirmButton(
|
||||||
@@ -509,21 +535,21 @@ fun ExternalOnlySelectionCard(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MoreAboutPasskeysIntroCard(
|
fun MoreAboutPasskeysIntroCard(
|
||||||
onBackPasskeyIntroButtonSelected: () -> Unit,
|
onBackPasskeyIntroButtonSelected: () -> Unit,
|
||||||
) {
|
) {
|
||||||
SheetContainerCard(topAppBar = {
|
SheetContainerCard(
|
||||||
|
topAppBar = {
|
||||||
MoreOptionTopAppBar(
|
MoreOptionTopAppBar(
|
||||||
text = stringResource(R.string.more_about_passkeys_title),
|
text = stringResource(R.string.more_about_passkeys_title),
|
||||||
onNavigationIconClicked = onBackPasskeyIntroButtonSelected,
|
onNavigationIconClicked = onBackPasskeyIntroButtonSelected,
|
||||||
)
|
)
|
||||||
}) {
|
},
|
||||||
LazyColumn(
|
contentVerticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
modifier = Modifier.fillMaxWidth().wrapContentHeight(),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
MoreAboutPasskeySectionHeader(
|
MoreAboutPasskeySectionHeader(
|
||||||
@@ -550,7 +576,6 @@ fun MoreAboutPasskeysIntroCard(
|
|||||||
BodyMediumText(text = stringResource(R.string.seamless_transition_detail))
|
BodyMediumText(text = stringResource(R.string.seamless_transition_detail))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material3.Divider
|
import androidx.compose.material3.Divider
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
@@ -141,6 +140,7 @@ fun PrimarySelectionCard(
|
|||||||
providerDisplayInfo.sortedUserNameToCredentialEntryList
|
providerDisplayInfo.sortedUserNameToCredentialEntryList
|
||||||
val authenticationEntryList = providerDisplayInfo.authenticationEntryList
|
val authenticationEntryList = providerDisplayInfo.authenticationEntryList
|
||||||
SheetContainerCard {
|
SheetContainerCard {
|
||||||
|
item {
|
||||||
HeadlineText(
|
HeadlineText(
|
||||||
text = stringResource(
|
text = stringResource(
|
||||||
if (sortedUserNameToCredentialEntryList
|
if (sortedUserNameToCredentialEntryList
|
||||||
@@ -160,42 +160,42 @@ fun PrimarySelectionCard(
|
|||||||
requestDisplayInfo.appName
|
requestDisplayInfo.appName
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
|
item {
|
||||||
CredentialContainerCard {
|
CredentialContainerCard {
|
||||||
|
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||||
val usernameForCredentialSize = sortedUserNameToCredentialEntryList.size
|
val usernameForCredentialSize = sortedUserNameToCredentialEntryList.size
|
||||||
val authenticationEntrySize = authenticationEntryList.size
|
val authenticationEntrySize = authenticationEntryList.size
|
||||||
LazyColumn(
|
|
||||||
verticalArrangement = Arrangement.spacedBy(2.dp)
|
|
||||||
) {
|
|
||||||
// Show max 4 entries in this primary page
|
// Show max 4 entries in this primary page
|
||||||
if (usernameForCredentialSize + authenticationEntrySize <= 4) {
|
if (usernameForCredentialSize + authenticationEntrySize <= 4) {
|
||||||
items(sortedUserNameToCredentialEntryList) {
|
sortedUserNameToCredentialEntryList.forEach {
|
||||||
CredentialEntryRow(
|
CredentialEntryRow(
|
||||||
credentialEntryInfo = it.sortedCredentialEntryList.first(),
|
credentialEntryInfo = it.sortedCredentialEntryList.first(),
|
||||||
onEntrySelected = onEntrySelected,
|
onEntrySelected = onEntrySelected,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
items(authenticationEntryList) {
|
authenticationEntryList.forEach {
|
||||||
AuthenticationEntryRow(
|
AuthenticationEntryRow(
|
||||||
authenticationEntryInfo = it,
|
authenticationEntryInfo = it,
|
||||||
onEntrySelected = onEntrySelected,
|
onEntrySelected = onEntrySelected,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (usernameForCredentialSize < 4) {
|
} else if (usernameForCredentialSize < 4) {
|
||||||
items(sortedUserNameToCredentialEntryList) {
|
sortedUserNameToCredentialEntryList.forEach {
|
||||||
CredentialEntryRow(
|
CredentialEntryRow(
|
||||||
credentialEntryInfo = it.sortedCredentialEntryList.first(),
|
credentialEntryInfo = it.sortedCredentialEntryList.first(),
|
||||||
onEntrySelected = onEntrySelected,
|
onEntrySelected = onEntrySelected,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
items(authenticationEntryList.take(4 - usernameForCredentialSize)) {
|
authenticationEntryList.take(4 - usernameForCredentialSize).forEach {
|
||||||
AuthenticationEntryRow(
|
AuthenticationEntryRow(
|
||||||
authenticationEntryInfo = it,
|
authenticationEntryInfo = it,
|
||||||
onEntrySelected = onEntrySelected,
|
onEntrySelected = onEntrySelected,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
items(sortedUserNameToCredentialEntryList.take(4)) {
|
sortedUserNameToCredentialEntryList.take(4).forEach {
|
||||||
CredentialEntryRow(
|
CredentialEntryRow(
|
||||||
credentialEntryInfo = it.sortedCredentialEntryList.first(),
|
credentialEntryInfo = it.sortedCredentialEntryList.first(),
|
||||||
onEntrySelected = onEntrySelected,
|
onEntrySelected = onEntrySelected,
|
||||||
@@ -204,7 +204,8 @@ fun PrimarySelectionCard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Divider(thickness = 24.dp, color = Color.Transparent)
|
}
|
||||||
|
item { Divider(thickness = 24.dp, color = Color.Transparent) }
|
||||||
var totalEntriesCount = sortedUserNameToCredentialEntryList
|
var totalEntriesCount = sortedUserNameToCredentialEntryList
|
||||||
.flatMap { it.sortedCredentialEntryList }.size + authenticationEntryList
|
.flatMap { it.sortedCredentialEntryList }.size + authenticationEntryList
|
||||||
.size + providerInfoList.flatMap { it.actionEntryList }.size
|
.size + providerInfoList.flatMap { it.actionEntryList }.size
|
||||||
@@ -212,6 +213,7 @@ fun PrimarySelectionCard(
|
|||||||
// Row horizontalArrangement differs on only one actionButton(should place on most
|
// Row horizontalArrangement differs on only one actionButton(should place on most
|
||||||
// left)/only one confirmButton(should place on most right)/two buttons exist the same
|
// left)/only one confirmButton(should place on most right)/two buttons exist the same
|
||||||
// time(should be one on the left, one on the right)
|
// time(should be one on the left, one on the right)
|
||||||
|
item {
|
||||||
CtaButtonRow(
|
CtaButtonRow(
|
||||||
leftButton = if (totalEntriesCount > 1) {
|
leftButton = if (totalEntriesCount > 1) {
|
||||||
{
|
{
|
||||||
@@ -231,6 +233,7 @@ fun PrimarySelectionCard(
|
|||||||
} else null,
|
} else null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Draws the secondary credential selection page, where all sign-in options are listed. */
|
/** Draws the secondary credential selection page, where all sign-in options are listed. */
|
||||||
@@ -252,7 +255,6 @@ fun AllSignInOptionCard(
|
|||||||
onNavigationIconClicked = if (isNoAccount) onCancel else onBackButtonClicked,
|
onNavigationIconClicked = if (isNoAccount) onCancel else onBackButtonClicked,
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
LazyColumn {
|
|
||||||
// For username
|
// For username
|
||||||
items(sortedUserNameToCredentialEntryList) { item ->
|
items(sortedUserNameToCredentialEntryList) { item ->
|
||||||
PerUserNameCredentials(
|
PerUserNameCredentials(
|
||||||
@@ -294,7 +296,6 @@ fun AllSignInOptionCard(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: create separate rows for primary and secondary pages.
|
// TODO: create separate rows for primary and secondary pages.
|
||||||
|
|||||||
Reference in New Issue
Block a user