diff --git a/app/src/main/java/com/tari/android/wallet/application/securityStage/StagedWalletSecurityManager.kt b/app/src/main/java/com/tari/android/wallet/application/securityStage/StagedWalletSecurityManager.kt index 32597528a..1faa031b9 100644 --- a/app/src/main/java/com/tari/android/wallet/application/securityStage/StagedWalletSecurityManager.kt +++ b/app/src/main/java/com/tari/android/wallet/application/securityStage/StagedWalletSecurityManager.kt @@ -1,93 +1,86 @@ package com.tari.android.wallet.application.securityStage -import android.text.SpannableString -import android.text.Spanned -import com.tari.android.wallet.R +import com.tari.android.wallet.application.securityStage.StagedWalletSecurityManager.StagedSecurityEffect.NoStagedSecurityPopUp +import com.tari.android.wallet.application.securityStage.StagedWalletSecurityManager.StagedSecurityEffect.ShowStagedSecurityPopUp import com.tari.android.wallet.data.sharedPrefs.securityStages.DisabledTimestampsDto import com.tari.android.wallet.data.sharedPrefs.securityStages.SecurityStagesRepository import com.tari.android.wallet.data.sharedPrefs.securityStages.WalletSecurityStage -import com.tari.android.wallet.data.sharedPrefs.securityStages.modules.SecurityStageHeadModule -import com.tari.android.wallet.event.EventBus -import com.tari.android.wallet.extension.addTo +import com.tari.android.wallet.data.sharedPrefs.tariSettings.TariSettingsSharedRepository +import com.tari.android.wallet.extension.isAfterNow import com.tari.android.wallet.model.BalanceInfo import com.tari.android.wallet.model.MicroTari -import com.tari.android.wallet.ui.common.CommonViewModel -import com.tari.android.wallet.ui.dialog.modular.DialogArgs -import com.tari.android.wallet.ui.dialog.modular.ModularDialogArgs -import com.tari.android.wallet.ui.dialog.modular.modules.body.BodyModule -import com.tari.android.wallet.ui.dialog.modular.modules.button.ButtonModule -import com.tari.android.wallet.ui.dialog.modular.modules.button.ButtonStyle -import com.tari.android.wallet.ui.dialog.modular.modules.space.SpaceModule -import com.tari.android.wallet.ui.fragment.settings.backup.backupOnboarding.item.BackupOnboardingArgs -import com.tari.android.wallet.ui.fragment.settings.backup.backupOnboarding.module.BackupOnboardingFlowItemModule import com.tari.android.wallet.ui.fragment.settings.backup.data.BackupSettingsRepository -import yat.android.ui.extension.HtmlHelper import java.math.BigDecimal import java.util.Calendar import javax.inject.Inject - -class StagedWalletSecurityManager : CommonViewModel() { - - @Inject - lateinit var securityStagesRepository: SecurityStagesRepository - - @Inject - lateinit var backupPrefsRepository: BackupSettingsRepository - - init { - component.inject(this) - - EventBus.balanceUpdates.publishSubject.subscribe { handleChange(it) }.addTo(compositeDisposable) - } - - val hasVerifiedSeedPhrase +import javax.inject.Singleton + +val MINIMUM_STAGE_ONE_BALANCE = MicroTari((BigDecimal.valueOf(10_000) * MicroTari.precisionValue).toBigInteger()) +val STAGE_TWO_THRESHOLD_BALANCE = MicroTari((BigDecimal.valueOf(100_000) * MicroTari.precisionValue).toBigInteger()) +val SAFE_HOT_WALLET_BALANCE = MicroTari((BigDecimal.valueOf(500_000_000) * MicroTari.precisionValue).toBigInteger()) +val MAX_HOT_WALLET_BALANCE = MicroTari((BigDecimal.valueOf(1_000_000_000) * MicroTari.precisionValue).toBigInteger()) + +@Singleton +class StagedWalletSecurityManager @Inject constructor( + private val securityStagesRepository: SecurityStagesRepository, + private val backupPrefsRepository: BackupSettingsRepository, + private val tariSettingsSharedRepository: TariSettingsSharedRepository, +) { + private val hasVerifiedSeedPhrase get() = tariSettingsSharedRepository.hasVerifiedSeedWords - val isBackupOn + private val isBackupOn get() = backupPrefsRepository.getOptionList.any { it.isEnable } - val isBackupPasswordSet + private val isBackupPasswordSet get() = !backupPrefsRepository.backupPassword.isNullOrEmpty() - val disabledTimestampSinceNow + private val disabledTimestampSinceNow: Calendar get() = Calendar.getInstance().also { it.add(Calendar.DAY_OF_YEAR, 7) } - var disabledTimestamps: MutableMap + private var disabledTimestamps: MutableMap get() = securityStagesRepository.disabledTimestamps?.timestamps ?: DisabledTimestampsDto(mutableMapOf()).timestamps set(value) { securityStagesRepository.disabledTimestamps = DisabledTimestampsDto(value) } - private fun updateTimestamp(securityStage: WalletSecurityStage) { - val newTimestamp = disabledTimestampSinceNow - disabledTimestamps = disabledTimestamps.also { it[securityStage] = newTimestamp } - } - - private fun handleChange(balance: BalanceInfo) { - val securityStage = getSecurityStages(balance) ?: return + /** + * Check the current security stage based on the balance and the user's security settings. + */ + fun handleBalanceChange(balance: BalanceInfo): StagedSecurityEffect { + val securityStage = checkSecurityStage(balance) ?: return NoStagedSecurityPopUp //todo Stage 3 is currently disabled - if (securityStage == WalletSecurityStage.Stage3) return - if (isActionDisabled(securityStage)) return + if (securityStage == WalletSecurityStage.Stage3) return NoStagedSecurityPopUp + if (isActionDisabled(securityStage)) return NoStagedSecurityPopUp updateTimestamp(securityStage) - showPopUp(securityStage) + + return ShowStagedSecurityPopUp(securityStage) } - private fun getSecurityStages(balanceInfo: BalanceInfo): WalletSecurityStage? { + private fun updateTimestamp(securityStage: WalletSecurityStage) { + val newTimestamp = disabledTimestampSinceNow + disabledTimestamps = disabledTimestamps.also { it[securityStage] = newTimestamp } + } + + /** + * Returns null if no security stage is required. + */ + private fun checkSecurityStage(balanceInfo: BalanceInfo): WalletSecurityStage? { val balance = balanceInfo.availableBalance return when { - balance >= minimumStageOneBalance && !hasVerifiedSeedPhrase -> WalletSecurityStage.Stage1A - balance >= minimumStageOneBalance && !isBackupOn -> WalletSecurityStage.Stage1B - balance >= stageTwoThresholdBalance && !isBackupPasswordSet -> WalletSecurityStage.Stage2 - balance >= safeHotWalletBalance -> WalletSecurityStage.Stage3 + balance >= MINIMUM_STAGE_ONE_BALANCE && !hasVerifiedSeedPhrase -> WalletSecurityStage.Stage1A + balance >= MINIMUM_STAGE_ONE_BALANCE && !isBackupOn -> WalletSecurityStage.Stage1B + balance >= STAGE_TWO_THRESHOLD_BALANCE && !isBackupPasswordSet -> WalletSecurityStage.Stage2 + balance >= SAFE_HOT_WALLET_BALANCE -> WalletSecurityStage.Stage3 else -> null } } private fun isActionDisabled(securityStage: WalletSecurityStage): Boolean { val timestamp = disabledTimestamps[securityStage] ?: return false - if (timestamp < Calendar.getInstance()) { + if (timestamp.isAfterNow()) { return true } @@ -95,119 +88,8 @@ class StagedWalletSecurityManager : CommonViewModel() { return false } - fun showPopUp(securityStage: WalletSecurityStage) { - when (securityStage) { - WalletSecurityStage.Stage1A -> showStage1APopUp() - WalletSecurityStage.Stage1B -> showStage1BPopUp() - WalletSecurityStage.Stage2 -> showStage2PopUp() - WalletSecurityStage.Stage3 -> showStage3PopUp() - } - } - - private fun showStage1APopUp() { - showPopup( - BackupOnboardingArgs.StageOne(resourceManager, this::openStage1), - resourceManager.getString(R.string.staged_wallet_security_stages_1a_title), - resourceManager.getString(R.string.staged_wallet_security_stages_1a_subtitle), - null, - resourceManager.getString(R.string.staged_wallet_security_stages_1a_buttons_positive), - HtmlHelper.getSpannedText(resourceManager.getString(R.string.staged_wallet_security_stages_1a_message)) - ) { openStage1() } - } - - private fun openStage1() { - dismissDialog.postValue(Unit) - tariNavigator?.let { - it.toAllSettings() - it.toBackupSettings(false) - it.toWalletBackupWithRecoveryPhrase() - } - } - - private fun showStage1BPopUp() { - showPopup( - BackupOnboardingArgs.StageTwo(resourceManager, this::openStage1B), - resourceManager.getString(R.string.staged_wallet_security_stages_1b_title), - resourceManager.getString(R.string.staged_wallet_security_stages_1b_subtitle), - resourceManager.getString(R.string.staged_wallet_security_stages_1b_message), - resourceManager.getString(R.string.staged_wallet_security_stages_1b_buttons_positive), - ) { openStage1() } - } - - private fun openStage1B() { - dismissDialog.postValue(Unit) - tariNavigator?.let { - it.toAllSettings() - it.toBackupSettings(true) - } - } - - private fun showStage2PopUp() { - showPopup( - BackupOnboardingArgs.StageThree(resourceManager, this::openStage2), - resourceManager.getString(R.string.staged_wallet_security_stages_2_title), - resourceManager.getString(R.string.staged_wallet_security_stages_2_subtitle), - resourceManager.getString(R.string.staged_wallet_security_stages_2_message), - resourceManager.getString(R.string.staged_wallet_security_stages_2_buttons_positive), - ) { openStage2() } - } - - private fun openStage2() { - dismissDialog.postValue(Unit) - tariNavigator?.let { - it.toAllSettings() - it.toBackupSettings(false) - it.toChangePassword() - } - } - - private fun showStage3PopUp() { - showPopup( - BackupOnboardingArgs.StageFour(resourceManager, this::openStage3), - resourceManager.getString(R.string.staged_wallet_security_stages_3_title), - resourceManager.getString(R.string.staged_wallet_security_stages_3_subtitle), - resourceManager.getString(R.string.staged_wallet_security_stages_3_message), - resourceManager.getString(R.string.staged_wallet_security_stages_3_buttons_positive), - ) { openStage3() } - } - - private fun openStage3() { - dismissDialog.postValue(Unit) - //todo for future - } - - private fun showPopup( - stage: BackupOnboardingArgs, - titleEmoji: String, - title: String, - body: String?, - positiveButtonTitle: String, - bodyHtml: Spanned? = null, - positiveAction: () -> Unit = {}, - ) { - val args = ModularDialogArgs( - DialogArgs(), listOf( - SecurityStageHeadModule(titleEmoji, title) { showBackupInfo(stage) }, - BodyModule(body, bodyHtml?.let { SpannableString(it) }), - ButtonModule(positiveButtonTitle, ButtonStyle.Normal) { positiveAction.invoke() }, - ButtonModule(resourceManager.getString(R.string.staged_wallet_security_buttons_remind_me_later), ButtonStyle.Close) - ) - ) - modularDialog.postValue(args) - } - - private fun showBackupInfo(stage: BackupOnboardingArgs) { - val args = ModularDialogArgs(DialogArgs(), listOf( - BackupOnboardingFlowItemModule(stage), - SpaceModule(20) - )) - modularDialog.postValue(args) - } - - companion object { - val minimumStageOneBalance = MicroTari((BigDecimal.valueOf(10_000) * MicroTari.precisionValue).toBigInteger()) - val stageTwoThresholdBalance = MicroTari((BigDecimal.valueOf(100_000) * MicroTari.precisionValue).toBigInteger()) - val safeHotWalletBalance = MicroTari((BigDecimal.valueOf(500_000_000) * MicroTari.precisionValue).toBigInteger()) - val maxHotWalletBalance = MicroTari((BigDecimal.valueOf(1_000_000_000) * MicroTari.precisionValue).toBigInteger()) + sealed class StagedSecurityEffect { + data class ShowStagedSecurityPopUp(val stage: WalletSecurityStage) : StagedSecurityEffect() + object NoStagedSecurityPopUp : StagedSecurityEffect() } } \ No newline at end of file diff --git a/app/src/main/java/com/tari/android/wallet/event/EffectChannelFlow.kt b/app/src/main/java/com/tari/android/wallet/event/EffectChannelFlow.kt new file mode 100644 index 000000000..81458f025 --- /dev/null +++ b/app/src/main/java/com/tari/android/wallet/event/EffectChannelFlow.kt @@ -0,0 +1,14 @@ +package com.tari.android.wallet.event + +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.receiveAsFlow + +class EffectChannelFlow { + private val channel: Channel = Channel(Channel.CONFLATED) + val flow: Flow = channel.receiveAsFlow() + + suspend fun send(effect: Effect) { + channel.send(effect) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tari/android/wallet/event/EventBus.kt b/app/src/main/java/com/tari/android/wallet/event/EventBus.kt index 47996ea9e..17c31e9f2 100644 --- a/app/src/main/java/com/tari/android/wallet/event/EventBus.kt +++ b/app/src/main/java/com/tari/android/wallet/event/EventBus.kt @@ -69,8 +69,6 @@ object EventBus : GeneralEventBus() { val walletRestorationState = BehaviorEventBus() - val balanceUpdates = BehaviorEventBus() - init { baseNodeSyncState.post(BaseNodeSyncState.Syncing) } diff --git a/app/src/main/java/com/tari/android/wallet/extension/AnyExtensions.kt b/app/src/main/java/com/tari/android/wallet/extension/AnyExtensions.kt new file mode 100644 index 000000000..640bc8f5f --- /dev/null +++ b/app/src/main/java/com/tari/android/wallet/extension/AnyExtensions.kt @@ -0,0 +1,12 @@ +package com.tari.android.wallet.extension + +/** + * These extensions can be used to write casts in a chained way. + * E.g. something.castTo().doSomething() instead of (something as Other).doSomething() + */ +@Suppress("UNCHECKED_CAST") +fun Any.castTo(): T = this as T + +// Simply returning `this as? T` does not work because the Kotlin compiler internally +// then still just casts it to the other type without checks +inline fun Any.safeCastTo(): T? = if (this is T) this else null diff --git a/app/src/main/java/com/tari/android/wallet/extension/DateExtensions.kt b/app/src/main/java/com/tari/android/wallet/extension/DateExtensions.kt index 1d9f21a4d..566d1e3c2 100644 --- a/app/src/main/java/com/tari/android/wallet/extension/DateExtensions.kt +++ b/app/src/main/java/com/tari/android/wallet/extension/DateExtensions.kt @@ -55,3 +55,7 @@ fun Date.txFormattedDate(): String { return SimpleDateFormat("MMMM d'$indicator' yyyy 'at' h:mm a", Locale.ENGLISH) .format(this) } + +fun Calendar.isAfterNow(): Boolean { + return this.after(Calendar.getInstance()) +} diff --git a/app/src/main/java/com/tari/android/wallet/ui/fragment/settings/backup/backupOnboarding/item/BackupOnboardingArgs.kt b/app/src/main/java/com/tari/android/wallet/ui/fragment/settings/backup/backupOnboarding/item/BackupOnboardingArgs.kt index b0de96d0f..74cacee69 100644 --- a/app/src/main/java/com/tari/android/wallet/ui/fragment/settings/backup/backupOnboarding/item/BackupOnboardingArgs.kt +++ b/app/src/main/java/com/tari/android/wallet/ui/fragment/settings/backup/backupOnboarding/item/BackupOnboardingArgs.kt @@ -3,7 +3,7 @@ package com.tari.android.wallet.ui.fragment.settings.backup.backupOnboarding.ite import android.graphics.Typeface import android.text.SpannableString import com.tari.android.wallet.R -import com.tari.android.wallet.application.securityStage.StagedWalletSecurityManager +import com.tari.android.wallet.application.securityStage.STAGE_TWO_THRESHOLD_BALANCE import com.tari.android.wallet.extension.applyCenterAlignment import com.tari.android.wallet.extension.applyColorStyle import com.tari.android.wallet.extension.applyTypefaceStyle @@ -108,7 +108,7 @@ sealed class BackupOnboardingArgs( 0 -> resourceManager.getString(R.string.onboarding_staged_wallet_security_footer_part3_any_funds) else -> resourceManager.getString( R.string.onboarding_staged_wallet_security_footer_part3_threshold, - StagedWalletSecurityManager.stageTwoThresholdBalance.formattedTariValue + STAGE_TWO_THRESHOLD_BALANCE.formattedTariValue, ) } val spannable = SpannableString("$firstPart $highlighted$part3") diff --git a/app/src/main/java/com/tari/android/wallet/ui/fragment/tx/HomeFragment.kt b/app/src/main/java/com/tari/android/wallet/ui/fragment/tx/HomeFragment.kt index b127f1a9a..7b93dc863 100644 --- a/app/src/main/java/com/tari/android/wallet/ui/fragment/tx/HomeFragment.kt +++ b/app/src/main/java/com/tari/android/wallet/ui/fragment/tx/HomeFragment.kt @@ -90,7 +90,6 @@ class HomeFragment : CommonFragment( viewModel.serviceConnection.reconnectToService() - subscribeVM(viewModel.stagedWalletSecurityManager) subscribeVM(deeplinkViewModel) checkPermission() diff --git a/app/src/main/java/com/tari/android/wallet/ui/fragment/tx/HomeFragmentViewModel.kt b/app/src/main/java/com/tari/android/wallet/ui/fragment/tx/HomeFragmentViewModel.kt index 4e701df57..43f37a3f2 100644 --- a/app/src/main/java/com/tari/android/wallet/ui/fragment/tx/HomeFragmentViewModel.kt +++ b/app/src/main/java/com/tari/android/wallet/ui/fragment/tx/HomeFragmentViewModel.kt @@ -1,6 +1,8 @@ package com.tari.android.wallet.ui.fragment.tx +import android.text.SpannableString +import android.text.Spanned import androidx.lifecycle.LiveData import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData @@ -12,12 +14,16 @@ import com.tari.android.wallet.R.string.error_no_connection_title import com.tari.android.wallet.R.string.error_node_unreachable_description import com.tari.android.wallet.R.string.error_node_unreachable_title import com.tari.android.wallet.application.securityStage.StagedWalletSecurityManager +import com.tari.android.wallet.application.securityStage.StagedWalletSecurityManager.StagedSecurityEffect import com.tari.android.wallet.data.sharedPrefs.SharedPrefsRepository +import com.tari.android.wallet.data.sharedPrefs.securityStages.WalletSecurityStage +import com.tari.android.wallet.data.sharedPrefs.securityStages.modules.SecurityStageHeadModule import com.tari.android.wallet.data.sharedPrefs.sentry.SentryPrefRepository import com.tari.android.wallet.event.Event import com.tari.android.wallet.event.EventBus import com.tari.android.wallet.extension.addTo import com.tari.android.wallet.extension.getWithError +import com.tari.android.wallet.extension.safeCastTo import com.tari.android.wallet.model.BalanceInfo import com.tari.android.wallet.service.service.WalletServiceLauncher import com.tari.android.wallet.ui.common.CommonViewModel @@ -30,15 +36,19 @@ import com.tari.android.wallet.ui.dialog.modular.modules.body.BodyModule import com.tari.android.wallet.ui.dialog.modular.modules.button.ButtonModule import com.tari.android.wallet.ui.dialog.modular.modules.button.ButtonStyle import com.tari.android.wallet.ui.dialog.modular.modules.head.HeadModule +import com.tari.android.wallet.ui.dialog.modular.modules.space.SpaceModule import com.tari.android.wallet.ui.fragment.contact_book.data.ContactsRepository import com.tari.android.wallet.ui.fragment.home.navigation.Navigation import com.tari.android.wallet.ui.fragment.send.finalize.TxFailureReason +import com.tari.android.wallet.ui.fragment.settings.backup.backupOnboarding.item.BackupOnboardingArgs +import com.tari.android.wallet.ui.fragment.settings.backup.backupOnboarding.module.BackupOnboardingFlowItemModule import com.tari.android.wallet.ui.fragment.settings.backup.data.BackupSettingsRepository import com.tari.android.wallet.ui.fragment.tx.adapter.TransactionItem import com.tari.android.wallet.util.extractEmojis import io.reactivex.BackpressureStrategy import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import yat.android.ui.extension.HtmlHelper import javax.inject.Inject @@ -62,7 +72,8 @@ class HomeFragmentViewModel : CommonViewModel() { @Inject lateinit var sentryPrefRepository: SentryPrefRepository - val stagedWalletSecurityManager = StagedWalletSecurityManager() + @Inject + lateinit var stagedWalletSecurityManager: StagedWalletSecurityManager private val _balanceInfo = MutableLiveData() val balanceInfo: LiveData = _balanceInfo @@ -132,9 +143,19 @@ class HomeFragmentViewModel : CommonViewModel() { } private fun fetchBalanceInfoData() { - walletService.getWithError { error, service -> service.getBalanceInfo(error) }?.let { - EventBus.balanceUpdates.post(it) - _balanceInfo.postValue(it) + walletService.getWithError { error, service -> service.getBalanceInfo(error) }?.let { balanceInfo -> + _balanceInfo.postValue(balanceInfo) + + stagedWalletSecurityManager.handleBalanceChange(balanceInfo) + .safeCastTo() + ?.let { effect -> + when (effect.stage) { + WalletSecurityStage.Stage1A -> showStagePopUp1A() + WalletSecurityStage.Stage1B -> showStagePopUp1B() + WalletSecurityStage.Stage2 -> showStagePopUp2() + WalletSecurityStage.Stage3 -> showStagePopUp3() + } + } } } @@ -195,6 +216,117 @@ class HomeFragmentViewModel : CommonViewModel() { modularDialog.postValue(errorDialogArgs.getModular(resourceManager)) } + /** + * Show staged security popups + */ + + private fun showStagePopUp1A() { + showPopup( + stage = BackupOnboardingArgs.StageOne(resourceManager, this::openStage1), + titleEmoji = resourceManager.getString(R.string.staged_wallet_security_stages_1a_title), + title = resourceManager.getString(R.string.staged_wallet_security_stages_1a_subtitle), + body = null, + positiveButtonTitle = resourceManager.getString(R.string.staged_wallet_security_stages_1a_buttons_positive), + bodyHtml = HtmlHelper.getSpannedText(resourceManager.getString(R.string.staged_wallet_security_stages_1a_message)), + positiveAction = { openStage1() }, + ) + } + + private fun showStagePopUp1B() { + showPopup( + stage = BackupOnboardingArgs.StageTwo(resourceManager, this::openStage1B), + titleEmoji = resourceManager.getString(R.string.staged_wallet_security_stages_1b_title), + title = resourceManager.getString(R.string.staged_wallet_security_stages_1b_subtitle), + body = resourceManager.getString(R.string.staged_wallet_security_stages_1b_message), + positiveButtonTitle = resourceManager.getString(R.string.staged_wallet_security_stages_1b_buttons_positive), + positiveAction = { openStage1() }, + ) + } + + private fun showStagePopUp2() { + showPopup( + stage = BackupOnboardingArgs.StageThree(resourceManager, this::openStage2), + titleEmoji = resourceManager.getString(R.string.staged_wallet_security_stages_2_title), + title = resourceManager.getString(R.string.staged_wallet_security_stages_2_subtitle), + body = resourceManager.getString(R.string.staged_wallet_security_stages_2_message), + positiveButtonTitle = resourceManager.getString(R.string.staged_wallet_security_stages_2_buttons_positive), + positiveAction = { openStage2() }, + ) + } + + private fun showStagePopUp3() { + showPopup( + stage = BackupOnboardingArgs.StageFour(resourceManager, this::openStage3), + titleEmoji = resourceManager.getString(R.string.staged_wallet_security_stages_3_title), + title = resourceManager.getString(R.string.staged_wallet_security_stages_3_subtitle), + body = resourceManager.getString(R.string.staged_wallet_security_stages_3_message), + positiveButtonTitle = resourceManager.getString(R.string.staged_wallet_security_stages_3_buttons_positive), + positiveAction = { openStage3() }, + ) + } + + private fun openStage1() { + dismissDialog.postValue(Unit) + tariNavigator.let { + it.toAllSettings() + it.toBackupSettings(false) + it.toWalletBackupWithRecoveryPhrase() + } + } + + private fun openStage1B() { + dismissDialog.postValue(Unit) + tariNavigator.let { + it.toAllSettings() + it.toBackupSettings(true) + } + } + + private fun openStage2() { + dismissDialog.postValue(Unit) + tariNavigator.let { + it.toAllSettings() + it.toBackupSettings(false) + it.toChangePassword() + } + } + + private fun openStage3() { + dismissDialog.postValue(Unit) + //todo for future + } + + private fun showPopup( + stage: BackupOnboardingArgs, + titleEmoji: String, + title: String, + body: String?, + positiveButtonTitle: String, + bodyHtml: Spanned? = null, + positiveAction: () -> Unit = {}, + ) { + val args = ModularDialogArgs( + DialogArgs(), listOf( + SecurityStageHeadModule(titleEmoji, title) { showBackupInfo(stage) }, + BodyModule(body, bodyHtml?.let { SpannableString(it) }), + ButtonModule(positiveButtonTitle, ButtonStyle.Normal) { positiveAction.invoke() }, + ButtonModule(resourceManager.getString(R.string.staged_wallet_security_buttons_remind_me_later), ButtonStyle.Close) + ) + ) + modularDialog.postValue(args) + } + + private fun showBackupInfo(stage: BackupOnboardingArgs) { + modularDialog.postValue( + ModularDialogArgs( + DialogArgs(), listOf( + BackupOnboardingFlowItemModule(stage), + SpaceModule(20), + ) + ) + ) + } + companion object { val amountOfTransactions = 2 }