From 79f9a58355e90c159b2eeeb3eab32ac7426853df Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 11:28:16 +0200 Subject: [PATCH 01/16] renamed passphrase setting item to mnemonic --- .../wallet/android/presentation/settings/SettingsItem.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/SettingsItem.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/SettingsItem.kt index 797e0071e8..7aac0ae1ef 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/SettingsItem.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/SettingsItem.kt @@ -89,7 +89,7 @@ sealed interface SettingsItem { data object LedgerNano : SecurityFactorsSettingsItem data object ArculusCard : SecurityFactorsSettingsItem data object Password : SecurityFactorsSettingsItem - data object Passphrase : SecurityFactorsSettingsItem + data object Mnemonic : SecurityFactorsSettingsItem @StringRes fun titleRes(): Int { @@ -97,7 +97,7 @@ sealed interface SettingsItem { is BiometricsPin -> R.string.factorSources_card_deviceTitle LedgerNano -> R.string.factorSources_card_ledgerTitle ArculusCard -> R.string.factorSources_card_arculusCardTitle - Passphrase -> R.string.factorSources_card_passphraseTitle + Mnemonic -> R.string.factorSources_card_passphraseTitle Password -> R.string.factorSources_card_passwordTitle } } @@ -108,7 +108,7 @@ sealed interface SettingsItem { is BiometricsPin -> R.string.factorSources_card_deviceDescription LedgerNano -> R.string.factorSources_card_ledgerDescription ArculusCard -> R.string.factorSources_card_arculusCardDescription - Passphrase -> R.string.factorSources_card_passphraseDescription + Mnemonic -> R.string.factorSources_card_passphraseDescription Password -> R.string.factorSources_card_passwordDescription } } @@ -120,7 +120,7 @@ sealed interface SettingsItem { LedgerNano -> DSR.ic_ledger_nano ArculusCard -> DSR.ic_arculus_card Password -> DSR.ic_password - Passphrase -> DSR.ic_passphrase + Mnemonic -> DSR.ic_passphrase } } } From 5875dada72a476a0fbf0641720f6ac31cb2de074 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 11:36:54 +0200 Subject: [PATCH 02/16] renamed SecurityFactorsScreen to SecurityFactorTypesScreen --- .../securitycenter/SecurityCenterNav.kt | 6 +-- ...actorsNav.kt => SecurityFactorTypesNav.kt} | 16 ++++---- ...Screen.kt => SecurityFactorTypesScreen.kt} | 38 +++++++++---------- ...del.kt => SecurityFactorTypesViewModel.kt} | 12 +++--- .../ChooseFactorSourceBottomSheet.kt | 2 +- .../ChooseFactorSourceViewModel.kt | 2 +- .../SecurityFactorTypesListView.kt | 8 ++-- 7 files changed, 42 insertions(+), 42 deletions(-) rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/{SecurityFactorsNav.kt => SecurityFactorTypesNav.kt} (70%) rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/{SecurityFactorsScreen.kt => SecurityFactorTypesScreen.kt} (81%) rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/{SecurityFactorsViewModel.kt => SecurityFactorTypesViewModel.kt} (81%) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt index 0a83e887cf..000e90c425 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt @@ -64,7 +64,7 @@ fun NavGraphBuilder.securityCenterNavGraph( navController.securityShieldOnboardingScreen() }, onSecurityFactorsClick = { - navController.securityFactors() + navController.securityFactorTypes() }, onBackupConfigurationClick = { navController.backupScreen() @@ -84,11 +84,11 @@ fun NavGraphBuilder.securityCenterNavGraph( ) { navController.popBackStack() } - securityFactors( + securityFactorTypes( onBackClick = { navController.popBackStack() }, - onSecurityFactorSettingItemClick = { item -> + onSecurityFactorTypeClick = { item -> when (item) { is SettingsItem.SecurityFactorsSettingsItem.LedgerNano -> { navController.ledgerHardwareWalletsScreen() diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesNav.kt similarity index 70% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsNav.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesNav.kt index 99e8275c8d..0615474bef 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesNav.kt @@ -9,20 +9,20 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import com.babylon.wallet.android.presentation.settings.SettingsItem -private const val ROUTE_SECURITY_FACTORS_SCREEN = "settings_security_factors_screen" +private const val ROUTE_SECURITY_FACTOR_TYPES_SCREEN = "settings_security_factor_types_screen" -fun NavController.securityFactors() { - navigate(ROUTE_SECURITY_FACTORS_SCREEN) { +fun NavController.securityFactorTypes() { + navigate(ROUTE_SECURITY_FACTOR_TYPES_SCREEN) { launchSingleTop = true } } -fun NavGraphBuilder.securityFactors( +fun NavGraphBuilder.securityFactorTypes( onBackClick: () -> Unit, - onSecurityFactorSettingItemClick: (SettingsItem.SecurityFactorsSettingsItem) -> Unit + onSecurityFactorTypeClick: (SettingsItem.SecurityFactorsSettingsItem) -> Unit ) { composable( - route = ROUTE_SECURITY_FACTORS_SCREEN, + route = ROUTE_SECURITY_FACTOR_TYPES_SCREEN, enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Left) }, @@ -36,10 +36,10 @@ fun NavGraphBuilder.securityFactors( slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Right) } ) { - SecurityFactorsScreen( + SecurityFactorTypesScreen( viewModel = hiltViewModel(), onBackClick = onBackClick, - onSecurityFactorSettingItemClick = onSecurityFactorSettingItemClick + onSecurityFactorTypeClick = onSecurityFactorTypeClick ) } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesScreen.kt similarity index 81% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsScreen.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesScreen.kt index b916f9aa59..17082104e6 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesScreen.kt @@ -31,26 +31,26 @@ import kotlinx.collections.immutable.toPersistentList import kotlinx.collections.immutable.toPersistentSet @Composable -fun SecurityFactorsScreen( +fun SecurityFactorTypesScreen( modifier: Modifier = Modifier, - viewModel: SecurityFactorsViewModel, - onSecurityFactorSettingItemClick: (SecurityFactorsSettingsItem) -> Unit, + viewModel: SecurityFactorTypesViewModel, + onSecurityFactorTypeClick: (SecurityFactorsSettingsItem) -> Unit, onBackClick: () -> Unit ) { val state by viewModel.state.collectAsStateWithLifecycle() - SecurityFactorsContent( + SecurityFactorTypesContent( modifier = modifier.fillMaxSize(), - securityFactorSettingItems = state.securityFactorSettingItems, - onSecurityFactorSettingItemClick = onSecurityFactorSettingItemClick, + securityFactorTypeSettingItems = state.securityFactorTypeSettingItems, + onSecurityFactorTypeClick = onSecurityFactorTypeClick, onBackClick = onBackClick, ) } @Composable -private fun SecurityFactorsContent( +private fun SecurityFactorTypesContent( modifier: Modifier = Modifier, - securityFactorSettingItems: ImmutableMap>, - onSecurityFactorSettingItemClick: (SecurityFactorsSettingsItem) -> Unit, + securityFactorTypeSettingItems: ImmutableMap>, + onSecurityFactorTypeClick: (SecurityFactorsSettingsItem) -> Unit, onBackClick: () -> Unit, ) { Scaffold( @@ -71,8 +71,8 @@ private fun SecurityFactorsContent( .padding(padding) .fillMaxSize(), isDescriptionVisible = true, - securityFactorSettingItems = securityFactorSettingItems, - onSecurityFactorSettingItemClick = onSecurityFactorSettingItemClick + securityFactorSettingItems = securityFactorTypeSettingItems, + onSecurityFactorTypeItemClick = onSecurityFactorTypeClick ) } } @@ -98,12 +98,12 @@ fun getSecurityWarnings(securityFactorsSettingsItem: SecurityFactorsSettingsItem @Preview(showBackground = true) @Composable -private fun SecurityFactorsPreview() { +private fun SecurityFactorTypesPreview() { RadixWalletTheme { - SecurityFactorsContent( + SecurityFactorTypesContent( modifier = Modifier, - securityFactorSettingItems = currentSecurityFactorTypeItems, - onSecurityFactorSettingItemClick = {}, + securityFactorTypeSettingItems = currentSecurityFactorTypeItems, + onSecurityFactorTypeClick = {}, onBackClick = {} ) } @@ -111,11 +111,11 @@ private fun SecurityFactorsPreview() { @Preview(showBackground = true) @Composable -private fun SecurityFactorsWithSecurityProblemsPreview() { +private fun SecurityFactorTypesWithSecurityProblemsPreview() { RadixWalletTheme { - SecurityFactorsContent( + SecurityFactorTypesContent( modifier = Modifier, - securityFactorSettingItems = persistentMapOf( + securityFactorTypeSettingItems = persistentMapOf( SecurityFactorCategory.Own to persistentSetOf( SecurityFactorsSettingsItem.BiometricsPin( securityProblems = setOf( @@ -133,7 +133,7 @@ private fun SecurityFactorsWithSecurityProblemsPreview() { SecurityFactorsSettingsItem.LedgerNano ) ), - onSecurityFactorSettingItemClick = {}, + onSecurityFactorTypeClick = {}, onBackClick = {} ) } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesViewModel.kt similarity index 81% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsViewModel.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesViewModel.kt index 197ed5ebea..eaa8a52349 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorsViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/SecurityFactorTypesViewModel.kt @@ -21,12 +21,12 @@ import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class SecurityFactorsViewModel @Inject constructor( +class SecurityFactorTypesViewModel @Inject constructor( getSecurityProblemsUseCase: GetSecurityProblemsUseCase, @DefaultDispatcher defaultDispatcher: CoroutineDispatcher -) : StateViewModel() { +) : StateViewModel() { - override fun initialState(): State = State(securityFactorSettingItems = currentSecurityFactorTypeItems) + override fun initialState(): State = State(securityFactorTypeSettingItems = currentSecurityFactorTypeItems) init { viewModelScope.launch { @@ -44,11 +44,11 @@ class SecurityFactorsViewModel @Inject constructor( ) ) _state.update { - it.copy(securityFactorSettingItems = updatedSecurityFactorsSettings) + it.copy(securityFactorTypeSettingItems = updatedSecurityFactorsSettings) } } else { _state.update { - it.copy(securityFactorSettingItems = currentSecurityFactorTypeItems) + it.copy(securityFactorTypeSettingItems = currentSecurityFactorTypeItems) } } } @@ -56,6 +56,6 @@ class SecurityFactorsViewModel @Inject constructor( } data class State( - val securityFactorSettingItems: ImmutableMap> + val securityFactorTypeSettingItems: ImmutableMap> ) : UiState } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceBottomSheet.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceBottomSheet.kt index 8d4ec97a16..bb56216ffd 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceBottomSheet.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceBottomSheet.kt @@ -135,7 +135,7 @@ private fun ChooseFactorSourceContent( State.Page.SelectFactorSourceType -> { SecurityFactorTypesListView( securityFactorSettingItems = state.securityFactorTypeItems, - onSecurityFactorSettingItemClick = onSecurityFactorTypeClick + onSecurityFactorTypeItemClick = onSecurityFactorTypeClick ) } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceViewModel.kt index a6955b7e8b..dc3272a954 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceViewModel.kt @@ -73,7 +73,7 @@ class ChooseFactorSourceViewModel @Inject constructor( SecurityFactorsSettingsItem.ArculusCard -> State.Page.ArculusCard.ordinal is SecurityFactorsSettingsItem.BiometricsPin -> State.Page.BiometricsPin.ordinal SecurityFactorsSettingsItem.LedgerNano -> State.Page.LedgerNano.ordinal - SecurityFactorsSettingsItem.Passphrase -> State.Page.Passphrase.ordinal + SecurityFactorsSettingsItem.Mnemonic -> State.Page.Passphrase.ordinal SecurityFactorsSettingsItem.Password -> State.Page.Password.ordinal } ) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/securityfactors/SecurityFactorTypesListView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/securityfactors/SecurityFactorTypesListView.kt index 4d5f0cc545..97cf018a26 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/securityfactors/SecurityFactorTypesListView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/securityfactors/SecurityFactorTypesListView.kt @@ -30,7 +30,7 @@ fun SecurityFactorTypesListView( modifier: Modifier = Modifier, isDescriptionVisible: Boolean = false, securityFactorSettingItems: ImmutableMap>, - onSecurityFactorSettingItemClick: (SecurityFactorsSettingsItem) -> Unit + onSecurityFactorTypeItemClick: (SecurityFactorsSettingsItem) -> Unit ) { LazyColumn( modifier = modifier.background(color = RadixTheme.colors.gray5) @@ -71,7 +71,7 @@ fun SecurityFactorTypesListView( subtitle = stringResource(id = securityFactorsItem.subtitleRes()), leadingIconRes = securityFactorsItem.getIcon(), onClick = { - onSecurityFactorSettingItemClick(securityFactorsItem) + onSecurityFactorTypeItemClick(securityFactorsItem) }, warnings = if (securityFactorsItem is SecurityFactorsSettingsItem.BiometricsPin) { getSecurityWarnings(securityFactorsSettingsItem = securityFactorsItem) @@ -106,7 +106,7 @@ val currentSecurityFactorTypeItems = if (BuildConfig.EXPERIMENTAL_FEATURES_ENABL ), SecurityFactorCategory.Information to persistentSetOf( SecurityFactorsSettingsItem.Password, - SecurityFactorsSettingsItem.Passphrase + SecurityFactorsSettingsItem.Mnemonic ) ) } else { @@ -124,7 +124,7 @@ private fun SecurityFactorTypesListPreview() { RadixWalletTheme { SecurityFactorTypesListView( securityFactorSettingItems = currentSecurityFactorTypeItems, - onSecurityFactorSettingItemClick = {} + onSecurityFactorTypeItemClick = {} ) } } From 6b253fbc5041c83c099a731cd143929eaee4d014 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 11:37:11 +0200 Subject: [PATCH 03/16] added GetFactorSourcesUseCaseOfType --- .../GetFactorSourcesUseCaseOfType.kt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesUseCaseOfType.kt diff --git a/app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesUseCaseOfType.kt b/app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesUseCaseOfType.kt new file mode 100644 index 0000000000..060ca3b7b3 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesUseCaseOfType.kt @@ -0,0 +1,24 @@ +package com.babylon.wallet.android.domain.usecases.factorsources + +import com.radixdlt.sargon.FactorSource +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.flatMapConcat +import rdx.works.profile.domain.GetProfileUseCase +import javax.inject.Inject + +class GetFactorSourcesUseCaseOfType @Inject constructor( + val getProfileUseCase: GetProfileUseCase +) { + + @OptIn(ExperimentalCoroutinesApi::class) + inline operator fun invoke(): Flow { + return getProfileUseCase.flow + .flatMapConcat { profile -> + profile.factorSources.asFlow() + } + .filterIsInstance() + } +} From 1ce6a355e785d648880032b081e28a84cfb8da88 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:14:09 +0200 Subject: [PATCH 04/16] updated InfoDialog glossary items --- .../wallet/android/presentation/dialogs/info/InfoDialog.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/InfoDialog.kt b/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/InfoDialog.kt index 983448d681..0188fc563c 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/InfoDialog.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/InfoDialog.kt @@ -229,6 +229,10 @@ private fun GlossaryItem.resolveTextFromGlossaryItem() = when (this) { GlossaryItem.securityshields -> stringResource(id = R.string.infoLink_glossary_securityshields) GlossaryItem.buildingshield -> stringResource(id = R.string.infoLink_glossary_buildingshield) GlossaryItem.biometricsPIN -> stringResource(id = R.string.infoLink_glossary_biometricspin) + GlossaryItem.arculus -> stringResource(id = R.string.infoLink_glossary_arculus) + GlossaryItem.ledgerNano -> stringResource(id = R.string.infoLink_glossary_ledgernano) + GlossaryItem.passwords -> stringResource(id = R.string.infoLink_glossary_passwords) + GlossaryItem.mnemonic -> stringResource(id = R.string.infoLink_glossary_passphrases) GlossaryItem.emergencyFallback -> "" // TODO crowdin } From b93605fc685bc199ddd5ef058ee7429e7562b546 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:24:31 +0200 Subject: [PATCH 05/16] updated BiometricsPinScreen with glossary item and factor source id when click factor source item --- .../biometricspin/BiometricsPinNav.kt | 11 +++++---- .../biometricspin/BiometricsPinScreen.kt | 7 +++--- .../biometricspin/BiometricsPinViewModel.kt | 23 ++++++------------- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinNav.kt index 7d7d6f8eaa..102238c54d 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinNav.kt @@ -8,6 +8,7 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem +import com.radixdlt.sargon.FactorSourceId private const val ROUTE_BIOMETRICS_PIN_SCREEN = "route_biometrics_pin_screen" @@ -18,10 +19,10 @@ fun NavController.biometricsPin() { } fun NavGraphBuilder.biometricsPin( - onBackClick: () -> Unit, - onNavigateToDeviceFactorSourceDetails: () -> Unit, + onNavigateToDeviceFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, onNavigateToAddBiometricPin: () -> Unit, - onInfoClick: (GlossaryItem) -> Unit + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit ) { composable( route = ROUTE_BIOMETRICS_PIN_SCREEN, @@ -40,10 +41,10 @@ fun NavGraphBuilder.biometricsPin( ) { BiometricsPinScreen( viewModel = hiltViewModel(), - onBackClick = onBackClick, onNavigateToDeviceFactorSourceDetails = onNavigateToDeviceFactorSourceDetails, onNavigateToAddBiometricPin = onNavigateToAddBiometricPin, - onInfoClick = onInfoClick + onInfoClick = onInfoClick, + onBackClick = onBackClick ) } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt index bb6aa75c0b..0354bf018c 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt @@ -40,7 +40,7 @@ import kotlinx.collections.immutable.persistentListOf fun BiometricsPinScreen( viewModel: BiometricsPinViewModel, onBackClick: () -> Unit, - onNavigateToDeviceFactorSourceDetails: () -> Unit, + onNavigateToDeviceFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, onNavigateToAddBiometricPin: () -> Unit, onInfoClick: (GlossaryItem) -> Unit ) { @@ -49,8 +49,8 @@ fun BiometricsPinScreen( LaunchedEffect(Unit) { viewModel.oneOffEvent.collect { event -> when (event) { - BiometricsPinViewModel.Event.NavigateToDeviceFactorSourceDetails -> { - onNavigateToDeviceFactorSourceDetails() + is BiometricsPinViewModel.Event.NavigateToDeviceFactorSourceDetails -> { + onNavigateToDeviceFactorSourceDetails(event.factorSourceId) } } } @@ -96,6 +96,7 @@ private fun BiometricsPinContent( factorSources = state.deviceFactorSources, factorSourceDescriptionText = R.string.factorSources_card_deviceDescription, addFactorSourceButtonTitle = R.string.factorSources_list_deviceAdd, + glossaryItem = GlossaryItem.biometricsPIN, onFactorSourceClick = onDeviceFactorSourceClick, onAddFactorSourceClick = onAddBiometricsPinClick, onInfoClick = onInfoClick diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinViewModel.kt index 8044d4ad77..268b370ec9 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinViewModel.kt @@ -2,6 +2,7 @@ package com.babylon.wallet.android.presentation.settings.securitycenter.security import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.di.coroutines.DefaultDispatcher +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType import com.babylon.wallet.android.presentation.common.OneOffEvent import com.babylon.wallet.android.presentation.common.OneOffEventHandler import com.babylon.wallet.android.presentation.common.OneOffEventHandlerImpl @@ -28,26 +29,20 @@ import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.flow.flatMapConcat import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import rdx.works.core.preferences.PreferencesManager -import rdx.works.profile.domain.GetProfileUseCase import javax.inject.Inject -@OptIn(ExperimentalCoroutinesApi::class) @HiltViewModel class BiometricsPinViewModel @Inject constructor( + getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, private val sargonOsManager: SargonOsManager, private val preferencesManager: PreferencesManager, - getProfileUseCase: GetProfileUseCase, @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher ) : StateViewModel(), OneOffEventHandler by OneOffEventHandlerImpl() { @@ -55,11 +50,7 @@ class BiometricsPinViewModel @Inject constructor( override fun initialState(): State = State() init { - getProfileUseCase.flow - .flatMapConcat { profile -> - profile.factorSources.asFlow() - } - .filterIsInstance() + getFactorSourcesUseCaseOfType() .map { deviceFactorSource -> val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( factorSource = FactorSource.Device(deviceFactorSource.value), @@ -98,10 +89,9 @@ class BiometricsPinViewModel @Inject constructor( .launchIn(viewModelScope) } - @Suppress("UnusedParameter") // TODO fun onDeviceFactorSourceClick(factorSourceId: FactorSourceId) { viewModelScope.launch { - sendEvent(Event.NavigateToDeviceFactorSourceDetails) + sendEvent(Event.NavigateToDeviceFactorSourceDetails(factorSourceId)) } } @@ -139,7 +129,8 @@ class BiometricsPinViewModel @Inject constructor( val backedUpFactorSourceIds = preferencesManager.getBackedUpFactorSourceIds().firstOrNull().orEmpty() return if (isDeviceFactorSourceLinkedToAnyEntities) { - val deviceFactorSourceIntegrity = entitiesLinkedToDeviceFactorSource.integrity as FactorSourceIntegrity.Device + val deviceFactorSourceIntegrity = + entitiesLinkedToDeviceFactorSource.integrity as FactorSourceIntegrity.Device deviceFactorSourceIntegrity.toMessages().toPersistentList() } else if (backedUpFactorSourceIds.contains(deviceFactorSourceId)) { // if not linked entities we can't check // the integrity, but we can check if the user backed up the seed phrase @@ -171,6 +162,6 @@ class BiometricsPinViewModel @Inject constructor( sealed interface Event : OneOffEvent { - data object NavigateToDeviceFactorSourceDetails : Event + data class NavigateToDeviceFactorSourceDetails(val factorSourceId: FactorSourceId) : Event } } From d33c8fb0c936b1ae1a85086e9de8876fb4583ea9 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:26:08 +0200 Subject: [PATCH 06/16] updated FactorSourcesList to pass glossary item and an optional addFactorSourceButtonContent --- .../composables/FactorSourcesList.kt | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/composables/FactorSourcesList.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/composables/FactorSourcesList.kt index 06568eb559..4c2b942145 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/composables/FactorSourcesList.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/composables/FactorSourcesList.kt @@ -24,6 +24,7 @@ import com.babylon.wallet.android.presentation.ui.composables.InfoButton import com.babylon.wallet.android.presentation.ui.composables.card.FactorSourceCardView import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.FactorSourceKind import kotlinx.collections.immutable.PersistentList @Composable @@ -32,9 +33,11 @@ fun FactorSourcesList( mainFactorSource: FactorSourceCard?, factorSources: PersistentList, @StringRes factorSourceDescriptionText: Int, - @StringRes addFactorSourceButtonTitle: Int, + @StringRes addFactorSourceButtonTitle: Int? = null, + glossaryItem: GlossaryItem, + addFactorSourceButtonContent: @Composable (() -> Unit)? = null, onFactorSourceClick: (FactorSourceId) -> Unit, - onAddFactorSourceClick: () -> Unit, + onAddFactorSourceClick: (() -> Unit)? = null, onInfoClick: (GlossaryItem) -> Unit, ) { LazyColumn( @@ -70,7 +73,7 @@ fun FactorSourcesList( } } - if (factorSources.isNotEmpty()) { + if (mainFactorSource != null || (factorSources.isNotEmpty() && factorSources.first().kind == FactorSourceKind.DEVICE)) { item { Text( text = stringResource(id = R.string.factorSources_list_others), @@ -89,14 +92,21 @@ fun FactorSourcesList( item { Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingDefault)) - RadixSecondaryButton( - modifier = Modifier - .fillMaxWidth() - .wrapContentWidth(align = Alignment.CenterHorizontally), - text = stringResource(id = addFactorSourceButtonTitle), - onClick = onAddFactorSourceClick, - throttleClicks = true - ) + + addFactorSourceButtonContent?.invoke() + ?: onAddFactorSourceClick?.let { + RadixSecondaryButton( + modifier = Modifier + .fillMaxWidth() + .wrapContentWidth(align = Alignment.CenterHorizontally), + text = addFactorSourceButtonTitle?.let { + stringResource(id = addFactorSourceButtonTitle) + } ?: stringResource(id = R.string.empty), + onClick = it, + throttleClicks = true + ) + } + InfoButton( modifier = Modifier .fillMaxWidth() @@ -105,9 +115,16 @@ fun FactorSourcesList( horizontal = RadixTheme.dimensions.paddingDefault, vertical = RadixTheme.dimensions.paddingLarge ), - text = "Learn about biometrics/PIN", // TODO + text = when (glossaryItem) { + GlossaryItem.biometricsPIN -> stringResource(R.string.infoLink_title_biometricspin) + GlossaryItem.arculus -> stringResource(R.string.infoLink_title_arculus) + GlossaryItem.ledgerNano -> stringResource(R.string.infoLink_title_ledgernano) + GlossaryItem.passwords -> stringResource(R.string.infoLink_title_passwords) + GlossaryItem.mnemonic -> stringResource(R.string.infoLink_title_passphrases) + else -> stringResource(R.string.empty) + }, onClick = { - onInfoClick(GlossaryItem.biometricsPIN) + onInfoClick(glossaryItem) } ) } From 2f4af0228052f8c3bac399aa73b141349b684bd0 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:26:20 +0200 Subject: [PATCH 07/16] added Glossary items --- .../android/presentation/dialogs/info/GlossaryItem.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/GlossaryItem.kt b/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/GlossaryItem.kt index e4725405fb..7cf74f26fb 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/GlossaryItem.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/GlossaryItem.kt @@ -35,6 +35,10 @@ enum class GlossaryItem { possibledappcalls, securityshields, buildingshield, + emergencyFallback, biometricsPIN, // TODO pending the right glossary item - emergencyFallback + arculus, // TODO pending the right glossary item + ledgerNano, // TODO pending the right glossary item + passwords, // TODO pending the right glossary item + mnemonic, // TODO pending the right glossary item } From 7d09ceba3c9cb3e6c3eb1ab6db2c383160a43017 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:28:37 +0200 Subject: [PATCH 08/16] renamed LedgerHardwareWalletsScreen to LedgerDevicesScreen and updated screen to use FactorSourceCard and moved screen to securityfactors package --- .../withledger/ChooseLedgerScreen.kt | 4 +- .../withledger/ChooseLedgerViewModel.kt | 2 +- .../LedgerHardwareWalletsViewModel.kt | 123 --------- .../ledgerdevice}/AddLedgerDeviceViewModel.kt | 2 +- .../ledgerdevice/LedgerDevicesNav.kt} | 11 +- .../ledgerdevice/LedgerDevicesScreen.kt} | 260 ++++++++---------- .../ledgerdevice/LedgerDevicesViewModel.kt | 186 +++++++++++++ .../ImportLegacyWalletScreen.kt | 2 +- .../ImportLegacyWalletViewModel.kt | 2 +- .../importlegacywallet/UseLedgerDelegate.kt | 2 +- .../ui/composables/AddLedgerDeviceScreen.kt | 2 +- ...LedgerAccountDeviceAccountViewModelTest.kt | 4 +- 12 files changed, 325 insertions(+), 275 deletions(-) delete mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsViewModel.kt rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/{ledgerhardwarewallets => securityfactors/ledgerdevice}/AddLedgerDeviceViewModel.kt (99%) rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/{ledgerhardwarewallets/LedgerHardwareWalletsNav.kt => securityfactors/ledgerdevice/LedgerDevicesNav.kt} (79%) rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/{ledgerhardwarewallets/LedgerHardwareWalletsScreen.kt => securityfactors/ledgerdevice/LedgerDevicesScreen.kt} (53%) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesViewModel.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/withledger/ChooseLedgerScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/withledger/ChooseLedgerScreen.kt index 15bba2c31e..9d7e1d1f43 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/withledger/ChooseLedgerScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/withledger/ChooseLedgerScreen.kt @@ -23,8 +23,8 @@ import com.babylon.wallet.android.domain.model.Selectable import com.babylon.wallet.android.presentation.common.UiMessage import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem import com.babylon.wallet.android.presentation.settings.linkedconnectors.AddLinkConnectorViewModel -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.AddLedgerDeviceViewModel -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.ShowLinkConnectorPromptState +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.AddLedgerDeviceViewModel +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.ShowLinkConnectorPromptState import com.babylon.wallet.android.presentation.ui.composables.AddLedgerDeviceScreen import com.babylon.wallet.android.presentation.ui.composables.AddLinkConnectorScreen import com.babylon.wallet.android.presentation.ui.composables.BackIconType diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/withledger/ChooseLedgerViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/withledger/ChooseLedgerViewModel.kt index 0887670e13..da2e4c7585 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/withledger/ChooseLedgerViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/account/createaccount/withledger/ChooseLedgerViewModel.kt @@ -10,7 +10,7 @@ import com.babylon.wallet.android.presentation.common.OneOffEventHandlerImpl import com.babylon.wallet.android.presentation.common.StateViewModel import com.babylon.wallet.android.presentation.common.UiMessage import com.babylon.wallet.android.presentation.common.UiState -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.ShowLinkConnectorPromptState +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.ShowLinkConnectorPromptState import com.babylon.wallet.android.utils.AppEvent import com.babylon.wallet.android.utils.AppEventBus import com.radixdlt.sargon.FactorSource diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsViewModel.kt deleted file mode 100644 index 6aa78eb9b5..0000000000 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsViewModel.kt +++ /dev/null @@ -1,123 +0,0 @@ -package com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets - -import androidx.lifecycle.viewModelScope -import com.babylon.wallet.android.data.dapp.LedgerMessenger -import com.babylon.wallet.android.data.repository.p2plink.P2PLinksRepository -import com.babylon.wallet.android.presentation.common.StateViewModel -import com.babylon.wallet.android.presentation.common.UiState -import com.radixdlt.sargon.FactorSource -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toPersistentList -import kotlinx.coroutines.flow.dropWhile -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import rdx.works.core.sargon.ledgerFactorSources -import rdx.works.profile.domain.GetProfileUseCase -import javax.inject.Inject - -@HiltViewModel -class LedgerHardwareWalletsViewModel @Inject constructor( - private val getProfileUseCase: GetProfileUseCase, - private val ledgerMessenger: LedgerMessenger, - private val p2PLinksRepository: P2PLinksRepository -) : StateViewModel() { - - override fun initialState(): LedgerHardwareWalletsUiState = LedgerHardwareWalletsUiState() - - init { - viewModelScope.launch { - getProfileUseCase.flow.map { it.ledgerFactorSources }.collect { ledgerDevices -> - _state.update { uiState -> - uiState.copy(ledgerDevices = ledgerDevices.toPersistentList()) - } - } - } - } - - fun onAddLedgerDeviceClick() { - viewModelScope.launch { - val hasAtLeastOneLinkedConnector = p2PLinksRepository.getP2PLinks() - .asList() - .isNotEmpty() - - if (hasAtLeastOneLinkedConnector) { - _state.update { - it.copy(showContent = LedgerHardwareWalletsUiState.ShowContent.AddLedger) - } - } else { - _state.update { - it.copy( - showLinkConnectorPromptState = ShowLinkConnectorPromptState.Show( - source = ShowLinkConnectorPromptState.Source.UseLedger - ) - ) - } - } - } - } - - fun dismissConnectorPrompt(linkConnector: Boolean) { - _state.update { - it.copy( - showContent = if (linkConnector) { - LedgerHardwareWalletsUiState.ShowContent.LinkNewConnector - } else { - it.showContent - }, - showLinkConnectorPromptState = ShowLinkConnectorPromptState.None - ) - } - } - - fun disableAddLedgerButtonUntilConnectionIsEstablished() { - _state.update { - it.copy(showContent = LedgerHardwareWalletsUiState.ShowContent.Details) - } - ledgerMessenger.isAnyLinkedConnectorConnected - .dropWhile { isConnected -> - _state.update { state -> - state.copy(isNewLinkedConnectorConnected = isConnected) - } - isConnected.not() // continue while isConnected is not true - } - .launchIn(viewModelScope) - } - - fun onCloseClick() { - _state.update { - it.copy(showContent = LedgerHardwareWalletsUiState.ShowContent.Details) - } - } - - fun onLinkConnectorClick() { - _state.update { - it.copy(showContent = LedgerHardwareWalletsUiState.ShowContent.AddLinkConnector) - } - } - - fun onNewConnectorCloseClick() { - _state.update { - it.copy(showContent = LedgerHardwareWalletsUiState.ShowContent.Details) - } - } -} - -data class LedgerHardwareWalletsUiState( - val loading: Boolean = false, - val showContent: ShowContent = ShowContent.Details, - val ledgerDevices: ImmutableList = persistentListOf(), - val showLinkConnectorPromptState: ShowLinkConnectorPromptState = ShowLinkConnectorPromptState.None, - val isNewLinkedConnectorConnected: Boolean = true -) : UiState { - - sealed interface ShowContent { - data object Details : ShowContent - data object AddLedger : ShowContent - data object LinkNewConnector : ShowContent - data object AddLinkConnector : ShowContent - } -} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/AddLedgerDeviceViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/AddLedgerDeviceViewModel.kt similarity index 99% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/AddLedgerDeviceViewModel.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/AddLedgerDeviceViewModel.kt index 89972f3049..9b104e4ab5 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/AddLedgerDeviceViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/AddLedgerDeviceViewModel.kt @@ -1,4 +1,4 @@ -package com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.data.dapp.LedgerMessenger diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesNav.kt similarity index 79% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsNav.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesNav.kt index f32be36312..39001c1b76 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesNav.kt @@ -1,4 +1,4 @@ -package com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.EnterTransition @@ -8,16 +8,18 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem +import com.radixdlt.sargon.FactorSourceId private const val ROUTE = "ledger_hardware_wallets_route" -fun NavController.ledgerHardwareWalletsScreen() { +fun NavController.ledgerDevices() { navigate(ROUTE) { launchSingleTop = true } } -fun NavGraphBuilder.ledgerHardwareWalletsScreen( +fun NavGraphBuilder.ledgerDevices( + onNavigateToLedgerFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, onInfoClick: (GlossaryItem) -> Unit, onBackClick: () -> Unit ) { @@ -36,8 +38,9 @@ fun NavGraphBuilder.ledgerHardwareWalletsScreen( slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Right) } ) { - LedgerHardwareWalletsScreen( + LedgerDevicesScreen( viewModel = hiltViewModel(), + onNavigateToLedgerFactorSourceDetails = onNavigateToLedgerFactorSourceDetails, addLedgerDeviceViewModel = hiltViewModel(), addLinkConnectorViewModel = hiltViewModel(), onInfoClick = onInfoClick, diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesScreen.kt similarity index 53% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsScreen.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesScreen.kt index 5009f7c93f..9577e12901 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/ledgerhardwarewallets/LedgerHardwareWalletsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesScreen.kt @@ -1,19 +1,13 @@ -package com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice import androidx.activity.compose.BackHandler -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Scaffold import androidx.compose.material3.Text @@ -23,12 +17,8 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.shadow import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow 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 @@ -36,29 +26,36 @@ import com.babylon.wallet.android.designsystem.theme.RadixTheme import com.babylon.wallet.android.designsystem.theme.RadixWalletTheme import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem import com.babylon.wallet.android.presentation.settings.linkedconnectors.AddLinkConnectorViewModel +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.composables.FactorSourcesList import com.babylon.wallet.android.presentation.ui.composables.AddLedgerDeviceScreen import com.babylon.wallet.android.presentation.ui.composables.AddLinkConnectorScreen import com.babylon.wallet.android.presentation.ui.composables.BackIconType import com.babylon.wallet.android.presentation.ui.composables.BasicPromptAlertDialog -import com.babylon.wallet.android.presentation.ui.composables.LedgerListItem import com.babylon.wallet.android.presentation.ui.composables.LinkConnectorScreen import com.babylon.wallet.android.presentation.ui.composables.RadixCenteredTopAppBar import com.babylon.wallet.android.presentation.ui.composables.statusBarsAndBanner -import com.radixdlt.sargon.FactorSource +import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard +import com.radixdlt.sargon.Account +import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.FactorSourceKind +import com.radixdlt.sargon.MnemonicWithPassphrase +import com.radixdlt.sargon.Persona import com.radixdlt.sargon.annotation.UsesSampleValues -import com.radixdlt.sargon.extensions.hex -import kotlinx.collections.immutable.ImmutableList +import com.radixdlt.sargon.extensions.init +import com.radixdlt.sargon.samples.sample +import com.radixdlt.sargon.samples.sampleMainnet +import com.radixdlt.sargon.samples.sampleStokenet +import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.launch -import rdx.works.core.sargon.sample @Composable -fun LedgerHardwareWalletsScreen( +fun LedgerDevicesScreen( modifier: Modifier = Modifier, - viewModel: LedgerHardwareWalletsViewModel, + viewModel: LedgerDevicesViewModel, addLedgerDeviceViewModel: AddLedgerDeviceViewModel, addLinkConnectorViewModel: AddLinkConnectorViewModel, + onNavigateToLedgerFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, onInfoClick: (GlossaryItem) -> Unit, onBackClick: () -> Unit ) { @@ -91,6 +88,16 @@ fun LedgerHardwareWalletsScreen( ) } + LaunchedEffect(Unit) { + viewModel.oneOffEvent.collect { event -> + when (event) { + is LedgerDevicesViewModel.Event.NavigateToLedgerFactorSourceDetails -> { + onNavigateToLedgerFactorSourceDetails(event.factorSourceId) + } + } + } + } + LaunchedEffect(Unit) { addLinkConnectorViewModel.oneOffEvent.collect { event -> when (event) { @@ -105,20 +112,20 @@ fun LedgerHardwareWalletsScreen( } } - Box( - modifier = modifier - ) { + Box(modifier = modifier) { when (state.showContent) { - LedgerHardwareWalletsUiState.ShowContent.Details -> { - LedgerHardwareWalletsContent( - ledgerDevices = state.ledgerDevices, + LedgerDevicesViewModel.State.ShowContent.Details -> { + LedgerDevicesContent( + ledgerFactorSources = state.ledgerFactorSources, + onLedgerFactorSourceClick = viewModel::onLedgerFactorSourceClick, onAddLedgerDeviceClick = viewModel::onAddLedgerDeviceClick, - onBackClick = onBackClick, - isNewLinkedConnectorConnected = state.isNewLinkedConnectorConnected + isNewLinkedConnectorConnected = state.isNewLinkedConnectorConnected, + onInfoClick = onInfoClick, + onBackClick = onBackClick ) } - LedgerHardwareWalletsUiState.ShowContent.AddLedger -> { + LedgerDevicesViewModel.State.ShowContent.AddLedger -> { AddLedgerDeviceScreen( showContent = addLedgerDeviceState.showContent, uiMessage = addLedgerDeviceState.uiMessage, @@ -139,7 +146,7 @@ fun LedgerHardwareWalletsScreen( ) } - is LedgerHardwareWalletsUiState.ShowContent.LinkNewConnector -> { + is LedgerDevicesViewModel.State.ShowContent.LinkNewConnector -> { LinkConnectorScreen( modifier = Modifier.fillMaxSize(), onLinkConnectorClick = viewModel::onLinkConnectorClick, @@ -147,7 +154,7 @@ fun LedgerHardwareWalletsScreen( ) } - is LedgerHardwareWalletsUiState.ShowContent.AddLinkConnector -> { + is LedgerDevicesViewModel.State.ShowContent.AddLinkConnector -> { AddLinkConnectorScreen( modifier = Modifier, state = addLinkConnectorState, @@ -165,10 +172,12 @@ fun LedgerHardwareWalletsScreen( } @Composable -private fun LedgerHardwareWalletsContent( - ledgerDevices: ImmutableList, +private fun LedgerDevicesContent( + ledgerFactorSources: PersistentList, isNewLinkedConnectorConnected: Boolean, + onLedgerFactorSourceClick: (FactorSourceId) -> Unit, onAddLedgerDeviceClick: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, onBackClick: () -> Unit ) { BackHandler(onBack = onBackClick) @@ -176,7 +185,7 @@ private fun LedgerHardwareWalletsContent( Scaffold( topBar = { RadixCenteredTopAppBar( - title = stringResource(R.string.accountSecuritySettings_ledgerHardwareWallets_title), + title = stringResource(R.string.factorSources_card_ledgerTitle), onBackClick = onBackClick, windowInsets = WindowInsets.statusBarsAndBanner ) @@ -188,101 +197,26 @@ private fun LedgerHardwareWalletsContent( horizontalAlignment = Alignment.CenterHorizontally ) { HorizontalDivider(color = RadixTheme.colors.gray4) - if (ledgerDevices.isNotEmpty()) { - LedgerDevicesListContent( - modifier = Modifier - .weight(1f) - .fillMaxWidth(), - ledgerDevices = ledgerDevices, - isNewLinkedConnectorConnected = isNewLinkedConnectorConnected, - onAddLedgerDeviceClick = onAddLedgerDeviceClick, - ) - } else { - Text( - modifier = Modifier.padding(vertical = RadixTheme.dimensions.paddingDefault), - text = stringResource(id = R.string.ledgerHardwareDevices_subtitleAllLedgers), - style = RadixTheme.typography.body1HighImportance, - color = RadixTheme.colors.gray2 - ) - Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingMedium)) - Text( - modifier = Modifier - .padding(horizontal = RadixTheme.dimensions.paddingDefault) - .fillMaxWidth() - .background(RadixTheme.colors.defaultBackground, RadixTheme.shapes.roundedRectSmall) - .padding(RadixTheme.dimensions.paddingLarge), - text = stringResource(id = R.string.ledgerHardwareDevices_subtitleNoLedgers), - style = RadixTheme.typography.body1Header, - color = RadixTheme.colors.gray2, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.Center - ) - Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingXLarge)) - RadixSecondaryButton( - text = stringResource(id = R.string.ledgerHardwareDevices_addNewLedger), - onClick = onAddLedgerDeviceClick, - modifier = Modifier - .fillMaxWidth(0.7f) - .imePadding(), - isLoading = isNewLinkedConnectorConnected.not(), - enabled = isNewLinkedConnectorConnected, - throttleClicks = true - ) - } - } - } -} - -@Composable -private fun LedgerDevicesListContent( - modifier: Modifier = Modifier, - ledgerDevices: ImmutableList, - isNewLinkedConnectorConnected: Boolean, - onAddLedgerDeviceClick: () -> Unit, -) { - LazyColumn( - modifier, - contentPadding = PaddingValues(horizontal = RadixTheme.dimensions.paddingDefault), - horizontalAlignment = Alignment.CenterHorizontally - ) { - item { - Text( - modifier = Modifier.padding(vertical = RadixTheme.dimensions.paddingDefault), - text = stringResource(id = R.string.ledgerHardwareDevices_subtitleAllLedgers), - style = RadixTheme.typography.body1HighImportance, - color = RadixTheme.colors.gray2 - ) - Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingMedium)) - } - items( - items = ledgerDevices, - key = { factorSource: FactorSource.Ledger -> - factorSource.value.id.body.hex - }, - itemContent = { item -> - LedgerListItem( - ledgerFactorSource = item, - modifier = Modifier - .shadow(elevation = 4.dp, shape = RadixTheme.shapes.roundedRectSmall) - .fillMaxWidth() - .background(RadixTheme.colors.defaultBackground, shape = RadixTheme.shapes.roundedRectSmall) - .padding(RadixTheme.dimensions.paddingLarge), - ) - Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingMedium)) - } - ) - item { - Spacer(modifier = Modifier.height(RadixTheme.dimensions.paddingDefault)) - RadixSecondaryButton( - modifier = Modifier - .fillMaxWidth(0.7f) - .padding(bottom = RadixTheme.dimensions.paddingDefault), - text = stringResource(id = R.string.ledgerHardwareDevices_addNewLedger), - onClick = onAddLedgerDeviceClick, - throttleClicks = true, - isLoading = isNewLinkedConnectorConnected.not(), - enabled = isNewLinkedConnectorConnected + FactorSourcesList( + mainFactorSource = null, + factorSources = ledgerFactorSources, + factorSourceDescriptionText = R.string.factorSources_card_ledgerDescription, + glossaryItem = GlossaryItem.ledgerNano, + addFactorSourceButtonContent = { + RadixSecondaryButton( + modifier = Modifier + .fillMaxWidth() + .wrapContentWidth(align = Alignment.CenterHorizontally), + text = stringResource(id = R.string.factorSources_list_ledgerAdd), + onClick = onAddLedgerDeviceClick, + throttleClicks = true, + isLoading = isNewLinkedConnectorConnected.not(), + enabled = isNewLinkedConnectorConnected + ) + }, + onFactorSourceClick = onLedgerFactorSourceClick, + onInfoClick = onInfoClick ) } } @@ -291,26 +225,76 @@ private fun LedgerDevicesListContent( @UsesSampleValues @Preview(showBackground = true) @Composable -fun LedgerHardwareWalletsScreenPreview() { +fun LedgerDevicesScreenPreview() { RadixWalletTheme { - LedgerHardwareWalletsContent( - ledgerDevices = FactorSource.Ledger.sample.all.toPersistentList(), + LedgerDevicesContent( + ledgerFactorSources = persistentListOf( + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.LEDGER_HQ_HARDWARE_WALLET, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "My Ledger", + includeDescription = false, + lastUsedOn = "Today", + kind = FactorSourceKind.LEDGER_HQ_HARDWARE_WALLET, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf( + Persona.sampleMainnet(), + Persona.sampleStokenet() + ), + hasHiddenEntities = true + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.LEDGER_HQ_HARDWARE_WALLET, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "XXX Ledger", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.LEDGER_HQ_HARDWARE_WALLET, + messages = persistentListOf(), + accounts = persistentListOf(), + personas = persistentListOf(), + hasHiddenEntities = true // TODO fix the message + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.LEDGER_HQ_HARDWARE_WALLET, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Gate13", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.LEDGER_HQ_HARDWARE_WALLET, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf(), + hasHiddenEntities = false + ) + ), + isNewLinkedConnectorConnected = true, + onLedgerFactorSourceClick = {}, onAddLedgerDeviceClick = {}, - onBackClick = {}, - isNewLinkedConnectorConnected = true + onInfoClick = {}, + onBackClick = {} ) } } @Preview(showBackground = true) @Composable -fun LedgerHardwareWalletsScreenEmptyPreview() { +fun LedgerDevicesEmptyScreenPreview() { RadixWalletTheme { - LedgerHardwareWalletsContent( - ledgerDevices = persistentListOf(), + LedgerDevicesContent( + ledgerFactorSources = persistentListOf(), + isNewLinkedConnectorConnected = true, + onLedgerFactorSourceClick = {}, onAddLedgerDeviceClick = {}, - onBackClick = {}, - isNewLinkedConnectorConnected = true + onInfoClick = {}, + onBackClick = {} ) } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesViewModel.kt new file mode 100644 index 0000000000..c15fda6833 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesViewModel.kt @@ -0,0 +1,186 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice + +import androidx.lifecycle.viewModelScope +import com.babylon.wallet.android.data.dapp.LedgerMessenger +import com.babylon.wallet.android.data.repository.p2plink.P2PLinksRepository +import com.babylon.wallet.android.di.coroutines.DefaultDispatcher +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.presentation.common.OneOffEvent +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.presentation.ui.model.factors.FactorSourceCard +import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceStatusMessage +import com.babylon.wallet.android.utils.relativeTimeFormatted +import com.radixdlt.sargon.Account +import com.radixdlt.sargon.FactorSource +import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.LedgerHardwareWalletFactorSource +import com.radixdlt.sargon.Persona +import com.radixdlt.sargon.ProfileToCheck +import com.radixdlt.sargon.extensions.asGeneral +import com.radixdlt.sargon.extensions.kind +import com.radixdlt.sargon.os.SargonOsManager +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.dropWhile +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class LedgerDevicesViewModel @Inject constructor( + getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + private val sargonOsManager: SargonOsManager, + private val ledgerMessenger: LedgerMessenger, + private val p2PLinksRepository: P2PLinksRepository, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher +) : StateViewModel(), + OneOffEventHandler by OneOffEventHandlerImpl() { + + override fun initialState(): State = State() + + init { + getFactorSourcesUseCaseOfType() + .map { ledgerFactorSource -> + val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( + factorSource = FactorSource.Ledger(ledgerFactorSource.value), + profileToCheck = ProfileToCheck.Current + ) + + val factorSourceCard = ledgerFactorSource.value.toFactorSourceCard( + messages = persistentListOf(), + accounts = entitiesLinkedToDeviceFactorSource.accounts.toPersistentList(), + personas = entitiesLinkedToDeviceFactorSource.personas.toPersistentList(), + hasHiddenEntities = entitiesLinkedToDeviceFactorSource.hiddenAccounts.isNotEmpty() || + entitiesLinkedToDeviceFactorSource.hiddenPersonas.isNotEmpty() + ) + + _state.update { state -> + state.copy(ledgerFactorSources = state.ledgerFactorSources.add(factorSourceCard)) + } + } + .flowOn(defaultDispatcher) + .launchIn(viewModelScope) + } + + private fun LedgerHardwareWalletFactorSource.toFactorSourceCard( + includeDescription: Boolean = false, + messages: PersistentList = persistentListOf(), + accounts: PersistentList = persistentListOf(), + personas: PersistentList = persistentListOf(), + hasHiddenEntities: Boolean + ): FactorSourceCard { + return FactorSourceCard( + id = id.asGeneral(), + name = hint.label, + includeDescription = includeDescription, + lastUsedOn = common.lastUsedOn.relativeTimeFormatted(), + kind = kind, + messages = messages, + accounts = accounts, + personas = personas, + hasHiddenEntities = hasHiddenEntities + ) + } + + fun onLedgerFactorSourceClick(factorSourceId: FactorSourceId) { + viewModelScope.launch { + sendEvent(Event.NavigateToLedgerFactorSourceDetails(factorSourceId)) + } + } + + fun onAddLedgerDeviceClick() { + viewModelScope.launch { + val hasAtLeastOneLinkedConnector = p2PLinksRepository.getP2PLinks() + .asList() + .isNotEmpty() + + if (hasAtLeastOneLinkedConnector) { + _state.update { + it.copy(showContent = State.ShowContent.AddLedger) + } + } else { + _state.update { + it.copy( + showLinkConnectorPromptState = ShowLinkConnectorPromptState.Show( + source = ShowLinkConnectorPromptState.Source.UseLedger + ) + ) + } + } + } + } + + fun dismissConnectorPrompt(linkConnector: Boolean) { + _state.update { + it.copy( + showContent = if (linkConnector) { + State.ShowContent.LinkNewConnector + } else { + it.showContent + }, + showLinkConnectorPromptState = ShowLinkConnectorPromptState.None + ) + } + } + + fun disableAddLedgerButtonUntilConnectionIsEstablished() { + _state.update { + it.copy(showContent = State.ShowContent.Details) + } + ledgerMessenger.isAnyLinkedConnectorConnected + .dropWhile { isConnected -> + _state.update { state -> + state.copy(isNewLinkedConnectorConnected = isConnected) + } + isConnected.not() // continue while isConnected is not true + } + .launchIn(viewModelScope) + } + + fun onCloseClick() { + _state.update { + it.copy(showContent = State.ShowContent.Details) + } + } + + fun onLinkConnectorClick() { + _state.update { + it.copy(showContent = State.ShowContent.AddLinkConnector) + } + } + + fun onNewConnectorCloseClick() { + _state.update { + it.copy(showContent = State.ShowContent.Details) + } + } + + data class State( + val showContent: ShowContent = ShowContent.Details, + val ledgerFactorSources: PersistentList = persistentListOf(), + val showLinkConnectorPromptState: ShowLinkConnectorPromptState = ShowLinkConnectorPromptState.None, + val isNewLinkedConnectorConnected: Boolean = true + ) : UiState { + + sealed interface ShowContent { + data object Details : ShowContent + data object AddLedger : ShowContent + data object LinkNewConnector : ShowContent + data object AddLinkConnector : ShowContent + } + } + + sealed interface Event : OneOffEvent { + + data class NavigateToLedgerFactorSourceDetails(val factorSourceId: FactorSourceId) : Event + } +} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/ImportLegacyWalletScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/ImportLegacyWalletScreen.kt index 428d458300..fffe01e345 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/ImportLegacyWalletScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/ImportLegacyWalletScreen.kt @@ -61,7 +61,7 @@ import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem import com.babylon.wallet.android.presentation.settings.linkedconnectors.AddLinkConnectorUiState import com.babylon.wallet.android.presentation.settings.linkedconnectors.AddLinkConnectorViewModel import com.babylon.wallet.android.presentation.settings.linkedconnectors.qrcode.CameraPreview -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.AddLedgerDeviceUiState +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.AddLedgerDeviceUiState import com.babylon.wallet.android.presentation.settings.troubleshooting.importlegacywallet.ImportLegacyWalletUiState.Page import com.babylon.wallet.android.presentation.ui.MockUiProvider.accountItemUiModelsList import com.babylon.wallet.android.presentation.ui.MockUiProvider.olympiaAccountsList diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/ImportLegacyWalletViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/ImportLegacyWalletViewModel.kt index f12d2b056a..304ff22cd1 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/ImportLegacyWalletViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/ImportLegacyWalletViewModel.kt @@ -20,7 +20,7 @@ import com.babylon.wallet.android.presentation.common.seedphrase.SeedPhraseInput import com.babylon.wallet.android.presentation.dapp.authorized.account.AccountItemUiModel import com.babylon.wallet.android.presentation.dapp.authorized.account.toUiModel import com.babylon.wallet.android.presentation.model.LedgerDeviceUiModel -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.AddLedgerDeviceUiState +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.AddLedgerDeviceUiState import com.babylon.wallet.android.utils.AppEvent import com.babylon.wallet.android.utils.AppEventBus import com.babylon.wallet.android.utils.Constants.DELAY_300_MS diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/UseLedgerDelegate.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/UseLedgerDelegate.kt index 2e29904903..dbe975294f 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/UseLedgerDelegate.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/troubleshooting/importlegacywallet/UseLedgerDelegate.kt @@ -5,7 +5,7 @@ import com.babylon.wallet.android.presentation.common.Stateful import com.babylon.wallet.android.presentation.common.UiMessage import com.babylon.wallet.android.presentation.common.UiState import com.babylon.wallet.android.presentation.model.LedgerDeviceUiModel -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.AddLedgerDeviceUiState +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.AddLedgerDeviceUiState import com.radixdlt.sargon.FactorSource import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.map diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/AddLedgerDeviceScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/AddLedgerDeviceScreen.kt index b582ece503..9753cfaa36 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/AddLedgerDeviceScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/AddLedgerDeviceScreen.kt @@ -39,7 +39,7 @@ import com.babylon.wallet.android.designsystem.theme.RadixTheme import com.babylon.wallet.android.designsystem.theme.RadixWalletTheme import com.babylon.wallet.android.presentation.common.FullscreenCircularProgressContent import com.babylon.wallet.android.presentation.common.UiMessage -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.AddLedgerDeviceUiState +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.AddLedgerDeviceUiState import com.radixdlt.sargon.LedgerHardwareWalletModel import rdx.works.core.sargon.displayName diff --git a/app/src/test/java/com/babylon/wallet/android/presentation/createaccount/withledger/AddLedgerAccountDeviceAccountViewModelTest.kt b/app/src/test/java/com/babylon/wallet/android/presentation/createaccount/withledger/AddLedgerAccountDeviceAccountViewModelTest.kt index c094bec7f5..8c1da549f5 100644 --- a/app/src/test/java/com/babylon/wallet/android/presentation/createaccount/withledger/AddLedgerAccountDeviceAccountViewModelTest.kt +++ b/app/src/test/java/com/babylon/wallet/android/presentation/createaccount/withledger/AddLedgerAccountDeviceAccountViewModelTest.kt @@ -4,8 +4,8 @@ import app.cash.turbine.test import com.babylon.wallet.android.data.dapp.LedgerMessenger import com.babylon.wallet.android.domain.model.messages.LedgerResponse import com.babylon.wallet.android.presentation.StateViewModelTest -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.AddLedgerDeviceUiState -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.AddLedgerDeviceViewModel +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.AddLedgerDeviceUiState +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.AddLedgerDeviceViewModel import com.radixdlt.sargon.Exactly32Bytes import com.radixdlt.sargon.FactorSource import com.radixdlt.sargon.FactorSourceCommon From 62a0ddb1b7683dd91d5c5efc42c024dc40822386 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:30:16 +0200 Subject: [PATCH 09/16] added ArculusCardsScreen --- .../arculuscard/ArculusCardsNav.kt | 50 ++++++ .../arculuscard/ArculusCardsScreen.kt | 161 ++++++++++++++++++ .../arculuscard/ArculusCardsViewModel.kt | 103 +++++++++++ 3 files changed, 314 insertions(+) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsNav.kt create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsScreen.kt create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsViewModel.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsNav.kt new file mode 100644 index 0000000000..30b9d04ecd --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsNav.kt @@ -0,0 +1,50 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.arculuscard + +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem +import com.radixdlt.sargon.FactorSourceId + +private const val ROUTE_ARCULUS_CARDS_SCREEN = "route_arculus_cards_screen" + +fun NavController.arculusCards() { + navigate(ROUTE_ARCULUS_CARDS_SCREEN) { + launchSingleTop = true + } +} + +fun NavGraphBuilder.arculusCards( + onNavigateToArculusFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, + onNavigateToAddArculusCard: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + composable( + route = ROUTE_ARCULUS_CARDS_SCREEN, + enterTransition = { + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Left) + }, + exitTransition = { + ExitTransition.None + }, + popEnterTransition = { + EnterTransition.None + }, + popExitTransition = { + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Right) + } + ) { + ArculusCardsScreen( + viewModel = hiltViewModel(), + onNavigateToArculusFactorSourceDetails = onNavigateToArculusFactorSourceDetails, + onNavigateToAddArculusCard = onNavigateToAddArculusCard, + onInfoClick = onInfoClick, + onBackClick = onBackClick + ) + } +} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsScreen.kt new file mode 100644 index 0000000000..b8c777d573 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsScreen.kt @@ -0,0 +1,161 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.arculuscard + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +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.tooling.preview.Preview +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.babylon.wallet.android.R +import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.designsystem.theme.RadixWalletTheme +import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.composables.FactorSourcesList +import com.babylon.wallet.android.presentation.ui.composables.RadixCenteredTopAppBar +import com.babylon.wallet.android.presentation.ui.composables.statusBarsAndBanner +import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard +import com.radixdlt.sargon.Account +import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.FactorSourceKind +import com.radixdlt.sargon.MnemonicWithPassphrase +import com.radixdlt.sargon.annotation.UsesSampleValues +import com.radixdlt.sargon.extensions.init +import com.radixdlt.sargon.samples.sample +import com.radixdlt.sargon.samples.sampleMainnet +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf + +@Composable +fun ArculusCardsScreen( + viewModel: ArculusCardsViewModel, + onNavigateToArculusFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, + onNavigateToAddArculusCard: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + val state by viewModel.state.collectAsStateWithLifecycle() + + LaunchedEffect(Unit) { + viewModel.oneOffEvent.collect { event -> + when (event) { + is ArculusCardsViewModel.Event.NavigateToArculusFactorSourceDetails -> { + onNavigateToArculusFactorSourceDetails(event.factorSourceId) + } + } + } + } + + ArculusCardsContent( + arculusFactorSources = state.arculusFactorSources, + onArculusFactorSourceClick = viewModel::onArculusFactorSourceClick, + onAddArculusCardClick = onNavigateToAddArculusCard, + onInfoClick = onInfoClick, + onBackClick = onBackClick + ) +} + +@Composable +private fun ArculusCardsContent( + modifier: Modifier = Modifier, + arculusFactorSources: PersistentList, + onArculusFactorSourceClick: (FactorSourceId) -> Unit, + onAddArculusCardClick: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + Scaffold( + modifier = modifier.fillMaxSize(), + topBar = { + RadixCenteredTopAppBar( + title = stringResource(R.string.factorSources_card_arculusCardTitle), + onBackClick = onBackClick, + windowInsets = WindowInsets.statusBarsAndBanner + ) + }, + containerColor = RadixTheme.colors.gray5 + ) { padding -> + Column( + modifier = Modifier.padding(padding), + horizontalAlignment = Alignment.Start + ) { + HorizontalDivider(color = RadixTheme.colors.gray4) + + FactorSourcesList( + mainFactorSource = null, + factorSources = arculusFactorSources, + factorSourceDescriptionText = R.string.factorSources_card_arculusCardDescription, + addFactorSourceButtonTitle = R.string.factorSources_list_arculusCardAdd, + glossaryItem = GlossaryItem.arculus, + onFactorSourceClick = onArculusFactorSourceClick, + onAddFactorSourceClick = onAddArculusCardClick, + onInfoClick = onInfoClick + ) + } + } +} + +@UsesSampleValues +@Preview(showBackground = true) +@Composable +fun ArculusCardsScreenPreview() { + RadixWalletTheme { + ArculusCardsContent( + arculusFactorSources = persistentListOf( + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.ARCULUS_CARD, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Panathinaikos", + includeDescription = false, + lastUsedOn = "Today", + kind = FactorSourceKind.ARCULUS_CARD, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf(), + hasHiddenEntities = false + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.ARCULUS_CARD, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Gate 13", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.ARCULUS_CARD, + messages = persistentListOf(), + accounts = persistentListOf(), + personas = persistentListOf(), + hasHiddenEntities = true // TODO fix the message + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.ARCULUS_CARD, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Gate13", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.ARCULUS_CARD, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf(), + hasHiddenEntities = false + ) + ), + onArculusFactorSourceClick = {}, + onAddArculusCardClick = {}, + onBackClick = {}, + onInfoClick = {} + ) + } +} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsViewModel.kt new file mode 100644 index 0000000000..823907fe77 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsViewModel.kt @@ -0,0 +1,103 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.arculuscard + +import androidx.lifecycle.viewModelScope +import com.babylon.wallet.android.di.coroutines.DefaultDispatcher +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.presentation.common.OneOffEvent +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.presentation.ui.model.factors.FactorSourceCard +import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceStatusMessage +import com.babylon.wallet.android.utils.relativeTimeFormatted +import com.radixdlt.sargon.Account +import com.radixdlt.sargon.ArculusCardFactorSource +import com.radixdlt.sargon.FactorSource +import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.Persona +import com.radixdlt.sargon.ProfileToCheck +import com.radixdlt.sargon.extensions.asGeneral +import com.radixdlt.sargon.extensions.kind +import com.radixdlt.sargon.os.SargonOsManager +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class ArculusCardsViewModel @Inject constructor( + getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + private val sargonOsManager: SargonOsManager, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher +) : StateViewModel(), + OneOffEventHandler by OneOffEventHandlerImpl() { + + override fun initialState(): State = State() + + init { + getFactorSourcesUseCaseOfType() + .map { arculusFactorSource -> + val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( + factorSource = FactorSource.ArculusCard(arculusFactorSource.value), + profileToCheck = ProfileToCheck.Current + ) + + val factorSourceCard = arculusFactorSource.value.toFactorSourceCard( + messages = persistentListOf(), + accounts = entitiesLinkedToDeviceFactorSource.accounts.toPersistentList(), + personas = entitiesLinkedToDeviceFactorSource.personas.toPersistentList(), + hasHiddenEntities = entitiesLinkedToDeviceFactorSource.hiddenAccounts.isNotEmpty() || + entitiesLinkedToDeviceFactorSource.hiddenPersonas.isNotEmpty() + ) + + _state.update { state -> + state.copy(arculusFactorSources = state.arculusFactorSources.add(factorSourceCard)) + } + } + .flowOn(defaultDispatcher) + .launchIn(viewModelScope) + } + + private fun ArculusCardFactorSource.toFactorSourceCard( + includeDescription: Boolean = false, + messages: PersistentList = persistentListOf(), + accounts: PersistentList = persistentListOf(), + personas: PersistentList = persistentListOf(), + hasHiddenEntities: Boolean + ): FactorSourceCard { + return FactorSourceCard( + id = id.asGeneral(), + name = hint.label, + includeDescription = includeDescription, + lastUsedOn = common.lastUsedOn.relativeTimeFormatted(), + kind = kind, + messages = messages, + accounts = accounts, + personas = personas, + hasHiddenEntities = hasHiddenEntities + ) + } + + fun onArculusFactorSourceClick(factorSourceId: FactorSourceId) { + viewModelScope.launch { + sendEvent(Event.NavigateToArculusFactorSourceDetails(factorSourceId)) + } + } + + data class State( + val arculusFactorSources: PersistentList = persistentListOf(), + ) : UiState + + sealed interface Event : OneOffEvent { + + data class NavigateToArculusFactorSourceDetails(val factorSourceId: FactorSourceId) : Event + } +} From 017f0043b2b262746023901866156049f68048ff Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:31:10 +0200 Subject: [PATCH 10/16] added PasswordsScreen --- .../securityfactors/password/PasswordsNav.kt | 50 ++++++ .../password/PasswordsScreen.kt | 161 ++++++++++++++++++ .../password/PasswordsViewModel.kt | 103 +++++++++++ 3 files changed, 314 insertions(+) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsNav.kt create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsScreen.kt create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsViewModel.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsNav.kt new file mode 100644 index 0000000000..79663ece7f --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsNav.kt @@ -0,0 +1,50 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.password + +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem +import com.radixdlt.sargon.FactorSourceId + +private const val ROUTE_PASSWORDS_SCREEN = "route_passwords_screen" + +fun NavController.passwords() { + navigate(ROUTE_PASSWORDS_SCREEN) { + launchSingleTop = true + } +} + +fun NavGraphBuilder.passwords( + onNavigateToPasswordFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, + onNavigateToAddPassword: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + composable( + route = ROUTE_PASSWORDS_SCREEN, + enterTransition = { + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Left) + }, + exitTransition = { + ExitTransition.None + }, + popEnterTransition = { + EnterTransition.None + }, + popExitTransition = { + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Right) + } + ) { + PasswordsScreen( + viewModel = hiltViewModel(), + onNavigateToPasswordFactorSourceDetails = onNavigateToPasswordFactorSourceDetails, + onNavigateToAddPassword = onNavigateToAddPassword, + onInfoClick = onInfoClick, + onBackClick = onBackClick + ) + } +} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsScreen.kt new file mode 100644 index 0000000000..741331e7bb --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsScreen.kt @@ -0,0 +1,161 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.password + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +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.tooling.preview.Preview +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.babylon.wallet.android.R +import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.designsystem.theme.RadixWalletTheme +import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.composables.FactorSourcesList +import com.babylon.wallet.android.presentation.ui.composables.RadixCenteredTopAppBar +import com.babylon.wallet.android.presentation.ui.composables.statusBarsAndBanner +import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard +import com.radixdlt.sargon.Account +import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.FactorSourceKind +import com.radixdlt.sargon.MnemonicWithPassphrase +import com.radixdlt.sargon.annotation.UsesSampleValues +import com.radixdlt.sargon.extensions.init +import com.radixdlt.sargon.samples.sample +import com.radixdlt.sargon.samples.sampleMainnet +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf + +@Composable +fun PasswordsScreen( + viewModel: PasswordsViewModel, + onNavigateToPasswordFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, + onNavigateToAddPassword: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + val state by viewModel.state.collectAsStateWithLifecycle() + + LaunchedEffect(Unit) { + viewModel.oneOffEvent.collect { event -> + when (event) { + is PasswordsViewModel.Event.NavigateToPasswordFactorSourceDetails -> { + onNavigateToPasswordFactorSourceDetails(event.factorSourceId) + } + } + } + } + + PasswordsContent( + passwordFactorSources = state.passwordFactorSources, + onPasswordFactorSourceClick = viewModel::onPasswordFactorSourceClick, + onAddPasswordClick = onNavigateToAddPassword, + onInfoClick = onInfoClick, + onBackClick = onBackClick, + ) +} + +@Composable +private fun PasswordsContent( + modifier: Modifier = Modifier, + passwordFactorSources: PersistentList, + onPasswordFactorSourceClick: (FactorSourceId) -> Unit, + onAddPasswordClick: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + Scaffold( + modifier = modifier.fillMaxSize(), + topBar = { + RadixCenteredTopAppBar( + title = stringResource(R.string.factorSources_card_passwordTitle), + onBackClick = onBackClick, + windowInsets = WindowInsets.statusBarsAndBanner + ) + }, + containerColor = RadixTheme.colors.gray5 + ) { padding -> + Column( + modifier = Modifier.padding(padding), + horizontalAlignment = Alignment.Start + ) { + HorizontalDivider(color = RadixTheme.colors.gray4) + + FactorSourcesList( + mainFactorSource = null, + factorSources = passwordFactorSources, + factorSourceDescriptionText = R.string.factorSources_card_passwordDescription, + addFactorSourceButtonTitle = R.string.factorSources_list_passwordAdd, + glossaryItem = GlossaryItem.passwords, + onFactorSourceClick = onPasswordFactorSourceClick, + onAddFactorSourceClick = onAddPasswordClick, + onInfoClick = onInfoClick + ) + } + } +} + +@UsesSampleValues +@Preview(showBackground = true) +@Composable +private fun PasswordsScreenPreview() { + RadixWalletTheme { + PasswordsContent( + passwordFactorSources = persistentListOf( + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.PASSWORD, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Panathinaikos", + includeDescription = false, + lastUsedOn = "Today", + kind = FactorSourceKind.PASSWORD, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf(), + hasHiddenEntities = false + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.PASSWORD, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Gate 13", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.PASSWORD, + messages = persistentListOf(), + accounts = persistentListOf(), + personas = persistentListOf(), + hasHiddenEntities = true // TODO fix the message + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.PASSWORD, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Gate13", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.PASSWORD, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf(), + hasHiddenEntities = false + ) + ), + onPasswordFactorSourceClick = {}, + onAddPasswordClick = {}, + onBackClick = {}, + onInfoClick = {} + ) + } +} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsViewModel.kt new file mode 100644 index 0000000000..082d115f70 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsViewModel.kt @@ -0,0 +1,103 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.password + +import androidx.lifecycle.viewModelScope +import com.babylon.wallet.android.di.coroutines.DefaultDispatcher +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.presentation.common.OneOffEvent +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.presentation.ui.model.factors.FactorSourceCard +import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceStatusMessage +import com.babylon.wallet.android.utils.relativeTimeFormatted +import com.radixdlt.sargon.Account +import com.radixdlt.sargon.FactorSource +import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.PasswordFactorSource +import com.radixdlt.sargon.Persona +import com.radixdlt.sargon.ProfileToCheck +import com.radixdlt.sargon.extensions.asGeneral +import com.radixdlt.sargon.extensions.kind +import com.radixdlt.sargon.os.SargonOsManager +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class PasswordsViewModel @Inject constructor( + getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + private val sargonOsManager: SargonOsManager, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher +) : StateViewModel(), + OneOffEventHandler by OneOffEventHandlerImpl() { + + override fun initialState(): State = State() + + init { + getFactorSourcesUseCaseOfType() + .map { passwordFactorSource -> + val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( + factorSource = FactorSource.Password(passwordFactorSource.value), + profileToCheck = ProfileToCheck.Current + ) + + val factorSourceCard = passwordFactorSource.value.toFactorSourceCard( + messages = persistentListOf(), + accounts = entitiesLinkedToDeviceFactorSource.accounts.toPersistentList(), + personas = entitiesLinkedToDeviceFactorSource.personas.toPersistentList(), + hasHiddenEntities = entitiesLinkedToDeviceFactorSource.hiddenAccounts.isNotEmpty() || + entitiesLinkedToDeviceFactorSource.hiddenPersonas.isNotEmpty() + ) + + _state.update { state -> + state.copy(passwordFactorSources = state.passwordFactorSources.add(factorSourceCard)) + } + } + .flowOn(defaultDispatcher) + .launchIn(viewModelScope) + } + + private fun PasswordFactorSource.toFactorSourceCard( + includeDescription: Boolean = false, + messages: PersistentList = persistentListOf(), + accounts: PersistentList = persistentListOf(), + personas: PersistentList = persistentListOf(), + hasHiddenEntities: Boolean + ): FactorSourceCard { + return FactorSourceCard( + id = id.asGeneral(), + name = hint.label, + includeDescription = includeDescription, + lastUsedOn = common.lastUsedOn.relativeTimeFormatted(), + kind = kind, + messages = messages, + accounts = accounts, + personas = personas, + hasHiddenEntities = hasHiddenEntities + ) + } + + fun onPasswordFactorSourceClick(factorSourceId: FactorSourceId) { + viewModelScope.launch { + sendEvent(Event.NavigateToPasswordFactorSourceDetails(factorSourceId)) + } + } + + data class State( + val passwordFactorSources: PersistentList = persistentListOf(), + ) : UiState + + sealed interface Event : OneOffEvent { + + data class NavigateToPasswordFactorSourceDetails(val factorSourceId: FactorSourceId) : Event + } +} From ed5fed4b1cebac34dae6ed54973f85ceb0c17a48 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:32:09 +0200 Subject: [PATCH 11/16] added MnemonicsScreen --- .../securityfactors/mnemonic/MnemonicsNav.kt | 50 ++++++ .../mnemonic/MnemonicsScreen.kt | 161 ++++++++++++++++++ .../mnemonic/MnemonicsViewModel.kt | 103 +++++++++++ 3 files changed, 314 insertions(+) create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsNav.kt create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt create mode 100644 app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsNav.kt new file mode 100644 index 0000000000..345b54684c --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsNav.kt @@ -0,0 +1,50 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.mnemonic + +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem +import com.radixdlt.sargon.FactorSourceId + +private const val ROUTE_MNEMONICS_SCREEN = "route_mnemonics_screen" + +fun NavController.mnemonics() { + navigate(ROUTE_MNEMONICS_SCREEN) { + launchSingleTop = true + } +} + +fun NavGraphBuilder.mnemonics( + onNavigateToMnemonicFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, + onNavigateToAddMnemonic: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + composable( + route = ROUTE_MNEMONICS_SCREEN, + enterTransition = { + slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Left) + }, + exitTransition = { + ExitTransition.None + }, + popEnterTransition = { + EnterTransition.None + }, + popExitTransition = { + slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Right) + } + ) { + MnemonicsScreen( + viewModel = hiltViewModel(), + onNavigateToMnemonicFactorSourceDetails = onNavigateToMnemonicFactorSourceDetails, + onNavigateToAddMnemonic = onNavigateToAddMnemonic, + onInfoClick = onInfoClick, + onBackClick = onBackClick + ) + } +} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt new file mode 100644 index 0000000000..e5020cced2 --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt @@ -0,0 +1,161 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.mnemonic + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +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.tooling.preview.Preview +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.babylon.wallet.android.R +import com.babylon.wallet.android.designsystem.theme.RadixTheme +import com.babylon.wallet.android.designsystem.theme.RadixWalletTheme +import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.composables.FactorSourcesList +import com.babylon.wallet.android.presentation.ui.composables.RadixCenteredTopAppBar +import com.babylon.wallet.android.presentation.ui.composables.statusBarsAndBanner +import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceCard +import com.radixdlt.sargon.Account +import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.FactorSourceKind +import com.radixdlt.sargon.MnemonicWithPassphrase +import com.radixdlt.sargon.annotation.UsesSampleValues +import com.radixdlt.sargon.extensions.init +import com.radixdlt.sargon.samples.sample +import com.radixdlt.sargon.samples.sampleMainnet +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf + +@Composable +fun MnemonicsScreen( + viewModel: MnemonicsViewModel, + onNavigateToMnemonicFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, + onNavigateToAddMnemonic: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + val state by viewModel.state.collectAsStateWithLifecycle() + + LaunchedEffect(Unit) { + viewModel.oneOffEvent.collect { event -> + when (event) { + is MnemonicsViewModel.Event.NavigateToMnemonicFactorSourceDetails -> { + onNavigateToMnemonicFactorSourceDetails(event.factorSourceId) + } + } + } + } + + MnemonicsContent( + mnemonicFactorSources = state.mnemonicFactorSources, + onMnemonicFactorSourceClick = viewModel::onMnemonicFactorSourceClick, + onAddMnemonicClick = onNavigateToAddMnemonic, + onInfoClick = onInfoClick, + onBackClick = onBackClick + ) +} + +@Composable +private fun MnemonicsContent( + modifier: Modifier = Modifier, + mnemonicFactorSources: PersistentList, + onMnemonicFactorSourceClick: (FactorSourceId) -> Unit, + onAddMnemonicClick: () -> Unit, + onInfoClick: (GlossaryItem) -> Unit, + onBackClick: () -> Unit +) { + Scaffold( + modifier = modifier.fillMaxSize(), + topBar = { + RadixCenteredTopAppBar( + title = stringResource(R.string.factorSources_card_passphraseTitle), + onBackClick = onBackClick, + windowInsets = WindowInsets.statusBarsAndBanner + ) + }, + containerColor = RadixTheme.colors.gray5 + ) { padding -> + Column( + modifier = Modifier.padding(padding), + horizontalAlignment = Alignment.Start + ) { + HorizontalDivider(color = RadixTheme.colors.gray4) + + FactorSourcesList( + mainFactorSource = null, + factorSources = mnemonicFactorSources, + factorSourceDescriptionText = R.string.factorSources_card_passphraseDescription, + addFactorSourceButtonTitle = R.string.factorSources_list_passphraseAdd, + glossaryItem = GlossaryItem.mnemonic, + onFactorSourceClick = onMnemonicFactorSourceClick, + onAddFactorSourceClick = onAddMnemonicClick, + onInfoClick = onInfoClick + ) + } + } +} + +@UsesSampleValues +@Preview(showBackground = true) +@Composable +private fun MnemonicsScreenPreview() { + RadixWalletTheme { + MnemonicsContent( + mnemonicFactorSources = persistentListOf( + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.OFF_DEVICE_MNEMONIC, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Panathinaikos", + includeDescription = false, + lastUsedOn = "Today", + kind = FactorSourceKind.OFF_DEVICE_MNEMONIC, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf(), + hasHiddenEntities = false + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.OFF_DEVICE_MNEMONIC, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Gate 13", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.OFF_DEVICE_MNEMONIC, + messages = persistentListOf(), + accounts = persistentListOf(), + personas = persistentListOf(), + hasHiddenEntities = true // TODO fix the message + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.OFF_DEVICE_MNEMONIC, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "Gate13", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.OFF_DEVICE_MNEMONIC, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf(), + hasHiddenEntities = false + ) + ), + onMnemonicFactorSourceClick = {}, + onAddMnemonicClick = {}, + onBackClick = {}, + onInfoClick = {} + ) + } +} diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt new file mode 100644 index 0000000000..405a6b332e --- /dev/null +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt @@ -0,0 +1,103 @@ +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.mnemonic + +import androidx.lifecycle.viewModelScope +import com.babylon.wallet.android.di.coroutines.DefaultDispatcher +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.presentation.common.OneOffEvent +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.presentation.ui.model.factors.FactorSourceCard +import com.babylon.wallet.android.presentation.ui.model.factors.FactorSourceStatusMessage +import com.babylon.wallet.android.utils.relativeTimeFormatted +import com.radixdlt.sargon.Account +import com.radixdlt.sargon.FactorSource +import com.radixdlt.sargon.FactorSourceId +import com.radixdlt.sargon.OffDeviceMnemonicFactorSource +import com.radixdlt.sargon.Persona +import com.radixdlt.sargon.ProfileToCheck +import com.radixdlt.sargon.extensions.asGeneral +import com.radixdlt.sargon.extensions.kind +import com.radixdlt.sargon.os.SargonOsManager +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class MnemonicsViewModel @Inject constructor( + getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + private val sargonOsManager: SargonOsManager, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher +) : StateViewModel(), + OneOffEventHandler by OneOffEventHandlerImpl() { + + override fun initialState(): State = State() + + init { + getFactorSourcesUseCaseOfType() + .map { offDeviceMnemonic -> + val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( + factorSource = FactorSource.OffDeviceMnemonic(offDeviceMnemonic.value), + profileToCheck = ProfileToCheck.Current + ) + + val factorSourceCard = offDeviceMnemonic.value.toFactorSourceCard( + messages = persistentListOf(), + accounts = entitiesLinkedToDeviceFactorSource.accounts.toPersistentList(), + personas = entitiesLinkedToDeviceFactorSource.personas.toPersistentList(), + hasHiddenEntities = entitiesLinkedToDeviceFactorSource.hiddenAccounts.isNotEmpty() || + entitiesLinkedToDeviceFactorSource.hiddenPersonas.isNotEmpty() + ) + + _state.update { state -> + state.copy(mnemonicFactorSources = state.mnemonicFactorSources.add(factorSourceCard)) + } + } + .flowOn(defaultDispatcher) + .launchIn(viewModelScope) + } + + private fun OffDeviceMnemonicFactorSource.toFactorSourceCard( + includeDescription: Boolean = false, + messages: PersistentList = persistentListOf(), + accounts: PersistentList = persistentListOf(), + personas: PersistentList = persistentListOf(), + hasHiddenEntities: Boolean + ): FactorSourceCard { + return FactorSourceCard( + id = id.asGeneral(), + name = hint.label.value, + includeDescription = includeDescription, + lastUsedOn = common.lastUsedOn.relativeTimeFormatted(), + kind = kind, + messages = messages, + accounts = accounts, + personas = personas, + hasHiddenEntities = hasHiddenEntities + ) + } + + fun onMnemonicFactorSourceClick(factorSourceId: FactorSourceId) { + viewModelScope.launch { + sendEvent(Event.NavigateToMnemonicFactorSourceDetails(factorSourceId)) + } + } + + data class State( + val mnemonicFactorSources: PersistentList = persistentListOf(), + ) : UiState + + sealed interface Event : OneOffEvent { + + data class NavigateToMnemonicFactorSourceDetails(val factorSourceId: FactorSourceId) : Event + } +} From 0107943bdb6a1b333ed4207578dd7b206846fceb Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:32:43 +0200 Subject: [PATCH 12/16] updated SecurityCenterNav --- .../securitycenter/SecurityCenterNav.kt | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt index 000e90c425..2feab78fa0 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt @@ -14,9 +14,12 @@ import com.babylon.wallet.android.presentation.onboarding.restore.mnemonics.Rest import com.babylon.wallet.android.presentation.onboarding.restore.mnemonics.restoreMnemonics import com.babylon.wallet.android.presentation.settings.SettingsItem import com.babylon.wallet.android.presentation.settings.securitycenter.backup.backupScreen -import com.babylon.wallet.android.presentation.settings.securitycenter.ledgerhardwarewallets.ledgerHardwareWalletsScreen +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.arculuscard.arculusCards import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.biometricspin.biometricsPin -import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.securityFactors +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.ledgerDevices +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.mnemonic.mnemonics +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.password.passwords +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.securityFactorTypes import com.babylon.wallet.android.presentation.settings.securitycenter.securityshields.onboarding.securityShieldOnboardingScreen import com.babylon.wallet.android.presentation.settings.securitycenter.securityshields.securityShieldsNavGraph import com.babylon.wallet.android.presentation.settings.securitycenter.securityshields.securityShieldsScreen @@ -90,49 +93,62 @@ fun NavGraphBuilder.securityCenterNavGraph( }, onSecurityFactorTypeClick = { item -> when (item) { - is SettingsItem.SecurityFactorsSettingsItem.LedgerNano -> { - navController.ledgerHardwareWalletsScreen() - } - is SettingsItem.SecurityFactorsSettingsItem.BiometricsPin -> { navController.biometricsPin() } + is SettingsItem.SecurityFactorsSettingsItem.LedgerNano -> { + navController.ledgerDevices() + } + SettingsItem.SecurityFactorsSettingsItem.ArculusCard -> { - // TODO + navController.arculusCards() } - SettingsItem.SecurityFactorsSettingsItem.Passphrase -> { - // TODO + SettingsItem.SecurityFactorsSettingsItem.Mnemonic -> { + navController.mnemonics() } SettingsItem.SecurityFactorsSettingsItem.Password -> { - // TODO + navController.passwords() } } } ) biometricsPin( - onBackClick = { navController.popBackStack() }, - onNavigateToDeviceFactorSourceDetails = {}, // TODO next task + onNavigateToDeviceFactorSourceDetails = { }, // TODO next task onNavigateToAddBiometricPin = { }, // TODO next task - onInfoClick = { glossaryItem -> - navController.infoDialog(glossaryItem) - } + onInfoClick = { glossaryItem -> navController.infoDialog(glossaryItem) }, + onBackClick = { navController.popBackStack() } ) - seedPhrases( + ledgerDevices( + onNavigateToLedgerFactorSourceDetails = { }, // TODO next task + onInfoClick = { glossaryItem -> navController.infoDialog(glossaryItem) }, + onBackClick = { navController.navigateUp() } + ) + arculusCards( + onNavigateToArculusFactorSourceDetails = { }, // TODO next task + onNavigateToAddArculusCard = { }, + onInfoClick = { glossaryItem -> navController.infoDialog(glossaryItem) }, + onBackClick = { navController.navigateUp() } + ) + mnemonics( + onNavigateToMnemonicFactorSourceDetails = { }, // TODO next task + onNavigateToAddMnemonic = { }, + onInfoClick = { glossaryItem -> navController.infoDialog(glossaryItem) }, + onBackClick = { navController.navigateUp() } + ) + passwords( + onNavigateToPasswordFactorSourceDetails = { }, // TODO next task + onNavigateToAddPassword = { }, + onInfoClick = { glossaryItem -> navController.infoDialog(glossaryItem) }, + onBackClick = { navController.navigateUp() } + ) + seedPhrases( // TODO remove it later onBackClick = { navController.popBackStack() }, onNavigateToRecoverMnemonic = { navController.restoreMnemonics(args = RestoreMnemonicsArgs(requestSource = RestoreMnemonicsRequestSource.Settings)) }, onNavigateToSeedPhrase = { navController.revealSeedPhrase(it) } ) - ledgerHardwareWalletsScreen( - onInfoClick = { glossaryItem -> - navController.infoDialog(glossaryItem) - }, - onBackClick = { - navController.navigateUp() - } - ) securityShieldsNavGraph(navController) } } From 7cca95a8eb34783af117f562a959c6ffed61f6cd Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 12:45:22 +0200 Subject: [PATCH 13/16] minor --- .../arculuscard/ArculusCardsScreen.kt | 2 +- .../biometricspin/BiometricsPinScreen.kt | 22 ++++++++++++++----- .../ledgerdevice/LedgerDevicesScreen.kt | 2 +- .../mnemonic/MnemonicsScreen.kt | 2 +- .../password/PasswordsScreen.kt | 2 +- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsScreen.kt index b8c777d573..f29f7821dc 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsScreen.kt @@ -135,7 +135,7 @@ fun ArculusCardsScreenPreview() { messages = persistentListOf(), accounts = persistentListOf(), personas = persistentListOf(), - hasHiddenEntities = true // TODO fix the message + hasHiddenEntities = false ), FactorSourceCard( id = FactorSourceId.Hash.init( diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt index 0354bf018c..8a1107d7da 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt @@ -122,9 +122,7 @@ private fun BiometricsPinPreview() { lastUsedOn = "Today", kind = FactorSourceKind.DEVICE, messages = persistentListOf(FactorSourceStatusMessage.NoSecurityIssues), - accounts = persistentListOf( - Account.sampleMainnet() - ), + accounts = persistentListOf(Account.sampleMainnet()), personas = persistentListOf( Persona.sampleMainnet(), Persona.sampleStokenet() @@ -142,14 +140,26 @@ private fun BiometricsPinPreview() { lastUsedOn = "Today", kind = FactorSourceKind.DEVICE, messages = persistentListOf(FactorSourceStatusMessage.SecurityPrompt.RecoveryRequired), - accounts = persistentListOf( - Account.sampleMainnet() - ), + accounts = persistentListOf(Account.sampleMainnet()), personas = persistentListOf( Persona.sampleMainnet(), Persona.sampleStokenet() ), hasHiddenEntities = true + ), + FactorSourceCard( + id = FactorSourceId.Hash.init( + kind = FactorSourceKind.DEVICE, + mnemonicWithPassphrase = MnemonicWithPassphrase.sample(), + ), + name = "XXX phone", + includeDescription = false, + lastUsedOn = "Last year", + kind = FactorSourceKind.DEVICE, + messages = persistentListOf(), + accounts = persistentListOf(Account.sampleMainnet()), + personas = persistentListOf(), + hasHiddenEntities = true // TODO fix the message ) ) ), diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesScreen.kt index 9577e12901..35bf6f6687 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesScreen.kt @@ -258,7 +258,7 @@ fun LedgerDevicesScreenPreview() { messages = persistentListOf(), accounts = persistentListOf(), personas = persistentListOf(), - hasHiddenEntities = true // TODO fix the message + hasHiddenEntities = false ), FactorSourceCard( id = FactorSourceId.Hash.init( diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt index e5020cced2..1522309848 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt @@ -135,7 +135,7 @@ private fun MnemonicsScreenPreview() { messages = persistentListOf(), accounts = persistentListOf(), personas = persistentListOf(), - hasHiddenEntities = true // TODO fix the message + hasHiddenEntities = false ), FactorSourceCard( id = FactorSourceId.Hash.init( diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsScreen.kt index 741331e7bb..5587938a97 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsScreen.kt @@ -135,7 +135,7 @@ private fun PasswordsScreenPreview() { messages = persistentListOf(), accounts = persistentListOf(), personas = persistentListOf(), - hasHiddenEntities = true // TODO fix the message + hasHiddenEntities = false ), FactorSourceCard( id = FactorSourceId.Hash.init( From 1591fc8056b08938aa45ad28816274338cd0a8b3 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 13:13:50 +0200 Subject: [PATCH 14/16] fixed linked hidden entities in FactorSourceCardView --- .../biometricspin/BiometricsPinScreen.kt | 4 +- .../composables/card/FactorSourceCardView.kt | 51 +++++++++++++++---- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt index 8a1107d7da..42bb0c6835 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinScreen.kt @@ -157,9 +157,9 @@ private fun BiometricsPinPreview() { lastUsedOn = "Last year", kind = FactorSourceKind.DEVICE, messages = persistentListOf(), - accounts = persistentListOf(Account.sampleMainnet()), + accounts = persistentListOf(), personas = persistentListOf(), - hasHiddenEntities = true // TODO fix the message + hasHiddenEntities = true ) ) ), 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 7289db49bf..2daa66f947 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 @@ -230,40 +230,40 @@ private fun LinkedEntitiesView( personas: PersistentList, hasHiddenEntities: Boolean ) { - if (accounts.isEmpty() && personas.isEmpty()) { + if (accounts.isEmpty() && personas.isEmpty() && !hasHiddenEntities) { return } val accountsText = when { - accounts.isEmpty() -> null + accounts.isEmpty() -> stringResource(id = R.string.factorSources_card_accountPlural, 0) accounts.size == 1 -> stringResource(id = R.string.factorSources_card_accountSingular) else -> stringResource(id = R.string.factorSources_card_accountPlural, accounts.size) } val personasText = when { - personas.isEmpty() -> null + personas.isEmpty() -> stringResource(id = R.string.factorSources_card_personaPlural, 0) personas.size == 1 -> stringResource(id = R.string.factorSources_card_personaSingular) else -> stringResource(id = R.string.factorSources_card_personaPlural, personas.size) } val linkedText = if (hasHiddenEntities) { when { - accountsText != null && personasText != null -> stringResource( + accounts.isNotEmpty() && personas.isNotEmpty() -> stringResource( id = R.string.factorSources_card_linkedAccountsAndPersonasSomeHidden, accountsText, personasText ) - accountsText != null -> stringResource(id = R.string.factorSources_card_linkedAccountsOrPersonasSomeHidden, accountsText) - personasText != null -> stringResource(id = R.string.factorSources_card_linkedAccountsOrPersonasSomeHidden, personasText) - else -> "" + accounts.isNotEmpty() -> stringResource(id = R.string.factorSources_card_linkedAccountsOrPersonasSomeHidden, accountsText) + personas.isNotEmpty() -> stringResource(id = R.string.factorSources_card_linkedAccountsOrPersonasSomeHidden, personasText) + else -> stringResource(id = R.string.factorSources_card_linkedAccountsAndPersonasSomeHidden, accountsText, personasText) } } else { when { - accountsText != null && personasText != null -> stringResource( + accounts.isNotEmpty() && personas.isNotEmpty() -> stringResource( id = R.string.factorSources_card_linkedAccountsAndPersonas, accountsText, personasText ) - accountsText != null -> stringResource(id = R.string.factorSources_card_linkedAccountsOrPersonas, accountsText) - personasText != null -> stringResource(id = R.string.factorSources_card_linkedAccountsOrPersonas, personasText) + accounts.isNotEmpty() -> stringResource(id = R.string.factorSources_card_linkedAccountsOrPersonas, accountsText) + personas.isNotEmpty() -> stringResource(id = R.string.factorSources_card_linkedAccountsOrPersonas, personasText) else -> "" } } @@ -504,6 +504,37 @@ class FactorSourceCardPreviewProvider : PreviewParameterProvider Date: Fri, 10 Jan 2025 13:26:01 +0200 Subject: [PATCH 15/16] fixed name --- ...cesUseCaseOfType.kt => GetFactorSourcesOfTypeUseCase.kt} | 2 +- .../securityfactors/arculuscard/ArculusCardsViewModel.kt | 6 +++--- .../securityfactors/biometricspin/BiometricsPinViewModel.kt | 6 +++--- .../securityfactors/ledgerdevice/LedgerDevicesViewModel.kt | 6 +++--- .../securityfactors/mnemonic/MnemonicsViewModel.kt | 6 +++--- .../securityfactors/password/PasswordsViewModel.kt | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) rename app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/{GetFactorSourcesUseCaseOfType.kt => GetFactorSourcesOfTypeUseCase.kt} (92%) diff --git a/app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesUseCaseOfType.kt b/app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesOfTypeUseCase.kt similarity index 92% rename from app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesUseCaseOfType.kt rename to app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesOfTypeUseCase.kt index 060ca3b7b3..39ead486a5 100644 --- a/app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesUseCaseOfType.kt +++ b/app/src/main/java/com/babylon/wallet/android/domain/usecases/factorsources/GetFactorSourcesOfTypeUseCase.kt @@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.flatMapConcat import rdx.works.profile.domain.GetProfileUseCase import javax.inject.Inject -class GetFactorSourcesUseCaseOfType @Inject constructor( +class GetFactorSourcesOfTypeUseCase @Inject constructor( val getProfileUseCase: GetProfileUseCase ) { diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsViewModel.kt index 823907fe77..9d93698cbd 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/arculuscard/ArculusCardsViewModel.kt @@ -2,7 +2,7 @@ package com.babylon.wallet.android.presentation.settings.securitycenter.security import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.di.coroutines.DefaultDispatcher -import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesOfTypeUseCase import com.babylon.wallet.android.presentation.common.OneOffEvent import com.babylon.wallet.android.presentation.common.OneOffEventHandler import com.babylon.wallet.android.presentation.common.OneOffEventHandlerImpl @@ -34,7 +34,7 @@ import javax.inject.Inject @HiltViewModel class ArculusCardsViewModel @Inject constructor( - getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + getFactorSourcesOfTypeUseCase: GetFactorSourcesOfTypeUseCase, private val sargonOsManager: SargonOsManager, @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher ) : StateViewModel(), @@ -43,7 +43,7 @@ class ArculusCardsViewModel @Inject constructor( override fun initialState(): State = State() init { - getFactorSourcesUseCaseOfType() + getFactorSourcesOfTypeUseCase() .map { arculusFactorSource -> val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( factorSource = FactorSource.ArculusCard(arculusFactorSource.value), diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinViewModel.kt index 268b370ec9..6f92f49c59 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/biometricspin/BiometricsPinViewModel.kt @@ -2,7 +2,7 @@ package com.babylon.wallet.android.presentation.settings.securitycenter.security import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.di.coroutines.DefaultDispatcher -import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesOfTypeUseCase import com.babylon.wallet.android.presentation.common.OneOffEvent import com.babylon.wallet.android.presentation.common.OneOffEventHandler import com.babylon.wallet.android.presentation.common.OneOffEventHandlerImpl @@ -40,7 +40,7 @@ import javax.inject.Inject @HiltViewModel class BiometricsPinViewModel @Inject constructor( - getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + getFactorSourcesOfTypeUseCase: GetFactorSourcesOfTypeUseCase, private val sargonOsManager: SargonOsManager, private val preferencesManager: PreferencesManager, @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher @@ -50,7 +50,7 @@ class BiometricsPinViewModel @Inject constructor( override fun initialState(): State = State() init { - getFactorSourcesUseCaseOfType() + getFactorSourcesOfTypeUseCase() .map { deviceFactorSource -> val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( factorSource = FactorSource.Device(deviceFactorSource.value), diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesViewModel.kt index c15fda6833..83bcc2710c 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/ledgerdevice/LedgerDevicesViewModel.kt @@ -4,7 +4,7 @@ import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.data.dapp.LedgerMessenger import com.babylon.wallet.android.data.repository.p2plink.P2PLinksRepository import com.babylon.wallet.android.di.coroutines.DefaultDispatcher -import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesOfTypeUseCase import com.babylon.wallet.android.presentation.common.OneOffEvent import com.babylon.wallet.android.presentation.common.OneOffEventHandler import com.babylon.wallet.android.presentation.common.OneOffEventHandlerImpl @@ -37,7 +37,7 @@ import javax.inject.Inject @HiltViewModel class LedgerDevicesViewModel @Inject constructor( - getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + getFactorSourcesOfTypeUseCase: GetFactorSourcesOfTypeUseCase, private val sargonOsManager: SargonOsManager, private val ledgerMessenger: LedgerMessenger, private val p2PLinksRepository: P2PLinksRepository, @@ -48,7 +48,7 @@ class LedgerDevicesViewModel @Inject constructor( override fun initialState(): State = State() init { - getFactorSourcesUseCaseOfType() + getFactorSourcesOfTypeUseCase() .map { ledgerFactorSource -> val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( factorSource = FactorSource.Ledger(ledgerFactorSource.value), diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt index 405a6b332e..49010423ee 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt @@ -2,7 +2,7 @@ package com.babylon.wallet.android.presentation.settings.securitycenter.security import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.di.coroutines.DefaultDispatcher -import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesOfTypeUseCase import com.babylon.wallet.android.presentation.common.OneOffEvent import com.babylon.wallet.android.presentation.common.OneOffEventHandler import com.babylon.wallet.android.presentation.common.OneOffEventHandlerImpl @@ -34,7 +34,7 @@ import javax.inject.Inject @HiltViewModel class MnemonicsViewModel @Inject constructor( - getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + getFactorSourcesOfTypeUseCase: GetFactorSourcesOfTypeUseCase, private val sargonOsManager: SargonOsManager, @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher ) : StateViewModel(), @@ -43,7 +43,7 @@ class MnemonicsViewModel @Inject constructor( override fun initialState(): State = State() init { - getFactorSourcesUseCaseOfType() + getFactorSourcesOfTypeUseCase() .map { offDeviceMnemonic -> val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( factorSource = FactorSource.OffDeviceMnemonic(offDeviceMnemonic.value), diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsViewModel.kt index 082d115f70..3c2bcc3592 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/password/PasswordsViewModel.kt @@ -2,7 +2,7 @@ package com.babylon.wallet.android.presentation.settings.securitycenter.security import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.di.coroutines.DefaultDispatcher -import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesUseCaseOfType +import com.babylon.wallet.android.domain.usecases.factorsources.GetFactorSourcesOfTypeUseCase import com.babylon.wallet.android.presentation.common.OneOffEvent import com.babylon.wallet.android.presentation.common.OneOffEventHandler import com.babylon.wallet.android.presentation.common.OneOffEventHandlerImpl @@ -34,7 +34,7 @@ import javax.inject.Inject @HiltViewModel class PasswordsViewModel @Inject constructor( - getFactorSourcesUseCaseOfType: GetFactorSourcesUseCaseOfType, + getFactorSourcesOfTypeUseCase: GetFactorSourcesOfTypeUseCase, private val sargonOsManager: SargonOsManager, @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher ) : StateViewModel(), @@ -43,7 +43,7 @@ class PasswordsViewModel @Inject constructor( override fun initialState(): State = State() init { - getFactorSourcesUseCaseOfType() + getFactorSourcesOfTypeUseCase() .map { passwordFactorSource -> val entitiesLinkedToDeviceFactorSource = sargonOsManager.sargonOs.entitiesLinkedToFactorSource( factorSource = FactorSource.Password(passwordFactorSource.value), From 349100bbe2f4e77624095e8c23e21d12e0438446 Mon Sep 17 00:00:00 2001 From: "giannis.tsepas" Date: Fri, 10 Jan 2025 16:27:48 +0200 Subject: [PATCH 16/16] renamed mnemonic to offdevicemnemonic --- .../presentation/dialogs/info/GlossaryItem.kt | 2 +- .../presentation/dialogs/info/InfoDialog.kt | 2 +- .../presentation/settings/SettingsItem.kt | 8 ++-- .../securitycenter/SecurityCenterNav.kt | 12 ++--- .../ChooseFactorSourceViewModel.kt | 2 +- .../composables/FactorSourcesList.kt | 2 +- .../OffDeviceMnemonicsNav.kt} | 22 ++++----- .../OffDeviceMnemonicsScreen.kt} | 48 +++++++++---------- .../OffDeviceMnemonicsViewModel.kt} | 18 +++---- .../SecurityFactorTypesListView.kt | 2 +- 10 files changed, 59 insertions(+), 59 deletions(-) rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/{mnemonic/MnemonicsNav.kt => offdevicemnemonic/OffDeviceMnemonicsNav.kt} (63%) rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/{mnemonic/MnemonicsScreen.kt => offdevicemnemonic/OffDeviceMnemonicsScreen.kt} (78%) rename app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/{mnemonic/MnemonicsViewModel.kt => offdevicemnemonic/OffDeviceMnemonicsViewModel.kt} (84%) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/GlossaryItem.kt b/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/GlossaryItem.kt index 7cf74f26fb..c933ba65fb 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/GlossaryItem.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/GlossaryItem.kt @@ -40,5 +40,5 @@ enum class GlossaryItem { arculus, // TODO pending the right glossary item ledgerNano, // TODO pending the right glossary item passwords, // TODO pending the right glossary item - mnemonic, // TODO pending the right glossary item + offDeviceMnemonic, // TODO pending the right glossary item } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/InfoDialog.kt b/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/InfoDialog.kt index 0188fc563c..057f6c75a2 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/InfoDialog.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/dialogs/info/InfoDialog.kt @@ -232,7 +232,7 @@ private fun GlossaryItem.resolveTextFromGlossaryItem() = when (this) { GlossaryItem.arculus -> stringResource(id = R.string.infoLink_glossary_arculus) GlossaryItem.ledgerNano -> stringResource(id = R.string.infoLink_glossary_ledgernano) GlossaryItem.passwords -> stringResource(id = R.string.infoLink_glossary_passwords) - GlossaryItem.mnemonic -> stringResource(id = R.string.infoLink_glossary_passphrases) + GlossaryItem.offDeviceMnemonic -> stringResource(id = R.string.infoLink_glossary_passphrases) GlossaryItem.emergencyFallback -> "" // TODO crowdin } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/SettingsItem.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/SettingsItem.kt index 7aac0ae1ef..b65367891a 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/SettingsItem.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/SettingsItem.kt @@ -89,7 +89,7 @@ sealed interface SettingsItem { data object LedgerNano : SecurityFactorsSettingsItem data object ArculusCard : SecurityFactorsSettingsItem data object Password : SecurityFactorsSettingsItem - data object Mnemonic : SecurityFactorsSettingsItem + data object OffDeviceMnemonic : SecurityFactorsSettingsItem @StringRes fun titleRes(): Int { @@ -97,7 +97,7 @@ sealed interface SettingsItem { is BiometricsPin -> R.string.factorSources_card_deviceTitle LedgerNano -> R.string.factorSources_card_ledgerTitle ArculusCard -> R.string.factorSources_card_arculusCardTitle - Mnemonic -> R.string.factorSources_card_passphraseTitle + OffDeviceMnemonic -> R.string.factorSources_card_passphraseTitle Password -> R.string.factorSources_card_passwordTitle } } @@ -108,7 +108,7 @@ sealed interface SettingsItem { is BiometricsPin -> R.string.factorSources_card_deviceDescription LedgerNano -> R.string.factorSources_card_ledgerDescription ArculusCard -> R.string.factorSources_card_arculusCardDescription - Mnemonic -> R.string.factorSources_card_passphraseDescription + OffDeviceMnemonic -> R.string.factorSources_card_passphraseDescription Password -> R.string.factorSources_card_passwordDescription } } @@ -120,7 +120,7 @@ sealed interface SettingsItem { LedgerNano -> DSR.ic_ledger_nano ArculusCard -> DSR.ic_arculus_card Password -> DSR.ic_password - Mnemonic -> DSR.ic_passphrase + OffDeviceMnemonic -> DSR.ic_passphrase } } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt index 2feab78fa0..fc2733aad6 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/SecurityCenterNav.kt @@ -17,7 +17,7 @@ import com.babylon.wallet.android.presentation.settings.securitycenter.backup.ba import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.arculuscard.arculusCards import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.biometricspin.biometricsPin import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.ledgerdevice.ledgerDevices -import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.mnemonic.mnemonics +import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.offdevicemnemonic.offDeviceMnemonics import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.password.passwords import com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.securityFactorTypes import com.babylon.wallet.android.presentation.settings.securitycenter.securityshields.onboarding.securityShieldOnboardingScreen @@ -104,8 +104,8 @@ fun NavGraphBuilder.securityCenterNavGraph( SettingsItem.SecurityFactorsSettingsItem.ArculusCard -> { navController.arculusCards() } - SettingsItem.SecurityFactorsSettingsItem.Mnemonic -> { - navController.mnemonics() + SettingsItem.SecurityFactorsSettingsItem.OffDeviceMnemonic -> { + navController.offDeviceMnemonics() } SettingsItem.SecurityFactorsSettingsItem.Password -> { navController.passwords() @@ -130,9 +130,9 @@ fun NavGraphBuilder.securityCenterNavGraph( onInfoClick = { glossaryItem -> navController.infoDialog(glossaryItem) }, onBackClick = { navController.navigateUp() } ) - mnemonics( - onNavigateToMnemonicFactorSourceDetails = { }, // TODO next task - onNavigateToAddMnemonic = { }, + offDeviceMnemonics( + onNavigateToOffDeviceMnemonicFactorSourceDetails = { }, // TODO next task + onNavigateToOffDeviceAddMnemonic = { }, onInfoClick = { glossaryItem -> navController.infoDialog(glossaryItem) }, onBackClick = { navController.navigateUp() } ) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceViewModel.kt index dc3272a954..b2b2fae3e8 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/choosefactor/ChooseFactorSourceViewModel.kt @@ -73,7 +73,7 @@ class ChooseFactorSourceViewModel @Inject constructor( SecurityFactorsSettingsItem.ArculusCard -> State.Page.ArculusCard.ordinal is SecurityFactorsSettingsItem.BiometricsPin -> State.Page.BiometricsPin.ordinal SecurityFactorsSettingsItem.LedgerNano -> State.Page.LedgerNano.ordinal - SecurityFactorsSettingsItem.Mnemonic -> State.Page.Passphrase.ordinal + SecurityFactorsSettingsItem.OffDeviceMnemonic -> State.Page.Passphrase.ordinal SecurityFactorsSettingsItem.Password -> State.Page.Password.ordinal } ) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/composables/FactorSourcesList.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/composables/FactorSourcesList.kt index 4c2b942145..c5792190f7 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/composables/FactorSourcesList.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/composables/FactorSourcesList.kt @@ -120,7 +120,7 @@ fun FactorSourcesList( GlossaryItem.arculus -> stringResource(R.string.infoLink_title_arculus) GlossaryItem.ledgerNano -> stringResource(R.string.infoLink_title_ledgernano) GlossaryItem.passwords -> stringResource(R.string.infoLink_title_passwords) - GlossaryItem.mnemonic -> stringResource(R.string.infoLink_title_passphrases) + GlossaryItem.offDeviceMnemonic -> stringResource(R.string.infoLink_title_passphrases) else -> stringResource(R.string.empty) }, onClick = { diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsNav.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsNav.kt similarity index 63% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsNav.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsNav.kt index 345b54684c..2f3983c762 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsNav.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsNav.kt @@ -1,4 +1,4 @@ -package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.mnemonic +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.offdevicemnemonic import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.EnterTransition @@ -10,22 +10,22 @@ import androidx.navigation.compose.composable import com.babylon.wallet.android.presentation.dialogs.info.GlossaryItem import com.radixdlt.sargon.FactorSourceId -private const val ROUTE_MNEMONICS_SCREEN = "route_mnemonics_screen" +private const val ROUTE_OFF_DEVICE_MNEMONICS_SCREEN = "route_off_device_mnemonics_screen" -fun NavController.mnemonics() { - navigate(ROUTE_MNEMONICS_SCREEN) { +fun NavController.offDeviceMnemonics() { + navigate(ROUTE_OFF_DEVICE_MNEMONICS_SCREEN) { launchSingleTop = true } } -fun NavGraphBuilder.mnemonics( - onNavigateToMnemonicFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, - onNavigateToAddMnemonic: () -> Unit, +fun NavGraphBuilder.offDeviceMnemonics( + onNavigateToOffDeviceMnemonicFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, + onNavigateToOffDeviceAddMnemonic: () -> Unit, onInfoClick: (GlossaryItem) -> Unit, onBackClick: () -> Unit ) { composable( - route = ROUTE_MNEMONICS_SCREEN, + route = ROUTE_OFF_DEVICE_MNEMONICS_SCREEN, enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Left) }, @@ -39,10 +39,10 @@ fun NavGraphBuilder.mnemonics( slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Right) } ) { - MnemonicsScreen( + OffDeviceMnemonicsScreen( viewModel = hiltViewModel(), - onNavigateToMnemonicFactorSourceDetails = onNavigateToMnemonicFactorSourceDetails, - onNavigateToAddMnemonic = onNavigateToAddMnemonic, + onNavigateToOffDeviceMnemonicFactorSourceDetails = onNavigateToOffDeviceMnemonicFactorSourceDetails, + onNavigateToAddOffDeviceMnemonic = onNavigateToOffDeviceAddMnemonic, onInfoClick = onInfoClick, onBackClick = onBackClick ) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsScreen.kt similarity index 78% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsScreen.kt index 1522309848..8649a30724 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsScreen.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsScreen.kt @@ -1,4 +1,4 @@ -package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.mnemonic +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.offdevicemnemonic import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets @@ -34,10 +34,10 @@ import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf @Composable -fun MnemonicsScreen( - viewModel: MnemonicsViewModel, - onNavigateToMnemonicFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, - onNavigateToAddMnemonic: () -> Unit, +fun OffDeviceMnemonicsScreen( + viewModel: OffDeviceMnemonicsViewModel, + onNavigateToOffDeviceMnemonicFactorSourceDetails: (factorSourceId: FactorSourceId) -> Unit, + onNavigateToAddOffDeviceMnemonic: () -> Unit, onInfoClick: (GlossaryItem) -> Unit, onBackClick: () -> Unit ) { @@ -46,28 +46,28 @@ fun MnemonicsScreen( LaunchedEffect(Unit) { viewModel.oneOffEvent.collect { event -> when (event) { - is MnemonicsViewModel.Event.NavigateToMnemonicFactorSourceDetails -> { - onNavigateToMnemonicFactorSourceDetails(event.factorSourceId) + is OffDeviceMnemonicsViewModel.Event.NavigateToOffDeviceMnemonicFactorSourceDetails -> { + onNavigateToOffDeviceMnemonicFactorSourceDetails(event.factorSourceId) } } } } - MnemonicsContent( - mnemonicFactorSources = state.mnemonicFactorSources, - onMnemonicFactorSourceClick = viewModel::onMnemonicFactorSourceClick, - onAddMnemonicClick = onNavigateToAddMnemonic, + OffDeviceMnemonicsContent( + offDeviceMnemonicFactorSources = state.offDeviceMnemonicFactorSources, + onOffDeviceMnemonicFactorSourceClick = viewModel::onOffDeviceMnemonicFactorSourceClick, + onAddOffDeviceMnemonicClick = onNavigateToAddOffDeviceMnemonic, onInfoClick = onInfoClick, onBackClick = onBackClick ) } @Composable -private fun MnemonicsContent( +private fun OffDeviceMnemonicsContent( modifier: Modifier = Modifier, - mnemonicFactorSources: PersistentList, - onMnemonicFactorSourceClick: (FactorSourceId) -> Unit, - onAddMnemonicClick: () -> Unit, + offDeviceMnemonicFactorSources: PersistentList, + onOffDeviceMnemonicFactorSourceClick: (FactorSourceId) -> Unit, + onAddOffDeviceMnemonicClick: () -> Unit, onInfoClick: (GlossaryItem) -> Unit, onBackClick: () -> Unit ) { @@ -90,12 +90,12 @@ private fun MnemonicsContent( FactorSourcesList( mainFactorSource = null, - factorSources = mnemonicFactorSources, + factorSources = offDeviceMnemonicFactorSources, factorSourceDescriptionText = R.string.factorSources_card_passphraseDescription, addFactorSourceButtonTitle = R.string.factorSources_list_passphraseAdd, - glossaryItem = GlossaryItem.mnemonic, - onFactorSourceClick = onMnemonicFactorSourceClick, - onAddFactorSourceClick = onAddMnemonicClick, + glossaryItem = GlossaryItem.offDeviceMnemonic, + onFactorSourceClick = onOffDeviceMnemonicFactorSourceClick, + onAddFactorSourceClick = onAddOffDeviceMnemonicClick, onInfoClick = onInfoClick ) } @@ -105,10 +105,10 @@ private fun MnemonicsContent( @UsesSampleValues @Preview(showBackground = true) @Composable -private fun MnemonicsScreenPreview() { +private fun OffDeviceMnemonicsPreview() { RadixWalletTheme { - MnemonicsContent( - mnemonicFactorSources = persistentListOf( + OffDeviceMnemonicsContent( + offDeviceMnemonicFactorSources = persistentListOf( FactorSourceCard( id = FactorSourceId.Hash.init( kind = FactorSourceKind.OFF_DEVICE_MNEMONIC, @@ -152,8 +152,8 @@ private fun MnemonicsScreenPreview() { hasHiddenEntities = false ) ), - onMnemonicFactorSourceClick = {}, - onAddMnemonicClick = {}, + onOffDeviceMnemonicFactorSourceClick = {}, + onAddOffDeviceMnemonicClick = {}, onBackClick = {}, onInfoClick = {} ) diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsViewModel.kt similarity index 84% rename from app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt rename to app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsViewModel.kt index 49010423ee..6d7bd7b9f1 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/mnemonic/MnemonicsViewModel.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/settings/securitycenter/securityfactors/offdevicemnemonic/OffDeviceMnemonicsViewModel.kt @@ -1,4 +1,4 @@ -package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.mnemonic +package com.babylon.wallet.android.presentation.settings.securitycenter.securityfactors.offdevicemnemonic import androidx.lifecycle.viewModelScope import com.babylon.wallet.android.di.coroutines.DefaultDispatcher @@ -33,12 +33,12 @@ import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class MnemonicsViewModel @Inject constructor( +class OffDeviceMnemonicsViewModel @Inject constructor( getFactorSourcesOfTypeUseCase: GetFactorSourcesOfTypeUseCase, private val sargonOsManager: SargonOsManager, @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher -) : StateViewModel(), - OneOffEventHandler by OneOffEventHandlerImpl() { +) : StateViewModel(), + OneOffEventHandler by OneOffEventHandlerImpl() { override fun initialState(): State = State() @@ -59,7 +59,7 @@ class MnemonicsViewModel @Inject constructor( ) _state.update { state -> - state.copy(mnemonicFactorSources = state.mnemonicFactorSources.add(factorSourceCard)) + state.copy(offDeviceMnemonicFactorSources = state.offDeviceMnemonicFactorSources.add(factorSourceCard)) } } .flowOn(defaultDispatcher) @@ -86,18 +86,18 @@ class MnemonicsViewModel @Inject constructor( ) } - fun onMnemonicFactorSourceClick(factorSourceId: FactorSourceId) { + fun onOffDeviceMnemonicFactorSourceClick(factorSourceId: FactorSourceId) { viewModelScope.launch { - sendEvent(Event.NavigateToMnemonicFactorSourceDetails(factorSourceId)) + sendEvent(Event.NavigateToOffDeviceMnemonicFactorSourceDetails(factorSourceId)) } } data class State( - val mnemonicFactorSources: PersistentList = persistentListOf(), + val offDeviceMnemonicFactorSources: PersistentList = persistentListOf(), ) : UiState sealed interface Event : OneOffEvent { - data class NavigateToMnemonicFactorSourceDetails(val factorSourceId: FactorSourceId) : Event + data class NavigateToOffDeviceMnemonicFactorSourceDetails(val factorSourceId: FactorSourceId) : Event } } diff --git a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/securityfactors/SecurityFactorTypesListView.kt b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/securityfactors/SecurityFactorTypesListView.kt index 97cf018a26..ab04ee2082 100644 --- a/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/securityfactors/SecurityFactorTypesListView.kt +++ b/app/src/main/java/com/babylon/wallet/android/presentation/ui/composables/securityfactors/SecurityFactorTypesListView.kt @@ -106,7 +106,7 @@ val currentSecurityFactorTypeItems = if (BuildConfig.EXPERIMENTAL_FEATURES_ENABL ), SecurityFactorCategory.Information to persistentSetOf( SecurityFactorsSettingsItem.Password, - SecurityFactorsSettingsItem.Mnemonic + SecurityFactorsSettingsItem.OffDeviceMnemonic ) ) } else {