From 7cc9c89e546377eb1217959eef0470133c7daf5f Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:21:33 +0200 Subject: [PATCH 01/19] moved StatusMessage to shared model package --- .../settings/debug/factors/SecurityFactorSamplesScreen.kt | 2 +- .../securitycenter/common/composables/ShieldSetupStatusView.kt | 2 +- .../securityshields/selectfactors/SelectFactorsScreen.kt | 2 +- .../android/presentation/ui/composables/StatusMessageText.kt | 2 +- .../presentation/ui/composables/card/FactorSourceCardView.kt | 3 +-- .../presentation/ui/model/factors/FactorSourceStatusMessage.kt | 1 + .../presentation/ui/model/{factors => shared}/StatusMessage.kt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename app/src/main/java/com/babylon/wallet/android/presentation/ui/model/{factors => shared}/StatusMessage.kt (82%) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/debug/factors/SecurityFactorSamplesScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/debug/factors/SecurityFactorSamplesScreen.kt index c92312d7e1..94ce5d75a2 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/debug/factors/SecurityFactorSamplesScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/debug/factors/SecurityFactorSamplesScreen.kt @@ -32,7 +32,7 @@ import com.babylon.wallet.android.presentation.ui.composables.statusBarsAndBanne import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceKindCard import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceStatusMessage -import com.babylon.wallet.android.presentation.ui.model.factors.StatusMessage +import com.babylon.wallet.android.presentation.ui.model.shared.StatusMessage import com.radixdlt.sargon.Account import com.radixdlt.sargon.FactorSourceId import com.radixdlt.sargon.FactorSourceKind diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/common/composables/ShieldSetupStatusView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/common/composables/ShieldSetupStatusView.kt index eb4026d242..0157d5ae79 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/common/composables/ShieldSetupStatusView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/common/composables/ShieldSetupStatusView.kt @@ -8,7 +8,7 @@ import com.babylon.wallet.android.R import com.babylon.wallet.android.designsystem.theme.RadixTheme import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem import com.babylon.wallet.android.presentation.ui.composables.StatusMessageText -import com.babylon.wallet.android.presentation.ui.model.factors.StatusMessage +import com.babylon.wallet.android.presentation.ui.model.shared.StatusMessage import com.babylon.wallet.android.presentation.ui.modifier.noIndicationClickable import com.babylon.wallet.android.utils.formattedSpans diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/selectfactors/SelectFactorsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/selectfactors/SelectFactorsScreen.kt index f875c61326..e8a7e84f75 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/selectfactors/SelectFactorsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/selectfactors/SelectFactorsScreen.kt @@ -42,7 +42,7 @@ import com.babylon.wallet.android.presentation.ui.composables.card.subtitle import com.babylon.wallet.android.presentation.ui.composables.card.title import com.babylon.wallet.android.presentation.ui.composables.statusBarsAndBanner import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard -import com.babylon.wallet.android.presentation.ui.model.factors.StatusMessage +import com.babylon.wallet.android.presentation.ui.model.shared.StatusMessage import com.babylon.wallet.android.presentation.ui.modifier.noIndicationClickable import com.babylon.wallet.android.utils.formattedSpans import com.radixdlt.sargon.FactorSourceId diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/StatusMessageText.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/StatusMessageText.kt index 86fcae3fa5..e0b659f62d 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/StatusMessageText.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/StatusMessageText.kt @@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import com.babylon.wallet.android.designsystem.theme.RadixTheme -import com.babylon.wallet.android.presentation.ui.model.factors.StatusMessage +import com.babylon.wallet.android.presentation.ui.model.shared.StatusMessage @Composable fun StatusMessageText( diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/FactorSourceCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/FactorSourceCardView.kt index 7f0158648d..c5d3b31a6d 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/FactorSourceCardView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/FactorSourceCardView.kt @@ -41,8 +41,7 @@ import com.babylon.wallet.android.presentation.ui.composables.StatusMessageText import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceKindCard import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceStatusMessage -import com.babylon.wallet.android.presentation.ui.model.factors.StatusMessage -import com.babylon.wallet.android.presentation.ui.modifier.defaultCardShadow +import com.babylon.wallet.android.presentation.ui.model.shared.StatusMessage import com.babylon.wallet.android.presentation.ui.modifier.enabledOpacity import com.babylon.wallet.android.presentation.ui.modifier.throttleClickable import com.babylon.wallet.android.utils.formattedSpans diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/factors/FactorSourceStatusMessage.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/factors/FactorSourceStatusMessage.kt index e82601bcde..58a013bbbb 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/factors/FactorSourceStatusMessage.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/factors/FactorSourceStatusMessage.kt @@ -6,6 +6,7 @@ import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.font.FontWeight import com.babylon.wallet.android.R import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.presentation.ui.model.shared.StatusMessage import com.babylon.wallet.android.utils.formattedSpans sealed interface FactorSourceStatusMessage { diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/factors/StatusMessage.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/shared/StatusMessage.kt similarity index 82% rename from app/src/main/java/com/babylon/wallet/android/presentation/ui/model/factors/StatusMessage.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/ui/model/shared/StatusMessage.kt index 00b997d1c7..2a675d709e 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/factors/StatusMessage.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/shared/StatusMessage.kt @@ -1,4 +1,4 @@ -package com.babylon.wallet.android.presentation.ui.model.factors +package com.babylon.wallet.android.presentation.ui.model.shared import androidx.compose.ui.text.AnnotatedString From c0d080e1ca8cdeba82f381da50f4dc101d3c1316 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:21:49 +0200 Subject: [PATCH 02/19] added missing string resource in ShieldSetupStatusView --- .../securitycenter/common/composables/ShieldSetupStatusView.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/common/composables/ShieldSetupStatusView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/common/composables/ShieldSetupStatusView.kt index 0157d5ae79..cd64a96cca 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/common/composables/ShieldSetupStatusView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/common/composables/ShieldSetupStatusView.kt @@ -53,8 +53,7 @@ fun ShieldSetupNotEnoughFactorsStatusView( StatusMessageText( modifier = modifier.noIndicationClickable { onInfoClick(GlossaryItem.buildingshield) }, message = StatusMessage( - // TODO crowdin - message = "You haven’t chosen enough factors to build a Shield. Learn about **Factors required for Shield**".formattedSpans( + message = stringResource(R.string.shieldSetupStatus_notEnoughFactors).formattedSpans( boldStyle = SpanStyle( color = RadixTheme.colors.blue2, fontWeight = RadixTheme.typography.body1StandaloneLink.fontWeight, From 143f86412336197649dcb522bd9ef5294b5a65bd Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:22:53 +0200 Subject: [PATCH 03/19] moved RadioButtonSelectorView to composables/shared package --- .../factors/SecurityFactorSamplesViewModel.kt | 2 +- .../SelectableFactorSourceKindCardView.kt | 23 +--------------- .../shared/RadioButtonSelectorView.kt | 27 +++++++++++++++++++ 3 files changed, 29 insertions(+), 23 deletions(-) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/shared/RadioButtonSelectorView.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/debug/factors/SecurityFactorSamplesViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/debug/factors/SecurityFactorSamplesViewModel.kt index 06f5f6de2c..b9f40431d4 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/debug/factors/SecurityFactorSamplesViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/debug/factors/SecurityFactorSamplesViewModel.kt @@ -6,7 +6,7 @@ import com.babylon.wallet.android.presentation.common.UiState import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceKindCard import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceStatusMessage -import com.babylon.wallet.android.presentation.ui.model.factors.StatusMessage +import com.babylon.wallet.android.presentation.ui.model.shared.StatusMessage import com.babylon.wallet.android.utils.relativeTimeFormatted import com.radixdlt.sargon.Account import com.radixdlt.sargon.DeviceFactorSource diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SelectableFactorSourceKindCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SelectableFactorSourceKindCardView.kt index 5945ef8d8b..1ab11dc381 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SelectableFactorSourceKindCardView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SelectableFactorSourceKindCardView.kt @@ -1,15 +1,11 @@ package com.babylon.wallet.android.presentation.ui.composables.card -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.width import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import com.babylon.wallet.android.designsystem.theme.RadixTheme import com.babylon.wallet.android.domain.model.Selectable import com.babylon.wallet.android.presentation.ui.RadixWalletPreviewTheme -import com.babylon.wallet.android.presentation.ui.composables.RadixRadioButton +import com.babylon.wallet.android.presentation.ui.composables.shared.RadioButtonSelectorView import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceKindCard import com.babylon.wallet.android.presentation.ui.modifier.noIndicationClickable import com.radixdlt.sargon.FactorSourceKind @@ -33,23 +29,6 @@ fun SelectableSingleChoiceFactorSourceKindCard( ) } -@Composable -private fun RadioButtonSelectorView( - isSelected: Boolean, - onSelectedChange: () -> Unit -) { - Row { - Spacer(modifier = Modifier.width(RadixTheme.dimensions.paddingSmall)) - - RadixRadioButton( - selected = isSelected, - onClick = onSelectedChange - ) - - Spacer(modifier = Modifier.width(RadixTheme.dimensions.paddingDefault)) - } -} - @Composable @Preview private fun SelectableSingleChoiceFactorSourceKindCardPreview() { diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/shared/RadioButtonSelectorView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/shared/RadioButtonSelectorView.kt new file mode 100644 index 0000000000..ae77b68597 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/shared/RadioButtonSelectorView.kt @@ -0,0 +1,27 @@ +package com.babylon.wallet.android.presentation.ui.composables.shared + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.presentation.ui.composables.RadixRadioButton + +@Composable +fun RadioButtonSelectorView( + modifier: Modifier = Modifier, + isSelected: Boolean, + onSelectedChange: () -> Unit +) { + Row(modifier = modifier) { + Spacer(modifier = Modifier.width(RadixTheme.dimensions.paddingSmall)) + + RadixRadioButton( + selected = isSelected, + onClick = onSelectedChange + ) + + Spacer(modifier = Modifier.width(RadixTheme.dimensions.paddingDefault)) + } +} From 1c78eeb6070f8f17b0b0dead8cd4a7c77e467e90 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:23:26 +0200 Subject: [PATCH 04/19] moved CardContainer to composables/shared package --- .../composables/card/FactorSourceCardView.kt | 22 +------------ .../ui/composables/shared/CardContainer.kt | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/shared/CardContainer.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/FactorSourceCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/FactorSourceCardView.kt index c5d3b31a6d..9c6845a2e1 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/FactorSourceCardView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/FactorSourceCardView.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -23,7 +22,6 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString @@ -38,6 +36,7 @@ import com.babylon.wallet.android.designsystem.theme.RadixTheme import com.babylon.wallet.android.presentation.ui.RadixWalletPreviewTheme import com.babylon.wallet.android.presentation.ui.composables.DSR import com.babylon.wallet.android.presentation.ui.composables.StatusMessageText +import com.babylon.wallet.android.presentation.ui.composables.shared.CardContainer import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceKindCard import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceStatusMessage @@ -189,25 +188,6 @@ fun SimpleFactorCardView( } } -@Composable -private fun CardContainer( - modifier: Modifier = Modifier, - content: @Composable ColumnScope.() -> Unit -) { - Column( - modifier = modifier - .defaultCardShadow(elevation = 6.dp) - .clip(RadixTheme.shapes.roundedRectMedium) - .fillMaxWidth() - .background( - color = RadixTheme.colors.white, - shape = RadixTheme.shapes.roundedRectDefault - ) - ) { - content() - } -} - @Composable private fun MessagesView( messages: PersistentList diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/shared/CardContainer.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/shared/CardContainer.kt new file mode 100644 index 0000000000..1355bd56d9 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/shared/CardContainer.kt @@ -0,0 +1,31 @@ +package com.babylon.wallet.android.presentation.ui.composables.shared + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.presentation.ui.modifier.defaultCardShadow + +@Composable +fun CardContainer( + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit +) { + Column( + modifier = modifier + .defaultCardShadow(elevation = 6.dp) + .clip(RadixTheme.shapes.roundedRectMedium) + .fillMaxWidth() + .background( + color = RadixTheme.colors.white, + shape = RadixTheme.shapes.roundedRectDefault + ) + ) { + content() + } +} From d7437595f55aa9c74a94d33fb0aca138b4c1277e Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:23:53 +0200 Subject: [PATCH 05/19] added logic to check for available security shields in SecurityCenterViewModel --- .../securitycenter/SecurityCenterViewModel.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterViewModel.kt index b107f9526b..53eed38847 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterViewModel.kt @@ -9,6 +9,8 @@ import com.babylon.wallet.android.presentation.common.OneOffEventHandler import com.babylon.wallet.android.presentation.common.OneOffEventHandlerImpl import com.babylon.wallet.android.presentation.common.StateViewModel import com.babylon.wallet.android.presentation.common.UiState +import com.babylon.wallet.android.utils.callSafely +import com.radixdlt.sargon.os.SargonOsManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.flowOn @@ -19,8 +21,9 @@ import javax.inject.Inject @HiltViewModel class SecurityCenterViewModel @Inject constructor( + private val sargonOsManager: SargonOsManager, getSecurityProblemsUseCase: GetSecurityProblemsUseCase, - @DefaultDispatcher dispatcher: CoroutineDispatcher + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher ) : StateViewModel(), OneOffEventHandler by OneOffEventHandlerImpl() { @@ -37,14 +40,15 @@ class SecurityCenterViewModel @Inject constructor( ) ) } - .flowOn(dispatcher) + .flowOn(defaultDispatcher) .launchIn(viewModelScope) } fun onSecurityShieldsClick() { viewModelScope.launch { - // TODO perform the actual check - val hasSecurityShields = false + val hasSecurityShields = sargonOsManager.callSafely(defaultDispatcher) { + getShieldsForDisplay().isNotEmpty() + }.getOrElse { false } sendEvent( if (hasSecurityShields) { Event.ToSecurityShields From 1be614f10ac9427e4a6b1c3395307b2e2ea5f72d Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:24:16 +0200 Subject: [PATCH 06/19] added SecurityShieldCard model --- .../ui/model/securityshields/SecurityShieldCard.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldCard.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldCard.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldCard.kt new file mode 100644 index 0000000000..74cc8b1cc9 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldCard.kt @@ -0,0 +1,12 @@ +package com.babylon.wallet.android.presentation.ui.model.securityshields + +import com.radixdlt.sargon.SecurityStructureId +import com.radixdlt.sargon.ShieldForDisplay +import kotlinx.collections.immutable.PersistentList + +data class SecurityShieldCard( + val shieldForDisplay: ShieldForDisplay, + val messages: PersistentList +) { + val id: SecurityStructureId = shieldForDisplay.metadata.id +} From 52dbd86fd357db8fa0e4854e6126a6b523012f75 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:24:29 +0200 Subject: [PATCH 07/19] added SecurityShieldStatusMessage --- .../SecurityShieldStatusMessage.kt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldStatusMessage.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldStatusMessage.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldStatusMessage.kt new file mode 100644 index 0000000000..0ab83bd667 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldStatusMessage.kt @@ -0,0 +1,26 @@ +package com.babylon.wallet.android.presentation.ui.model.securityshields + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import com.babylon.wallet.android.R +import com.babylon.wallet.android.presentation.ui.model.shared.StatusMessage + +sealed interface SecurityShieldStatusMessage { + + data object AppliedAndWorking : SecurityShieldStatusMessage + + data object ActionRequired : SecurityShieldStatusMessage + + @Composable + fun getMessage(): StatusMessage = when (this) { + AppliedAndWorking -> StatusMessage( + message = stringResource(id = R.string.securityShields_status_applied), + type = StatusMessage.Type.SUCCESS + ) + + ActionRequired -> StatusMessage( + message = stringResource(id = R.string.securityShields_status_actionRequired), + type = StatusMessage.Type.WARNING + ) + } +} From a276e25656cf844048eabae906250f05e9cf0de7 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:24:42 +0200 Subject: [PATCH 08/19] added SecurityShieldCardView --- .../card/SecurityShieldCardView.kt | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt new file mode 100644 index 0000000000..482a7cce5b --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt @@ -0,0 +1,244 @@ +package com.babylon.wallet.android.presentation.ui.composables.card + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp +import com.babylon.wallet.android.R +import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.presentation.ui.RadixWalletPreviewTheme +import com.babylon.wallet.android.presentation.ui.composables.DSR +import com.babylon.wallet.android.presentation.ui.composables.StatusMessageText +import com.babylon.wallet.android.presentation.ui.composables.shared.CardContainer +import com.babylon.wallet.android.presentation.ui.model.securityshields.SecurityShieldCard +import com.babylon.wallet.android.presentation.ui.model.securityshields.SecurityShieldStatusMessage +import com.radixdlt.sargon.DisplayName +import com.radixdlt.sargon.SecurityStructureFlag +import com.radixdlt.sargon.SecurityStructureId +import com.radixdlt.sargon.SecurityStructureMetadata +import com.radixdlt.sargon.ShieldForDisplay +import com.radixdlt.sargon.Timestamp +import com.radixdlt.sargon.annotation.UsesSampleValues +import com.radixdlt.sargon.samples.sample +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf + +@Composable +fun SecurityShieldCardView( + modifier: Modifier = Modifier, + item: SecurityShieldCard +) { + CardContainer { + Row( + modifier = modifier + .padding( + horizontal = RadixTheme.dimensions.paddingDefault, + vertical = RadixTheme.dimensions.paddingLarge + ), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + modifier = Modifier.size(80.dp), + painter = painterResource(id = DSR.ic_security_shields), + contentDescription = null, + tint = Color.Unspecified + ) + + Column( + modifier = Modifier + .weight(1f) + .padding(horizontal = RadixTheme.dimensions.paddingSmall) + ) { + Text( + text = item.shieldForDisplay.metadata.displayName.value, + style = RadixTheme.typography.body1Header, + color = RadixTheme.colors.gray1 + ) + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingXSmall)) + + Text( + text = stringResource(R.string.securityShields_assigned_title), + style = RadixTheme.typography.body2HighImportance, + color = RadixTheme.colors.gray2 + ) + + Text( + text = linkedEntitiesView( + accounts = item.shieldForDisplay.numberOfLinkedAccounts.toInt(), + personas = item.shieldForDisplay.numberOfLinkedPersonas.toInt() + ), + style = RadixTheme.typography.body2Regular, + color = RadixTheme.colors.gray2 + ) + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingXSmall)) + + MessagesView(messages = item.messages) + } + } + } +} + +@Composable +private fun linkedEntitiesView( + accounts: Int, + personas: Int +): String { + val accountsText = when (accounts) { + 0 -> stringResource(id = R.string.empty) + 1 -> stringResource(id = R.string.securityShields_assigned_accountSingular) + else -> stringResource(id = R.string.securityShields_assigned_accountPlural, accounts) + } + val personasText = when (personas) { + 0 -> stringResource(id = R.string.empty) + 1 -> stringResource(id = R.string.securityShields_assigned_personaSingular) + else -> stringResource(id = R.string.securityShields_assigned_personaPlural, personas) + } + val linkedText = if (accounts == 0 && personas == 0) { + stringResource(R.string.common_none) + } else { + when { + accounts != 0 && personas != 0 -> { + accountsText + " " + stringResource(id = R.string.dot_separator) + " " + personasText + } + accounts != 0 -> accountsText + else -> personasText + } + } + return linkedText +} + +@Composable +private fun MessagesView(messages: PersistentList) { + if (messages.isEmpty()) { + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingLarge)) + } else { + Column(verticalArrangement = Arrangement.spacedBy(RadixTheme.dimensions.paddingXSmall)) { + messages.forEach { + StatusMessageText( + message = it.getMessage() + ) + } + } + } +} + +@UsesSampleValues +@Composable +@Preview +private fun SecurityShieldCardPreview( + @PreviewParameter(SecurityShieldCardPreviewProvider::class) item: SecurityShieldCard +) { + RadixWalletPreviewTheme { + SecurityShieldCardView( + item = item + ) + } +} + +@UsesSampleValues +val mainShieldForDisplaySample = SecurityShieldCard( + ShieldForDisplay( + metadata = SecurityStructureMetadata( + id = SecurityStructureId.randomUUID(), + displayName = DisplayName("Panathinaikos"), + createdOn = Timestamp.now(), + lastUpdatedOn = Timestamp.now(), + flags = listOf(SecurityStructureFlag.MAIN) + ), + numberOfLinkedAccounts = 2.toUInt(), + numberOfLinkedHiddenAccounts = 3.toUInt(), + numberOfLinkedPersonas = 1.toUInt(), + numberOfLinkedHiddenPersonas = 0.toUInt() + ), + messages = persistentListOf(SecurityShieldStatusMessage.AppliedAndWorking) +) + +@UsesSampleValues +val otherShieldsForDisplaySample = persistentListOf( + SecurityShieldCard( + shieldForDisplay = ShieldForDisplay( + metadata = SecurityStructureMetadata( + id = SecurityStructureId.randomUUID(), + displayName = DisplayName("cool shield"), + createdOn = Timestamp.now(), + lastUpdatedOn = Timestamp.now(), + flags = emptyList() + ), + numberOfLinkedAccounts = 21.toUInt(), + numberOfLinkedHiddenAccounts = 0.toUInt(), + numberOfLinkedPersonas = 1.toUInt(), + numberOfLinkedHiddenPersonas = 0.toUInt() + ), + messages = persistentListOf(SecurityShieldStatusMessage.AppliedAndWorking) + ), + SecurityShieldCard( + ShieldForDisplay( + metadata = SecurityStructureMetadata( + id = SecurityStructureId.randomUUID(), + displayName = DisplayName.sample.other(), + createdOn = Timestamp.now(), + lastUpdatedOn = Timestamp.now(), + flags = emptyList() + ), + numberOfLinkedAccounts = 0.toUInt(), + numberOfLinkedHiddenAccounts = 0.toUInt(), + numberOfLinkedPersonas = 1.toUInt(), + numberOfLinkedHiddenPersonas = 0.toUInt() + ), + messages = persistentListOf(SecurityShieldStatusMessage.ActionRequired) + ), + SecurityShieldCard( + ShieldForDisplay( + metadata = SecurityStructureMetadata( + id = SecurityStructureId.randomUUID(), + displayName = DisplayName("666"), + createdOn = Timestamp.now(), + lastUpdatedOn = Timestamp.now(), + flags = emptyList() + ), + numberOfLinkedAccounts = 0.toUInt(), + numberOfLinkedHiddenAccounts = 0.toUInt(), + numberOfLinkedPersonas = 0.toUInt(), + numberOfLinkedHiddenPersonas = 0.toUInt() + ), + messages = persistentListOf() + ), + SecurityShieldCard( + ShieldForDisplay( + metadata = SecurityStructureMetadata( + id = SecurityStructureId.randomUUID(), + displayName = DisplayName.sample(), + createdOn = Timestamp.now(), + lastUpdatedOn = Timestamp.now(), + flags = emptyList() + ), + numberOfLinkedAccounts = 23.toUInt(), + numberOfLinkedHiddenAccounts = 32.toUInt(), + numberOfLinkedPersonas = 11.toUInt(), + numberOfLinkedHiddenPersonas = 10.toUInt() + ), + messages = persistentListOf(SecurityShieldStatusMessage.AppliedAndWorking) + ) +) + +@UsesSampleValues +class SecurityShieldCardPreviewProvider : PreviewParameterProvider { + + override val values: Sequence + get() = otherShieldsForDisplaySample.asSequence() +} From 6a09a78cb9d7de7b79b7f9fb42dd1dee9b07759a Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:24:53 +0200 Subject: [PATCH 09/19] added SelectableSingleChoiceSecurityShieldCard --- ...electableSingleChoiceSecurityShieldCard.kt | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SelectableSingleChoiceSecurityShieldCard.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SelectableSingleChoiceSecurityShieldCard.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SelectableSingleChoiceSecurityShieldCard.kt new file mode 100644 index 0000000000..df383f257b --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SelectableSingleChoiceSecurityShieldCard.kt @@ -0,0 +1,103 @@ +package com.babylon.wallet.android.presentation.ui.composables.card + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.domain.model.Selectable +import com.babylon.wallet.android.presentation.ui.RadixWalletPreviewTheme +import com.babylon.wallet.android.presentation.ui.composables.DSR +import com.babylon.wallet.android.presentation.ui.composables.shared.CardContainer +import com.babylon.wallet.android.presentation.ui.composables.shared.RadioButtonSelectorView +import com.babylon.wallet.android.presentation.ui.model.securityshields.SecurityShieldCard +import com.babylon.wallet.android.presentation.ui.modifier.enabledOpacity +import com.babylon.wallet.android.presentation.ui.modifier.noIndicationClickable +import com.radixdlt.sargon.annotation.UsesSampleValues + +@Composable +fun SelectableSingleChoiceSecurityShieldCard( + modifier: Modifier = Modifier, + item: Selectable, + onSelect: (SecurityShieldCard) -> Unit +) { + SimpleSecurityShieldCardView( + modifier = modifier.noIndicationClickable { onSelect(item.data) }, + title = item.data.shieldForDisplay.metadata.displayName.value, + iconRes = DSR.ic_security_shields, + endContent = { + RadioButtonSelectorView( + isSelected = item.selected, + onSelectedChange = { onSelect(item.data) } + ) + } + ) +} + +@Composable +private fun SimpleSecurityShieldCardView( + modifier: Modifier = Modifier, + title: String, + @DrawableRes iconRes: Int, + isEnabled: Boolean = true, + endContent: (@Composable () -> Unit)? = null +) { + CardContainer(modifier = modifier) { + Row( + modifier = Modifier + .enabledOpacity(isEnabled) + .padding(start = RadixTheme.dimensions.paddingDefault) + .padding(vertical = RadixTheme.dimensions.paddingSemiLarge), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + modifier = Modifier.size(36.dp), + painter = painterResource(id = iconRes), + contentDescription = null, + tint = Color.Unspecified + ) + + Spacer(modifier = Modifier.width(RadixTheme.dimensions.paddingMedium)) + + Text( + modifier = Modifier.weight(1f), + text = title, + style = RadixTheme.typography.body1Header, + color = RadixTheme.colors.gray1 + ) + + Box( + Modifier.enabledOpacity(isEnabled) + ) { + endContent?.invoke() + } + } + } +} + +@Composable +@Preview +@UsesSampleValues +private fun SelectableSingleChoiceSecurityShieldCardPreview( + @PreviewParameter(SecurityShieldCardPreviewProvider::class) item: SecurityShieldCard +) { + RadixWalletPreviewTheme { + SelectableSingleChoiceSecurityShieldCard( + item = Selectable(item), + onSelect = {} + ) + } +} From 8ce081d53a3f1a43c0d6f8c2d5b1c5491d04c494 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:25:31 +0200 Subject: [PATCH 10/19] updated SecurityShieldsViewModel --- .../SecurityShieldsViewModel.kt | 120 +++++++++++++++++- 1 file changed, 117 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsViewModel.kt index d972bea2bc..17f6089f43 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsViewModel.kt @@ -1,16 +1,130 @@ package com.babylon.wallet.android.presentation.settings.securitycenter.securityshields +import androidx.lifecycle.viewModelScope +import com.babylon.wallet.android.di.coroutines.DefaultDispatcher +import com.babylon.wallet.android.domain.model.Selectable import com.babylon.wallet.android.presentation.common.StateViewModel import com.babylon.wallet.android.presentation.common.UiState +import com.babylon.wallet.android.presentation.ui.model.securityshields.SecurityShieldCard +import com.babylon.wallet.android.utils.callSafely +import com.radixdlt.sargon.SecurityStructureId +import com.radixdlt.sargon.ShieldForDisplay +import com.radixdlt.sargon.extensions.isMain +import com.radixdlt.sargon.os.SargonOsManager import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import timber.log.Timber import javax.inject.Inject @HiltViewModel -class SecurityShieldsViewModel @Inject constructor() : StateViewModel() { +class SecurityShieldsViewModel @Inject constructor( + private val sargonOsManager: SargonOsManager, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher +) : StateViewModel() { override fun initialState(): State = State() + init { + viewModelScope.launch { + getSecurityShields() + } + } + + private suspend fun getSecurityShields() { + sargonOsManager.callSafely(defaultDispatcher) { + val securityShields = getShieldsForDisplay() + val mainSecurityShield = securityShields.find { it.metadata.isMain } + val otherSecurityShields = securityShields.toMutableList().apply { remove(mainSecurityShield) } + + _state.update { state -> + state.copy( + mainSecurityShield = mainSecurityShield?.toSecurityShieldCard(), + otherSecurityShields = otherSecurityShields.map { it.toSecurityShieldCard() }.toPersistentList(), + isLoading = false + ) + } + }.onFailure { error -> + Timber.e("Failed to get security shields for display: $error") + } + } + + private fun resetSecurityShieldsList() { + viewModelScope.launch { + _state.update { state -> + state.copy( + isLoading = true, + mainSecurityShield = null, + otherSecurityShields = persistentListOf() + ) + } + getSecurityShields() + } + } + + private fun ShieldForDisplay.toSecurityShieldCard(): SecurityShieldCard { + return SecurityShieldCard( + shieldForDisplay = this, + messages = persistentListOf() + ) + } + + fun onChangeMainSecurityShieldClick() { + _state.update { state -> state.copy(isMainSecurityShieldBottomSheetVisible = true) } + } + + fun onSecurityShieldSelect(securityShieldCard: SecurityShieldCard) { + _state.update { it.copy(selectedSecurityShieldId = securityShieldCard.id) } + } + + fun onConfirmChangeMainSecurityShield() { + viewModelScope.launch { + _state.update { state -> state.copy(isChangingMainSecurityShieldInProgress = true) } + _state.value.selectedSecurityShieldId?.let { id -> + sargonOsManager.callSafely(defaultDispatcher) { + setMainSecurityStructure(shieldId = id) + }.onFailure { error -> + Timber.e("Failed to set main security shield: $error") + } + } + _state.update { state -> state.copy(isChangingMainSecurityShieldInProgress = false) } + onDismissMainSecurityShieldBottomSheet() + resetSecurityShieldsList() + } + } + + fun onDismissMainSecurityShieldBottomSheet() { + _state.update { state -> + state.copy( + isMainSecurityShieldBottomSheetVisible = false, + selectedSecurityShieldId = null + ) + } + } + data class State( - val isLoading: Boolean = true - ) : UiState + val isLoading: Boolean = true, + val mainSecurityShield: SecurityShieldCard? = null, + val otherSecurityShields: PersistentList = persistentListOf(), + val isMainSecurityShieldBottomSheetVisible: Boolean = false, + val selectedSecurityShieldId: SecurityStructureId? = null, + val isChangingMainSecurityShieldInProgress: Boolean = false, + ) : UiState { + + val isContinueButtonEnabled: Boolean + get() = selectableOtherSecurityShieldIds.any { it.selected } + + val selectableOtherSecurityShieldIds: ImmutableList> = otherSecurityShields.map { + Selectable( + data = it, + selected = selectedSecurityShieldId == it.id + ) + }.toImmutableList() + } } From 55f3d1ec53f4d591485c445016ad857a582bba6d Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 14:25:42 +0200 Subject: [PATCH 11/19] updated SecurityShieldsScreen --- .../securityshields/SecurityShieldsNav.kt | 5 +- .../securityshields/SecurityShieldsScreen.kt | 395 ++++++++++++++++-- 2 files changed, 374 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsNav.kt index 85f3f6227c..fbecb41a7a 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsNav.kt @@ -9,6 +9,7 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptionsBuilder import androidx.navigation.compose.composable import androidx.navigation.navigation +import com.babylon.wallet.android.presentation.dialogs.info.infoDialog import com.babylon.wallet.android.presentation.settings.securitycenter.applyshield.applyShieldNavGraph import com.babylon.wallet.android.presentation.settings.securitycenter.securityshields.addfactor.addFactor import com.babylon.wallet.android.presentation.settings.securitycenter.securityshields.factorsready.factorsReady @@ -70,8 +71,10 @@ fun NavGraphBuilder.securityShieldsScreen( ) { SecurityShieldsScreen( viewModel = hiltViewModel(), + onNavigateToSecurityShieldDetails = { /* TODO security shield details screen */ }, + onCreateNewSecurityShieldClick = { navController.securityShieldOnboarding() }, + onInfoClick = { glossaryItem -> navController.infoDialog(glossaryItem) }, onBackClick = { navController.navigateUp() }, - onCreateShieldClick = { navController.securityShieldOnboarding() } ) } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsScreen.kt index a95baa311c..5bbf77b2cd 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsScreen.kt @@ -1,41 +1,112 @@ package com.babylon.wallet.android.presentation.settings.securitycenter.securityshields +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.babylon.wallet.android.R import com.babylon.wallet.android.designsystem.composable.RadixSecondaryButton +import com.babylon.wallet.android.designsystem.composable.RadixTextButton import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.domain.model.Selectable import com.babylon.wallet.android.presentation.common.FullscreenCircularProgressContent +import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem import com.babylon.wallet.android.presentation.ui.RadixWalletPreviewTheme +import com.babylon.wallet.android.presentation.ui.composables.BackIconType +import com.babylon.wallet.android.presentation.ui.composables.DefaultModalSheetLayout +import com.babylon.wallet.android.presentation.ui.composables.InfoButton +import com.babylon.wallet.android.presentation.ui.composables.RadixBottomBar import com.babylon.wallet.android.presentation.ui.composables.RadixCenteredTopAppBar +import com.babylon.wallet.android.presentation.ui.composables.card.SecurityShieldCardView +import com.babylon.wallet.android.presentation.ui.composables.card.SelectableSingleChoiceSecurityShieldCard +import com.babylon.wallet.android.presentation.ui.composables.card.mainShieldForDisplaySample +import com.babylon.wallet.android.presentation.ui.composables.card.otherShieldsForDisplaySample import com.babylon.wallet.android.presentation.ui.composables.statusBarsAndBanner +import com.babylon.wallet.android.presentation.ui.composables.utils.SyncSheetState +import com.babylon.wallet.android.presentation.ui.model.securityshields.SecurityShieldCard +import com.radixdlt.sargon.DisplayName +import com.radixdlt.sargon.SecurityStructureId +import com.radixdlt.sargon.SecurityStructureMetadata +import com.radixdlt.sargon.ShieldForDisplay +import com.radixdlt.sargon.Timestamp +import com.radixdlt.sargon.annotation.UsesSampleValues +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toPersistentList +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SecurityShieldsScreen( modifier: Modifier = Modifier, viewModel: SecurityShieldsViewModel, + onNavigateToSecurityShieldDetails: (securityShieldId: SecurityStructureId) -> Unit, + onCreateNewSecurityShieldClick: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, onBackClick: () -> Unit, - onCreateShieldClick: () -> Unit ) { val state by viewModel.state.collectAsStateWithLifecycle() SecurityShieldsContent( modifier = modifier, state = state, - onCreateShieldClick = onCreateShieldClick, - onBackClick = onBackClick + onChangeMainSecurityShieldClick = viewModel::onChangeMainSecurityShieldClick, + onSecurityShieldClick = onNavigateToSecurityShieldDetails, + onCreateNewSecurityShieldClick = onCreateNewSecurityShieldClick, + onBackClick = onBackClick, + onInfoClick = onInfoClick ) + + val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + SyncSheetState( + sheetState = bottomSheetState, + isSheetVisible = state.isMainSecurityShieldBottomSheetVisible, + onSheetClosed = viewModel::onDismissMainSecurityShieldBottomSheet + ) + + if (state.isMainSecurityShieldBottomSheetVisible) { + DefaultModalSheetLayout( + enableImePadding = false, + sheetState = bottomSheetState, + sheetContent = { + ChangeMainSecurityShieldContent( + otherSecurityShields = state.selectableOtherSecurityShieldIds, + isContinueButtonEnabled = state.isContinueButtonEnabled, + isChangingSecurityShieldInProgress = state.isChangingMainSecurityShieldInProgress, + onSecurityShieldSelect = viewModel::onSecurityShieldSelect, + onConfirmClick = viewModel::onConfirmChangeMainSecurityShield, + onDismissClick = viewModel::onDismissMainSecurityShieldBottomSheet + ) + }, + onDismissRequest = viewModel::onDismissMainSecurityShieldBottomSheet + ) + } } @Composable @@ -43,13 +114,16 @@ fun SecurityShieldsContent( modifier: Modifier = Modifier, state: SecurityShieldsViewModel.State, onBackClick: () -> Unit, - onCreateShieldClick: () -> Unit + onChangeMainSecurityShieldClick: () -> Unit, + onSecurityShieldClick: (SecurityStructureId) -> Unit, + onCreateNewSecurityShieldClick: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit ) { Scaffold( modifier = modifier.fillMaxSize(), topBar = { RadixCenteredTopAppBar( - title = "Security Shields", // TODO crowdin + title = stringResource(R.string.securityShields_title), onBackClick = onBackClick, windowInsets = WindowInsets.statusBarsAndBanner, ) @@ -60,37 +134,308 @@ fun SecurityShieldsContent( FullscreenCircularProgressContent() } else { Column( - modifier = Modifier - .fillMaxSize() - .verticalScroll(rememberScrollState()) - .padding(padding) - .padding(horizontal = RadixTheme.dimensions.paddingDefault), - horizontalAlignment = Alignment.CenterHorizontally + modifier = Modifier.padding(padding), + horizontalAlignment = Alignment.Start ) { - RadixSecondaryButton( + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingDefault)) + SecurityShieldsList( + mainSecurityShield = state.mainSecurityShield, + otherSecurityShields = state.otherSecurityShields, + onChangeMainSecurityShieldClick = onChangeMainSecurityShieldClick, + onSecurityShieldClick = onSecurityShieldClick, + onCreateNewSecurityShieldClick = onCreateNewSecurityShieldClick, + onInfoClick = onInfoClick + ) + } + } + } +} + +@Composable +private fun SecurityShieldsList( + modifier: Modifier = Modifier, + mainSecurityShield: SecurityShieldCard?, + otherSecurityShields: PersistentList, + onChangeMainSecurityShieldClick: () -> Unit, + onSecurityShieldClick: (SecurityStructureId) -> Unit, + onCreateNewSecurityShieldClick: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit +) { + LazyColumn( + modifier = modifier.fillMaxWidth(), + contentPadding = PaddingValues(horizontal = RadixTheme.dimensions.paddingDefault) + ) { + mainSecurityShield?.let { + item { + if (otherSecurityShields.isNotEmpty()) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(id = R.string.securityShields_default), + style = RadixTheme.typography.body1HighImportance, + color = RadixTheme.colors.gray2 + ) + Spacer(Modifier.weight(1f).fillMaxHeight()) + RadixTextButton( + text = stringResource(R.string.securityShields_change), + onClick = onChangeMainSecurityShieldClick + ) + } + } else { + Text( + modifier = Modifier.padding(vertical = RadixTheme.dimensions.paddingDefault), + text = stringResource(id = R.string.securityShields_default), + style = RadixTheme.typography.body1HighImportance, + color = RadixTheme.colors.gray2 + ) + } + + SecurityShieldCardView( modifier = Modifier - .fillMaxWidth() - .padding( - horizontal = RadixTheme.dimensions.paddingLarge, - vertical = RadixTheme.dimensions.paddingLarge - ), - text = "Create New Security shield", // TODO crowdin - onClick = onCreateShieldClick, - throttleClicks = true + .padding(bottom = RadixTheme.dimensions.paddingMedium) + .clickable { onSecurityShieldClick(it.id) }, + item = mainSecurityShield + ) + if (otherSecurityShields.isEmpty()) { + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingDefault)) + } + } + } + + if (otherSecurityShields.isNotEmpty()) { + item { + if (mainSecurityShield != null) { + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingXLarge)) + Text( + text = stringResource(id = R.string.securityShields_others), + style = RadixTheme.typography.body1HighImportance, + color = RadixTheme.colors.gray2 + ) + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingMedium)) + } else { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(id = R.string.securityShields_others), + style = RadixTheme.typography.body1HighImportance, + color = RadixTheme.colors.gray2 + ) + Spacer( + Modifier + .weight(1f) + .fillMaxHeight() + ) + RadixTextButton( + text = stringResource(R.string.securityShields_change), + onClick = onChangeMainSecurityShieldClick + ) + } + } + } + } + + items(otherSecurityShields) { + SecurityShieldCardView( + modifier = Modifier.clickable { onSecurityShieldClick(it.id) }, + item = it + ) + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingDefault)) + } + + item { + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingSemiLarge)) + + RadixSecondaryButton( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = RadixTheme.dimensions.paddingXXLarge), + text = stringResource(R.string.securityShields_createShieldButton), + onClick = onCreateNewSecurityShieldClick, + throttleClicks = true + ) + + InfoButton( + modifier = Modifier + .fillMaxWidth() + .wrapContentWidth(align = Alignment.CenterHorizontally) + .padding( + horizontal = RadixTheme.dimensions.paddingDefault, + vertical = RadixTheme.dimensions.paddingLarge + ), + text = stringResource(R.string.infoLink_title_securityshields), + onClick = { + onInfoClick(GlossaryItem.securityshields) + } + ) + } + } +} + +@Composable +private fun ChangeMainSecurityShieldContent( + modifier: Modifier = Modifier, + otherSecurityShields: ImmutableList>, + isContinueButtonEnabled: Boolean, + isChangingSecurityShieldInProgress: Boolean, + onSecurityShieldSelect: (SecurityShieldCard) -> Unit, + onConfirmClick: () -> Unit, + onDismissClick: () -> Unit +) { + Scaffold( + modifier = modifier.fillMaxSize(), + topBar = { + RadixCenteredTopAppBar( + title = stringResource(R.string.empty), + containerColor = RadixTheme.colors.defaultBackground, + windowInsets = WindowInsets(0.dp), + backIconType = BackIconType.Close, + onBackClick = onDismissClick, + ) + }, + bottomBar = { + RadixBottomBar( + enabled = isContinueButtonEnabled, + isLoading = isChangingSecurityShieldInProgress, + onClick = onConfirmClick, + text = stringResource(R.string.common_confirm), + insets = WindowInsets(0.dp) + ) + } + ) { padding -> + LazyColumn( + modifier = Modifier + .background(RadixTheme.colors.defaultBackground) + .fillMaxSize() + .padding(padding), + horizontalAlignment = Alignment.CenterHorizontally, + contentPadding = PaddingValues(horizontal = RadixTheme.dimensions.paddingDefault), + verticalArrangement = Arrangement.spacedBy(RadixTheme.dimensions.paddingDefault) + ) { + item { + Text( + modifier = Modifier.padding(horizontal = RadixTheme.dimensions.paddingDefault), + text = stringResource(R.string.securityShields_changeMain_title), + style = RadixTheme.typography.title, + color = RadixTheme.colors.gray1, + textAlign = TextAlign.Center + ) + } + + item { + Text( + modifier = Modifier.padding(horizontal = RadixTheme.dimensions.paddingSmall), + text = stringResource(id = R.string.securityShields_changeMain_subtitle), + style = RadixTheme.typography.body1Regular, + color = RadixTheme.colors.gray1, + textAlign = TextAlign.Center + ) + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingMedium)) + } + + items(otherSecurityShields) { + SelectableSingleChoiceSecurityShieldCard( + item = it, + onSelect = onSecurityShieldSelect ) } } } } +@UsesSampleValues @Composable @Preview -private fun SecurityShieldsPreview() { +private fun SecurityShieldsWithMainAndOthersPreview() { RadixWalletPreviewTheme { SecurityShieldsContent( - state = SecurityShieldsViewModel.State(), + state = SecurityShieldsViewModel.State( + isLoading = false, + mainSecurityShield = mainShieldForDisplaySample, + otherSecurityShields = otherShieldsForDisplaySample, + isChangingMainSecurityShieldInProgress = false + ), onBackClick = {}, - onCreateShieldClick = {} + onChangeMainSecurityShieldClick = {}, + onSecurityShieldClick = {}, + onCreateNewSecurityShieldClick = {}, + onInfoClick = {} + ) + } +} + +@UsesSampleValues +@Composable +@Preview +private fun SecurityShieldsWithMainPreview() { + RadixWalletPreviewTheme { + SecurityShieldsContent( + state = SecurityShieldsViewModel.State( + isLoading = false, + mainSecurityShield = SecurityShieldCard( + ShieldForDisplay( + metadata = SecurityStructureMetadata( + id = SecurityStructureId.randomUUID(), + displayName = DisplayName("XXX"), + createdOn = Timestamp.now(), + lastUpdatedOn = Timestamp.now(), + flags = emptyList() + ), + numberOfLinkedAccounts = 2.toUInt(), + numberOfLinkedHiddenAccounts = 3.toUInt(), + numberOfLinkedPersonas = 1.toUInt(), + numberOfLinkedHiddenPersonas = 0.toUInt() + ), + messages = persistentListOf() + ), + otherSecurityShields = persistentListOf(), + isChangingMainSecurityShieldInProgress = false + ), + onBackClick = {}, + onChangeMainSecurityShieldClick = {}, + onSecurityShieldClick = {}, + onCreateNewSecurityShieldClick = {}, + onInfoClick = {} + ) + } +} + +@UsesSampleValues +@Composable +@Preview +private fun SecurityShieldsWithOthersPreview() { + RadixWalletPreviewTheme { + SecurityShieldsContent( + state = SecurityShieldsViewModel.State( + isLoading = false, + mainSecurityShield = null, + otherSecurityShields = otherShieldsForDisplaySample.subList(0, 3).toPersistentList(), + isChangingMainSecurityShieldInProgress = false + ), + onBackClick = {}, + onChangeMainSecurityShieldClick = {}, + onSecurityShieldClick = {}, + onCreateNewSecurityShieldClick = {}, + onInfoClick = {} + ) + } +} + +@Composable +@Preview +@UsesSampleValues +private fun ChangeMainSecurityShieldBottomSheetPreview() { + RadixWalletPreviewTheme { + ChangeMainSecurityShieldContent( + otherSecurityShields = otherShieldsForDisplaySample.map { Selectable(it) }.toImmutableList(), + isChangingSecurityShieldInProgress = false, + isContinueButtonEnabled = false, + onSecurityShieldSelect = {}, + onConfirmClick = {}, + onDismissClick = {} ) } } From 0d6ed6ce9ddf4812c4920ebf662dea8fa74d15bb Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 15:36:01 +0200 Subject: [PATCH 12/19] keep the same size of the card when status message is not present --- .../card/SecurityShieldCardView.kt | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt index 482a7cce5b..5492cf51e9 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt @@ -35,7 +35,6 @@ import com.radixdlt.sargon.ShieldForDisplay import com.radixdlt.sargon.Timestamp import com.radixdlt.sargon.annotation.UsesSampleValues import com.radixdlt.sargon.samples.sample -import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf @Composable @@ -49,7 +48,9 @@ fun SecurityShieldCardView( .padding( horizontal = RadixTheme.dimensions.paddingDefault, vertical = RadixTheme.dimensions.paddingLarge - ), + ) + // keep the same height of the card if status message is not present + .padding(vertical = if (item.messages.isEmpty()) RadixTheme.dimensions.paddingMedium else 0.dp), verticalAlignment = Alignment.CenterVertically, ) { Icon( @@ -87,7 +88,15 @@ fun SecurityShieldCardView( ) Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingXSmall)) - MessagesView(messages = item.messages) + if (item.messages.isNotEmpty()) { + Column(verticalArrangement = Arrangement.spacedBy(RadixTheme.dimensions.paddingXSmall)) { + item.messages.forEach { + StatusMessageText( + message = it.getMessage() + ) + } + } + } } } } @@ -122,21 +131,6 @@ private fun linkedEntitiesView( return linkedText } -@Composable -private fun MessagesView(messages: PersistentList) { - if (messages.isEmpty()) { - Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingLarge)) - } else { - Column(verticalArrangement = Arrangement.spacedBy(RadixTheme.dimensions.paddingXSmall)) { - messages.forEach { - StatusMessageText( - message = it.getMessage() - ) - } - } - } -} - @UsesSampleValues @Composable @Preview From da41256e9d732b1c0b44cf89ff6d483a736373dc Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 19:27:53 +0200 Subject: [PATCH 13/19] updated text for linked entities --- .../card/SecurityShieldCardView.kt | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt index 5492cf51e9..50b33dcf91 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt @@ -80,8 +80,10 @@ fun SecurityShieldCardView( Text( text = linkedEntitiesView( - accounts = item.shieldForDisplay.numberOfLinkedAccounts.toInt(), - personas = item.shieldForDisplay.numberOfLinkedPersonas.toInt() + accountsCount = item.shieldForDisplay.numberOfLinkedAccounts.toInt(), + personasCount = item.shieldForDisplay.numberOfLinkedPersonas.toInt(), + hasAnyHiddenEntities = item.shieldForDisplay.numberOfLinkedHiddenAccounts.toInt() != 0 || + item.shieldForDisplay.numberOfLinkedHiddenPersonas.toInt() != 0 ), style = RadixTheme.typography.body2Regular, color = RadixTheme.colors.gray2 @@ -104,31 +106,30 @@ fun SecurityShieldCardView( @Composable private fun linkedEntitiesView( - accounts: Int, - personas: Int + accountsCount: Int, + personasCount: Int, + hasAnyHiddenEntities: Boolean ): String { - val accountsText = when (accounts) { + val accountsText = when (accountsCount) { 0 -> stringResource(id = R.string.empty) 1 -> stringResource(id = R.string.securityShields_assigned_accountSingular) - else -> stringResource(id = R.string.securityShields_assigned_accountPlural, accounts) + else -> stringResource(id = R.string.securityShields_assigned_accountPlural, accountsCount) } - val personasText = when (personas) { + val personasText = when (personasCount) { 0 -> stringResource(id = R.string.empty) 1 -> stringResource(id = R.string.securityShields_assigned_personaSingular) - else -> stringResource(id = R.string.securityShields_assigned_personaPlural, personas) + else -> stringResource(id = R.string.securityShields_assigned_personaPlural, personasCount) } - val linkedText = if (accounts == 0 && personas == 0) { - stringResource(R.string.common_none) - } else { - when { - accounts != 0 && personas != 0 -> { - accountsText + " " + stringResource(id = R.string.dot_separator) + " " + personasText - } - accounts != 0 -> accountsText - else -> personasText - } + + val linkedText = when { + accountsCount == 0 && personasCount == 0 && hasAnyHiddenEntities -> "Hidden Accounts or Personas" // TODO + accountsCount == 0 && personasCount == 0 -> stringResource(R.string.common_none) + accountsCount != 0 && personasCount != 0 -> "$accountsText ${stringResource(id = R.string.dot_separator)} $personasText" + accountsCount != 0 -> accountsText + else -> personasText } - return linkedText + + return if (hasAnyHiddenEntities && (accountsCount != 0 || personasCount != 0)) "$linkedText (and some hidden)" else linkedText } @UsesSampleValues @@ -190,7 +191,7 @@ val otherShieldsForDisplaySample = persistentListOf( flags = emptyList() ), numberOfLinkedAccounts = 0.toUInt(), - numberOfLinkedHiddenAccounts = 0.toUInt(), + numberOfLinkedHiddenAccounts = 1.toUInt(), numberOfLinkedPersonas = 1.toUInt(), numberOfLinkedHiddenPersonas = 0.toUInt() ), @@ -227,6 +228,22 @@ val otherShieldsForDisplaySample = persistentListOf( numberOfLinkedHiddenPersonas = 10.toUInt() ), messages = persistentListOf(SecurityShieldStatusMessage.AppliedAndWorking) + ), + SecurityShieldCard( + ShieldForDisplay( + metadata = SecurityStructureMetadata( + id = SecurityStructureId.randomUUID(), + displayName = DisplayName("ALFZ PSF"), + createdOn = Timestamp.now(), + lastUpdatedOn = Timestamp.now(), + flags = emptyList() + ), + numberOfLinkedAccounts = 0.toUInt(), + numberOfLinkedHiddenAccounts = 0.toUInt(), + numberOfLinkedPersonas = 0.toUInt(), + numberOfLinkedHiddenPersonas = 1.toUInt() + ), + messages = persistentListOf() ) ) From 5891d64ee4a2b20562ae5d1fe4dd86604e7c71d5 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 20:05:42 +0200 Subject: [PATCH 14/19] added icons --- .../ic_shield_action_required.png | Bin 0 -> 4765 bytes .../res/drawable-xxhdpi/ic_shield_applied.png | Bin 0 -> 5394 bytes .../ic_shield_action_required.png | Bin 0 -> 7218 bytes .../drawable-xxxhdpi/ic_shield_applied.png | Bin 0 -> 8360 bytes .../res/drawable/ic_shield_not_applied.xml | 73 ++++++++++++++++++ 5 files changed, 73 insertions(+) create mode 100644 designsystem/src/main/res/drawable-xxhdpi/ic_shield_action_required.png create mode 100644 designsystem/src/main/res/drawable-xxhdpi/ic_shield_applied.png create mode 100644 designsystem/src/main/res/drawable-xxxhdpi/ic_shield_action_required.png create mode 100644 designsystem/src/main/res/drawable-xxxhdpi/ic_shield_applied.png create mode 100644 designsystem/src/main/res/drawable/ic_shield_not_applied.xml diff --git a/designsystem/src/main/res/drawable-xxhdpi/ic_shield_action_required.png b/designsystem/src/main/res/drawable-xxhdpi/ic_shield_action_required.png new file mode 100644 index 0000000000000000000000000000000000000000..db1353170f4f727ae86cf11d068b2d72965acfd4 GIT binary patch literal 4765 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 literal 0 HcmV?d00001 diff --git a/designsystem/src/main/res/drawable-xxhdpi/ic_shield_applied.png b/designsystem/src/main/res/drawable-xxhdpi/ic_shield_applied.png new file mode 100644 index 0000000000000000000000000000000000000000..dc8af8d0cc590da4a728f562d82d64a6c20be96d GIT binary patch literal 5394 zcmV+t747PYP)005u}0{{R3yb+fl00004XF*Lt006O% z3;baP00001b5ch_0Itp)=>Px&08mU+MMrQ<&d}D*(ALh-*3Zw@8j$nP&)3h-*Ur$^ z(9PP;(ALh-)*V{$6K%sGUfIvj*Ur$_1YNMs(AK;HhtAN}yeY%a&)NzguFuca;3lpm z6_*7_wX!YM4m-CXPwg0Y`g=9;7*g;UN$}6m))!^>7E2 z`i>>v1#hmyISvl_Tz_9_)!G?iEb+x*F@t73$Cw>K@q27ctjT_ZC_2FFo`ZVC@{Y)E8U#9IV&a z5$PSt&KY^;9mUT@h4~)T%YRz*I6Lzkveh0!^+tO6CqVQWe)$qp>KSYJ7iQ}ibLdB` z;%+2Nw=t;rdNTcRNbNAv8>EICQMw;odP4O9i zQ}P14kf~Dg>NS_0JTW40_0{EA5Ue%NWPOhqd(Y zGrMm(@mRm(ZIt(tt@_ck`D||Xzp(lc#jJaw_uo9jtTMQ#5u1Hy^%$_oi(~Y(tol28 z@6|BWm0|QsBEv>0*Wq=ebpQYWN_0|AQviUFpI|>gAm0%0zd#@mP;mXv{;wf0{xJUj zjQm4lef_`b-|v@@zdfANyklzL%#h>Xn&02LwR_*`>Du4#Rqvmlkl)96ug|YR%9#xS z01;YAL_t(|+U%QcOjKtU$C0<;Wk3qrnE38$QngJ#xVB$*+if?yo1lZJ189SYFQ8GB zf~XJ_(fWcqDoO*WFp8pRN2NGG6qwL3VO3HjG=oDUl?C0>`a@ z6fkn!N*D+k4v&nSG=6I^&_B@2FlF2s*T*|h;|pQqAlVaxq3FETzG8qc1o*sTL_+{^ zMX(#oOn9e&!4$$*%Q6`6wCPMD`e_Ug1L@oE7SIq7_Ft7)CW;mO59X; z=!}KmU#B4fZh|mrXWD<*e{|$Af%Y$ho7{enAs}9-0s^7Q6cu%Rp3!Yu^pFsLSf39y zbNls42$`_vx|rcj$anns39U>cVz@qy#aDA-GA>-b`s7I-QQ{+jCr<1=I%ko3ru}`# zu!;Hm_zvGz=B~ydd@><=m;>BUM(?-h^U{GVZwLx zXkk&&;u-Ger$>7P9k@R3@Mh=dCu0yiPDEvf0kE*JX#4h!ix-8sZ4@35PI14mKyFj> z^94dyLxOmlvj_z&LconFDgQEhX`f!gJTq>9)^Ibv6|ji#B_^(2{PAS9 zlm&Zs{F|b^P#I?@VWj3$LV_q%qM)G!c%08L1zfvh)>o6&lkCa))H^c3pq|^@+*|^f z1c0fMhRKqMCr_#ixE=T?;Le?E7JTfI9OI>&VZnVqKNsdief3A;(82g5fO0Z%IM|Wwtb~1V(82{X0re&iI|$CDx!Li zA$*CVfB?Abn-#8^9%Y2gn`1JYDPcx7D`KipiL9L&0aY@*lK?I!fJ>K73)LsPQBfw7 zNl7S|A}^v=j}ZW60aq+tw#-j2KtyCk%wf!um!L`4Kbt`Y^r z{HCU!o~9;&&~*&+J%(Cj*9ruT@zeOo;dTZ7O44W+2qi@16A7Do4vRq;H7%kL5Hl5$0G%Kz&%;YGy`I` z)oQWWnU}5z zS+|AhgA+%8!~?(_g@~x46Zo8v=v<4HdId%7LBJ~_AK+EyVGO7XxJ9Q?clvaWB;qDO zq=a^x&5B;J5xm0|OB1&3!;OuE@CTN#c))cGqkyrx0iIS7(Pp#R!73=E)lLkJ5;i%V zSbvW@NIZpTA%H@LWdUQ>t&7zQaP#KVyojU_382|*r>^gDCL713m}HQMax6&rdb8+wi< z345aAth6zur5FK~drUlLc(j1N0o)PGct(xT4Bey=GM!-=>UGpP9L+DR&~lP`WD{?P z3|Hp0jTupmjwNE$4cVa-CxR z0bahWiU^}vkgvV2PC#rXfLBDo6be{9OW9-e1w5-xXtxrq_8}+EK1(wtyt4NMSfm4b zG&%(MTGndxn9Kt|=>-UcmkA+{NRWmy=$dFU+X?Tl#KQ=*uWy&!0bk0P#p&z>CZ_<30MPCVuJZ zNT?JM1+2qC{GuJDbo2pX-xBqxRqipdaR7Mhf=-hp9SI4dLQCZy5iB`2F{1@Rd6>!@PjEF8rtyU;-uNMLdWW0kfcU?O9nbFyXi+y4<)uKtNTC zoYxHy36&yt62Q|rSc=X)6cG2sqsr?93aGFM_LvLj?~WGG*PFe{2}wvukVTXbv7>-j z`VrLLhYiMto2<)~r2wedV<5xle`MQCmq0hcNKg?GklLXX-^i;1tT?Pm zS`rf*gx}ub&q}dzRKUy-b~udujSwIHxliZ@La3}nEWR=z>=%Kc60@4M09|?vSmbUD zx8jX_k|=L-cJJPxB4QcZ_l!hX*N6MV5)N=J52)xdETF+7K;=!&Zjms7BgC@n$By%+ zzqj{AQ;x7c)WLXrUMB?qu$8e}g@{=9#;iil}w-1hQ= zo#iy%H09t>Y41Rbv?AbI0{B2>)h9jX?u`Z9)3=e=;1n0Y{rlC@jB~BMxm=7stjZ;= zMIvB>1SnZ#89gfr0$y97`H{mu3gb>q|2TGRKPRH#l{T^fI{GPJGnsiq^fXKXcM!m6 z^&SI&pRsixKKf^2pC3~a3L=)#Io$4WIE0?sjmzFBFm*(;}^j5!B{<8OJPhwfMj51o+9Tef!izEG;c9>#vhh9D|VQ zr(}w_0jw zfKRYU)qlR!>tWsfZz&-sVnPA%5j%Ibm6eru;t~ceN4RjqsIIQAt*yOt=hCHLlui2l z4FG)dkzP+bKiIkz5t&K^#I}Nhf;R9BtWspkPJ`zl(}y4@O8Zj{K0eT{X<)ML?A36fV2`R zAueI%PoK6xu#Oy~nf2_GpT9eF zNGW1PML~B01#C-8YeNa~bk9FIgeKi30ZJA@3s+ry`6V}8J$m&yT(J?>zY++UO01}; z=mxVurc0p`DIgHKJQksVE*v|H$jXU}$$ z5`+qDc!UCWb)kSa@41ZOs<@Z)`Da@m)u6xP)t>3~udbfsMI?ZtSqchhC8l+j$sR@l z(Ze?pFeWB`i`-+dOGkX9`S5K-`%Dn)`_M0bzIs&@QK-a+C6Hr6SV0imaDgZ*6S_3C z7yw+3Jq7@kiy&Ggg3p+z|1rkEpRuOazdCYNA!12MNd@UR-GmR<2gtPC1hE3CfH&_+ zSC+Sg9upripZmD6zIQae{{E383K1V7A?@1Y0s)E68%P|0MGzE3KoIaAvj{R4iO_A% z(fFeNzpDr$;}rlbdB{#@bV>`cFaeB?-iClnm%3&+KH^iIUyYhte}B~~UPK~cNyS5v zkYu_vQ2?y1#Z4MAe2+ORF#^ul88EaSBwVEskrGxs?B2h-yPKMMJ-tr&e>-Or+Qb&c z@uUsO%;+RdYpvB(@GVjWTUrr6z>mdK@CEc~AEol9PyATa2yR@JY`PF}B`!)g+J!q^ zs7N>py~JW&b5f8=ry<-V@1&CJZG z0uEJ)@&xVt5Mp6kS-7@P%#44b4 zK4x%9mW|)*@IBJ(SU9-|gz*F_VmXsFmv;>7cHryI&dy#>{j3WB3loV1yAyRHYSjsU z4w!EBN0$KbcpU*D_YY_05JGJyT0XtP4tx^hqZ5!omV2{M7{<-n?CU z`l*C-g~GZfVnx8U;=l<>+)7x=uGM-cm|goSK2yDq6Bsy=4mM>?HW0I!&~UyHyU zbQ-V~zlV>~H7;aVSLYwRN)SZC_xP_L9qF`6*cZgYlj9R1=m?SnJR%|m%&yMQPd$7x zCM9m&y!+qubVo;r0(h+py%KP!dz_7%sNawFs}jyny&Spm@Wt%xv4>Fku4y_z4c2p3k&qB}cLhBSG`|mDBJt=kknopdM^QR^*OWHDQv}O2 zZvTD@?Yu&jFRnFZh(Br4w-B9kam<=JKgD1DulU?rW3Jl&M!&sW9AZZ1D+$$Xd3x9A zs&fhWsymX0yp0-v%D4Dz{?H}ktOuR&;8_|zu~QkW!eO~dix6{V64*}iM64Z2ox9Z3 zXh1qJ4SVOHGhqa;r|}l>a%hNXa%Gy|4v%u>J~FVQDQu10kgbg#Y`X1DSk)CUZmzTt w+ZCS0+Csa0U^Yo~4(#fY<9oJed)5H^A7ys4mw2PLXaE2J07*qoM6N<$g1o;$+5i9m literal 0 HcmV?d00001 diff --git a/designsystem/src/main/res/drawable-xxxhdpi/ic_shield_action_required.png b/designsystem/src/main/res/drawable-xxxhdpi/ic_shield_action_required.png new file mode 100644 index 0000000000000000000000000000000000000000..439b70fa870951d64981726458c885257eb31542 GIT binary patch literal 7218 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 AqW}N^ literal 0 HcmV?d00001 diff --git a/designsystem/src/main/res/drawable-xxxhdpi/ic_shield_applied.png b/designsystem/src/main/res/drawable-xxxhdpi/ic_shield_applied.png new file mode 100644 index 0000000000000000000000000000000000000000..9df1818dad847fd4b19440d67f8f086f50d8d0cf GIT binary patch literal 8360 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 literal 0 HcmV?d00001 diff --git a/designsystem/src/main/res/drawable/ic_shield_not_applied.xml b/designsystem/src/main/res/drawable/ic_shield_not_applied.xml new file mode 100644 index 0000000000..f8edd5807e --- /dev/null +++ b/designsystem/src/main/res/drawable/ic_shield_not_applied.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 63678daf6fd68da8295c5a25d1b02b368597c70c Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Mon, 17 Feb 2025 20:06:09 +0200 Subject: [PATCH 15/19] fixed size --- .../ui/composables/card/SecurityShieldCardView.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt index 50b33dcf91..e1453cdd4b 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt @@ -47,7 +47,7 @@ fun SecurityShieldCardView( modifier = modifier .padding( horizontal = RadixTheme.dimensions.paddingDefault, - vertical = RadixTheme.dimensions.paddingLarge + vertical = RadixTheme.dimensions.paddingSemiLarge ) // keep the same height of the card if status message is not present .padding(vertical = if (item.messages.isEmpty()) RadixTheme.dimensions.paddingMedium else 0.dp), @@ -55,7 +55,7 @@ fun SecurityShieldCardView( ) { Icon( modifier = Modifier.size(80.dp), - painter = painterResource(id = DSR.ic_security_shields), + painter = painterResource(id = DSR.ic_shield_not_applied), contentDescription = null, tint = Color.Unspecified ) From ed96778933d4441e62379851ac5472da28444493 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Tue, 18 Feb 2025 10:05:16 +0200 Subject: [PATCH 16/19] replaced hardcoded strings --- .../ui/composables/card/SecurityShieldCardView.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt index e1453cdd4b..64655a5e56 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt @@ -122,14 +122,20 @@ private fun linkedEntitiesView( } val linkedText = when { - accountsCount == 0 && personasCount == 0 && hasAnyHiddenEntities -> "Hidden Accounts or Personas" // TODO + accountsCount == 0 && personasCount == 0 && hasAnyHiddenEntities -> stringResource( + R.string.securityShields_assigned_onlyHiddenEntities + ) accountsCount == 0 && personasCount == 0 -> stringResource(R.string.common_none) accountsCount != 0 && personasCount != 0 -> "$accountsText ${stringResource(id = R.string.dot_separator)} $personasText" accountsCount != 0 -> accountsText else -> personasText } - return if (hasAnyHiddenEntities && (accountsCount != 0 || personasCount != 0)) "$linkedText (and some hidden)" else linkedText + return if (hasAnyHiddenEntities && (accountsCount != 0 || personasCount != 0)) { + "$linkedText ${stringResource(R.string.securityShields_assigned_someHiddenEntities)}" + } else { + linkedText + } } @UsesSampleValues From c895cc340ba3fa3c55bf4c87d237060190d07280 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Tue, 18 Feb 2025 10:33:50 +0200 Subject: [PATCH 17/19] added space at the bottom because list can be long --- .../securitycenter/securityshields/SecurityShieldsScreen.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsScreen.kt index 5bbf77b2cd..9dc58b8a09 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsScreen.kt @@ -342,6 +342,10 @@ private fun ChangeMainSecurityShieldContent( onSelect = onSecurityShieldSelect ) } + + item { + Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingDefault)) + } } } } From a326fed065e01b4f3c8ae02fc903a8bafc9ed685 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Tue, 18 Feb 2025 10:34:05 +0200 Subject: [PATCH 18/19] fixed navigation when added new shield --- .../securityshields/shieldcreated/ShieldCreatedNav.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/shieldcreated/ShieldCreatedNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/shieldcreated/ShieldCreatedNav.kt index 3d4c917cdd..cd35ef7957 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/shieldcreated/ShieldCreatedNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/shieldcreated/ShieldCreatedNav.kt @@ -12,6 +12,7 @@ import androidx.navigation.compose.composable import androidx.navigation.navArgument import com.babylon.wallet.android.presentation.settings.securitycenter.applyshield.applyShieldNavGraph import com.babylon.wallet.android.presentation.settings.securitycenter.securityshields.ROUTE_SECURITY_SHIELDS_GRAPH +import com.babylon.wallet.android.presentation.settings.securitycenter.securityshields.securityShieldsScreen import com.radixdlt.sargon.SecurityStructureId private const val ROUTE_SHIELD_CREATED = "shield_created" @@ -47,7 +48,11 @@ fun NavGraphBuilder.shieldCreated( ) { ShieldCreatedScreen( viewModel = hiltViewModel(), - onDismiss = { navController.popBackStack(ROUTE_SECURITY_SHIELDS_GRAPH, false) }, + onDismiss = { + navController.securityShieldsScreen { + popUpTo(ROUTE_SECURITY_SHIELDS_GRAPH) { inclusive = false } + } + }, onApply = { id -> navController.applyShieldNavGraph(id) { popUpTo(ROUTE_SECURITY_SHIELDS_GRAPH) { inclusive = false } From e90a2e7064495228d06149bda2d26f691b26d69f Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Tue, 18 Feb 2025 12:40:48 +0200 Subject: [PATCH 19/19] improvements --- .../securityshields/SecurityShieldsViewModel.kt | 2 +- .../ui/composables/card/SecurityShieldCardView.kt | 7 +++---- .../ui/model/securityshields/SecurityShieldCard.kt | 7 +++++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsViewModel.kt index 17f6089f43..fc17896d70 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityshields/SecurityShieldsViewModel.kt @@ -93,7 +93,6 @@ class SecurityShieldsViewModel @Inject constructor( Timber.e("Failed to set main security shield: $error") } } - _state.update { state -> state.copy(isChangingMainSecurityShieldInProgress = false) } onDismissMainSecurityShieldBottomSheet() resetSecurityShieldsList() } @@ -102,6 +101,7 @@ class SecurityShieldsViewModel @Inject constructor( fun onDismissMainSecurityShieldBottomSheet() { _state.update { state -> state.copy( + isChangingMainSecurityShieldInProgress = false, isMainSecurityShieldBottomSheetVisible = false, selectedSecurityShieldId = null ) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt index 64655a5e56..250d451063 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/card/SecurityShieldCardView.kt @@ -80,10 +80,9 @@ fun SecurityShieldCardView( Text( text = linkedEntitiesView( - accountsCount = item.shieldForDisplay.numberOfLinkedAccounts.toInt(), - personasCount = item.shieldForDisplay.numberOfLinkedPersonas.toInt(), - hasAnyHiddenEntities = item.shieldForDisplay.numberOfLinkedHiddenAccounts.toInt() != 0 || - item.shieldForDisplay.numberOfLinkedHiddenPersonas.toInt() != 0 + accountsCount = item.numberOfLinkedAccounts, + personasCount = item.numberOfLinkedPersonas, + hasAnyHiddenEntities = item.hasAnyHiddenLinkedEntities ), style = RadixTheme.typography.body2Regular, color = RadixTheme.colors.gray2 diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldCard.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldCard.kt index 74cc8b1cc9..d93b3e5b4f 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldCard.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/model/securityshields/SecurityShieldCard.kt @@ -9,4 +9,11 @@ data class SecurityShieldCard( val messages: PersistentList ) { val id: SecurityStructureId = shieldForDisplay.metadata.id + + val numberOfLinkedAccounts: Int = shieldForDisplay.numberOfLinkedAccounts.toInt() + + val numberOfLinkedPersonas: Int = shieldForDisplay.numberOfLinkedPersonas.toInt() + + val hasAnyHiddenLinkedEntities: Boolean = shieldForDisplay.numberOfLinkedHiddenAccounts.toInt() != 0 || + shieldForDisplay.numberOfLinkedHiddenPersonas.toInt() != 0 }