Updated on 2026-08-14
This commit is contained in:
parent
f086d6bb74
commit
40fe8bb5cb
56 changed files with 82 additions and 1491 deletions
|
|
@ -147,7 +147,6 @@ dependencies {
|
|||
implementation(projects.features.kyc.api)
|
||||
implementation(projects.features.tokenRecieve.api)
|
||||
implementation(projects.features.yieldSupply.api)
|
||||
implementation(projects.features.tangempay.details.api)
|
||||
implementation(projects.features.feed.api)
|
||||
implementation(projects.features.promoBanners.api)
|
||||
implementation(projects.features.tangempay.main.api)
|
||||
|
|
|
|||
|
|
@ -14,12 +14,13 @@ import com.tangem.core.decompose.model.Model
|
|||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.account.status.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.apptheme.GetAppThemeModeUseCase
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
import com.tangem.domain.assetsdiscovery.usecase.StartAssetsDiscoveryUseCase
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.wallet.*
|
||||
|
|
@ -27,7 +28,6 @@ import com.tangem.domain.notifications.GetIsHuaweiDeviceWithoutGoogleServicesUse
|
|||
import com.tangem.domain.notifications.repository.NotificationsRepository
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase
|
||||
import com.tangem.domain.qrscanning.models.ClassifiedQrContent
|
||||
import com.tangem.domain.qrscanning.models.QrResultSource
|
||||
import com.tangem.domain.qrscanning.models.QrSendTarget
|
||||
|
|
@ -38,8 +38,6 @@ import com.tangem.domain.settings.*
|
|||
import com.tangem.domain.tokens.RefreshMultiCurrencyWalletQuotesUseCase
|
||||
import com.tangem.domain.walletconnect.WcPairService
|
||||
import com.tangem.domain.walletconnect.model.WcPairRequest
|
||||
import com.tangem.domain.assetsdiscovery.usecase.StartAssetsDiscoveryUseCase
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyUpdateUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -62,15 +60,15 @@ import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSend
|
|||
import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.KycRejectedCallbacks
|
||||
import com.tangem.feature.wallet.presentation.wallet.utils.ScreenLifecycleProvider
|
||||
import com.tangem.features.biometry.AskBiometryComponent
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.features.wallet.deeplink.WalletDeepLinkActionListener
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.*
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.*
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val TANGEM_PAY_UPDATE_INTERVAL = 60_000L
|
||||
|
|
@ -108,7 +106,6 @@ internal class WalletModel @Inject constructor(
|
|||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val yieldSupplyApyUpdateUseCase: YieldSupplyApyUpdateUseCase,
|
||||
private val tangemPayOnboardingRepository: OnboardingRepository,
|
||||
private val tangemPayMainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase,
|
||||
private val getAppThemeModeUseCase: GetAppThemeModeUseCase,
|
||||
private val trackingContextProxy: TrackingContextProxy,
|
||||
private val singleAccountListSupplier: SingleAccountListSupplier,
|
||||
|
|
@ -121,7 +118,6 @@ internal class WalletModel @Inject constructor(
|
|||
private val wcPairService: WcPairService,
|
||||
private val resolveQrSendTargetsUseCase: ResolveQrSendTargetsUseCase,
|
||||
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val startAssetsDiscoveryUseCase: StartAssetsDiscoveryUseCase,
|
||||
|
|
@ -436,17 +432,14 @@ internal class WalletModel @Inject constructor(
|
|||
if (isShouldLaunchPeriodicUpdate) {
|
||||
updateTangemPayJobHolder.cancel()
|
||||
modelScope.launch {
|
||||
tangemPayMainScreenCustomerInfoUseCase.fetch(userWalletId)
|
||||
paymentAccountStatusFetcher.invoke(PaymentAccountStatusFetcher.Params(userWalletId))
|
||||
while (isActive) {
|
||||
delay(TANGEM_PAY_UPDATE_INTERVAL)
|
||||
tangemPayMainScreenCustomerInfoUseCase.fetch(userWalletId)
|
||||
paymentAccountStatusFetcher.invoke(PaymentAccountStatusFetcher.Params(userWalletId))
|
||||
}
|
||||
}.saveIn(updateTangemPayJobHolder)
|
||||
} else {
|
||||
// Don't refresh customer info periodically if the card was already issued, only update on swipe to refresh
|
||||
tangemPayMainScreenCustomerInfoUseCase.fetch(userWalletId)
|
||||
paymentAccountStatusFetcher.invoke(PaymentAccountStatusFetcher.Params(userWalletId))
|
||||
}
|
||||
}.launchIn(modelScope)
|
||||
|
|
@ -555,7 +548,6 @@ internal class WalletModel @Inject constructor(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = tangemPayFeatureToggles.isTangemPayAccountsRefactorEnabled,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -602,7 +594,6 @@ internal class WalletModel @Inject constructor(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = tangemPayFeatureToggles.isTangemPayAccountsRefactorEnabled,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -624,7 +615,6 @@ internal class WalletModel @Inject constructor(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = tangemPayFeatureToggles.isTangemPayAccountsRefactorEnabled,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -639,7 +629,6 @@ internal class WalletModel @Inject constructor(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = tangemPayFeatureToggles.isTangemPayAccountsRefactorEnabled,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -701,7 +690,6 @@ internal class WalletModel @Inject constructor(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = tangemPayFeatureToggles.isTangemPayAccountsRefactorEnabled,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,11 +22,10 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.TangemPayDetailsConfig
|
||||
import com.tangem.domain.pay.TangemPayEligibilityManager
|
||||
import com.tangem.domain.pay.model.TangemPayEntryPoint
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
|
||||
import com.tangem.domain.pay.model.TangemPayEntryPoint
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
|
||||
import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletDialogConfig
|
||||
|
|
@ -72,7 +71,6 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
|
|||
private val produceInitialDataTangemPay: ProduceTangemPayInitialDataUseCase,
|
||||
private val getWalletMetainfoUseCase: GetWalletMetaInfoUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val tangemPayMainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase,
|
||||
private val tangemPayOnboardingRepository: OnboardingRepository,
|
||||
private val tangemPayEligibilityManager: TangemPayEligibilityManager,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
|
|
@ -85,7 +83,6 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
|
|||
if (!onboardingRepository.isTangemPayInitialDataProduced(userWalletId)) {
|
||||
return
|
||||
}
|
||||
tangemPayMainScreenCustomerInfoUseCase.fetch(userWalletId)
|
||||
paymentAccountStatusFetcher.invoke(PaymentAccountStatusFetcher.Params(userWalletId))
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +97,6 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
|
|||
modelScope.launch {
|
||||
produceInitialDataTangemPay.invoke(userWallet.walletId)
|
||||
.onRight {
|
||||
tangemPayMainScreenCustomerInfoUseCase.fetch(userWallet.walletId)
|
||||
paymentAccountStatusFetcher.invoke(PaymentAccountStatusFetcher.Params(userWallet.walletId))
|
||||
}
|
||||
.onLeft {
|
||||
|
|
@ -277,7 +273,6 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
|
|||
modelScope.launch {
|
||||
tangemPayOnboardingRepository.disableTangemPay(userWalletId)
|
||||
.onRight {
|
||||
tangemPayMainScreenCustomerInfoUseCase.fetch(userWalletId)
|
||||
paymentAccountStatusFetcher.invoke(PaymentAccountStatusFetcher.Params(userWalletId))
|
||||
}
|
||||
.onLeft { uiMessageSender.send(ToastMessage(resourceReference(R.string.common_something_went_wrong))) }
|
||||
|
|
|
|||
|
|
@ -217,15 +217,8 @@ internal object WalletScreenPreviewDataLegacy {
|
|||
isFlickering = false,
|
||||
onItemClick = { },
|
||||
),
|
||||
tangemPayState = TangemPayState.Card(
|
||||
lastFourDigits = stringReference("*1234"),
|
||||
balanceText = stringReference("$10"),
|
||||
balanceSymbol = stringReference("USDC"),
|
||||
onClick = {},
|
||||
),
|
||||
type = WalletType.Cold,
|
||||
tangemPayMainUM = TangemPayMainUM.Empty,
|
||||
isTangemPayRefactorEnabled = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.analytics.utils
|
|||
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.models.kyc.KycStatus
|
||||
import com.tangem.domain.pay.model.MainScreenCustomerInfo
|
||||
import com.tangem.domain.pay.model.OrderStatus
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.feature.wallet.presentation.wallet.utils.ScreenLifecycleProvider
|
||||
import javax.inject.Inject
|
||||
|
|
@ -15,26 +13,23 @@ internal class WalletTangemPayAnalyticsEventSender @Inject constructor(
|
|||
private val screenLifecycleProvider: ScreenLifecycleProvider,
|
||||
) {
|
||||
|
||||
private val sentEvents = mutableSetOf<TangemPayAnalyticsEvents>()
|
||||
private val sentEvents = mutableSetOf<String>()
|
||||
|
||||
fun send(customerInfo: MainScreenCustomerInfo) {
|
||||
fun send(statusValue: PaymentAccountStatusValue) {
|
||||
if (screenLifecycleProvider.isBackgroundState.value) return
|
||||
|
||||
val cardInfo = customerInfo.info.cardInfo
|
||||
val productInstance = customerInfo.info.productInstance
|
||||
|
||||
// TODO: TangemPay refactor analytics
|
||||
// when statement copied from TangemPayUpdateInfoStateTransformer. Be careful when editing
|
||||
val event = when {
|
||||
// ignore cancelled state on analytics
|
||||
customerInfo.orderStatus == OrderStatus.CANCELED -> return
|
||||
// ignore kyc not approved state on analytics
|
||||
customerInfo.info.kycStatus != KycStatus.APPROVED -> return
|
||||
cardInfo != null && productInstance != null -> return
|
||||
else -> TangemPayAnalyticsEvents.IssuingBannerDisplayed()
|
||||
val event = when (statusValue) {
|
||||
is PaymentAccountStatusValue.IssuingCard -> TangemPayAnalyticsEvents.IssuingBannerDisplayed()
|
||||
PaymentAccountStatusValue.Empty,
|
||||
is PaymentAccountStatusValue.Error,
|
||||
is PaymentAccountStatusValue.Loaded,
|
||||
PaymentAccountStatusValue.Loading,
|
||||
PaymentAccountStatusValue.NotCreated,
|
||||
is PaymentAccountStatusValue.UnderReview,
|
||||
-> return
|
||||
}
|
||||
|
||||
if (sentEvents.add(event)) {
|
||||
if (sentEvents.add(event.id)) {
|
||||
analyticsEventHandler.send(event)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,15 @@ package com.tangem.feature.wallet.presentation.wallet.domain
|
|||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tokens.wallet.WalletBalanceFetcher
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveInAndJoin
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
@ -28,7 +27,6 @@ import javax.inject.Singleton
|
|||
internal class WalletContentFetcher @Inject constructor(
|
||||
private val walletBalanceFetcher: WalletBalanceFetcher,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
) {
|
||||
|
||||
private val fetchingJobMap = ConcurrentHashMap<UserWalletId, JobHolder>()
|
||||
|
|
@ -66,12 +64,8 @@ internal class WalletContentFetcher @Inject constructor(
|
|||
TangemLogger.d("Start fetching for $userWalletId")
|
||||
|
||||
val maybeResult = launch {
|
||||
walletBalanceFetcher(
|
||||
params = WalletBalanceFetcher.Params(
|
||||
userWalletId = userWalletId,
|
||||
isPaymentAccountRefactorEnabled = tangemPayFeatureToggles.isTangemPayAccountsRefactorEnabled,
|
||||
),
|
||||
).onLeft { TangemLogger.e("Error", it) }
|
||||
walletBalanceFetcher(params = WalletBalanceFetcher.Params(userWalletId = userWalletId))
|
||||
.onLeft { TangemLogger.e("Error", it) }
|
||||
}
|
||||
.saveInAndJoin(jobHolder)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.model
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
@Immutable
|
||||
internal sealed class TangemPayState {
|
||||
|
||||
object Empty : TangemPayState()
|
||||
|
||||
data object Loading : TangemPayState()
|
||||
|
||||
data class OnboardingBanner(
|
||||
val onClick: () -> Unit,
|
||||
val closeOnClick: () -> Unit,
|
||||
) : TangemPayState()
|
||||
|
||||
data class Progress(
|
||||
val title: TextReference,
|
||||
val description: TextReference,
|
||||
val buttonText: TextReference,
|
||||
@DrawableRes val iconRes: Int,
|
||||
val onButtonClick: () -> Unit,
|
||||
val showProgress: Boolean = false,
|
||||
) : TangemPayState()
|
||||
|
||||
data class FailedIssue(
|
||||
val title: TextReference,
|
||||
val description: TextReference,
|
||||
@DrawableRes val iconRes: Int,
|
||||
val onButtonClick: () -> Unit,
|
||||
) : TangemPayState()
|
||||
|
||||
data class Card(
|
||||
val lastFourDigits: TextReference,
|
||||
val balanceText: TextReference,
|
||||
val balanceSymbol: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
) : TangemPayState()
|
||||
|
||||
data class RefreshNeeded(
|
||||
val notification: WalletNotification,
|
||||
) : TangemPayState()
|
||||
|
||||
data class TemporaryUnavailable(val notification: WalletNotification) : TangemPayState()
|
||||
|
||||
data object ExposedDevice : TangemPayState()
|
||||
}
|
||||
|
|
@ -24,9 +24,7 @@ internal sealed interface WalletState : WalletStateHolder {
|
|||
abstract val tokensListState: WalletTokensListState
|
||||
abstract val nftState: WalletNFTItemUM
|
||||
abstract val type: WalletType
|
||||
abstract val tangemPayState: TangemPayState
|
||||
abstract val tangemPayMainUM: TangemPayMainUM
|
||||
abstract val isTangemPayRefactorEnabled: Boolean // TANGEM_PAY_ACCOUNTS_REFACTOR_ENABLED
|
||||
abstract val assetsDiscoveryProgressUM: AssetsDiscoveryProgressUM
|
||||
|
||||
data class Content(
|
||||
|
|
@ -38,9 +36,7 @@ internal sealed interface WalletState : WalletStateHolder {
|
|||
override val tokensListState: WalletTokensListState,
|
||||
override val nftState: WalletNFTItemUM,
|
||||
override val type: WalletType,
|
||||
override val tangemPayState: TangemPayState,
|
||||
override val tangemPayMainUM: TangemPayMainUM,
|
||||
override val isTangemPayRefactorEnabled: Boolean,
|
||||
override val assetsDiscoveryProgressUM: AssetsDiscoveryProgressUM = AssetsDiscoveryProgressUM.Idle,
|
||||
) : MultiCurrency()
|
||||
|
||||
|
|
@ -60,9 +56,7 @@ internal sealed interface WalletState : WalletStateHolder {
|
|||
|
||||
override val tokensListState = WalletTokensListState.ContentState.Locked
|
||||
override val nftState: WalletNFTItemUM = WalletNFTItemUM.Hidden
|
||||
override val tangemPayState: TangemPayState = TangemPayState.Empty
|
||||
override val tangemPayMainUM: TangemPayMainUM = TangemPayMainUM.Empty
|
||||
override val isTangemPayRefactorEnabled: Boolean = false
|
||||
override val assetsDiscoveryProgressUM: AssetsDiscoveryProgressUM = AssetsDiscoveryProgressUM.Idle
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ internal class AddWalletTransformer(
|
|||
private val clickIntents: WalletClickIntents,
|
||||
private val walletImageResolver: WalletImageResolver,
|
||||
private val getWalletIconUseCase: GetWalletIconUseCase,
|
||||
private val isTangemPayRefactorEnabled: Boolean,
|
||||
) : WalletScreenStateTransformer {
|
||||
|
||||
private val walletLoadingStateFactory by lazy {
|
||||
|
|
@ -21,7 +20,6 @@ internal class AddWalletTransformer(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = isTangemPayRefactorEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ internal class InitializeWalletsTransformer(
|
|||
private val clickIntents: WalletClickIntents,
|
||||
private val walletImageResolver: WalletImageResolver,
|
||||
private val getWalletIconUseCase: GetWalletIconUseCase,
|
||||
private val isTangemPayRefactorEnabled: Boolean,
|
||||
) : WalletScreenStateTransformer {
|
||||
|
||||
private val walletLoadingStateFactory by lazy {
|
||||
|
|
@ -35,7 +34,6 @@ internal class InitializeWalletsTransformer(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = isTangemPayRefactorEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ internal class ReinitializeNewWalletTransformer(
|
|||
private val clickIntents: WalletClickIntents,
|
||||
private val walletImageResolver: WalletImageResolver,
|
||||
private val getWalletIconUseCase: GetWalletIconUseCase,
|
||||
private val isTangemPayRefactorEnabled: Boolean,
|
||||
) : WalletScreenStateTransformer {
|
||||
|
||||
private val walletLoadingStateFactory by lazy {
|
||||
|
|
@ -32,7 +31,6 @@ internal class ReinitializeNewWalletTransformer(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = isTangemPayRefactorEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ internal class ReinitializeWalletTransformer(
|
|||
private val clickIntents: WalletClickIntents,
|
||||
private val walletImageResolver: WalletImageResolver,
|
||||
private val getWalletIconUseCase: GetWalletIconUseCase,
|
||||
private val isTangemPayRefactorEnabled: Boolean,
|
||||
) : WalletStateTransformer(userWalletId = userWallet.walletId) {
|
||||
|
||||
private val walletLoadingStateFactory by lazy {
|
||||
|
|
@ -28,7 +27,6 @@ internal class ReinitializeWalletTransformer(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = isTangemPayRefactorEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
||||
internal class TangemPayExposedDeviceTransformer(
|
||||
userWalletId: UserWalletId,
|
||||
) : WalletStateTransformer(userWalletId) {
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
return if (prevState is WalletState.MultiCurrency.Content) {
|
||||
prevState.copy(tangemPayState = TangemPayState.ExposedDevice)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
return walletUM // todo redesign main
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
||||
internal class TangemPayHiddenStateTransformer(
|
||||
userWalletId: UserWalletId,
|
||||
) : WalletStateTransformer(userWalletId) {
|
||||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
return if (prevState is WalletState.MultiCurrency.Content) {
|
||||
prevState.copy(tangemPayState = TangemPayState.Empty)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
return walletUM // todo redesign main
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayMainUM
|
||||
|
|
@ -12,7 +11,7 @@ internal class TangemPayHideOnboardingStateTransformer(
|
|||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
return if (prevState is WalletState.MultiCurrency.Content) {
|
||||
prevState.copy(tangemPayState = TangemPayState.Empty, tangemPayMainUM = TangemPayMainUM.Empty)
|
||||
prevState.copy(tangemPayMainUM = TangemPayMainUM.Empty)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
||||
internal class TangemPayLoadingStateTransformer(userWalletId: UserWalletId) : WalletStateTransformer(userWalletId) {
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
return if (prevState is WalletState.MultiCurrency.Content) {
|
||||
prevState.copy(tangemPayState = TangemPayState.Loading)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
return walletUM // todo redesign main
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
||||
internal class TangemPayOnboardingBannerStateTransformer(
|
||||
userWalletId: UserWalletId,
|
||||
private val onClick: (UserWalletId) -> Unit,
|
||||
private val closeOnClick: (UserWalletId) -> Unit,
|
||||
) : WalletStateTransformer(userWalletId) {
|
||||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
return if (prevState is WalletState.MultiCurrency.Content) {
|
||||
prevState.copy(
|
||||
tangemPayState = TangemPayState.OnboardingBanner(
|
||||
onClick = { onClick(userWalletId) },
|
||||
closeOnClick = { closeOnClick(userWalletId) },
|
||||
),
|
||||
)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
return walletUM // todo redesign main
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification.Warning.TangemPayRefreshNeeded
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
||||
internal class TangemPayRefreshNeededStateTransformer(
|
||||
userWalletId: UserWalletId,
|
||||
private val userWallet: UserWallet,
|
||||
private val onRefreshClick: () -> Unit,
|
||||
) : WalletStateTransformer(userWalletId = userWalletId) {
|
||||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
val tangemPayState = TangemPayState.RefreshNeeded(
|
||||
notification = TangemPayRefreshNeeded(
|
||||
buttonText = when (userWallet) {
|
||||
is UserWallet.Cold -> resourceReference(id = R.string.home_button_scan)
|
||||
is UserWallet.Hot -> resourceReference(id = R.string.tangempay_sync_needed_restore_access)
|
||||
},
|
||||
onRefreshClick = onRefreshClick,
|
||||
shouldShowProgress = false,
|
||||
),
|
||||
)
|
||||
return if (prevState is WalletState.MultiCurrency.Content) {
|
||||
prevState.copy(tangemPayState = tangemPayState)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
return walletUM // todo redesign main
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
|
@ -14,9 +13,6 @@ internal class TangemPayRefreshShowProgressTransformer(
|
|||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
val multiContentState = prevState as? WalletState.MultiCurrency.Content ?: return prevState
|
||||
val refreshNeededState = multiContentState.tangemPayState as? TangemPayState.RefreshNeeded ?: return prevState
|
||||
val refreshNotification =
|
||||
refreshNeededState.notification as? WalletNotification.Warning.TangemPayRefreshNeeded ?: return prevState
|
||||
val newWarnings = prevState.warnings.map { warning ->
|
||||
if (warning is WalletNotification.Warning.TangemPayRefreshNeeded) {
|
||||
warning.copy(shouldShowProgress = shouldShowProgress)
|
||||
|
|
@ -25,12 +21,7 @@ internal class TangemPayRefreshShowProgressTransformer(
|
|||
}
|
||||
}
|
||||
|
||||
return multiContentState.copy(
|
||||
tangemPayState = refreshNeededState.copy(
|
||||
notification = refreshNotification.copy(shouldShowProgress = shouldShowProgress),
|
||||
),
|
||||
warnings = newWarnings.toImmutableList(),
|
||||
)
|
||||
return multiContentState.copy(warnings = newWarnings.toImmutableList())
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
|
||||
internal class TangemPayUnavailableStateTransformer(
|
||||
userWalletId: UserWalletId,
|
||||
) : WalletStateTransformer(userWalletId) {
|
||||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
return if (prevState is WalletState.MultiCurrency.Content) {
|
||||
prevState.copy(
|
||||
tangemPayState = TangemPayState.TemporaryUnavailable(
|
||||
notification = WalletNotification.Warning.TangemPayUnreachable,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
return walletUM // todo redesign main
|
||||
}
|
||||
}
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.models.kyc.KycStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.TangemPayDetailsConfig
|
||||
import com.tangem.domain.pay.model.CustomerInfo.CardInfo
|
||||
import com.tangem.domain.pay.model.CustomerInfo.ProductInstance
|
||||
import com.tangem.domain.pay.model.MainScreenCustomerInfo
|
||||
import com.tangem.domain.pay.model.OrderStatus
|
||||
import com.tangem.domain.visa.model.TangemPayCardFrozenState
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.TangemPayIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState.Progress
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
import java.util.Currency
|
||||
|
||||
/**
|
||||
* Hardcode Polygon chain id only for F&F.
|
||||
* Later chain id will be fetched from BFF.
|
||||
*/
|
||||
private const val POLYGON_CHAIN_ID = 137
|
||||
|
||||
internal class TangemPayUpdateInfoStateTransformer(
|
||||
userWalletId: UserWalletId,
|
||||
private val value: MainScreenCustomerInfo,
|
||||
private val cardFrozenState: TangemPayCardFrozenState,
|
||||
private val tangemPayClickIntents: TangemPayIntents,
|
||||
) : WalletStateTransformer(userWalletId = userWalletId) {
|
||||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
val tangemPayState = createInitialState()
|
||||
return if (prevState is WalletState.MultiCurrency.Content) {
|
||||
prevState.copy(tangemPayState = tangemPayState)
|
||||
} else {
|
||||
prevState
|
||||
}
|
||||
}
|
||||
|
||||
override fun transform(walletUM: WalletUM): WalletUM {
|
||||
return walletUM // todo redesign main
|
||||
}
|
||||
|
||||
private fun createInitialState(): TangemPayState {
|
||||
val cardInfo = value.info.cardInfo
|
||||
val productInstance = value.info.productInstance
|
||||
val customerId = value.info.customerId ?: "Unknown"
|
||||
|
||||
// when statement copied to WalletTangemPayAnalyticsEventSender. Be careful when editing.
|
||||
return when {
|
||||
value.info.kycStatus != KycStatus.APPROVED && !value.info.customerId.isNullOrEmpty() ->
|
||||
createKycInProgressState(kycStatus = value.info.kycStatus, customerId = customerId)
|
||||
value.orderStatus == OrderStatus.CANCELED -> createCancelledState(customerId)
|
||||
cardInfo != null && productInstance != null && value.orderStatus == OrderStatus.COMPLETED ->
|
||||
getCardInfoState(customerId, cardInfo, productInstance)
|
||||
else -> createIssueProgressState()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCardInfoState(
|
||||
customerId: String,
|
||||
cardInfo: CardInfo,
|
||||
productInstance: ProductInstance,
|
||||
): TangemPayState = TangemPayState.Card(
|
||||
lastFourDigits = TextReference.Str("*${cardInfo.lastFourDigits}"),
|
||||
balanceText = TextReference.Str(getBalanceText(cardInfo)),
|
||||
balanceSymbol = stringReference("USDC"), // TODO hardcode for now
|
||||
onClick = {
|
||||
tangemPayClickIntents.openDetails(
|
||||
userWalletId,
|
||||
TangemPayDetailsConfig(
|
||||
customerId = customerId,
|
||||
cardId = productInstance.cardId,
|
||||
isPinSet = cardInfo.isPinSet,
|
||||
cardFrozenState = cardFrozenState,
|
||||
cardNumberEnd = cardInfo.lastFourDigits,
|
||||
chainId = POLYGON_CHAIN_ID,
|
||||
displayName = productInstance.displayName,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
private fun getBalanceText(cardInfo: CardInfo): String {
|
||||
val currency = Currency.getInstance(cardInfo.currencyCode)
|
||||
return cardInfo.balance.format {
|
||||
fiat(fiatCurrencyCode = currency.currencyCode, fiatCurrencySymbol = currency.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createKycInProgressState(kycStatus: KycStatus, customerId: String): TangemPayState = Progress(
|
||||
title = TextReference.Res(R.string.tangempay_payment_account),
|
||||
description = when (kycStatus) {
|
||||
KycStatus.REJECTED -> TextReference.Res(R.string.tangempay_kyc_has_failed)
|
||||
else -> TextReference.Res(R.string.tangempay_kyc_in_progress)
|
||||
},
|
||||
buttonText = TextReference.Res(R.string.tangempay_kyc_in_progress_notification_button),
|
||||
iconRes = R.drawable.ic_promo_kyc_36,
|
||||
onButtonClick = {
|
||||
when (kycStatus) {
|
||||
KycStatus.REJECTED -> tangemPayClickIntents.onKycRejectedClicked(
|
||||
userWalletId = userWalletId,
|
||||
customerId = customerId,
|
||||
)
|
||||
else -> tangemPayClickIntents.onKycProgressClicked(userWalletId)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
private fun createIssueProgressState(): TangemPayState = Progress(
|
||||
title = TextReference.Res(R.string.tangempay_payment_account),
|
||||
description = TextReference.Res(R.string.tangempay_issuing_your_card),
|
||||
buttonText = TextReference.EMPTY,
|
||||
iconRes = R.drawable.ic_tangem_pay_promo_card_36,
|
||||
onButtonClick = tangemPayClickIntents::onIssuingCardClicked,
|
||||
showProgress = true,
|
||||
)
|
||||
|
||||
private fun createCancelledState(customerId: String): TangemPayState = TangemPayState.FailedIssue(
|
||||
title = TextReference.Res(R.string.tangempay_payment_account),
|
||||
description = TextReference.Res(R.string.tangempay_failed_to_issue_card),
|
||||
iconRes = R.drawable.ic_alert_24,
|
||||
onButtonClick = { tangemPayClickIntents.onIssuingFailedClicked(customerId) },
|
||||
)
|
||||
}
|
||||
|
|
@ -9,16 +9,15 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenSta
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletLoadingStateFactory
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
|
||||
internal class UnlockWalletTransformer(
|
||||
private val unlockedWallets: List<UserWallet>,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
private val walletImageResolver: WalletImageResolver,
|
||||
private val getWalletIconUseCase: GetWalletIconUseCase,
|
||||
private val isTangemPayRefactorEnabled: Boolean,
|
||||
) : WalletScreenStateTransformer {
|
||||
|
||||
private val walletLoadingStateFactory by lazy {
|
||||
|
|
@ -26,7 +25,6 @@ internal class UnlockWalletTransformer(
|
|||
clickIntents = clickIntents,
|
||||
walletImageResolver = walletImageResolver,
|
||||
getWalletIconUseCase = getWalletIconUseCase,
|
||||
isTangemPayRefactorEnabled = isTangemPayRefactorEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ internal class WalletLoadingStateFactory(
|
|||
private val clickIntents: WalletClickIntents,
|
||||
private val walletImageResolver: WalletImageResolver,
|
||||
private val getWalletIconUseCase: GetWalletIconUseCase,
|
||||
private val isTangemPayRefactorEnabled: Boolean,
|
||||
) {
|
||||
|
||||
fun create(userWallet: UserWallet): WalletState {
|
||||
|
|
@ -83,9 +82,7 @@ internal class WalletLoadingStateFactory(
|
|||
tokensListState = WalletTokensListState.ContentState.Loading,
|
||||
nftState = WalletNFTItemUM.Hidden,
|
||||
type = WalletType.Hot,
|
||||
tangemPayState = TangemPayState.Empty,
|
||||
tangemPayMainUM = TangemPayMainUM.Empty,
|
||||
isTangemPayRefactorEnabled = isTangemPayRefactorEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -99,9 +96,7 @@ internal class WalletLoadingStateFactory(
|
|||
tokensListState = WalletTokensListState.ContentState.Loading,
|
||||
nftState = WalletNFTItemUM.Hidden,
|
||||
type = WalletType.Cold,
|
||||
tangemPayState = TangemPayState.Empty,
|
||||
tangemPayMainUM = TangemPayMainUM.Empty,
|
||||
isTangemPayRefactorEnabled = isTangemPayRefactorEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,122 +1,38 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.model.MainCustomerInfoContentState
|
||||
import com.tangem.domain.pay.model.MainScreenCustomerInfo
|
||||
import com.tangem.domain.pay.model.TangemPayCustomerInfoError
|
||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.domain.pay.repository.TangemPayWithdrawRepository
|
||||
import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase
|
||||
import com.tangem.domain.visa.model.TangemPayCardFrozenState
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletTangemPayAnalyticsEventSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.*
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class TangemPayMainSubscriber @AssistedInject constructor(
|
||||
@Assisted private val userWallet: UserWallet,
|
||||
private val stateController: WalletStateController,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||
private val tangemPayMainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase,
|
||||
private val tangemPayWithdrawRepository: TangemPayWithdrawRepository,
|
||||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||
private val analytics: WalletTangemPayAnalyticsEventSender,
|
||||
) : WalletSubscriber() {
|
||||
|
||||
override fun create(coroutineScope: CoroutineScope): Flow<*> {
|
||||
coroutineScope.launch {
|
||||
// TODO: Doston move this logic to proper place(e.g. WalletBalanceFetcher)
|
||||
tangemPayWithdrawRepository.pollWithdrawOrdersIfNeeds(userWallet)
|
||||
}
|
||||
return subscribeOnTangemPayInfoUpdates()
|
||||
subscribeToStatus(coroutineScope)
|
||||
return emptyFlow<Any>()
|
||||
}
|
||||
|
||||
private fun subscribeOnTangemPayInfoUpdates(): Flow<*> {
|
||||
return tangemPayMainScreenCustomerInfoUseCase(userWalletId = userWallet.walletId)
|
||||
private fun subscribeToStatus(coroutineScope: CoroutineScope) {
|
||||
paymentAccountStatusSupplier.invoke(userWalletId = userWallet.walletId)
|
||||
.map { it.value }
|
||||
.distinctUntilChanged()
|
||||
.onEach { mainInfoData ->
|
||||
val userWalletId = userWallet.walletId
|
||||
mainInfoData.onLeft { tangemPayError ->
|
||||
when (tangemPayError) {
|
||||
TangemPayCustomerInfoError.RefreshNeededError -> {
|
||||
stateController.update(
|
||||
transformer = TangemPayRefreshNeededStateTransformer(
|
||||
userWalletId = userWalletId,
|
||||
userWallet = userWallet,
|
||||
onRefreshClick = { clickIntents.onRefreshPayToken(userWallet) },
|
||||
),
|
||||
)
|
||||
}
|
||||
TangemPayCustomerInfoError.UnavailableError -> {
|
||||
stateController.update(
|
||||
transformer = TangemPayUnavailableStateTransformer(userWalletId),
|
||||
)
|
||||
}
|
||||
TangemPayCustomerInfoError.ExposedDeviceError -> {
|
||||
stateController.update(TangemPayExposedDeviceTransformer(userWalletId))
|
||||
}
|
||||
TangemPayCustomerInfoError.DeactivatedError -> {
|
||||
stateController.update(
|
||||
transformer = TangemPayHiddenStateTransformer(userWalletId),
|
||||
)
|
||||
}
|
||||
TangemPayCustomerInfoError.UnknownError -> {
|
||||
// hide TangemPay block
|
||||
TangemLogger.e("Failed when loading main screen TangemPay info: $tangemPayError")
|
||||
stateController.update(
|
||||
transformer = TangemPayHiddenStateTransformer(userWalletId),
|
||||
)
|
||||
}
|
||||
}
|
||||
}.onRight { contentState -> handleContentState(state = contentState) }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun handleContentState(state: MainCustomerInfoContentState) {
|
||||
val userWalletId = userWallet.walletId
|
||||
when (state) {
|
||||
MainCustomerInfoContentState.Loading -> stateController.update(
|
||||
transformer = TangemPayLoadingStateTransformer(userWalletId),
|
||||
)
|
||||
is MainCustomerInfoContentState.Content -> {
|
||||
updateTangemPay(data = state.info, userWalletId = userWalletId)
|
||||
analytics.send(customerInfo = state.info)
|
||||
}
|
||||
is MainCustomerInfoContentState.OnboardingBanner -> stateController.update(
|
||||
transformer = TangemPayOnboardingBannerStateTransformer(
|
||||
userWalletId = userWalletId,
|
||||
onClick = clickIntents::onOnboardingBannerClick,
|
||||
closeOnClick = clickIntents::onOnboardingBannerCloseClick,
|
||||
),
|
||||
)
|
||||
is MainCustomerInfoContentState.Empty -> stateController.update(
|
||||
transformer = TangemPayHiddenStateTransformer(userWalletId),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateTangemPay(data: MainScreenCustomerInfo, userWalletId: UserWalletId) {
|
||||
val cardFrozenState =
|
||||
data.info.productInstance?.cardId?.let { cardDetailsRepository.cardFrozenStateSync(it) }
|
||||
?: TangemPayCardFrozenState.Unfrozen
|
||||
stateController.update(
|
||||
transformer = TangemPayUpdateInfoStateTransformer(
|
||||
userWalletId = userWalletId,
|
||||
value = data,
|
||||
cardFrozenState = cardFrozenState,
|
||||
tangemPayClickIntents = clickIntents,
|
||||
),
|
||||
)
|
||||
.onEach(analytics::send)
|
||||
.launchIn(coroutineScope)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ import com.tangem.feature.wallet.presentation.wallet.ui.components.common.*
|
|||
import com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrency.nftCollections
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrency.organizeTokensButton
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency.marketPriceBlock
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.TangemPayMainScreenBlock
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.utils.changeWalletAnimator
|
||||
import com.tangem.features.tangempay.component.TangemPayMainBlockComponent
|
||||
import com.tangem.features.tangempay.entity.TangemPayMainUM
|
||||
|
|
@ -752,14 +751,8 @@ internal fun LazyListScope.tangemPayItem(
|
|||
) {
|
||||
if (state !is WalletState.MultiCurrency) return
|
||||
|
||||
if (state.isTangemPayRefactorEnabled) {
|
||||
with(tangemPayComponent) {
|
||||
tangemPayMainContent(modifier = modifier, state = state.tangemPayMainUM, isBalanceHidden = isHidingMode)
|
||||
}
|
||||
} else {
|
||||
item(key = "TangemPayMainScreenBlock", contentType = state.tangemPayState::class.java) {
|
||||
TangemPayMainScreenBlock(modifier = modifier, state = state.tangemPayState, isBalanceHidden = isHidingMode)
|
||||
}
|
||||
with(tangemPayComponent) {
|
||||
tangemPayMainContent(modifier = modifier, state = state.tangemPayMainUM, isBalanceHidden = isHidingMode)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.orMaskWithStars
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.TangemPayMainScreenBlock
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayCardMainBlock(
|
||||
state: TangemPayState.Card,
|
||||
isBalanceHidden: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Surface(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
color = TangemTheme.colors.background.primary,
|
||||
onClick = state.onClick,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(IntrinsicSize.Min)
|
||||
.padding(horizontal = 12.dp, vertical = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(R.drawable.img_visa_36),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(36.dp),
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.tangempay_payment_account),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
text = state.lastFourDigits.resolveReference(),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.fillMaxHeight(),
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
horizontalAlignment = Alignment.End,
|
||||
) {
|
||||
Text(
|
||||
text = state.balanceText.resolveReference().orMaskWithStars(isBalanceHidden),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.End,
|
||||
)
|
||||
Text(
|
||||
text = state.balanceSymbol.resolveReference(),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
textAlign = TextAlign.End,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TangemPayCardMainBlockPreview() {
|
||||
TangemThemePreview {
|
||||
TangemPayMainScreenBlock(
|
||||
TangemPayState.Card(
|
||||
lastFourDigits = TextReference.Str("*1234"),
|
||||
balanceText = TextReference.Str("$ 0.00"),
|
||||
balanceSymbol = TextReference.Str("USDC"),
|
||||
onClick = {},
|
||||
),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.components.inputrow.InputRowImageBase
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
private const val DISABLED_ALPHA = 0.6F
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayExposedDeviceState(modifier: Modifier = Modifier) {
|
||||
BlockCard(
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(size = TangemTheme.dimens.radius14))
|
||||
.background(TangemTheme.colors.background.primary)
|
||||
.alpha(DISABLED_ALPHA),
|
||||
enabled = false,
|
||||
onClick = {},
|
||||
) {
|
||||
InputRowImageBase(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
all = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
subtitle = resourceReference(R.string.tangempay_payment_account),
|
||||
caption = resourceReference(R.string.tangem_pay_rooted_device_subtitle),
|
||||
subtitleColor = TangemTheme.colors.text.primary1,
|
||||
captionColor = TangemTheme.colors.text.tertiary,
|
||||
iconResWebp = R.drawable.img_visa_36,
|
||||
endIconTint = TangemTheme.colors.icon.warning,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.components.inputrow.InputRowImageBase
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayFailedIssueState(state: TangemPayState.FailedIssue, modifier: Modifier = Modifier) {
|
||||
BlockCard(
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(size = TangemTheme.dimens.radius14))
|
||||
.background(TangemTheme.colors.background.primary),
|
||||
onClick = state.onButtonClick,
|
||||
) {
|
||||
InputRowImageBase(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
all = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
subtitle = state.title,
|
||||
caption = state.description,
|
||||
subtitleColor = TangemTheme.colors.text.primary1,
|
||||
captionColor = TangemTheme.colors.text.tertiary,
|
||||
iconResWebp = com.tangem.core.ui.R.drawable.img_visa_36,
|
||||
iconEndRes = state.iconRes,
|
||||
endIconTint = TangemTheme.colors.icon.warning,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.CircleShimmer
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
import com.tangem.core.ui.components.SpacerWMax
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayLoadingScreenBlock(modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(color = TangemTheme.colors.background.primary, shape = TangemTheme.shapes.roundedCornersXMedium)
|
||||
.padding(horizontal = 12.dp, vertical = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
CircleShimmer(modifier = Modifier.size(36.dp))
|
||||
Column(
|
||||
modifier = Modifier.padding(start = 12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
RectangleShimmer(modifier = Modifier.padding(vertical = 4.dp).sizeIn(minWidth = 70.dp, minHeight = 12.dp))
|
||||
RectangleShimmer(modifier = Modifier.padding(vertical = 2.dp).sizeIn(minWidth = 52.dp, minHeight = 12.dp))
|
||||
}
|
||||
SpacerWMax()
|
||||
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
|
||||
RectangleShimmer(modifier = Modifier.padding(vertical = 4.dp).sizeIn(minWidth = 40.dp, minHeight = 12.dp))
|
||||
RectangleShimmer(modifier = Modifier.padding(vertical = 2.dp).sizeIn(minWidth = 40.dp, minHeight = 12.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState.Progress
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification.Warning.TangemPayRefreshNeeded
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency.TangemPayCardMainBlock
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayMainScreenBlock(state: TangemPayState, isBalanceHidden: Boolean, modifier: Modifier = Modifier) {
|
||||
when (state) {
|
||||
is Progress -> TangemPayProgressState(state, modifier)
|
||||
is TangemPayState.Card -> TangemPayCardMainBlock(state, isBalanceHidden, modifier)
|
||||
is TangemPayState.Empty -> Unit
|
||||
is TangemPayState.RefreshNeeded -> TangemPayRefreshBlock(state, modifier)
|
||||
is TangemPayState.TemporaryUnavailable -> TangemPayUnavailableBlock(state, modifier)
|
||||
is TangemPayState.FailedIssue -> TangemPayFailedIssueState(state, modifier)
|
||||
is TangemPayState.OnboardingBanner -> TangemPayOnboardingBanner(state, modifier)
|
||||
is TangemPayState.ExposedDevice -> TangemPayExposedDeviceState(modifier)
|
||||
is TangemPayState.Loading -> TangemPayLoadingScreenBlock(modifier)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TangemPayMainScreenBlockPreview() {
|
||||
TangemThemePreview {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8)) {
|
||||
TangemPayMainScreenBlock(state = TangemPayState.Loading, isBalanceHidden = false)
|
||||
TangemPayMainScreenBlock(
|
||||
state = TangemPayState.RefreshNeeded(
|
||||
TangemPayRefreshNeeded(
|
||||
buttonText = resourceReference(id = R.string.home_button_scan),
|
||||
onRefreshClick = {},
|
||||
shouldShowProgress = false,
|
||||
),
|
||||
),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
TangemPayMainScreenBlock(
|
||||
state = TangemPayState.TemporaryUnavailable(WalletNotification.Warning.TangemPayUnreachable),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
TangemPayMainScreenBlock(
|
||||
state = TangemPayState.OnboardingBanner(onClick = {}, closeOnClick = {}),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
|
||||
TangemPayMainScreenBlock(state = TangemPayState.ExposedDevice, isBalanceHidden = false)
|
||||
TangemPayMainScreenBlock(
|
||||
state = TangemPayState.FailedIssue(
|
||||
title = TextReference.Res(R.string.tangempay_payment_account),
|
||||
description = TextReference.Res(R.string.tangempay_failed_to_issue_card),
|
||||
iconRes = R.drawable.ic_alert_24,
|
||||
onButtonClick = { },
|
||||
),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
|
||||
TangemPayMainScreenBlock(
|
||||
Progress(
|
||||
title = TextReference.Res(R.string.tangempay_payment_account),
|
||||
description = TextReference.Res(R.string.tangempay_kyc_in_progress),
|
||||
buttonText = TextReference.Res(R.string.tangempay_kyc_in_progress_notification_button),
|
||||
iconRes = R.drawable.ic_promo_kyc_36,
|
||||
onButtonClick = {},
|
||||
),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
|
||||
TangemPayMainScreenBlock(
|
||||
Progress(
|
||||
title = TextReference.Res(R.string.tangempay_payment_account),
|
||||
description = TextReference.Res(R.string.tangempay_issuing_your_card),
|
||||
buttonText = TextReference.EMPTY,
|
||||
iconRes = R.drawable.ic_tangem_pay_promo_card_36,
|
||||
onButtonClick = {},
|
||||
showProgress = true,
|
||||
),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
|
||||
TangemPayMainScreenBlock(
|
||||
TangemPayState.Card(
|
||||
lastFourDigits = TextReference.Str("*1234"),
|
||||
balanceText = TextReference.Str("$ 0.00"),
|
||||
balanceSymbol = TextReference.Str("USDC"),
|
||||
onClick = {},
|
||||
),
|
||||
isBalanceHidden = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.constraintlayout.compose.Dimension
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
|
||||
private const val GRADIENT_START_COLOR = 0xFF252934
|
||||
private const val GRADIENT_END_COLOR = 0xFF12141E
|
||||
private const val GRADIENT_OFFSET_X = 0f
|
||||
private const val GRADIENT_OFFSET_Y = 80F
|
||||
private const val GRADIENT_RADIUS = 200F
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayOnboardingBanner(state: TangemPayState.OnboardingBanner, modifier: Modifier = Modifier) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(
|
||||
brush = Brush.radialGradient(
|
||||
colors = listOf(Color(GRADIENT_START_COLOR), Color(GRADIENT_END_COLOR)),
|
||||
center = Offset(GRADIENT_OFFSET_X, GRADIENT_OFFSET_Y),
|
||||
radius = GRADIENT_RADIUS,
|
||||
),
|
||||
)
|
||||
.clickable(onClick = state.onClick),
|
||||
) {
|
||||
ConstraintLayout(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
val (image, text, close) = createRefs()
|
||||
|
||||
Image(
|
||||
painter = painterResource(R.drawable.ic_close_24),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(16.dp)
|
||||
.clickable(onClick = state.closeOnClick)
|
||||
.constrainAs(close) {
|
||||
top.linkTo(parent.top, margin = 16.dp)
|
||||
end.linkTo(parent.end, margin = 16.dp)
|
||||
},
|
||||
colorFilter = ColorFilter.tint(TangemTheme.colors.icon.inactive),
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.constrainAs(text) {
|
||||
top.linkTo(parent.top)
|
||||
start.linkTo(image.end, margin = 12.dp)
|
||||
end.linkTo(close.start, margin = 12.dp)
|
||||
width = Dimension.fillToConstraints
|
||||
}
|
||||
.padding(top = 16.dp, bottom = 16.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.tangempay_onboarding_banner_title),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.constantWhite,
|
||||
)
|
||||
|
||||
SpacerH(6.dp)
|
||||
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.tangempay_onboarding_banner_description),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
|
||||
Image(
|
||||
painter = painterResource(R.drawable.img_tangem_pay_onboarding_banner),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.padding(top = 8.dp, start = 24.dp)
|
||||
.constrainAs(image) {
|
||||
start.linkTo(parent.start)
|
||||
top.linkTo(text.top)
|
||||
bottom.linkTo(text.bottom)
|
||||
height = Dimension.fillToConstraints
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun PreviewTangemOnboardingBanner() {
|
||||
TangemThemePreview {
|
||||
TangemPayOnboardingBanner(
|
||||
TangemPayState.OnboardingBanner(
|
||||
onClick = {},
|
||||
closeOnClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.components.inputrow.InputRowImageBase
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayProgressState(state: TangemPayState.Progress, modifier: Modifier = Modifier) {
|
||||
BlockCard(
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(size = TangemTheme.dimens.radius14))
|
||||
.background(TangemTheme.colors.background.primary),
|
||||
onClick = state.onButtonClick,
|
||||
) {
|
||||
InputRowImageBase(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
all = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
subtitle = state.title,
|
||||
caption = state.description,
|
||||
subtitleColor = TangemTheme.colors.text.primary1,
|
||||
captionColor = TangemTheme.colors.text.tertiary,
|
||||
iconResWebp = R.drawable.img_visa_36,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.SpacerH12
|
||||
import com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.components.inputrow.InputRowImageBase
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification.Warning.TangemPayRefreshNeeded
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayRefreshBlock(state: TangemPayState.RefreshNeeded, modifier: Modifier = Modifier) {
|
||||
Column(modifier) {
|
||||
Notification(
|
||||
config = state.notification.config,
|
||||
iconTint = when (state.notification) {
|
||||
is WalletNotification.Critical -> TangemTheme.colors.icon.warning
|
||||
is WalletNotification.Informational -> TangemTheme.colors.icon.accent
|
||||
is WalletNotification.RateApp -> TangemTheme.colors.icon.attention
|
||||
is WalletNotification.UnlockWallets -> TangemTheme.colors.icon.primary1
|
||||
is WalletNotification.UsedOutdatedData -> TangemTheme.colors.text.attention
|
||||
else -> null
|
||||
},
|
||||
)
|
||||
SpacerH12()
|
||||
|
||||
BlockCard(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(size = TangemTheme.dimens.radius14))
|
||||
.background(TangemTheme.colors.background.primary),
|
||||
enabled = false,
|
||||
) {
|
||||
InputRowImageBase(
|
||||
modifier = Modifier.padding(
|
||||
all = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
subtitle = resourceReference(R.string.tangempay_payment_account),
|
||||
caption = resourceReference(R.string.tangempay_payment_account_sync_needed),
|
||||
subtitleColor = TangemTheme.colors.text.tertiary,
|
||||
captionColor = TangemTheme.colors.text.tertiary,
|
||||
iconResWebp = R.drawable.img_visa_36,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TangemPayRefreshBlockPreview() {
|
||||
TangemThemePreview {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8)) {
|
||||
TangemPayRefreshBlock(
|
||||
state = TangemPayState.RefreshNeeded(
|
||||
TangemPayRefreshNeeded(
|
||||
buttonText = resourceReference(id = R.string.tangempay_sync_needed_restore_access),
|
||||
onRefreshClick = {},
|
||||
shouldShowProgress = true,
|
||||
),
|
||||
),
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.SpacerH12
|
||||
import com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.components.inputrow.InputRowImageBase
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayUnavailableBlock(state: TangemPayState.TemporaryUnavailable, modifier: Modifier = Modifier) {
|
||||
Column(modifier) {
|
||||
Notification(
|
||||
config = state.notification.config,
|
||||
iconTint = when (state.notification) {
|
||||
is WalletNotification.Critical -> TangemTheme.colors.icon.warning
|
||||
is WalletNotification.Informational -> TangemTheme.colors.icon.accent
|
||||
is WalletNotification.RateApp -> TangemTheme.colors.icon.attention
|
||||
is WalletNotification.UnlockWallets -> TangemTheme.colors.icon.primary1
|
||||
is WalletNotification.UsedOutdatedData -> TangemTheme.colors.text.attention
|
||||
else -> null
|
||||
},
|
||||
)
|
||||
SpacerH12()
|
||||
|
||||
BlockCard(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(size = TangemTheme.dimens.radius14))
|
||||
.background(TangemTheme.colors.background.primary),
|
||||
enabled = false,
|
||||
) {
|
||||
InputRowImageBase(
|
||||
modifier = Modifier.padding(
|
||||
all = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
subtitle = resourceReference(R.string.tangempay_payment_account),
|
||||
caption = TextReference.Str(DASH_SIGN),
|
||||
subtitleColor = TangemTheme.colors.text.tertiary,
|
||||
captionColor = TangemTheme.colors.text.tertiary,
|
||||
iconResWebp = R.drawable.img_visa_36,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TangemPayUnavailableBlockPreview() {
|
||||
TangemThemePreview {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8)) {
|
||||
TangemPayUnavailableBlock(
|
||||
state = TangemPayState.TemporaryUnavailable(
|
||||
WalletNotification.Warning.TangemPayUnreachable,
|
||||
),
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue