Updated on 2026-08-14
This commit is contained in:
parent
a96fb4b2f4
commit
721115e64e
9 changed files with 160 additions and 56 deletions
|
|
@ -274,6 +274,10 @@
|
|||
<item quantity="one">day</item>
|
||||
<item quantity="other">days</item>
|
||||
</plurals>
|
||||
<plurals name="common_days_time_ago">
|
||||
<item quantity="one">%d day ago</item>
|
||||
<item quantity="other">%d days ago</item>
|
||||
</plurals>
|
||||
<string name="common_delete">Delete</string>
|
||||
<string name="common_disable">Disable</string>
|
||||
<string name="common_disabled">Disabled</string>
|
||||
|
|
@ -308,6 +312,10 @@
|
|||
<string name="common_hide">Hide</string>
|
||||
<string name="common_hold_to">Hold to %s</string>
|
||||
<string name="common_hour">hour</string>
|
||||
<plurals name="common_hours_time_ago">
|
||||
<item quantity="one">%dh ago</item>
|
||||
<item quantity="other">%dh ago</item>
|
||||
</plurals>
|
||||
<string name="common_import">Import</string>
|
||||
<string name="common_in_progress">In progress</string>
|
||||
<string name="common_insufficient_balance">Insufficient balance</string>
|
||||
|
|
@ -318,6 +326,10 @@
|
|||
<string name="common_locked">Locked</string>
|
||||
<string name="common_locked_wallets">Locked Wallets</string>
|
||||
<string name="common_main_network">Main network</string>
|
||||
<plurals name="common_minutes_time_ago">
|
||||
<item quantity="one">%d minute ago</item>
|
||||
<item quantity="other">%d minutes ago</item>
|
||||
</plurals>
|
||||
<string name="common_month">month</string>
|
||||
<string name="common_network_fee_title">Network fee</string>
|
||||
<string name="common_network_fee_warning_content">Amount sent will be reduced by %1$s (%2$s) to cover the selected fee level</string>
|
||||
|
|
@ -487,7 +499,6 @@
|
|||
<string name="dynamic_addresses_disable_title">Disable dynamic addresses</string>
|
||||
<string name="dynamic_addresses_disabled_popup_title">Dynamic addresses disabled</string>
|
||||
<string name="dynamic_addresses_enabled_toast_title">Dynamic addresses enabled</string>
|
||||
<string name="dynamic_addresses_receive_badge">Dynamic address</string>
|
||||
<string name="dynamic_addresses_enter_features_privacy_description">Use a new address for each transaction to reduce traceability and improve on-chain privacy.</string>
|
||||
<string name="dynamic_addresses_enter_features_privacy_title">Enhanced Privacy</string>
|
||||
<string name="dynamic_addresses_enter_features_receving_description">Easily receive funds in UTXO-based networks with automatic address generation — no manual address management required.</string>
|
||||
|
|
@ -498,6 +509,9 @@
|
|||
<string name="dynamic_addresses_error_has_custom_token_title">Dynamic Addresses Unavailable</string>
|
||||
<string name="dynamic_addresses_error_service_unavailable_description">We can’t connect to the provider right now. Please try again later.</string>
|
||||
<string name="dynamic_addresses_error_service_unavailable_title">Service unavailable. Please try again.</string>
|
||||
<string name="dynamic_addresses_notification_funds_found_description">Funds were found on additional addresses. Enable Dynamic Addresses to access them.</string>
|
||||
<string name="dynamic_addresses_notification_funds_found_title">Funds found on additional addresses</string>
|
||||
<string name="dynamic_addresses_receive_badge">Dynamic address</string>
|
||||
<string name="earn_best_opportunities">Best opportunities</string>
|
||||
<string name="earn_clear_filter">Clear filter</string>
|
||||
<string name="earn_empty">The list is temporarily empty as it’s being refreshed. Check back in a moment.</string>
|
||||
|
|
@ -569,6 +583,7 @@
|
|||
<string name="express_provider">Provider</string>
|
||||
<string name="express_provider_best_rate">Best rate</string>
|
||||
<string name="express_provider_fca_warning_list">FCA Warning List</string>
|
||||
<string name="express_provider_fixed_rate_is_unavailable">Fixed rate is unavailable</string>
|
||||
<string name="express_provider_great_rate">Competitive rate</string>
|
||||
<string name="express_provider_in_fca_warning_list">Provider in FCA warning list</string>
|
||||
<string name="express_provider_max_amount">Available up to %s</string>
|
||||
|
|
@ -781,6 +796,7 @@
|
|||
<string name="markets_loading_no_data_title">No data</string>
|
||||
<string name="markets_portfolio_block_add_token_title">**Add to your portfolio** to start buying, exchanging or receiving this asset</string>
|
||||
<string name="markets_portfolio_block_subtitle">In your portfolio</string>
|
||||
<string name="markets_portfolio_block_title">Your portfolio</string>
|
||||
<string name="markets_pulse_common_title">Market Pulse</string>
|
||||
<string name="markets_quick_actions">Quick actions</string>
|
||||
<string name="markets_search_clear_all_hints">Clear all</string>
|
||||
|
|
@ -1020,7 +1036,9 @@
|
|||
<string name="onboarding_getting_started">Getting started</string>
|
||||
<string name="onboarding_linking_error_card_with_wallets">Another wallet has already been created on the card you\'re trying to add. If you have funds in this wallet, please withdraw it and then reset this card and add it as a backup.</string>
|
||||
<string name="onboarding_navbar_save_wallet">Save your wallet</string>
|
||||
<string name="onboarding_navbar_title_biometrics">Use biometrics</string>
|
||||
<string name="onboarding_navbar_title_creating_backup">Creating a backup</string>
|
||||
<string name="onboarding_navbar_title_last_step">Last step</string>
|
||||
<string name="onboarding_navbar_upgrade_wallet_biometrics">Biometrics</string>
|
||||
<string name="onboarding_seed_button_read_more">Read more about seed phrase</string>
|
||||
<plurals name="onboarding_seed_generate_message_words_count">
|
||||
|
|
@ -1516,13 +1534,21 @@
|
|||
<string name="swap_story_fifth_subtitle">Feel confident with round-the-clock support to help with any issues</string>
|
||||
<string name="swap_story_fifth_title">Always Here</string>
|
||||
<string name="swap_story_first_subtitle">Multiple trusted providers in one place—swap any asset effortlessly in your wallet</string>
|
||||
<string name="swap_story_first_subtitle_v2">Exchange crypto directly in Tangem\nNo additional transfers
\nNo moving funds to exchanges</string>
|
||||
<string name="swap_story_first_title">Swap With Us</string>
|
||||
<string name="swap_story_first_title_v2">Swap Inside Your Wallet</string>
|
||||
<string name="swap_story_forth_subtitle">No fumbles, no turnovers, no blind spots—your transaction is always protected</string>
|
||||
<string name="swap_story_forth_subtitle_v2">Swaps are executed through trusted providers. Your keys remain in your Tangem wallet at all times.
Clear. Transparent. Self-custodial.</string>
|
||||
<string name="swap_story_forth_title">Impenetrable Defense</string>
|
||||
<string name="swap_story_forth_title_v2">You Stay in Control</string>
|
||||
<string name="swap_story_second_subtitle">Maximize your value with rates sourced from a wide network of trusted providers, always choosing the best one</string>
|
||||
<string name="swap_story_second_subtitle_v2">Tangem compares multiple providers, both DEX and CEX. The best rate is selected automatically. Prefer another provider? You can choose it manually.</string>
|
||||
<string name="swap_story_second_title">Unbeatable Rates</string>
|
||||
<string name="swap_story_second_title_v2">Best Available Rate</string>
|
||||
<string name="swap_story_third_subtitle">Hassle-free and intuitive, allowing you to swap tokens in just a few taps</string>
|
||||
<string name="swap_story_third_subtitle_v2">Swap across major networks
and thousands of tokens 0% fee on stablecoin-to-stablecoin swaps</string>
|
||||
<string name="swap_story_third_title">Simply Convenient</string>
|
||||
<string name="swap_story_third_title_v2">90+ Blockchains
\n16,000+ Assets</string>
|
||||
<string name="swap_via_provider">Swap via provider</string>
|
||||
<string name="swap_your_assets_title">Your assets</string>
|
||||
<string name="swapping_alert_cex_description">The amount includes:\n• service provider\'s fee\n• network fee for sending %s from the exchange back to the user\'s address.</string>
|
||||
|
|
@ -1557,17 +1583,6 @@
|
|||
<string name="tangem_pay_explore_transaction">Explore transaction</string>
|
||||
<string name="tangem_pay_fee_subtitle">Service fees</string>
|
||||
<string name="tangem_pay_fee_title">Fee</string>
|
||||
<string name="tangempay_card_details_reissue_card">Replace card</string>
|
||||
<string name="tangempay_reissue_card_title">Replace your card?</string>
|
||||
<string name="tangempay_reissue_card_description">This generates a new set of card details. Your old details will stop working. You can\'t undo this.</string>
|
||||
<string name="tangempay_reissue_card_fee_label">Replacement fee</string>
|
||||
<string name="tangempay_reissue_card_confirm">Replace card</string>
|
||||
<string name="tangempay_reissue_card_in_progress">Replacing your digital card</string>
|
||||
<string name="tangempay_reissue_card_in_progress_description">Usually takes up to 5 minutes. In rare cases, up to 48 hours.</string>
|
||||
<string name="tangempay_reissue_card_insufficient_funds">Insufficient funds to replace the card</string>
|
||||
<string name="tangempay_reissue_card_insufficient_funds_title">Unable to cover fee</string>
|
||||
<string name="tangempay_reissue_card_insufficient_funds_subtitle">Deposit USDC to payment account to cover the issuing fee</string>
|
||||
<string name="tangempay_reissue_card_fee_unreachable_error_title">Replacement fee info unreachable</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Keep your money safe. You can unfreeze anytime.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">Freeze your card?</string>
|
||||
<string name="tangem_pay_freeze_card_failed">Failed to freeze the card. Try again later.</string>
|
||||
|
|
@ -1629,6 +1644,7 @@
|
|||
<string name="tangempay_card_details_receive_description">Share your address or show QR-code</string>
|
||||
<string name="tangempay_card_details_receive_error_description">Technical issues detected. Please try again later or contact support.</string>
|
||||
<string name="tangempay_card_details_receive_error_title">Receive unavailable now</string>
|
||||
<string name="tangempay_card_details_reissue_card">Replace card</string>
|
||||
<string name="tangempay_card_details_rename_card_invalid_description">Only letters and numbers are allowed.</string>
|
||||
<string name="tangempay_card_details_rename_card_invalid_title">Invalid characters</string>
|
||||
<string name="tangempay_card_details_reveal_text">Reveal</string>
|
||||
|
|
@ -1643,14 +1659,18 @@
|
|||
<string name="tangempay_card_details_withdraw_error_title">Withdraw unavailable now</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">You can\'t initiate swap or new withdrawal till the current one is finished</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">Withdrawal in progress</string>
|
||||
<string name="tangempay_card_page_settings_title">Card settings</string>
|
||||
<string name="tangempay_card_page_daily_limit_title">Daily limit</string>
|
||||
<string name="tangempay_card_page_daily_limit_current_limit">Current limit</string>
|
||||
<string name="tangempay_card_page_daily_limit_change">Change</string>
|
||||
<string name="tangempay_card_page_daily_limit_error_title">Daily limit unavailable</string>
|
||||
<string name="tangempay_card_page_daily_limit_current_limit">Current limit</string>
|
||||
<string name="tangempay_card_page_daily_limit_error_description">We couldn\'t load your daily limit. Please try again.</string>
|
||||
<string name="tangempay_card_page_daily_limit_error_title">Daily limit unavailable</string>
|
||||
<string name="tangempay_card_page_daily_limit_success_description">You can change it again anytime you like</string>
|
||||
<string name="tangempay_card_page_daily_limit_success_title">Daily limit is set</string>
|
||||
<string name="tangempay_card_page_daily_limit_title">Daily limit</string>
|
||||
<string name="tangempay_card_page_settings_title">Card settings</string>
|
||||
<string name="tangempay_change_pin_code">Change PIN-code</string>
|
||||
<string name="tangempay_come_back_if_forget_pin">Come back to the app if you forget it.</string>
|
||||
<string name="tangempay_daily_limit_hint" formatted="false">Set a limit from %s to %s</string>
|
||||
<string name="tangempay_daily_limit_set_button">Set limits</string>
|
||||
<string name="tangempay_digital_card">Digital card</string>
|
||||
<string name="tangempay_factory_settings_warning_title">I understand that I will completely lose access to my Tangem Pay Card and all funds on it without the possibility of recovery</string>
|
||||
<string name="tangempay_failed_to_issue_card">Failed to issue card</string>
|
||||
|
|
@ -1693,12 +1713,22 @@
|
|||
<string name="tangempay_payment_account">Payment account</string>
|
||||
<string name="tangempay_payment_account_sync_needed">Payment account is not synced</string>
|
||||
<string name="tangempay_pin_validation_error_message">Invalid PIN: avoid sequences or repeats</string>
|
||||
<string name="tangempay_reissue_card_confirm">Replace card</string>
|
||||
<string name="tangempay_reissue_card_description">This generates a new set of card details. Your old details will stop working. You can\'t undo this.</string>
|
||||
<string name="tangempay_reissue_card_fee_label">Replacement fee</string>
|
||||
<string name="tangempay_reissue_card_fee_unreachable_error_title">Replacement fee info unreachable</string>
|
||||
<string name="tangempay_reissue_card_in_progress">Replacing your digital card</string>
|
||||
<string name="tangempay_reissue_card_in_progress_description">Usually takes up to 5 minutes. In rare cases, up to 48 hours.</string>
|
||||
<string name="tangempay_reissue_card_insufficient_funds">Insufficient funds to replace the card</string>
|
||||
<string name="tangempay_reissue_card_insufficient_funds_subtitle">Deposit USDC to payment account to cover the issuing fee</string>
|
||||
<string name="tangempay_reissue_card_insufficient_funds_title">Unable to cover fee</string>
|
||||
<string name="tangempay_reissue_card_title">Replace your card?</string>
|
||||
<string name="tangempay_service_unavailable_description">We’re fixing a technical issue. Please try again later.</string>
|
||||
<string name="tangempay_service_unavailable_title">Service temporarily unavailable</string>
|
||||
<string name="tangempay_service_unreachable_try_later">Unable to display details. However, card payments are still working.</string>
|
||||
<string name="tangempay_set_pin_code">Set \nPIN code</string>
|
||||
<string name="tangempay_sync_needed">Session expired</string>
|
||||
<string name="tangempay_sync_needed_restore_access">Restore access</string>
|
||||
<string name="tangempay_sync_needed_restore_access">Renew session</string>
|
||||
<string name="tangempay_tangem_visa_card">Use USDC for everyday payments</string>
|
||||
<string name="tangempay_temporarily_unavailable">Tangem Pay is temporarily unreachable</string>
|
||||
<string name="tangempay_title">Tangem Pay</string>
|
||||
|
|
@ -1786,7 +1816,7 @@
|
|||
<string name="unlock_wallet_description_full">Use %s or scan a card/ring to have access to your wallet</string>
|
||||
<string name="unsupported_wc_version">Connection failed: This dApp uses Wallet Connect version 1.0, which is not supported. Please ensure the dApp supports Wallet Connect version 2.0 to connect successfully.</string>
|
||||
<string name="update_approval_permission_fee_note">Previous permission will be revoked and a new one will be issued. Network will charge token approval fee for each of theses actions. You will see a zero-amount transaction in the history as a revoke evidence.</string>
|
||||
<string name="update_approval_permission_subtitle">Transaction exceeds previously granted permission amount.\nUpdate permission to proceed</string>
|
||||
<string name="update_approval_permission_subtitle">Transaction exceeds previously granted permission amount.\nUpdate permission to proceed</string>
|
||||
<string name="update_approval_permission_title">Update permission</string>
|
||||
<string name="upgrade_to_hardware_wallet_button_title">Upgrade to hardware wallet</string>
|
||||
<string name="user_push_notification_agreement_argument_one">Stay up to date with the latest features and news</string>
|
||||
|
|
@ -2157,8 +2187,6 @@
|
|||
<string name="wc_specify_networks_subtitle">At least one network is required for dApp connection</string>
|
||||
<string name="wc_specify_networks_title">Specify selected networks</string>
|
||||
<string name="wc_successfully_signed">Successfully signed</string>
|
||||
<string name="wc_get_addresses_title">Share Addresses</string>
|
||||
<string name="wc_get_addresses_addresses_title">Addresses to share</string>
|
||||
<string name="wc_transaction_flow_title" translatable="false">WalletConnect</string>
|
||||
<string name="wc_transaction_info_to_title">To</string>
|
||||
<string name="wc_transaction_request">Transaction request</string>
|
||||
|
|
@ -2268,7 +2296,7 @@
|
|||
<string name="yield_module_start_earning_sheet_next_deposits_v2">All your future incoming %1$s deposits will be automatically supplied to Aave.</string>
|
||||
<string name="yield_module_status_active">Active</string>
|
||||
<string name="yield_module_status_paused">Paused</string>
|
||||
<string name="yield_module_stop_earning">Disabling Yield Mode</string>
|
||||
<string name="yield_module_stop_earning">Disable Yield Mode</string>
|
||||
<string name="yield_module_stop_earning_sheet_description">Turning this off will withdraw your assets from Aave, convert them back to %s in your wallet, and stop yield accrual.</string>
|
||||
<string name="yield_module_stop_earning_sheet_fee_note">A network fee is charged by the blockchain when you exit Yield Mode.</string>
|
||||
<string name="yield_module_stop_earning_sheet_title">Disable Yield Mode</string>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.onboarding.v2.addresssync
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.arkivanov.decompose.DelicateDecomposeApi
|
||||
|
|
@ -18,6 +17,7 @@ import com.tangem.features.onboarding.v2.addresssync.model.AddressSyncIntent
|
|||
import com.tangem.features.onboarding.v2.addresssync.model.AddressSyncModel
|
||||
import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep
|
||||
import com.tangem.features.onboarding.v2.addresssync.ui.AddressSyncContent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsComponent
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsParams
|
||||
|
|
@ -25,11 +25,12 @@ import com.tangem.features.pushnotifications.api.PushNotificationsParams
|
|||
@OptIn(DelicateDecomposeApi::class)
|
||||
internal class DefaultAddressSyncComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: MultiWalletChildParams,
|
||||
private val askBiometryComponentFactory: AskBiometryComponent.Factory,
|
||||
private val pushNotificationsComponentFactory: PushNotificationsComponent.Factory,
|
||||
) : AppComponentContext by appComponentContext, AddressSyncComponent {
|
||||
|
||||
private val model: AddressSyncModel = getOrCreateModel()
|
||||
private val model: AddressSyncModel = getOrCreateModel(params)
|
||||
|
||||
private val childStack: Value<ChildStack<AddressSyncStep, ComposableContentComponent>> =
|
||||
childStack(
|
||||
|
|
@ -58,10 +59,6 @@ internal class DefaultAddressSyncComponent(
|
|||
}
|
||||
},
|
||||
)
|
||||
|
||||
BackHandler {
|
||||
model.onIntent(AddressSyncIntent.Back)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createChild(step: AddressSyncStep, childContext: AppComponentContext): ComposableContentComponent {
|
||||
|
|
@ -82,7 +79,6 @@ internal class DefaultAddressSyncComponent(
|
|||
model.onIntent(
|
||||
AddressSyncIntent.Next(
|
||||
step = AddressSyncStep.ASK_NOTIFICATIONS,
|
||||
shouldReplace = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -91,7 +87,6 @@ internal class DefaultAddressSyncComponent(
|
|||
model.onIntent(
|
||||
AddressSyncIntent.Next(
|
||||
step = AddressSyncStep.ASK_NOTIFICATIONS,
|
||||
shouldReplace = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -109,7 +104,6 @@ internal class DefaultAddressSyncComponent(
|
|||
model.onIntent(
|
||||
AddressSyncIntent.Next(
|
||||
step = AddressSyncStep.ADDRESS_SYNC,
|
||||
shouldReplace = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -118,7 +112,6 @@ internal class DefaultAddressSyncComponent(
|
|||
model.onIntent(
|
||||
AddressSyncIntent.Next(
|
||||
step = AddressSyncStep.ADDRESS_SYNC,
|
||||
shouldReplace = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -127,7 +120,6 @@ internal class DefaultAddressSyncComponent(
|
|||
model.onIntent(
|
||||
AddressSyncIntent.Next(
|
||||
step = AddressSyncStep.ADDRESS_SYNC,
|
||||
shouldReplace = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@ package com.tangem.features.onboarding.v2.addresssync.model
|
|||
import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep
|
||||
|
||||
sealed interface AddressSyncIntent {
|
||||
data class Next(val step: AddressSyncStep, val shouldReplace: Boolean) : AddressSyncIntent
|
||||
data class Next(val step: AddressSyncStep) : AddressSyncIntent
|
||||
data object Back : AddressSyncIntent
|
||||
}
|
||||
|
|
@ -3,16 +3,19 @@ package com.tangem.features.onboarding.v2.addresssync.model
|
|||
import com.arkivanov.decompose.DelicateDecomposeApi
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.pop
|
||||
import com.arkivanov.decompose.router.stack.push
|
||||
import com.arkivanov.decompose.router.stack.replaceCurrent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.settings.CanUseBiometryUseCase
|
||||
import com.tangem.domain.settings.ShouldAskPermissionUseCase
|
||||
import com.tangem.domain.settings.ShouldShowAskBiometryUseCase
|
||||
import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -23,10 +26,24 @@ internal class AddressSyncModel @Inject constructor(
|
|||
private val shouldShowAskBiometryUseCase: ShouldShowAskBiometryUseCase,
|
||||
private val canUseBiometryUseCase: CanUseBiometryUseCase,
|
||||
private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<MultiWalletChildParams>()
|
||||
val stackNavigation = StackNavigation<AddressSyncStep>()
|
||||
|
||||
init {
|
||||
params.innerNavigation.update { innerNavigationState ->
|
||||
innerNavigationState.copy(
|
||||
stackSize = AddressSyncStep.ASK_BIOMETRY.pageNumber,
|
||||
stackMaxSize = ADDRESS_SYNC_MAX_STEPS,
|
||||
)
|
||||
}
|
||||
modelScope.launch {
|
||||
trySkippingScreen(AddressSyncStep.ASK_BIOMETRY)
|
||||
}
|
||||
}
|
||||
|
||||
fun onIntent(intent: AddressSyncIntent) {
|
||||
when (intent) {
|
||||
is AddressSyncIntent.Next -> nextScreen(intent)
|
||||
|
|
@ -35,27 +52,24 @@ internal class AddressSyncModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun nextScreen(next: AddressSyncIntent.Next) {
|
||||
val (nextStep, replace) = next
|
||||
if (replace) {
|
||||
stackNavigation.replaceCurrent(configuration = nextStep)
|
||||
} else {
|
||||
stackNavigation.push(configuration = nextStep)
|
||||
}
|
||||
modelScope.launch { trySkippingScreen(next) }
|
||||
stackNavigation.replaceCurrent(configuration = next.step)
|
||||
updateStepperPage(next)
|
||||
updateTitle(next)
|
||||
modelScope.launch { trySkippingScreen(next.step) }
|
||||
}
|
||||
|
||||
private suspend fun trySkippingScreen(next: AddressSyncIntent.Next) {
|
||||
when (next.step) {
|
||||
private suspend fun trySkippingScreen(step: AddressSyncStep) {
|
||||
when (step) {
|
||||
AddressSyncStep.ASK_BIOMETRY -> {
|
||||
val shouldShowAskBiometry = canUseBiometryUseCase.strict() && shouldShowAskBiometryUseCase()
|
||||
if (shouldShowAskBiometry.not()) {
|
||||
nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = true))
|
||||
nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS))
|
||||
}
|
||||
}
|
||||
AddressSyncStep.ASK_NOTIFICATIONS -> {
|
||||
val shouldShowAskNotification = shouldAskPermissionUseCase(PUSH_PERMISSION)
|
||||
if (shouldShowAskNotification.not()) {
|
||||
nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ADDRESS_SYNC, shouldReplace = true))
|
||||
nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ADDRESS_SYNC))
|
||||
}
|
||||
}
|
||||
AddressSyncStep.ADDRESS_SYNC -> Unit
|
||||
|
|
@ -65,4 +79,22 @@ internal class AddressSyncModel @Inject constructor(
|
|||
private fun goBack() {
|
||||
stackNavigation.pop()
|
||||
}
|
||||
|
||||
private fun updateStepperPage(next: AddressSyncIntent.Next) {
|
||||
params.innerNavigation.update { innerNavigationState ->
|
||||
innerNavigationState.copy(
|
||||
stackSize = next.step.pageNumber,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTitle(next: AddressSyncIntent.Next) {
|
||||
params.parentParams.titleProvider.changeTitle(
|
||||
text = resourceReference(next.step.stringId),
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val ADDRESS_SYNC_MAX_STEPS = 3
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
package com.tangem.features.onboarding.v2.addresssync.navigation
|
||||
|
||||
enum class AddressSyncStep {
|
||||
ASK_BIOMETRY,
|
||||
ASK_NOTIFICATIONS,
|
||||
ADDRESS_SYNC,
|
||||
import androidx.annotation.StringRes
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
||||
enum class AddressSyncStep(val pageNumber: Int, @StringRes val stringId: Int) {
|
||||
ASK_BIOMETRY(pageNumber = 1, stringId = R.string.onboarding_navbar_title_biometrics),
|
||||
ASK_NOTIFICATIONS(pageNumber = 2, stringId = R.string.onboarding_title_notifications),
|
||||
ADDRESS_SYNC(pageNumber = 3, stringId = R.string.onboarding_navbar_title_last_step),
|
||||
}
|
||||
|
|
@ -194,6 +194,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
)
|
||||
AddressSync -> DefaultAddressSyncComponent(
|
||||
appComponentContext = childContext,
|
||||
params = childParams,
|
||||
askBiometryComponentFactory = askBiometryComponentFactory,
|
||||
pushNotificationsComponentFactory = pushNotificationsComponentFactory,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.model
|
||||
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.ui.userwallet.converter.ArtworkUMConverter
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
|
|
@ -70,7 +71,11 @@ internal class OnboardingMultiWalletModel @Inject constructor(
|
|||
onConfirm = {
|
||||
modelScope.launch {
|
||||
onboardingRepository.clearUnfinishedFinalizeOnboarding()
|
||||
router.pop()
|
||||
if (params.mode == OnboardingMultiWalletComponent.Mode.AddressSync) {
|
||||
router.replaceAll(AppRoute.Wallet)
|
||||
} else {
|
||||
router.pop()
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ fun screenTitleByStep(step: OnboardingMultiWalletState.Step): TextReference = wh
|
|||
OnboardingMultiWalletState.Step.Finalize -> resourceReference(R.string.onboarding_button_finalize_backup)
|
||||
OnboardingMultiWalletState.Step.Done -> resourceReference(R.string.common_done)
|
||||
OnboardingMultiWalletState.Step.UpgradeWallet -> resourceReference(R.string.common_tangem)
|
||||
OnboardingMultiWalletState.Step.AddressSync -> TODO("Will be implemented during [REDACTED_TASK_KEY]")
|
||||
OnboardingMultiWalletState.Step.AddressSync -> resourceReference(R.string.onboarding_navbar_title_biometrics)
|
||||
}
|
||||
|
|
@ -1,15 +1,23 @@
|
|||
package com.tangem.features.onboarding.v2.addresssync.model
|
||||
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.settings.CanUseBiometryUseCase
|
||||
import com.tangem.domain.settings.ShouldAskPermissionUseCase
|
||||
import com.tangem.domain.settings.ShouldShowAskBiometryUseCase
|
||||
import com.tangem.features.onboarding.v2.TitleProvider
|
||||
import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.MultiWalletInnerNavigationState
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
|
|
@ -23,12 +31,36 @@ internal class AddressSyncModelTest {
|
|||
private val shouldShowAskBiometryUseCase: ShouldShowAskBiometryUseCase = mockk()
|
||||
private val canUseBiometryUseCase: CanUseBiometryUseCase = mockk()
|
||||
private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase = mockk()
|
||||
private val paramsContainer: ParamsContainer = mockk()
|
||||
private val testInnerNavigation = MutableStateFlow(
|
||||
value = MultiWalletInnerNavigationState(
|
||||
stackSize = 0,
|
||||
stackMaxSize = 0,
|
||||
)
|
||||
)
|
||||
private val titleProvider: TitleProvider = mockk(relaxUnitFun = true)
|
||||
private val params: MultiWalletChildParams = mockk {
|
||||
every { innerNavigation } returns testInnerNavigation
|
||||
every { parentParams } returns mockk {
|
||||
every { titleProvider } returns this@AddressSyncModelTest.titleProvider
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
coEvery { canUseBiometryUseCase.strict() } returns false
|
||||
coEvery { shouldShowAskBiometryUseCase() } returns false
|
||||
coEvery { shouldAskPermissionUseCase(PUSH_PERMISSION) } returns false
|
||||
every { paramsContainer.require<MultiWalletChildParams>() } returns params
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN model is created THEN inner navigation stack size and max size are set`() = runTest {
|
||||
createModel(this)
|
||||
|
||||
val state = testInnerNavigation.value
|
||||
assert(state.stackSize == AddressSyncStep.ASK_BIOMETRY.pageNumber)
|
||||
assert(state.stackMaxSize == AddressSyncStep.entries.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -39,10 +71,11 @@ internal class AddressSyncModelTest {
|
|||
val model = createModel(this)
|
||||
val stack = model.stackNavigation.trackStack()
|
||||
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false))
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY))
|
||||
advanceUntilIdle()
|
||||
|
||||
assert(stack == listOf(AddressSyncStep.ASK_BIOMETRY))
|
||||
assertStepperAndTitleFor(AddressSyncStep.ASK_BIOMETRY)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -55,10 +88,11 @@ internal class AddressSyncModelTest {
|
|||
val model = createModel(this)
|
||||
val stack = model.stackNavigation.trackStack()
|
||||
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false))
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY))
|
||||
advanceUntilIdle()
|
||||
|
||||
assert(stack == listOf(AddressSyncStep.ASK_NOTIFICATIONS))
|
||||
assertStepperAndTitleFor(AddressSyncStep.ASK_NOTIFICATIONS)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -70,10 +104,11 @@ internal class AddressSyncModelTest {
|
|||
val model = createModel(this)
|
||||
val stack = model.stackNavigation.trackStack()
|
||||
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false))
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY))
|
||||
advanceUntilIdle()
|
||||
|
||||
assert(stack == listOf(AddressSyncStep.ADDRESS_SYNC))
|
||||
assertStepperAndTitleFor(AddressSyncStep.ADDRESS_SYNC)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -83,10 +118,11 @@ internal class AddressSyncModelTest {
|
|||
val model = createModel(this)
|
||||
val stack = model.stackNavigation.trackStack()
|
||||
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = false))
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS))
|
||||
advanceUntilIdle()
|
||||
|
||||
assert(stack == listOf(AddressSyncStep.ASK_NOTIFICATIONS))
|
||||
assertStepperAndTitleFor(AddressSyncStep.ASK_NOTIFICATIONS)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -96,10 +132,16 @@ internal class AddressSyncModelTest {
|
|||
val model = createModel(this)
|
||||
val stack = model.stackNavigation.trackStack()
|
||||
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = false))
|
||||
model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS))
|
||||
advanceUntilIdle()
|
||||
|
||||
assert(stack == listOf(AddressSyncStep.ADDRESS_SYNC))
|
||||
assertStepperAndTitleFor(AddressSyncStep.ADDRESS_SYNC)
|
||||
}
|
||||
|
||||
private fun assertStepperAndTitleFor(step: AddressSyncStep) {
|
||||
assert(testInnerNavigation.value.stackSize == step.pageNumber)
|
||||
verify { titleProvider.changeTitle(resourceReference(step.stringId)) }
|
||||
}
|
||||
|
||||
private fun StackNavigation<AddressSyncStep>.trackStack(): List<AddressSyncStep> {
|
||||
|
|
@ -118,6 +160,7 @@ internal class AddressSyncModelTest {
|
|||
shouldShowAskBiometryUseCase = shouldShowAskBiometryUseCase,
|
||||
canUseBiometryUseCase = canUseBiometryUseCase,
|
||||
shouldAskPermissionUseCase = shouldAskPermissionUseCase,
|
||||
paramsContainer = paramsContainer,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue