diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt index 44c9a4dd6d..eb7f85d306 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt @@ -93,6 +93,7 @@ fun getActiveIconRes(blockchainId: String): Int { "scroll", "scroll/test" -> R.drawable.ic_alert_24 // FIXME: add icon during full integration "zklink", "zklink/test" -> R.drawable.img_zklink_22 "vanar-chain", "vanar-chain/test" -> R.drawable.img_vanar_22 + "pepecoin", "pepecoin/test" -> R.drawable.img_pepecoin_22 else -> R.drawable.ic_alert_24 } } @@ -184,6 +185,7 @@ fun getActiveIconResByCoinId(coinId: String): Int { "scroll", "scroll/test" -> R.drawable.ic_alert_24 // FIXME: add icon during full integration "zklink", "zklink/test" -> R.drawable.img_zklink_22 "vanar-chain", "vanar-chain/test" -> R.drawable.img_vanar_22 + "pepecoin-network", "pepecoin-network/test" -> R.drawable.img_pepecoin_22 else -> R.drawable.ic_alert_24 } } @@ -278,6 +280,7 @@ fun getGreyedOutIconRes(blockchainId: String): Int { "scroll", "scroll/test" -> R.drawable.ic_alert_24 // FIXME: add icon during full integration "zklink", "zklink/test" -> R.drawable.ic_zklink_22 "vanar-chain", "vanar-chain/test" -> R.drawable.ic_vanar_22 + "pepecoin", "pepecoin/test" -> R.drawable.ic_pepecoin_22 else -> R.drawable.ic_alert_24 } } \ No newline at end of file diff --git a/core/ui/src/main/res/drawable/ic_pepecoin_22.xml b/core/ui/src/main/res/drawable/ic_pepecoin_22.xml new file mode 100644 index 0000000000..d7a3b4222b --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_pepecoin_22.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/ui/src/main/res/drawable/img_pepecoin_22.xml b/core/ui/src/main/res/drawable/img_pepecoin_22.xml new file mode 100644 index 0000000000..6c6907e9d7 --- /dev/null +++ b/core/ui/src/main/res/drawable/img_pepecoin_22.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt index 15c4a85353..021509cd04 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/note/impl/child/topup/model/OnboardingNoteTopUpModel.kt @@ -72,6 +72,7 @@ internal class OnboardingNoteTopUpModel @Inject constructor( observeArtwork() modelScope.launch { createUserWalletIfNull() + cardRepository.finishCardActivation(scanResponse.card.cardId) observeCryptoCurrencyStatus() refreshBalance() } @@ -163,10 +164,7 @@ internal class OnboardingNoteTopUpModel @Inject constructor( val amountToCreateAccount = (status.value as? CryptoCurrencyStatus.NoAccount)?.amountToCreateAccount if (amount?.isPositive() == true || hasCurrentNetworkTransactions) { - modelScope.launch { - cardRepository.finishCardActivation(scanResponse.card.cardId) - params.onDone() - } + params.onDone() } _uiState.update { diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/model/OnboardingTwinModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/model/OnboardingTwinModel.kt index 13f2c6af15..1219a5763f 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/model/OnboardingTwinModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/model/OnboardingTwinModel.kt @@ -27,6 +27,7 @@ import com.tangem.datasource.local.config.issuers.IssuersConfigStorage import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.common.TwinCardNumber import com.tangem.domain.common.getTwinCardNumber +import com.tangem.domain.common.util.twinsIsTwinned import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.scan.ScanResponse @@ -54,6 +55,7 @@ import com.tangem.sdk.extensions.localizedDescriptionRes import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.saveIn +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.firstOrNull @@ -108,10 +110,14 @@ internal class OnboardingTwinModel @Inject constructor( ) } Mode.CreateWallet -> { - OnboardingTwinUM.Welcome( - pairCardNumber = firstCardTwinNumber.pairNumber().number, - onContinueClick = ::navigateToFirstScan, - ) + if (params.scanResponse.twinsIsTwinned()) { + OnboardingTwinUM.TopUpPrepare + } else { + OnboardingTwinUM.Welcome( + pairCardNumber = firstCardTwinNumber.pairNumber().number, + onContinueClick = ::navigateToFirstScan, + ) + } } }, ) @@ -120,11 +126,19 @@ internal class OnboardingTwinModel @Inject constructor( val innerNavigationState = MutableStateFlow(DefaultOnboardingTwinComponent.TwinInnerNavigationState(1)) init { - if (_uiState.value is OnboardingTwinUM.Welcome) { - analyticsEventHandler.send(OnboardingEvent.Twins.ScreenOpened) - modelScope.launch { - saveTwinsOnboardingShownUseCase() + when (_uiState.value) { + is OnboardingTwinUM.Welcome -> { + analyticsEventHandler.send(OnboardingEvent.Twins.ScreenOpened) + modelScope.launch { + saveTwinsOnboardingShownUseCase() + } } + OnboardingTwinUM.TopUpPrepare -> { + modelScope.launch { + setTopUpState(params.scanResponse) + } + } + else -> {} } } @@ -298,55 +312,60 @@ internal class OnboardingTwinModel @Inject constructor( Mode.CreateWallet -> { modelScope.launch { setLoading(true) - - val userWallet = userWalletBuilderFactory.create(scanResponse).build() ?: run { - Timber.e("User wallet not created") - setLoading(false) - return@launch - } - - userWalletsListManager.save(userWallet, canOverride = true) - - fetchCurrencyStatusUseCase.invoke( - userWalletId = userWallet.walletId, - refresh = true, - ).onLeft { - Timber.e("Unable to fetch currency status: $it") - setLoading(false) - } - - val cryptoCurrencyStatus = - getPrimaryCurrencyStatusUpdatesUseCase.invoke(userWallet.walletId).firstOrNull()?.getOrNull() - ?: run { - setLoading(false) - Timber.e("Unable to get currency status") - return@launch - } - - launch { - getPrimaryCurrencyStatusUpdatesUseCase.invoke(userWallet.walletId) - .collect { - it.onRight { status -> - applyCryptoCurrencyStatusToState(status) - } - } - } - - _uiState.value = OnboardingTwinUM.TopUp( - onBuyCryptoClick = { onBuyCryptoClick(cryptoCurrencyStatus) }, - onRefreshClick = { onRefreshBalanceClick(userWallet) }, - onShowAddressClick = { onShowAddressClick(cryptoCurrencyStatus) }, - isLoading = true, - ) - - innerNavigationState.update { - it.copy(stackSize = 4) - } + setTopUpState(scanResponse) }.saveIn(cryptoCurrencyStatusJobHolder) } } } + private suspend fun setTopUpState(scanResponse: ScanResponse) = coroutineScope { + val userWallet = userWalletBuilderFactory.create(scanResponse).build() ?: run { + Timber.e("User wallet not created") + setLoading(false) + return@coroutineScope + } + + userWalletsListManager.save(userWallet, canOverride = true) + + cardRepository.finishCardActivation(params.scanResponse.card.cardId) + + fetchCurrencyStatusUseCase.invoke( + userWalletId = userWallet.walletId, + refresh = true, + ).onLeft { + Timber.e("Unable to fetch currency status: $it") + setLoading(false) + } + + val cryptoCurrencyStatus = + getPrimaryCurrencyStatusUpdatesUseCase.invoke(userWallet.walletId).firstOrNull()?.getOrNull() + ?: run { + setLoading(false) + Timber.e("Unable to get currency status") + return@coroutineScope + } + + launch { + getPrimaryCurrencyStatusUpdatesUseCase.invoke(userWallet.walletId) + .collect { + it.onRight { status -> + applyCryptoCurrencyStatusToState(status) + } + } + } + + _uiState.value = OnboardingTwinUM.TopUp( + onBuyCryptoClick = { onBuyCryptoClick(cryptoCurrencyStatus) }, + onRefreshClick = { onRefreshBalanceClick(userWallet) }, + onShowAddressClick = { onShowAddressClick(cryptoCurrencyStatus) }, + isLoading = true, + ) + + innerNavigationState.update { + it.copy(stackSize = 4) + } + } + private fun applyCryptoCurrencyStatusToState(status: CryptoCurrencyStatus) { val amount = (status.value as? CryptoCurrencyStatus.Loaded)?.amount ?: return if (amount > BigDecimal.ZERO) { diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/ui/OnboardingTwin.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/ui/OnboardingTwin.kt index 01799c96cc..c67669148b 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/ui/OnboardingTwin.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/ui/OnboardingTwin.kt @@ -62,6 +62,7 @@ internal fun OnboardingTwin(state: OnboardingTwinUM, modifier: Modifier = Modifi is OnboardingTwinUM.ScanCard -> ScanCard(st) is OnboardingTwinUM.TopUp -> TopUp(st) is OnboardingTwinUM.Welcome -> Welcome(st) + OnboardingTwinUM.TopUpPrepare -> {} } } } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/ui/state/OnboardingTwinUM.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/ui/state/OnboardingTwinUM.kt index 89ffc6efc6..7341af8545 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/ui/state/OnboardingTwinUM.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/twin/impl/ui/state/OnboardingTwinUM.kt @@ -11,6 +11,12 @@ internal sealed class OnboardingTwinUM { abstract val isLoading: Boolean abstract val artwork: TwinWalletArtworkUM + data object TopUpPrepare : OnboardingTwinUM() { + override val stepIndex: Int = 0 + override val isLoading: Boolean = false + override val artwork: TwinWalletArtworkUM = TwinWalletArtworkUM.Spread + } + data class Welcome( override val isLoading: Boolean = false, val pairCardNumber: Int = 2, @@ -67,5 +73,6 @@ internal sealed class OnboardingTwinUM { is ResetWarning -> copy() is ScanCard -> copy(isLoading = isLoading) is TopUp -> copy(isLoading = isLoading) + TopUpPrepare -> this } } \ No newline at end of file