diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt index 05c3965563..28244b0ef5 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt @@ -37,6 +37,9 @@ internal class DefaultOnboardingRepository @Inject constructor( private val cardFrozenStateStore: TangemPayCardFrozenStateStore, ) : OnboardingRepository { + // Save data for a session + private var lastFetchedCustomerInfo: CustomerInfo? = null + override suspend fun validateDeeplink(link: String): Either { return requestHelper.runWithErrorLogs(TAG) { val result = tangemPayApi.validateDeeplink(DeeplinkValidityRequest(link)) @@ -115,6 +118,10 @@ internal class DefaultOnboardingRepository @Inject constructor( } } + override fun getSavedCustomerInfo(): CustomerInfo? { + return lastFetchedCustomerInfo + } + override suspend fun createOrder(): Either = withContext(dispatcherProvider.io) { requestHelper.runWithErrorLogs(TAG) { val walletAddress = requestHelper.getCustomerWalletAddress() @@ -162,7 +169,7 @@ internal class DefaultOnboardingRepository @Inject constructor( productInstance = productInstance, isKycApproved = response?.kyc?.status == APPROVED_KYC_STATUS, cardInfo = cardInfo, - ) + ).also { lastFetchedCustomerInfo = it } } private suspend fun getOrderStatus(orderId: String): OrderStatus { diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/OnboardingRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/OnboardingRepository.kt index 88d98ab106..8a21700f0e 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/OnboardingRepository.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/OnboardingRepository.kt @@ -21,4 +21,6 @@ interface OnboardingRepository { * Returns only if the user already authorised at least once */ suspend fun getMainScreenCustomerInfo(): Either + + fun getSavedCustomerInfo(): CustomerInfo? } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index b46968d616..e6007b1416 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -19,6 +19,8 @@ import com.tangem.domain.models.wallet.isMultiCurrency import com.tangem.domain.nft.ObserveAndClearNFTCacheIfNeedUseCase import com.tangem.domain.notifications.GetIsHuaweiDeviceWithoutGoogleServicesUseCase import com.tangem.domain.notifications.repository.NotificationsRepository +import com.tangem.domain.pay.model.MainScreenCustomerInfo +import com.tangem.domain.pay.model.OrderStatus import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import com.tangem.domain.pay.usecase.TangemPayIssueOrderUseCase @@ -358,6 +360,13 @@ internal class WalletModel @Inject constructor( // fast exit if (!tangemPayFeatureToggles.isTangemPayEnabled) return@onEach + // Don't refresh customer info periodically if the card was already issued, only update on swipe to refresh + val savedCustomerInfo = tangemPayOnboardingRepository.getSavedCustomerInfo() + if (savedCustomerInfo?.cardInfo != null) { + updateTangemPay(MainScreenCustomerInfo(info = savedCustomerInfo, orderStatus = OrderStatus.COMPLETED)) + return@onEach + } + updateTangemPayJobHolder.cancel() modelScope.launch { @@ -378,25 +387,27 @@ internal class WalletModel @Inject constructor( private suspend fun refreshTangemPayInfo() { val info = tangemPayMainScreenCustomerInfoUseCase() - if (info != null) { - val cardFrozenState = - info.info.productInstance?.cardId?.let { cardDetailsRepository.cardFrozenStateSync(it) } - ?: TangemPayCardFrozenState.Unfrozen - stateHolder.update( - transformer = TangemPayInitialStateTransformer( - value = info, - cardFrozenState = cardFrozenState, - onClickIssue = ::issueOrder, - onClickKyc = innerWalletRouter::openTangemPayOnboarding, - openDetails = { config -> - innerWalletRouter.openTangemPayDetails( - userWalletId = stateHolder.getSelectedWalletId(), - config = config, - ) - }, - ), - ) - } + if (info != null) updateTangemPay(info) + } + + private suspend fun updateTangemPay(info: MainScreenCustomerInfo) { + val cardFrozenState = + info.info.productInstance?.cardId?.let { cardDetailsRepository.cardFrozenStateSync(it) } + ?: TangemPayCardFrozenState.Unfrozen + stateHolder.update( + transformer = TangemPayInitialStateTransformer( + value = info, + cardFrozenState = cardFrozenState, + onClickIssue = ::issueOrder, + onClickKyc = innerWalletRouter::openTangemPayOnboarding, + openDetails = { config -> + innerWalletRouter.openTangemPayDetails( + userWalletId = stateHolder.getSelectedWalletId(), + config = config, + ) + }, + ), + ) } private fun issueOrder() { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt new file mode 100644 index 0000000000..bb38d85931 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt @@ -0,0 +1,60 @@ +package com.tangem.feature.wallet.child.wallet.model.intents + +import com.tangem.core.decompose.di.ModelScoped +import com.tangem.domain.pay.repository.OnboardingRepository +import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository +import com.tangem.domain.pay.usecase.TangemPayIssueOrderUseCase +import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase +import com.tangem.domain.visa.model.TangemPayCardFrozenState +import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController +import com.tangem.feature.wallet.presentation.wallet.state.transformers.TangemPayInitialStateTransformer +import com.tangem.feature.wallet.presentation.wallet.state.transformers.TangemPayIssueAvailableStateTransformer +import com.tangem.feature.wallet.presentation.wallet.state.transformers.TangemPayIssueProgressStateTransformer +import com.tangem.features.tangempay.TangemPayFeatureToggles +import kotlinx.coroutines.launch +import javax.inject.Inject + +internal interface TangemPayIntents { + + suspend fun onPullToRefresh() +} + +@ModelScoped +internal class TangemPayClickIntentsImplementor @Inject constructor( + private val stateHolder: WalletStateController, + private val mainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase, + private val issueOrderUseCase: TangemPayIssueOrderUseCase, + private val featureToggles: TangemPayFeatureToggles, + private val onboardingRepository: OnboardingRepository, + private val cardDetailsRepository: TangemPayCardDetailsRepository, +) : BaseWalletClickIntents(), TangemPayIntents { + + override suspend fun onPullToRefresh() { + if (!featureToggles.isTangemPayEnabled || !onboardingRepository.isTangemPayInitialDataProduced()) return + val info = mainScreenCustomerInfoUseCase() + val userWalletId = stateHolder.getSelectedWalletId() + if (info != null) { + val cardFrozenState = + info.info.productInstance?.cardId?.let { cardDetailsRepository.cardFrozenStateSync(it) } + ?: TangemPayCardFrozenState.Unfrozen + stateHolder.update( + transformer = TangemPayInitialStateTransformer( + value = info, + onClickIssue = ::issueOrder, + onClickKyc = router::openTangemPayOnboarding, + openDetails = { config -> router.openTangemPayDetails(userWalletId, config) }, + cardFrozenState = cardFrozenState, + ), + ) + } + } + + private fun issueOrder() { + modelScope.launch { + stateHolder.update(TangemPayIssueProgressStateTransformer()) + issueOrderUseCase().onLeft { + stateHolder.update(TangemPayIssueAvailableStateTransformer(onClickIssue = ::issueOrder)) + } + } + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletClickIntents.kt index 115b1114ba..2bc5de2881 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletClickIntents.kt @@ -39,13 +39,15 @@ internal class WalletClickIntents @Inject constructor( private val rampStateManager: RampStateManager, private val fetchHotCryptoUseCase: FetchHotCryptoUseCase, private val onrampStatusFactory: OnrampStatusFactory, + private val tangemPayIntents: TangemPayClickIntentsImplementor, ) : BaseWalletClickIntents(), WalletCardClickIntents by walletCardClickIntentsImplementor, WalletWarningsClickIntents by warningsClickIntentsImplementer, WalletCurrencyActionsClickIntents by currencyActionsClickIntentsImplementor, WalletContentClickIntents by contentClickIntentsImplementor, VisaWalletIntents by visaWalletIntentsImplementor, - WalletPushPermissionClickIntents by pushPermissionClickIntentsImplementor { + WalletPushPermissionClickIntents by pushPermissionClickIntentsImplementor, + TangemPayIntents by tangemPayIntents { override fun initialize(router: InnerWalletRouter, coroutineScope: CoroutineScope) { super.initialize(router, coroutineScope) @@ -56,6 +58,7 @@ internal class WalletClickIntents @Inject constructor( contentClickIntentsImplementor.initialize(router, coroutineScope) visaWalletIntentsImplementor.initialize(router, coroutineScope) pushPermissionClickIntentsImplementor.initialize(router, coroutineScope) + tangemPayIntents.initialize(router, coroutineScope) } fun onWalletChange(index: Int, onlyState: Boolean) { @@ -121,8 +124,8 @@ internal class WalletClickIntents @Inject constructor( buildList { async { rampStateManager.fetchSellServiceData() }.let(::add) - async { fetchHotCryptoUseCase() }.let(::add) + async { tangemPayIntents.onPullToRefresh() }.let(::add) } .awaitAll()