Updated on 2026-08-14
This commit is contained in:
parent
84198eb103
commit
b4d11538ea
57 changed files with 361 additions and 4136 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
package com.tangem.features.tangempay
|
package com.tangem.features.tangempay
|
||||||
|
|
||||||
interface TangemPayFeatureToggles {
|
interface TangemPayFeatureToggles {
|
||||||
val isRedesignEnabled: Boolean
|
|
||||||
val isRemoveAccountEnabled: Boolean
|
val isRemoveAccountEnabled: Boolean
|
||||||
val isTiersPlusPlanEnabled: Boolean
|
val isTiersPlusPlanEnabled: Boolean
|
||||||
val isCashbackEnabled: Boolean
|
val isCashbackEnabled: Boolean
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||||
internal class DefaultTangemPayFeatureToggles(
|
internal class DefaultTangemPayFeatureToggles(
|
||||||
private val featureTogglesManager: FeatureTogglesManager,
|
private val featureTogglesManager: FeatureTogglesManager,
|
||||||
) : TangemPayFeatureToggles {
|
) : TangemPayFeatureToggles {
|
||||||
override val isRedesignEnabled: Boolean
|
|
||||||
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.APP_REDESIGN_ENABLED)
|
|
||||||
|
|
||||||
override val isRemoveAccountEnabled: Boolean
|
override val isRemoveAccountEnabled: Boolean
|
||||||
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15741_VISA_PAY_REMOVE_ACCOUNT)
|
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15741_VISA_PAY_REMOVE_ACCOUNT)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.domain.pay.model.TangemPayTopUpData
|
import com.tangem.domain.pay.model.TangemPayTopUpData
|
||||||
import com.tangem.features.tangempay.model.TangemPayAddFundsModel
|
import com.tangem.features.tangempay.model.TangemPayAddFundsModel
|
||||||
import com.tangem.features.tangempay.ui.TangemPayAddFundsContent
|
|
||||||
import com.tangem.features.tangempay.ui.TangemPayAddFundsContentV2
|
import com.tangem.features.tangempay.ui.TangemPayAddFundsContentV2
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
|
@ -26,11 +25,7 @@ internal class TangemPayAddFundsComponent(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun BottomSheet() {
|
override fun BottomSheet() {
|
||||||
if (model.isRedesignEnabled()) {
|
TangemPayAddFundsContentV2(state = model.uiState)
|
||||||
TangemPayAddFundsContentV2(state = model.uiState)
|
|
||||||
} else {
|
|
||||||
TangemPayAddFundsContent(state = model.uiState)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(
|
data class Params(
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,15 @@ package com.tangem.features.tangempay.components
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.decompose.model.getOrCreateModel
|
import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
|
||||||
import com.tangem.domain.models.pay.TangemPayCard
|
import com.tangem.domain.models.pay.TangemPayCard
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.features.tangempay.model.TangemPayAddToWalletModel
|
import com.tangem.features.tangempay.model.TangemPayAddToWalletModel
|
||||||
import com.tangem.features.tangempay.ui.TangemPayAddToWalletScreen
|
|
||||||
import com.tangem.features.tangempay.ui.TangemPayAddToWalletScreenV2
|
import com.tangem.features.tangempay.ui.TangemPayAddToWalletScreenV2
|
||||||
|
|
||||||
internal class TangemPayAddToWalletComponent(
|
internal class TangemPayAddToWalletComponent(
|
||||||
|
|
@ -28,19 +25,10 @@ internal class TangemPayAddToWalletComponent(
|
||||||
val state by model.uiState.collectAsStateWithLifecycle()
|
val state by model.uiState.collectAsStateWithLifecycle()
|
||||||
val cardDetailsState by model.cardDetailsState.collectAsStateWithLifecycle()
|
val cardDetailsState by model.cardDetailsState.collectAsStateWithLifecycle()
|
||||||
BackHandler(onBack = router::pop)
|
BackHandler(onBack = router::pop)
|
||||||
CompositionLocalProvider(LocalVisaRedesignEnabled provides model.isRedesignEnabled()) {
|
TangemPayAddToWalletScreenV2(
|
||||||
if (model.isRedesignEnabled()) {
|
state = state,
|
||||||
TangemPayAddToWalletScreenV2(
|
cardDetailsState = cardDetailsState,
|
||||||
state = state,
|
)
|
||||||
cardDetailsState = cardDetailsState,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TangemPayAddToWalletScreen(
|
|
||||||
state = state,
|
|
||||||
cardDetailsState = cardDetailsState,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import com.tangem.core.decompose.factory.ComponentFactory
|
||||||
import com.tangem.core.decompose.navigation.inner.InnerRouter
|
import com.tangem.core.decompose.navigation.inner.InnerRouter
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.domain.models.account.AccountStatus
|
import com.tangem.domain.models.account.AccountStatus
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.limit.setup.TangemPayCardLimitSetupComponent
|
import com.tangem.features.tangempay.limit.setup.TangemPayCardLimitSetupComponent
|
||||||
import com.tangem.features.tangempay.limit.setup.TangemPayCardLimitSetupSuccessComponent
|
import com.tangem.features.tangempay.limit.setup.TangemPayCardLimitSetupSuccessComponent
|
||||||
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
||||||
|
|
@ -33,7 +32,6 @@ internal class TangemPayCardPageComponent @AssistedInject constructor(
|
||||||
@Assisted private val params: Params,
|
@Assisted private val params: Params,
|
||||||
private val tokenReceiveComponentFactory: TokenReceiveComponent.Factory,
|
private val tokenReceiveComponentFactory: TokenReceiveComponent.Factory,
|
||||||
private val virtualAccountAddFundsComponentFactory: VirtualAccountAddFundsBottomSheetComponent.Factory,
|
private val virtualAccountAddFundsComponentFactory: VirtualAccountAddFundsBottomSheetComponent.Factory,
|
||||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
|
||||||
) : ComposableContentComponent, AppComponentContext by appComponentContext {
|
) : ComposableContentComponent, AppComponentContext by appComponentContext {
|
||||||
|
|
||||||
private val stackNavigation = StackNavigation<TangemPayCardDetailsInnerRoute>()
|
private val stackNavigation = StackNavigation<TangemPayCardDetailsInnerRoute>()
|
||||||
|
|
@ -85,7 +83,6 @@ internal class TangemPayCardPageComponent @AssistedInject constructor(
|
||||||
componentContext = componentContext,
|
componentContext = componentContext,
|
||||||
router = innerRouter,
|
router = innerRouter,
|
||||||
),
|
),
|
||||||
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
|
|
||||||
)
|
)
|
||||||
is TangemPayCardDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent(
|
is TangemPayCardDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent(
|
||||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||||
|
|
@ -110,7 +107,6 @@ internal class TangemPayCardPageComponent @AssistedInject constructor(
|
||||||
)
|
)
|
||||||
TangemPayCardDetailsInnerRoute.LimitSetupSuccess -> TangemPayCardLimitSetupSuccessComponent(
|
TangemPayCardDetailsInnerRoute.LimitSetupSuccess -> TangemPayCardLimitSetupSuccessComponent(
|
||||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||||
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
|
|
||||||
)
|
)
|
||||||
TangemPayCardDetailsInnerRoute.VirtualAccountDepositSuccess ->
|
TangemPayCardDetailsInnerRoute.VirtualAccountDepositSuccess ->
|
||||||
TangemPayVirtualAccountDepositSuccessComponent(
|
TangemPayVirtualAccountDepositSuccessComponent(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.tangem.features.tangempay.components
|
package com.tangem.features.tangempay.components
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
|
@ -15,7 +14,6 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
||||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
|
||||||
import com.tangem.features.tangempay.closure.TangemPayCloseCardComponent
|
import com.tangem.features.tangempay.closure.TangemPayCloseCardComponent
|
||||||
import com.tangem.features.tangempay.entity.TangemPayCardNavigation
|
import com.tangem.features.tangempay.entity.TangemPayCardNavigation
|
||||||
import com.tangem.features.tangempay.model.TangemPayCardPageModel
|
import com.tangem.features.tangempay.model.TangemPayCardPageModel
|
||||||
|
|
@ -50,17 +48,15 @@ internal class TangemPayCardPageScreenComponent(
|
||||||
val selectedCardId by model.selectedCardIdState.collectAsStateWithLifecycle()
|
val selectedCardId by model.selectedCardIdState.collectAsStateWithLifecycle()
|
||||||
val bottomSheet by bottomSheetSlot.subscribeAsState()
|
val bottomSheet by bottomSheetSlot.subscribeAsState()
|
||||||
|
|
||||||
CompositionLocalProvider(LocalVisaRedesignEnabled provides model.isRedesignEnabled()) {
|
NavigationBar3ButtonsScrim()
|
||||||
NavigationBar3ButtonsScrim()
|
TangemPayCardPageScreen(
|
||||||
TangemPayCardPageScreen(
|
state = state,
|
||||||
state = state,
|
cardControllers = cardControllers,
|
||||||
cardControllers = cardControllers,
|
selectedCardId = selectedCardId,
|
||||||
selectedCardId = selectedCardId,
|
onCardSelect = model::onCardPageSelected,
|
||||||
onCardSelect = model::onCardPageSelected,
|
modifier = modifier,
|
||||||
modifier = modifier,
|
)
|
||||||
)
|
bottomSheet.child?.instance?.BottomSheet()
|
||||||
bottomSheet.child?.instance?.BottomSheet()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect
|
||||||
import com.tangem.domain.models.pay.TangemPayCard
|
import com.tangem.domain.models.pay.TangemPayCard
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.features.tangempay.model.TangemPayChangePinModel
|
import com.tangem.features.tangempay.model.TangemPayChangePinModel
|
||||||
import com.tangem.features.tangempay.ui.TangemPayChangePinScreen
|
|
||||||
import com.tangem.features.tangempay.ui.TangemPayChangePinScreenV2
|
import com.tangem.features.tangempay.ui.TangemPayChangePinScreenV2
|
||||||
|
|
||||||
internal class TangemPayChangePinComponent(
|
internal class TangemPayChangePinComponent(
|
||||||
|
|
@ -27,17 +26,10 @@ internal class TangemPayChangePinComponent(
|
||||||
val state by model.uiState.collectAsStateWithLifecycle()
|
val state by model.uiState.collectAsStateWithLifecycle()
|
||||||
BackHandler(onBack = router::pop)
|
BackHandler(onBack = router::pop)
|
||||||
DisableScreenshotsDisposableEffect()
|
DisableScreenshotsDisposableEffect()
|
||||||
if (model.isRedesignEnabled()) {
|
TangemPayChangePinScreenV2(
|
||||||
TangemPayChangePinScreenV2(
|
state = state,
|
||||||
state = state,
|
onBackClick = router::pop,
|
||||||
onBackClick = router::pop,
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TangemPayChangePinScreen(
|
|
||||||
state = state,
|
|
||||||
onBackClick = router::pop,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,16 @@ import androidx.compose.ui.Modifier
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
||||||
import com.tangem.features.tangempay.ui.TangemPayChangePinCodeSuccessScreen
|
|
||||||
import com.tangem.features.tangempay.ui.TangemPayChangePinCodeSuccessScreenV2
|
import com.tangem.features.tangempay.ui.TangemPayChangePinCodeSuccessScreenV2
|
||||||
|
|
||||||
internal class TangemPayChangePinSuccessComponent(
|
internal class TangemPayChangePinSuccessComponent(
|
||||||
private val appComponentContext: AppComponentContext,
|
private val appComponentContext: AppComponentContext,
|
||||||
private val isRedesignEnabled: Boolean,
|
|
||||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content(modifier: Modifier) {
|
override fun Content(modifier: Modifier) {
|
||||||
BackHandler(onBack = ::backToDetails)
|
BackHandler(onBack = ::backToDetails)
|
||||||
if (isRedesignEnabled) {
|
TangemPayChangePinCodeSuccessScreenV2(onClose = ::backToDetails)
|
||||||
TangemPayChangePinCodeSuccessScreenV2(onClose = ::backToDetails)
|
|
||||||
} else {
|
|
||||||
TangemPayChangePinCodeSuccessScreen(onClick = ::backToDetails)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun backToDetails() {
|
private fun backToDetails() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.tangem.features.tangempay.components
|
package com.tangem.features.tangempay.components
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
@ -18,13 +17,11 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
|
||||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
|
||||||
import com.tangem.features.promobanners.api.PromoBannersBlockComponent
|
import com.tangem.features.promobanners.api.PromoBannersBlockComponent
|
||||||
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
|
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
|
||||||
import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryDetailsComponent
|
import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryDetailsComponent
|
||||||
import com.tangem.features.tangempay.entity.TangemPayDetailsNavigation
|
import com.tangem.features.tangempay.entity.TangemPayDetailsNavigation
|
||||||
import com.tangem.features.tangempay.model.TangemPayDetailsModel
|
import com.tangem.features.tangempay.model.TangemPayDetailsModel
|
||||||
import com.tangem.features.tangempay.ui.TangemPayDetailsScreen
|
|
||||||
import com.tangem.features.tangempay.ui.TangemPayDetailsScreenV2
|
import com.tangem.features.tangempay.ui.TangemPayDetailsScreenV2
|
||||||
import com.tangem.features.tangempay.utils.VA_DAILY_DEPOSIT_LIMIT_PLACEHOLDER
|
import com.tangem.features.tangempay.utils.VA_DAILY_DEPOSIT_LIMIT_PLACEHOLDER
|
||||||
import com.tangem.features.tangempay.utils.requireLoaded
|
import com.tangem.features.tangempay.utils.requireLoaded
|
||||||
|
|
@ -98,26 +95,15 @@ internal class TangemPayDetailsComponent(
|
||||||
horizontalItemPadding = 16.dp,
|
horizontalItemPadding = 16.dp,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CompositionLocalProvider(LocalVisaRedesignEnabled provides model.isRedesignEnabled()) {
|
NavigationBar3ButtonsScrim()
|
||||||
NavigationBar3ButtonsScrim()
|
TangemPayDetailsScreenV2(
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
state = state,
|
||||||
TangemPayDetailsScreenV2(
|
txHistoryComponent = txHistoryComponent,
|
||||||
state = state,
|
expressTransactionsComponent = expressTransactionsComponent,
|
||||||
txHistoryComponent = txHistoryComponent,
|
promoBannersBlockComponent = promoBannersBlock,
|
||||||
expressTransactionsComponent = expressTransactionsComponent,
|
modifier = modifier,
|
||||||
promoBannersBlockComponent = promoBannersBlock,
|
)
|
||||||
modifier = modifier,
|
bottomSheet.child?.instance?.BottomSheet()
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TangemPayDetailsScreen(
|
|
||||||
state = state,
|
|
||||||
txHistoryComponent = txHistoryComponent,
|
|
||||||
expressTransactionsComponent = expressTransactionsComponent,
|
|
||||||
modifier = modifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
bottomSheet.child?.instance?.BottomSheet()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,17 @@ package com.tangem.features.tangempay.components
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.decompose.model.getOrCreateModel
|
import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
|
||||||
import com.tangem.domain.models.pay.TangemPayCard
|
import com.tangem.domain.models.pay.TangemPayCard
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.features.tangempay.entity.DisplayNameState
|
import com.tangem.features.tangempay.entity.DisplayNameState
|
||||||
import com.tangem.features.tangempay.model.TangemPayEditDisplayNameModel
|
import com.tangem.features.tangempay.model.TangemPayEditDisplayNameModel
|
||||||
import com.tangem.features.tangempay.ui.TangemPayEditDisplayNameScreen
|
import com.tangem.features.tangempay.ui.TangemPayEditDisplayNameScreenV2
|
||||||
|
|
||||||
internal class TangemPayEditDisplayNameComponent(
|
internal class TangemPayEditDisplayNameComponent(
|
||||||
private val appComponentContext: AppComponentContext,
|
private val appComponentContext: AppComponentContext,
|
||||||
|
|
@ -38,14 +36,11 @@ internal class TangemPayEditDisplayNameComponent(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
BackHandler(onBack = state.onDismiss)
|
BackHandler(onBack = state.onDismiss)
|
||||||
CompositionLocalProvider(LocalVisaRedesignEnabled provides model.isRedesignEnabled()) {
|
TangemPayEditDisplayNameScreenV2(
|
||||||
TangemPayEditDisplayNameScreen(
|
state = state,
|
||||||
state = state,
|
cardDetailsState = editingCardDetailsState,
|
||||||
cardDetailsState = editingCardDetailsState,
|
modifier = modifier,
|
||||||
modifier = modifier,
|
)
|
||||||
isRedesignEnabled = model.isRedesignEnabled(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.features.tangempay.model.TangemPayReissueCardModel
|
import com.tangem.features.tangempay.model.TangemPayReissueCardModel
|
||||||
import com.tangem.features.tangempay.ui.TangemPayReissueCardContent
|
|
||||||
import com.tangem.features.tangempay.ui.TangemPayReissueCardContentV2
|
import com.tangem.features.tangempay.ui.TangemPayReissueCardContentV2
|
||||||
|
|
||||||
internal class TangemPayReissueCardComponent(
|
internal class TangemPayReissueCardComponent(
|
||||||
|
|
@ -23,11 +22,7 @@ internal class TangemPayReissueCardComponent(
|
||||||
@Composable
|
@Composable
|
||||||
override fun BottomSheet() {
|
override fun BottomSheet() {
|
||||||
val state by model.state.collectAsStateWithLifecycle()
|
val state by model.state.collectAsStateWithLifecycle()
|
||||||
if (model.isRedesignEnabled()) {
|
TangemPayReissueCardContentV2(state)
|
||||||
TangemPayReissueCardContentV2(state)
|
|
||||||
} else {
|
|
||||||
TangemPayReissueCardContent(state)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(
|
data class Params(
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||||
import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect
|
import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.features.tangempay.model.TangemPayViewPinModel
|
import com.tangem.features.tangempay.model.TangemPayViewPinModel
|
||||||
import com.tangem.features.tangempay.ui.TangemPayViewPinContent
|
|
||||||
import com.tangem.features.tangempay.ui.TangemPayViewPinContentV2
|
import com.tangem.features.tangempay.ui.TangemPayViewPinContentV2
|
||||||
|
|
||||||
internal class TangemPayViewPinComponent(
|
internal class TangemPayViewPinComponent(
|
||||||
|
|
@ -29,11 +28,7 @@ internal class TangemPayViewPinComponent(
|
||||||
val state by model.uiState.collectAsStateWithLifecycle()
|
val state by model.uiState.collectAsStateWithLifecycle()
|
||||||
BackHandler(onBack = ::dismiss)
|
BackHandler(onBack = ::dismiss)
|
||||||
DisableScreenshotsDisposableEffect()
|
DisableScreenshotsDisposableEffect()
|
||||||
if (model.isRedesignEnabled()) {
|
TangemPayViewPinContentV2(state = state)
|
||||||
TangemPayViewPinContentV2(state = state)
|
|
||||||
} else {
|
|
||||||
TangemPayViewPinContent(state = state)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(
|
data class Params(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
||||||
import com.tangem.features.tangempay.model.TangemPayTxHistoryModel
|
import com.tangem.features.tangempay.model.TangemPayTxHistoryModel
|
||||||
import com.tangem.features.tangempay.ui.tangemPayTxHistoryItems
|
|
||||||
import com.tangem.features.tangempay.ui.tangemPayTxHistoryItemsV2
|
import com.tangem.features.tangempay.ui.tangemPayTxHistoryItemsV2
|
||||||
import com.tangem.features.tangempay.utils.TangemPayTxHistoryUiActions
|
import com.tangem.features.tangempay.utils.TangemPayTxHistoryUiActions
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
@ -21,11 +20,7 @@ internal class DefaultTangemPayTxHistoryComponent(
|
||||||
override val state: StateFlow<TangemPayTxHistoryUM> = model.uiState
|
override val state: StateFlow<TangemPayTxHistoryUM> = model.uiState
|
||||||
|
|
||||||
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM) {
|
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM) {
|
||||||
if (model.isRedesignEnabled()) {
|
tangemPayTxHistoryItemsV2(listState, state)
|
||||||
tangemPayTxHistoryItemsV2(listState, state)
|
|
||||||
} else {
|
|
||||||
tangemPayTxHistoryItems(listState, state)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(
|
data class Params(
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
import com.tangem.features.tangempay.details.impl.R
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTransactionState
|
import com.tangem.features.tangempay.entity.TangemPayTransactionState
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
||||||
import com.tangem.features.tangempay.ui.tangemPayTxHistoryItems
|
import com.tangem.features.tangempay.ui.tangemPayTxHistoryItemsV2
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
@ -19,7 +19,7 @@ internal class PreviewTangemPayTxHistoryComponent(txHistoryUM: TangemPayTxHistor
|
||||||
override val state: StateFlow<TangemPayTxHistoryUM> = MutableStateFlow(txHistoryUM)
|
override val state: StateFlow<TangemPayTxHistoryUM> = MutableStateFlow(txHistoryUM)
|
||||||
|
|
||||||
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM) {
|
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM) {
|
||||||
tangemPayTxHistoryItems(listState = listState, state = state)
|
tangemPayTxHistoryItemsV2(listState = listState, state = state)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,8 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.tangem.core.decompose.context.AppComponentContext
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.decompose.model.getOrCreateModel
|
import com.tangem.core.decompose.model.getOrCreateModel
|
||||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
|
||||||
import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent
|
import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUiState
|
|
||||||
import com.tangem.features.tangempay.model.TangemPayTxHistoryDetailsModel
|
import com.tangem.features.tangempay.model.TangemPayTxHistoryDetailsModel
|
||||||
import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContent
|
|
||||||
import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContentV2
|
import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContentV2
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
|
|
@ -28,15 +25,8 @@ internal class TangemPayTxHistoryDetailsComponent @AssistedInject constructor(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun BottomSheet() {
|
override fun BottomSheet() {
|
||||||
val states by model.uiState.collectAsStateWithLifecycle()
|
val state by model.uiState.collectAsStateWithLifecycle()
|
||||||
when (val uiState = states.toUiState(isRedesignEnabled = LocalVisaRedesignEnabled.current)) {
|
TangemPayTxHistoryDetailsContentV2(state = state)
|
||||||
is TangemPayTxHistoryDetailsUiState.Legacy -> {
|
|
||||||
TangemPayTxHistoryDetailsContent(state = uiState.state)
|
|
||||||
}
|
|
||||||
is TangemPayTxHistoryDetailsUiState.Redesign -> {
|
|
||||||
TangemPayTxHistoryDetailsContentV2(state = uiState.state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.ui.R as CoreUiR
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
internal data class TangemPayCardPageUM(
|
internal data class TangemPayCardPageUM(
|
||||||
val settings: ImmutableList<TangemPayCardPageSetting>,
|
|
||||||
val settingsV2: ImmutableList<TangemPayCardPageSettingV2>,
|
val settingsV2: ImmutableList<TangemPayCardPageSettingV2>,
|
||||||
val onBackClick: () -> Unit,
|
val onBackClick: () -> Unit,
|
||||||
val dailyLimitState: TangemPayDailyLimitBlockState,
|
val dailyLimitState: TangemPayDailyLimitBlockState,
|
||||||
|
|
@ -26,17 +25,11 @@ internal data class TangemPayCardPageUM(
|
||||||
onClick = {},
|
onClick = {},
|
||||||
onClickClose = {},
|
onClickClose = {},
|
||||||
),
|
),
|
||||||
settings: ImmutableList<TangemPayCardPageSetting> = persistentListOf(
|
|
||||||
TangemPayCardPageSetting(TextReference.Str("Pin Code")) {},
|
|
||||||
TangemPayCardPageSetting(TextReference.Str("Freeze Card")) {},
|
|
||||||
TangemPayCardPageSetting(TextReference.Str("Reissue Card")) {},
|
|
||||||
),
|
|
||||||
cardState: TangemPayCardState = TangemPayCardState.Active,
|
cardState: TangemPayCardState = TangemPayCardState.Active,
|
||||||
dailyLimitState: TangemPayDailyLimitBlockState = TangemPayDailyLimitBlockState.Content.stub(),
|
dailyLimitState: TangemPayDailyLimitBlockState = TangemPayDailyLimitBlockState.Content.stub(),
|
||||||
settingsV2: ImmutableList<TangemPayCardPageSettingV2> = TangemPayCardPageSettingV2.stubList(),
|
settingsV2: ImmutableList<TangemPayCardPageSettingV2> = TangemPayCardPageSettingV2.stubList(),
|
||||||
) = TangemPayCardPageUM(
|
) = TangemPayCardPageUM(
|
||||||
addToWalletBlockState = addToWalletBlockState,
|
addToWalletBlockState = addToWalletBlockState,
|
||||||
settings = settings,
|
|
||||||
settingsV2 = settingsV2,
|
settingsV2 = settingsV2,
|
||||||
onBackClick = {},
|
onBackClick = {},
|
||||||
cardState = cardState,
|
cardState = cardState,
|
||||||
|
|
@ -46,13 +39,6 @@ internal data class TangemPayCardPageUM(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
|
||||||
internal data class TangemPayCardPageSetting(
|
|
||||||
val title: TextReference,
|
|
||||||
val testTag: String? = null,
|
|
||||||
val onSettingClick: () -> Unit,
|
|
||||||
)
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
internal data class TangemPayCardPageSettingV2(
|
internal data class TangemPayCardPageSettingV2(
|
||||||
val id: Id,
|
val id: Id,
|
||||||
|
|
|
||||||
|
|
@ -15,18 +15,17 @@ internal class TangemPayDetailsNotificationFactory(
|
||||||
private val intents: TangemPayDetailIntents,
|
private val intents: TangemPayDetailIntents,
|
||||||
private val isRemoveAccountEnabled: Boolean,
|
private val isRemoveAccountEnabled: Boolean,
|
||||||
private val isTiersPlusPlanEnabled: Boolean,
|
private val isTiersPlusPlanEnabled: Boolean,
|
||||||
private val isRedesignEnabled: Boolean,
|
|
||||||
) {
|
) {
|
||||||
fun createErrorConfig(error: PaymentAccountStatusValue.Error?): NotificationConfig? = when (error) {
|
fun createErrorConfig(error: PaymentAccountStatusValue.Error?): NotificationConfig? = when (error) {
|
||||||
null -> null
|
null -> null
|
||||||
PaymentAccountStatusValue.Error.NotSynced -> createRenewSessionNotificationConfig(isRedesignEnabled)
|
PaymentAccountStatusValue.Error.NotSynced -> createRenewSessionNotificationConfig()
|
||||||
else -> createAccountUnavailableConfig(isRedesignEnabled)
|
else -> createAccountUnavailableConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createAccountDeactivatedConfig(isRedesignEnabled: Boolean) = NotificationConfig(
|
fun createAccountDeactivatedConfig() = NotificationConfig(
|
||||||
title = resourceReference(R.string.tangempay_account_deactivated_message_title),
|
title = resourceReference(R.string.tangempay_account_deactivated_message_title),
|
||||||
subtitle = resourceReference(R.string.tangempay_account_deactivated_message_subtitle),
|
subtitle = resourceReference(R.string.tangempay_account_deactivated_message_subtitle),
|
||||||
iconResId = if (isRedesignEnabled) R.drawable.ic_alert_circle_24 else R.drawable.img_attention_20,
|
iconResId = R.drawable.ic_alert_circle_24,
|
||||||
buttonsState = if (isRemoveAccountEnabled) {
|
buttonsState = if (isRemoveAccountEnabled) {
|
||||||
NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||||
text = resourceReference(R.string.tangempay_remove_account),
|
text = resourceReference(R.string.tangempay_remove_account),
|
||||||
|
|
@ -65,10 +64,10 @@ internal class TangemPayDetailsNotificationFactory(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createRenewSessionNotificationConfig(isRedesignEnabled: Boolean) = NotificationConfig(
|
private fun createRenewSessionNotificationConfig() = NotificationConfig(
|
||||||
title = resourceReference(R.string.tangempay_sync_needed_title),
|
title = resourceReference(R.string.tangempay_sync_needed_title),
|
||||||
subtitle = resourceReference(R.string.tangempay_sync_needed_body),
|
subtitle = resourceReference(R.string.tangempay_sync_needed_body),
|
||||||
iconResId = if (isRedesignEnabled) 0 else R.drawable.img_attention_20,
|
iconResId = 0,
|
||||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||||
text = resourceReference(R.string.tangempay_sync_needed_button),
|
text = resourceReference(R.string.tangempay_sync_needed_button),
|
||||||
onClick = intents::onRenewSession,
|
onClick = intents::onRenewSession,
|
||||||
|
|
@ -76,10 +75,10 @@ internal class TangemPayDetailsNotificationFactory(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createAccountUnavailableConfig(isRedesignEnabled: Boolean) = NotificationConfig(
|
private fun createAccountUnavailableConfig() = NotificationConfig(
|
||||||
title = resourceReference(R.string.tangempay_temporarily_unavailable),
|
title = resourceReference(R.string.tangempay_temporarily_unavailable),
|
||||||
subtitle = resourceReference(R.string.tangempay_service_unreachable_try_later),
|
subtitle = resourceReference(R.string.tangempay_service_unreachable_try_later),
|
||||||
iconResId = if (isRedesignEnabled) R.drawable.ic_alert_circle_24 else R.drawable.img_attention_20,
|
iconResId = R.drawable.ic_alert_circle_24,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createTariffSystemDownGradePendingConfig(tariffPlan: TangemPayTariffPlanState): NotificationConfig? {
|
private fun createTariffSystemDownGradePendingConfig(tariffPlan: TangemPayTariffPlanState): NotificationConfig? {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ internal class TangemPayDetailsStateFactory(
|
||||||
private val onBack: () -> Unit,
|
private val onBack: () -> Unit,
|
||||||
private val onOpenMenu: () -> Unit,
|
private val onOpenMenu: () -> Unit,
|
||||||
private val intents: TangemPayDetailIntents,
|
private val intents: TangemPayDetailIntents,
|
||||||
private val isRedesignEnabled: Boolean,
|
|
||||||
private val isRemoveAccountEnabled: Boolean,
|
private val isRemoveAccountEnabled: Boolean,
|
||||||
private val isTiersPlusPlanEnabled: Boolean,
|
private val isTiersPlusPlanEnabled: Boolean,
|
||||||
) {
|
) {
|
||||||
|
|
@ -41,7 +40,6 @@ internal class TangemPayDetailsStateFactory(
|
||||||
intents = intents,
|
intents = intents,
|
||||||
isRemoveAccountEnabled = isRemoveAccountEnabled,
|
isRemoveAccountEnabled = isRemoveAccountEnabled,
|
||||||
isTiersPlusPlanEnabled = isTiersPlusPlanEnabled,
|
isTiersPlusPlanEnabled = isTiersPlusPlanEnabled,
|
||||||
isRedesignEnabled = isRedesignEnabled,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getLoadingState(): TangemPayDetailsUM {
|
fun getLoadingState(): TangemPayDetailsUM {
|
||||||
|
|
@ -130,7 +128,7 @@ internal class TangemPayDetailsStateFactory(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDeactivatedState(hasWithdrawableBalance: Boolean): TangemPayDetailsUM {
|
fun getDeactivatedState(hasWithdrawableBalance: Boolean): TangemPayDetailsUM {
|
||||||
val accountDeactivatedNotification = notificationFactory.createAccountDeactivatedConfig(isRedesignEnabled)
|
val accountDeactivatedNotification = notificationFactory.createAccountDeactivatedConfig()
|
||||||
return TangemPayDetailsUM(
|
return TangemPayDetailsUM(
|
||||||
topBarConfig = TangemPayDetailsTopBarConfig(
|
topBarConfig = TangemPayDetailsTopBarConfig(
|
||||||
onBackClick = onBack,
|
onBackClick = onBack,
|
||||||
|
|
@ -327,11 +325,7 @@ internal class TangemPayDetailsStateFactory(
|
||||||
action = TangemPayAction.AddFunds,
|
action = TangemPayAction.AddFunds,
|
||||||
config = ActionButtonConfig(
|
config = ActionButtonConfig(
|
||||||
text = resourceReference(id = R.string.tangempay_card_details_add_funds),
|
text = resourceReference(id = R.string.tangempay_card_details_add_funds),
|
||||||
iconResId = if (isRedesignEnabled) {
|
iconResId = R.drawable.ic_arrow_down_24,
|
||||||
R.drawable.ic_arrow_down_24
|
|
||||||
} else {
|
|
||||||
R.drawable.ic_plus_24
|
|
||||||
},
|
|
||||||
onClick = intents::onClickAddFunds,
|
onClick = intents::onClickAddFunds,
|
||||||
isEnabled = isAddFundsEnabled,
|
isEnabled = isAddFundsEnabled,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,9 @@
|
||||||
package com.tangem.features.tangempay.entity
|
package com.tangem.features.tangempay.entity
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
|
||||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||||
import com.tangem.core.ui.extensions.ColorReference
|
|
||||||
import com.tangem.core.ui.extensions.ImageReference
|
import com.tangem.core.ui.extensions.ImageReference
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
|
||||||
|
|
||||||
internal data class TangemPayTxHistoryDetailsUM(
|
|
||||||
val isBalanceHidden: Boolean,
|
|
||||||
val title: TextReference,
|
|
||||||
val iconState: ImageReference,
|
|
||||||
val transactionTitle: TextReference,
|
|
||||||
val transactionSubtitle: TextReference,
|
|
||||||
val transactionAmount: String,
|
|
||||||
val transactionAmountColor: ColorReference,
|
|
||||||
val localTransactionText: String?,
|
|
||||||
val labelState: LabelUM?,
|
|
||||||
val notification: NotificationState?,
|
|
||||||
val buttons: ImmutableList<ButtonState>,
|
|
||||||
val dismiss: () -> Unit,
|
|
||||||
) {
|
|
||||||
|
|
||||||
data class NotificationState(
|
|
||||||
val config: NotificationConfig,
|
|
||||||
val titleColor: ColorReference,
|
|
||||||
val iconTint: ColorReference,
|
|
||||||
val containerColor: ColorReference?,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal data class ButtonState(
|
internal data class ButtonState(
|
||||||
val text: TextReference,
|
val text: TextReference,
|
||||||
|
|
@ -78,23 +51,4 @@ internal sealed interface TransactionDetailUM {
|
||||||
data class Error(val onRefreshClick: () -> Unit) : TransactionDetailUM
|
data class Error(val onRefreshClick: () -> Unit) : TransactionDetailUM
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum class TransactionLoadState { Loading, Loaded, Error }
|
internal enum class TransactionLoadState { Loading, Loaded, Error }
|
||||||
|
|
||||||
@Immutable
|
|
||||||
internal sealed interface TangemPayTxHistoryDetailsUiState {
|
|
||||||
data class Legacy(val state: TangemPayTxHistoryDetailsUM) : TangemPayTxHistoryDetailsUiState
|
|
||||||
data class Redesign(val state: TangemPayTxHistoryDetailsUMV2) : TangemPayTxHistoryDetailsUiState
|
|
||||||
}
|
|
||||||
|
|
||||||
internal data class TangemPayTxHistoryDetailsUiStates(
|
|
||||||
val legacy: TangemPayTxHistoryDetailsUM,
|
|
||||||
val redesign: TangemPayTxHistoryDetailsUMV2,
|
|
||||||
) {
|
|
||||||
fun toUiState(isRedesignEnabled: Boolean): TangemPayTxHistoryDetailsUiState {
|
|
||||||
return if (isRedesignEnabled) {
|
|
||||||
TangemPayTxHistoryDetailsUiState.Redesign(redesign)
|
|
||||||
} else {
|
|
||||||
TangemPayTxHistoryDetailsUiState.Legacy(legacy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -22,17 +22,10 @@ internal class TangemPayCardLimitSetupComponent(
|
||||||
override fun Content(modifier: Modifier) {
|
override fun Content(modifier: Modifier) {
|
||||||
val state by model.uiState.collectAsStateWithLifecycle()
|
val state by model.uiState.collectAsStateWithLifecycle()
|
||||||
BackHandler(onBack = router::pop)
|
BackHandler(onBack = router::pop)
|
||||||
if (model.inRedesignEnabled()) {
|
TangemPayCardLimitSetupScreenV2(
|
||||||
TangemPayCardLimitSetupScreenV2(
|
state = state,
|
||||||
state = state,
|
modifier = modifier,
|
||||||
modifier = modifier,
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TangemPayCardLimitSetupScreen(
|
|
||||||
state = state,
|
|
||||||
modifier = modifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import com.tangem.domain.models.pay.TangemPayCardLimitPeriod
|
||||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||||
import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase
|
import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase
|
||||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
import com.tangem.features.tangempay.details.impl.R
|
||||||
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
|
@ -46,7 +45,6 @@ internal class TangemPayCardLimitSetupModel @Inject constructor(
|
||||||
private val setTangemPayCardLimitUseCase: SetTangemPayCardLimitUseCase,
|
private val setTangemPayCardLimitUseCase: SetTangemPayCardLimitUseCase,
|
||||||
private val uiMessageSender: UiMessageSender,
|
private val uiMessageSender: UiMessageSender,
|
||||||
private val analytics: AnalyticsEventHandler,
|
private val analytics: AnalyticsEventHandler,
|
||||||
private val featureToggles: TangemPayFeatureToggles,
|
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
private val params: TangemPayCardLimitSetupComponent.Params = paramsContainer.require()
|
private val params: TangemPayCardLimitSetupComponent.Params = paramsContainer.require()
|
||||||
|
|
@ -78,8 +76,6 @@ internal class TangemPayCardLimitSetupModel @Inject constructor(
|
||||||
observeCardState()
|
observeCardState()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun inRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
private fun observeCardState() {
|
private fun observeCardState() {
|
||||||
paymentAccountStatusSupplier.invoke(userWalletId)
|
paymentAccountStatusSupplier.invoke(userWalletId)
|
||||||
.map { it.value }
|
.map { it.value }
|
||||||
|
|
|
||||||
|
|
@ -1,185 +0,0 @@
|
||||||
package com.tangem.features.tangempay.limit.setup
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
|
||||||
import com.tangem.core.ui.components.SpacerH12
|
|
||||||
import com.tangem.core.ui.components.TextShimmer
|
|
||||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
|
||||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
|
||||||
import com.tangem.core.ui.components.fields.AmountTextField
|
|
||||||
import com.tangem.core.ui.components.fields.TangemAmountTextFieldColors
|
|
||||||
import com.tangem.core.ui.components.fields.visualtransformations.AmountVisualTransformation
|
|
||||||
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.core.ui.utils.rememberDecimalFormat
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayCardLimitSetupScreen(state: TangemPayCardLimitSetupUM, modifier: Modifier = Modifier) {
|
|
||||||
Scaffold(
|
|
||||||
modifier = modifier,
|
|
||||||
topBar = {
|
|
||||||
TangemTopAppBar(
|
|
||||||
modifier = Modifier.statusBarsPadding(),
|
|
||||||
title = stringResourceSafe(R.string.tangempay_card_page_daily_limit_title),
|
|
||||||
startButton = TopAppBarButtonUM.Close(onCloseClick = state.onBackClick),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
|
||||||
) { scaffoldPaddings ->
|
|
||||||
Content(
|
|
||||||
state = state,
|
|
||||||
modifier = Modifier.padding(scaffoldPaddings),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Content(state: TangemPayCardLimitSetupUM, modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.imePadding(),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
|
||||||
) {
|
|
||||||
AmountBlock(
|
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
|
||||||
state = state,
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
|
||||||
PrimaryButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_daily_limit_set_button),
|
|
||||||
enabled = state.isSubmitButtonEnabled,
|
|
||||||
showProgress = state.isSubmitButtonLoading,
|
|
||||||
onClick = state.onSubmitClick,
|
|
||||||
)
|
|
||||||
PresetsRow(presets = state.presets)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun AmountBlock(state: TangemPayCardLimitSetupUM, modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clip(RoundedCornerShape(14.dp))
|
|
||||||
.background(TangemTheme.colors.background.action)
|
|
||||||
.padding(vertical = 48.dp, horizontal = 16.dp),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.common_amount),
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
SpacerH12()
|
|
||||||
if (state.isInitialDataLoading) {
|
|
||||||
TextShimmer(
|
|
||||||
style = TangemTheme.typography.head,
|
|
||||||
text = "$5000",
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val colors = TangemAmountTextFieldColors
|
|
||||||
AmountTextField(
|
|
||||||
value = state.amountFieldModel.value,
|
|
||||||
decimals = state.amountFieldModel.decimals,
|
|
||||||
onValueChange = state.amountFieldModel.onValueChange,
|
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
|
||||||
colors = colors,
|
|
||||||
visualTransformation = AmountVisualTransformation(
|
|
||||||
decimals = state.amountFieldModel.decimals,
|
|
||||||
symbol = state.currencyCode,
|
|
||||||
currencyCode = state.currencyCode,
|
|
||||||
decimalFormat = rememberDecimalFormat(),
|
|
||||||
symbolColor = if (state.amountFieldModel.value.isBlank()) {
|
|
||||||
colors.disabledTextColor
|
|
||||||
} else {
|
|
||||||
colors.textColor
|
|
||||||
},
|
|
||||||
),
|
|
||||||
textStyle = TangemTheme.typography.head.copy(
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
),
|
|
||||||
isAutoResize = true,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.padding(top = 8.dp))
|
|
||||||
Text(
|
|
||||||
text = state.subtitle.resolveReference(),
|
|
||||||
style = TangemTheme.typography.caption2,
|
|
||||||
color = TangemTheme.colors.text.secondary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PresetsRow(presets: ImmutableList<TangemPayCardLimitSetupUM.LimitPresetUM>) {
|
|
||||||
if (presets.isEmpty()) return
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(color = TangemTheme.colors.button.secondary)
|
|
||||||
.padding(horizontal = 8.dp, vertical = 12.dp),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
|
||||||
) {
|
|
||||||
presets.forEach { preset ->
|
|
||||||
PresetChip(
|
|
||||||
preset = preset,
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PresetChip(preset: TangemPayCardLimitSetupUM.LimitPresetUM, modifier: Modifier = Modifier) {
|
|
||||||
Row(
|
|
||||||
modifier = modifier
|
|
||||||
.clip(RoundedCornerShape(16.dp))
|
|
||||||
.background(TangemTheme.colors.background.primary)
|
|
||||||
.clickable(onClick = preset.onClick)
|
|
||||||
.padding(horizontal = 12.dp, vertical = 4.dp)
|
|
||||||
.wrapContentHeight(),
|
|
||||||
horizontalArrangement = Arrangement.Center,
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = preset.label,
|
|
||||||
style = TangemTheme.typography.caption1,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
maxLines = 1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun preview() = TangemThemePreview {
|
|
||||||
TangemPayCardLimitSetupScreen(
|
|
||||||
state = TangemPayCardLimitSetupUM.stub(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -8,24 +8,16 @@ import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
||||||
|
|
||||||
internal class TangemPayCardLimitSetupSuccessComponent(
|
internal class TangemPayCardLimitSetupSuccessComponent(
|
||||||
private val isRedesignEnabled: Boolean,
|
|
||||||
appComponentContext: AppComponentContext,
|
appComponentContext: AppComponentContext,
|
||||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content(modifier: Modifier) {
|
override fun Content(modifier: Modifier) {
|
||||||
BackHandler(onBack = ::backToDetails)
|
BackHandler(onBack = ::backToDetails)
|
||||||
if (isRedesignEnabled) {
|
TangemPayCardLimitSetupSuccessScreenV2(
|
||||||
TangemPayCardLimitSetupSuccessScreenV2(
|
modifier = modifier,
|
||||||
modifier = modifier,
|
onDoneClick = ::backToDetails,
|
||||||
onDoneClick = ::backToDetails,
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TangemPayCardLimitSetupSuccessScreen(
|
|
||||||
modifier = modifier,
|
|
||||||
onDoneClick = ::backToDetails,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun backToDetails() {
|
private fun backToDetails() {
|
||||||
|
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
package com.tangem.features.tangempay.limit.setup
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import androidx.compose.ui.res.vectorResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
|
||||||
import com.tangem.core.ui.components.SpacerH12
|
|
||||||
import com.tangem.core.ui.components.SpacerH32
|
|
||||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
|
||||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayCardLimitSetupSuccessScreen(onDoneClick: () -> Unit, modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.navigationBarsPadding(),
|
|
||||||
) {
|
|
||||||
TangemTopAppBar(
|
|
||||||
modifier = Modifier.statusBarsPadding(),
|
|
||||||
startButton = TopAppBarButtonUM.Close(onCloseClick = onDoneClick),
|
|
||||||
)
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
SuccessContent(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.weight(1f),
|
|
||||||
)
|
|
||||||
PrimaryButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.padding(bottom = 16.dp),
|
|
||||||
text = stringResourceSafe(R.string.common_done),
|
|
||||||
onClick = onDoneClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun SuccessContent(modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier,
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = ImageVector.vectorResource(R.drawable.ic_success_blue_76),
|
|
||||||
tint = Color.Unspecified,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier.size(76.dp),
|
|
||||||
)
|
|
||||||
SpacerH32()
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(horizontal = 32.dp),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_success_title),
|
|
||||||
style = TangemTheme.typography.h2,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
SpacerH12()
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(horizontal = 32.dp),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_success_description),
|
|
||||||
style = TangemTheme.typography.body1,
|
|
||||||
color = TangemTheme.colors.text.secondary,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Composable
|
|
||||||
private fun Preview() {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayCardLimitSetupSuccessScreen(onDoneClick = {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,7 +9,6 @@ import com.tangem.domain.models.ReceiveAddressModel
|
||||||
import com.tangem.domain.models.ReceiveAddressModel.DisplayType
|
import com.tangem.domain.models.ReceiveAddressModel.DisplayType
|
||||||
import com.tangem.domain.pay.model.TangemPayTopUpData
|
import com.tangem.domain.pay.model.TangemPayTopUpData
|
||||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.components.TangemPayAddFundsComponent
|
import com.tangem.features.tangempay.components.TangemPayAddFundsComponent
|
||||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
|
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
|
||||||
import com.tangem.features.tangempay.model.transformers.TangemPayAddFundsUMConverter
|
import com.tangem.features.tangempay.model.transformers.TangemPayAddFundsUMConverter
|
||||||
|
|
@ -22,7 +21,6 @@ import javax.inject.Inject
|
||||||
internal class TangemPayAddFundsModel @Inject constructor(
|
internal class TangemPayAddFundsModel @Inject constructor(
|
||||||
paramsContainer: ParamsContainer,
|
paramsContainer: ParamsContainer,
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
|
||||||
virtualAccountToggles: VirtualAccountFeatureToggles,
|
virtualAccountToggles: VirtualAccountFeatureToggles,
|
||||||
analytics: AnalyticsEventHandler,
|
analytics: AnalyticsEventHandler,
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
@ -55,13 +53,10 @@ internal class TangemPayAddFundsModel @Inject constructor(
|
||||||
)
|
)
|
||||||
return TangemPayAddFundsUMConverter(
|
return TangemPayAddFundsUMConverter(
|
||||||
listener = params.listener,
|
listener = params.listener,
|
||||||
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
|
|
||||||
shouldShowBankTransfer = isBankTransferShown,
|
shouldShowBankTransfer = isBankTransferShown,
|
||||||
).convert(data)
|
).convert(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
fun onDismiss() {
|
fun onDismiss() {
|
||||||
params.listener.onDismissAddFunds()
|
params.listener.onDismissAddFunds()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.core.decompose.navigation.Router
|
import com.tangem.core.decompose.navigation.Router
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.components.TangemPayAddToWalletComponent
|
import com.tangem.features.tangempay.components.TangemPayAddToWalletComponent
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
import com.tangem.features.tangempay.details.impl.R
|
||||||
import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM
|
import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM
|
||||||
|
|
@ -27,7 +26,6 @@ internal class TangemPayAddToWalletModel @Inject constructor(
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val router: Router,
|
private val router: Router,
|
||||||
private val googleWalletUtil: GoogleWalletUtil,
|
private val googleWalletUtil: GoogleWalletUtil,
|
||||||
private val featureToggles: TangemPayFeatureToggles,
|
|
||||||
cardDetailsControllerFactory: TangemPayCardDetailsController.Factory,
|
cardDetailsControllerFactory: TangemPayCardDetailsController.Factory,
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
|
|
@ -49,8 +47,6 @@ internal class TangemPayAddToWalletModel @Inject constructor(
|
||||||
val uiState: StateFlow<TangemPayAddToWalletUM>
|
val uiState: StateFlow<TangemPayAddToWalletUM>
|
||||||
field = MutableStateFlow(getInitialState())
|
field = MutableStateFlow(getInitialState())
|
||||||
|
|
||||||
fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
@Suppress("MagicNumber")
|
@Suppress("MagicNumber")
|
||||||
private fun getInitialState(): TangemPayAddToWalletUM {
|
private fun getInitialState(): TangemPayAddToWalletUM {
|
||||||
return TangemPayAddToWalletUM(
|
return TangemPayAddToWalletUM(
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ import com.tangem.domain.pay.model.TangemPayTopUpData
|
||||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||||
import com.tangem.domain.pay.usecase.ChangeCardFrozenStateUseCase
|
import com.tangem.domain.pay.usecase.ChangeCardFrozenStateUseCase
|
||||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.closure.CloseCardListener
|
import com.tangem.features.tangempay.closure.CloseCardListener
|
||||||
import com.tangem.features.tangempay.components.AddFundsListener
|
import com.tangem.features.tangempay.components.AddFundsListener
|
||||||
import com.tangem.features.tangempay.components.ReissueCardListener
|
import com.tangem.features.tangempay.components.ReissueCardListener
|
||||||
|
|
@ -81,7 +80,6 @@ internal class TangemPayCardPageModel @Inject constructor(
|
||||||
private val uiMessageSender: UiMessageSender,
|
private val uiMessageSender: UiMessageSender,
|
||||||
private val changeCardFrozenStateUseCase: ChangeCardFrozenStateUseCase,
|
private val changeCardFrozenStateUseCase: ChangeCardFrozenStateUseCase,
|
||||||
private val cardDetailsEventListener: CardDetailsEventListener,
|
private val cardDetailsEventListener: CardDetailsEventListener,
|
||||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
|
||||||
private val cardDetailsControllerFactory: TangemPayCardDetailsController.Factory,
|
private val cardDetailsControllerFactory: TangemPayCardDetailsController.Factory,
|
||||||
) : Model(), ViewPinListener, ReissueCardListener, AddFundsListener, CloseCardListener {
|
) : Model(), ViewPinListener, ReissueCardListener, AddFundsListener, CloseCardListener {
|
||||||
|
|
||||||
|
|
@ -116,7 +114,6 @@ internal class TangemPayCardPageModel @Inject constructor(
|
||||||
TangemPayCardPageUM(
|
TangemPayCardPageUM(
|
||||||
onBackClick = router::pop,
|
onBackClick = router::pop,
|
||||||
dailyLimitState = TangemPayDailyLimitBlockState.Loading,
|
dailyLimitState = TangemPayDailyLimitBlockState.Loading,
|
||||||
settings = persistentListOf(),
|
|
||||||
settingsV2 = persistentListOf(),
|
settingsV2 = persistentListOf(),
|
||||||
menuItems = buildMenuItems(
|
menuItems = buildMenuItems(
|
||||||
isLastCard = params.initialStatus.ifLoadedOrNull { it.cards.isLastCard() } ?: false,
|
isLastCard = params.initialStatus.ifLoadedOrNull { it.cards.isLastCard() } ?: false,
|
||||||
|
|
@ -170,8 +167,6 @@ internal class TangemPayCardPageModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
/** Reports the card the user swiped to so per-card UI and reveal target it. */
|
/** Reports the card the user swiped to so per-card UI and reveal target it. */
|
||||||
fun onCardPageSelected(index: Int) {
|
fun onCardPageSelected(index: Int) {
|
||||||
cardControllersState.value.getOrNull(index)?.let { selectedCardId.value = it.cardId }
|
cardControllersState.value.getOrNull(index)?.let { selectedCardId.value = it.cardId }
|
||||||
|
|
@ -223,7 +218,6 @@ internal class TangemPayCardPageModel @Inject constructor(
|
||||||
uiState.update { uiState ->
|
uiState.update { uiState ->
|
||||||
uiState.copy(
|
uiState.copy(
|
||||||
dailyLimitState = buildDailyLimitState(state),
|
dailyLimitState = buildDailyLimitState(state),
|
||||||
settings = buildSettings(card),
|
|
||||||
settingsV2 = buildSettingsV2(card),
|
settingsV2 = buildSettingsV2(card),
|
||||||
menuItems = buildMenuItems(isLastCard = status.cards.isLastCard()),
|
menuItems = buildMenuItems(isLastCard = status.cards.isLastCard()),
|
||||||
cardState = card.state,
|
cardState = card.state,
|
||||||
|
|
@ -239,34 +233,7 @@ internal class TangemPayCardPageModel @Inject constructor(
|
||||||
return (status as? PaymentAccountStatusValue.Loaded)?.findCardWithId(selectedCardId.value)
|
return (status as? PaymentAccountStatusValue.Loaded)?.findCardWithId(selectedCardId.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildSettings(card: TangemPayCard): ImmutableList<TangemPayCardPageSetting> {
|
|
||||||
if (isRedesignEnabled()) return persistentListOf()
|
|
||||||
return persistentListOf(
|
|
||||||
TangemPayCardPageSetting(
|
|
||||||
title = TextReference.Res(R.string.tangempay_card_details_change_pin),
|
|
||||||
onSettingClick = { onClickChangePIN(card.hasPinCode) },
|
|
||||||
testTag = TangemPayTestTags.CHANGE_PIN_ROW,
|
|
||||||
),
|
|
||||||
TangemPayCardPageSetting(
|
|
||||||
title = TextReference.Res(
|
|
||||||
if (card.isFrozen) {
|
|
||||||
R.string.tangempay_card_details_unfreeze_card
|
|
||||||
} else {
|
|
||||||
R.string.tangempay_card_details_freeze_card
|
|
||||||
},
|
|
||||||
),
|
|
||||||
onSettingClick = { onClickFreezeOrUnfreezeCard(card.isFrozen) },
|
|
||||||
testTag = TangemPayTestTags.FREEZE_CARD_ROW,
|
|
||||||
),
|
|
||||||
TangemPayCardPageSetting(
|
|
||||||
title = TextReference.Res(R.string.tangempay_card_details_reissue_card),
|
|
||||||
onSettingClick = ::onClickReissueCard,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun subscribeOnDetailsState() {
|
private suspend fun subscribeOnDetailsState() {
|
||||||
if (!isRedesignEnabled()) return
|
|
||||||
combine(cardDetailsEventListener.event, selectedCardId) { event, selectedId ->
|
combine(cardDetailsEventListener.event, selectedCardId) { event, selectedId ->
|
||||||
event is CardDetailsEvent.Show && event.cardId == selectedId
|
event is CardDetailsEvent.Show && event.cardId == selectedId
|
||||||
}.collect { isDetailsShown ->
|
}.collect { isDetailsShown ->
|
||||||
|
|
@ -287,7 +254,6 @@ internal class TangemPayCardPageModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildSettingsV2(card: TangemPayCard): ImmutableList<TangemPayCardPageSettingV2> {
|
private fun buildSettingsV2(card: TangemPayCard): ImmutableList<TangemPayCardPageSettingV2> {
|
||||||
if (!isRedesignEnabled()) return persistentListOf()
|
|
||||||
return persistentListOf(
|
return persistentListOf(
|
||||||
TangemPayCardPageSettingV2(
|
TangemPayCardPageSettingV2(
|
||||||
id = TangemPayCardPageSettingV2.Id.Details,
|
id = TangemPayCardPageSettingV2.Id.Details,
|
||||||
|
|
@ -395,15 +361,9 @@ internal class TangemPayCardPageModel @Inject constructor(
|
||||||
if (frozenStateJobHolder.isActive) return
|
if (frozenStateJobHolder.isActive) return
|
||||||
|
|
||||||
val message = if (isFrozen) {
|
val message = if (isFrozen) {
|
||||||
TangemPayMessagesFactory.createUnfreezeCardMessage(
|
TangemPayMessagesFactory.createUnfreezeCardMessage(onUnfreezeClicked = ::unfreezeCard)
|
||||||
onUnfreezeClicked = ::unfreezeCard,
|
|
||||||
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
TangemPayMessagesFactory.createFreezeCardMessage(
|
TangemPayMessagesFactory.createFreezeCardMessage(onFreezeClicked = ::freezeCard)
|
||||||
onFreezeClicked = ::freezeCard,
|
|
||||||
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
uiMessageSender.send(message)
|
uiMessageSender.send(message)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
|
||||||
import com.tangem.domain.pay.model.SetPinResult
|
import com.tangem.domain.pay.model.SetPinResult
|
||||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.components.TangemPayChangePinComponent
|
import com.tangem.features.tangempay.components.TangemPayChangePinComponent
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
import com.tangem.features.tangempay.details.impl.R
|
||||||
import com.tangem.features.tangempay.entity.TangemPayChangePinUM
|
import com.tangem.features.tangempay.entity.TangemPayChangePinUM
|
||||||
|
|
@ -38,7 +37,6 @@ internal class TangemPayChangePinModel @Inject constructor(
|
||||||
private val router: Router,
|
private val router: Router,
|
||||||
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||||
private val analytics: AnalyticsEventHandler,
|
private val analytics: AnalyticsEventHandler,
|
||||||
private val featureToggles: TangemPayFeatureToggles,
|
|
||||||
private val fetcher: PaymentAccountStatusFetcher,
|
private val fetcher: PaymentAccountStatusFetcher,
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
|
|
@ -50,13 +48,11 @@ internal class TangemPayChangePinModel @Inject constructor(
|
||||||
analytics.send(TangemPayAnalyticsEvents.ChangePinScreenShown())
|
analytics.send(TangemPayAnalyticsEvents.ChangePinScreenShown())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
private fun onPinCodeChange(pin: String) {
|
private fun onPinCodeChange(pin: String) {
|
||||||
uiState.update(transformer = PinCodeChangeTransformer(newPin = pin))
|
uiState.update(transformer = PinCodeChangeTransformer(newPin = pin))
|
||||||
val state = uiState.value
|
val state = uiState.value
|
||||||
// In the redesign there is no submit button: a valid full PIN is submitted automatically.
|
// There is no submit button: a valid full PIN is submitted automatically.
|
||||||
if (featureToggles.isRedesignEnabled && state.submitButtonEnabled && !state.submitButtonLoading) {
|
if (state.submitButtonEnabled && !state.submitButtonLoading) {
|
||||||
onClickSubmit()
|
onClickSubmit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,6 @@ internal class TangemPayDetailsModel @Inject constructor(
|
||||||
onBack = router::pop,
|
onBack = router::pop,
|
||||||
onOpenMenu = ::onOpenMenu,
|
onOpenMenu = ::onOpenMenu,
|
||||||
intents = this,
|
intents = this,
|
||||||
isRedesignEnabled = isRedesignEnabled(),
|
|
||||||
isRemoveAccountEnabled = tangemPayFeatureToggles.isRemoveAccountEnabled,
|
isRemoveAccountEnabled = tangemPayFeatureToggles.isRemoveAccountEnabled,
|
||||||
isTiersPlusPlanEnabled = tangemPayFeatureToggles.isTiersPlusPlanEnabled,
|
isTiersPlusPlanEnabled = tangemPayFeatureToggles.isTiersPlusPlanEnabled,
|
||||||
)
|
)
|
||||||
|
|
@ -198,8 +197,6 @@ internal class TangemPayDetailsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
override fun onClickAddFunds() {
|
override fun onClickAddFunds() {
|
||||||
analytics.send(TangemPayAnalyticsEvents.AddFundsClicked())
|
analytics.send(TangemPayAnalyticsEvents.AddFundsClicked())
|
||||||
val balance = currentStatus.value.balanceOrNull()
|
val balance = currentStatus.value.balanceOrNull()
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import com.tangem.domain.models.account.requireCardWithId
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||||
import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase
|
import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.components.TangemPayEditDisplayNameComponent
|
import com.tangem.features.tangempay.components.TangemPayEditDisplayNameComponent
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
import com.tangem.features.tangempay.details.impl.R
|
||||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||||
|
|
@ -39,7 +38,6 @@ internal class TangemPayEditDisplayNameModel @Inject constructor(
|
||||||
private val updateCardNameUseCase: UpdateTangemPayCardNameUseCase,
|
private val updateCardNameUseCase: UpdateTangemPayCardNameUseCase,
|
||||||
private val uiMessageSender: UiMessageSender,
|
private val uiMessageSender: UiMessageSender,
|
||||||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||||
private val featureToggles: TangemPayFeatureToggles,
|
|
||||||
cardDetailsControllerFactory: TangemPayCardDetailsController.Factory,
|
cardDetailsControllerFactory: TangemPayCardDetailsController.Factory,
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
|
|
@ -80,8 +78,6 @@ internal class TangemPayEditDisplayNameModel @Inject constructor(
|
||||||
subscribeToCardNameChanges(card.id, params.userWalletId)
|
subscribeToCardNameChanges(card.id, params.userWalletId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRedesignEnabled() = featureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
private fun subscribeToCardNameChanges(cardId: String, userWalletId: UserWalletId) {
|
private fun subscribeToCardNameChanges(cardId: String, userWalletId: UserWalletId) {
|
||||||
paymentAccountStatusSupplier.invoke(userWalletId)
|
paymentAccountStatusSupplier.invoke(userWalletId)
|
||||||
.onEach { state ->
|
.onEach { state ->
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||||
import com.tangem.domain.pay.repository.TangemPayReissueCardRepository
|
import com.tangem.domain.pay.repository.TangemPayReissueCardRepository
|
||||||
import com.tangem.domain.pay.usecase.ReissueTangemPayCardUseCase
|
import com.tangem.domain.pay.usecase.ReissueTangemPayCardUseCase
|
||||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.components.TangemPayReissueCardComponent
|
import com.tangem.features.tangempay.components.TangemPayReissueCardComponent
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
import com.tangem.features.tangempay.details.impl.R
|
||||||
import com.tangem.features.tangempay.entity.TangemPayReissueCardError
|
import com.tangem.features.tangempay.entity.TangemPayReissueCardError
|
||||||
|
|
@ -42,7 +41,6 @@ internal class TangemPayReissueCardModel @Inject constructor(
|
||||||
private val reissueTangemPayCardUseCase: ReissueTangemPayCardUseCase,
|
private val reissueTangemPayCardUseCase: ReissueTangemPayCardUseCase,
|
||||||
private val uiMessageSender: UiMessageSender,
|
private val uiMessageSender: UiMessageSender,
|
||||||
private val analytics: AnalyticsEventHandler,
|
private val analytics: AnalyticsEventHandler,
|
||||||
private val featureToggles: TangemPayFeatureToggles,
|
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
private val params = paramsContainer.require<TangemPayReissueCardComponent.Params>()
|
private val params = paramsContainer.require<TangemPayReissueCardComponent.Params>()
|
||||||
|
|
@ -69,8 +67,6 @@ internal class TangemPayReissueCardModel @Inject constructor(
|
||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
fun onDismiss() {
|
fun onDismiss() {
|
||||||
reissueJobHolder.cancel()
|
reissueJobHolder.cancel()
|
||||||
params.listener.onDismissReissueCard()
|
params.listener.onDismissReissueCard()
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,8 @@ import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
|
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
|
||||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
||||||
import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent
|
import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUiStates
|
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUMV2
|
||||||
import com.tangem.features.tangempay.entity.TransactionLoadState
|
import com.tangem.features.tangempay.entity.TransactionLoadState
|
||||||
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverter
|
|
||||||
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverterV2
|
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverterV2
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
|
@ -46,16 +45,16 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor(
|
||||||
private val transactionLoadState = MutableStateFlow(TransactionLoadState.Loading)
|
private val transactionLoadState = MutableStateFlow(TransactionLoadState.Loading)
|
||||||
private var loadTransactionJob: Job? = null
|
private var loadTransactionJob: Job? = null
|
||||||
|
|
||||||
val uiState: StateFlow<TangemPayTxHistoryDetailsUiStates> = combine(
|
val uiState: StateFlow<TangemPayTxHistoryDetailsUMV2> = combine(
|
||||||
balanceHidingSettings.isBalanceHidden(),
|
balanceHidingSettings.isBalanceHidden(),
|
||||||
transaction,
|
transaction,
|
||||||
transactionLoadState,
|
transactionLoadState,
|
||||||
) { isBalanceHidden, transaction, transactionLoadState ->
|
) { isBalanceHidden, transaction, transactionLoadState ->
|
||||||
buildUiStates(isBalanceHidden, transaction, transactionLoadState)
|
buildUiState(isBalanceHidden, transaction, transactionLoadState)
|
||||||
}.stateIn(
|
}.stateIn(
|
||||||
scope = modelScope,
|
scope = modelScope,
|
||||||
started = SharingStarted.Eagerly,
|
started = SharingStarted.Eagerly,
|
||||||
initialValue = buildUiStates(
|
initialValue = buildUiState(
|
||||||
isBalanceHidden = params.isBalanceHidden,
|
isBalanceHidden = params.isBalanceHidden,
|
||||||
transaction = params.transaction,
|
transaction = params.transaction,
|
||||||
transactionLoadState = transactionLoadState.value,
|
transactionLoadState = transactionLoadState.value,
|
||||||
|
|
@ -88,30 +87,20 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildUiStates(
|
private fun buildUiState(
|
||||||
isBalanceHidden: Boolean,
|
isBalanceHidden: Boolean,
|
||||||
transaction: TangemPayTxHistoryItem,
|
transaction: TangemPayTxHistoryItem,
|
||||||
transactionLoadState: TransactionLoadState,
|
transactionLoadState: TransactionLoadState,
|
||||||
): TangemPayTxHistoryDetailsUiStates {
|
): TangemPayTxHistoryDetailsUMV2 {
|
||||||
val converterInput = TangemPayTxHistoryDetailsConverter.Input(
|
return TangemPayTxHistoryDetailsConverterV2.convert(
|
||||||
item = transaction,
|
value = TangemPayTxHistoryDetailsConverterV2.Input(
|
||||||
isBalanceHidden = isBalanceHidden,
|
item = transaction,
|
||||||
onExplorerClick = ::openExplorer,
|
isBalanceHidden = isBalanceHidden,
|
||||||
onDisputeClick = { dispute(customerId = params.customerId) },
|
transactionLoadState = transactionLoadState,
|
||||||
onDismiss = ::dismiss,
|
onExplorerClick = ::openExplorer,
|
||||||
)
|
onDisputeClick = { dispute(customerId = params.customerId) },
|
||||||
return TangemPayTxHistoryDetailsUiStates(
|
onCardRefreshClick = ::loadTransaction,
|
||||||
legacy = TangemPayTxHistoryDetailsConverter.convert(converterInput),
|
onDismiss = ::dismiss,
|
||||||
redesign = TangemPayTxHistoryDetailsConverterV2.convert(
|
|
||||||
value = TangemPayTxHistoryDetailsConverterV2.Input(
|
|
||||||
item = converterInput.item,
|
|
||||||
isBalanceHidden = converterInput.isBalanceHidden,
|
|
||||||
transactionLoadState = transactionLoadState,
|
|
||||||
onExplorerClick = converterInput.onExplorerClick,
|
|
||||||
onDisputeClick = converterInput.onDisputeClick,
|
|
||||||
onCardRefreshClick = ::loadTransaction,
|
|
||||||
onDismiss = converterInput.onDismiss,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||||
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
|
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
|
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
||||||
import com.tangem.features.tangempay.utils.TangemPayTxHistoryListManager
|
import com.tangem.features.tangempay.utils.TangemPayTxHistoryListManager
|
||||||
|
|
@ -26,7 +25,6 @@ internal class TangemPayTxHistoryModel @Inject constructor(
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||||
private val txHistoryUpdateListener: TangemPayTxHistoryUpdateListener,
|
private val txHistoryUpdateListener: TangemPayTxHistoryUpdateListener,
|
||||||
private val featureToggles: TangemPayFeatureToggles,
|
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
private val params: DefaultTangemPayTxHistoryComponent.Params = paramsContainer.require()
|
private val params: DefaultTangemPayTxHistoryComponent.Params = paramsContainer.require()
|
||||||
|
|
@ -46,8 +44,6 @@ internal class TangemPayTxHistoryModel @Inject constructor(
|
||||||
subscribeToUpdateListener()
|
subscribeToUpdateListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
private fun launchPagination() {
|
private fun launchPagination() {
|
||||||
modelScope.launch { listManager.launchPagination(params.userWalletId) }
|
modelScope.launch { listManager.launchPagination(params.userWalletId) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.components.TangemPayViewPinComponent
|
import com.tangem.features.tangempay.components.TangemPayViewPinComponent
|
||||||
import com.tangem.features.tangempay.entity.TangemPayViewPinUM
|
import com.tangem.features.tangempay.entity.TangemPayViewPinUM
|
||||||
import com.tangem.features.tangempay.model.transformers.TangemPayViewPinErrorStateTransformer
|
import com.tangem.features.tangempay.model.transformers.TangemPayViewPinErrorStateTransformer
|
||||||
|
|
@ -26,7 +25,6 @@ internal class TangemPayViewPinModel @Inject constructor(
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||||
private val analytics: AnalyticsEventHandler,
|
private val analytics: AnalyticsEventHandler,
|
||||||
private val featureToggles: TangemPayFeatureToggles,
|
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
private val params = paramsContainer.require<TangemPayViewPinComponent.Params>()
|
private val params = paramsContainer.require<TangemPayViewPinComponent.Params>()
|
||||||
|
|
@ -39,8 +37,6 @@ internal class TangemPayViewPinModel @Inject constructor(
|
||||||
getCardPin()
|
getCardPin()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRedesignEnabled(): Boolean = featureToggles.isRedesignEnabled
|
|
||||||
|
|
||||||
private fun getCardPin() {
|
private fun getCardPin() {
|
||||||
modelScope.launch {
|
modelScope.launch {
|
||||||
cardDetailsRepository.getPin(userWalletId = params.walletId, cardId = params.cardId)
|
cardDetailsRepository.getPin(userWalletId = params.walletId, cardId = params.cardId)
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import kotlinx.collections.immutable.toPersistentList
|
||||||
|
|
||||||
internal class TangemPayAddFundsUMConverter(
|
internal class TangemPayAddFundsUMConverter(
|
||||||
val listener: AddFundsListener,
|
val listener: AddFundsListener,
|
||||||
val isRedesignEnabled: Boolean,
|
|
||||||
val shouldShowBankTransfer: Boolean,
|
val shouldShowBankTransfer: Boolean,
|
||||||
) : Converter<TangemPayTopUpData, TangemPayAddFundsUM> {
|
) : Converter<TangemPayTopUpData, TangemPayAddFundsUM> {
|
||||||
|
|
||||||
|
|
@ -27,41 +26,23 @@ internal class TangemPayAddFundsUMConverter(
|
||||||
return TangemPayAddFundsUM(
|
return TangemPayAddFundsUM(
|
||||||
items = buildList {
|
items = buildList {
|
||||||
TangemPayAddFundsItemUM(
|
TangemPayAddFundsItemUM(
|
||||||
icon = if (isRedesignEnabled) {
|
icon = TangemIconUM.Icon(
|
||||||
TangemIconUM.Icon(
|
imageVector = Icons.ic_logo_tangem_20,
|
||||||
imageVector = Icons.ic_logo_tangem_20,
|
tintReference = {
|
||||||
tintReference = {
|
TangemTheme.colors3.icon.brand
|
||||||
TangemTheme.colors3.icon.brand
|
},
|
||||||
},
|
),
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TangemIconUM.Icon(
|
|
||||||
iconRes = R.drawable.ic_exchange_vertical_24,
|
|
||||||
tintReference = {
|
|
||||||
TangemTheme.colors.icon.accent
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
title = resourceReference(R.string.tangempay_topup_swap_title),
|
title = resourceReference(R.string.tangempay_topup_swap_title),
|
||||||
description = resourceReference(R.string.tangempay_topup_swap_body),
|
description = resourceReference(R.string.tangempay_topup_swap_body),
|
||||||
onClick = { listener.onClickSwap(value) },
|
onClick = { listener.onClickSwap(value) },
|
||||||
).let(::add)
|
).let(::add)
|
||||||
TangemPayAddFundsItemUM(
|
TangemPayAddFundsItemUM(
|
||||||
icon = if (isRedesignEnabled) {
|
icon = TangemIconUM.Icon(
|
||||||
TangemIconUM.Icon(
|
imageVector = Icons.ic_card_20,
|
||||||
imageVector = Icons.ic_card_20,
|
tintReference = {
|
||||||
tintReference = {
|
TangemTheme.colors3.icon.brand
|
||||||
TangemTheme.colors3.icon.brand
|
},
|
||||||
},
|
),
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TangemIconUM.Icon(
|
|
||||||
iconRes = R.drawable.ic_arrow_down_24,
|
|
||||||
tintReference = {
|
|
||||||
TangemTheme.colors.icon.accent
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
title = resourceReference(R.string.tangempay_topup_receive_title),
|
title = resourceReference(R.string.tangempay_topup_receive_title),
|
||||||
description = resourceReference(R.string.tangempay_topup_receive_body),
|
description = resourceReference(R.string.tangempay_topup_receive_body),
|
||||||
onClick = { listener.onClickReceive(value) },
|
onClick = { listener.onClickReceive(value) },
|
||||||
|
|
|
||||||
|
|
@ -1,313 +0,0 @@
|
||||||
package com.tangem.features.tangempay.model.transformers
|
|
||||||
|
|
||||||
import com.tangem.core.ui.components.label.entity.LabelStyle
|
|
||||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
|
||||||
import com.tangem.core.ui.extensions.*
|
|
||||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
|
||||||
import com.tangem.core.ui.format.bigdecimal.format
|
|
||||||
import com.tangem.core.ui.format.bigdecimal.price
|
|
||||||
import com.tangem.core.ui.res.TangemColorPalette
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.utils.DateTimeFormatters
|
|
||||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import com.tangem.features.tangempay.entity.ButtonState
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
|
|
||||||
import com.tangem.utils.StringsSigns
|
|
||||||
import com.tangem.utils.converter.Converter
|
|
||||||
import com.tangem.utils.extensions.isPositive
|
|
||||||
import com.tangem.utils.extensions.isZero
|
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
|
||||||
|
|
||||||
internal object TangemPayTxHistoryDetailsConverter :
|
|
||||||
Converter<TangemPayTxHistoryDetailsConverter.Input, TangemPayTxHistoryDetailsUM> {
|
|
||||||
private val dateFormatter = DateTimeFormatters.getBestFormatterBySkeleton("dd MMMM")
|
|
||||||
|
|
||||||
private val paySpendSubtitleConverter = PayDetailsSpendSubtitleConverter
|
|
||||||
|
|
||||||
override fun convert(value: Input): TangemPayTxHistoryDetailsUM {
|
|
||||||
val transaction = value.item
|
|
||||||
return TangemPayTxHistoryDetailsUM(
|
|
||||||
isBalanceHidden = value.isBalanceHidden,
|
|
||||||
title = transaction.extractDate(),
|
|
||||||
iconState = transaction.extractIcon(),
|
|
||||||
transactionTitle = transaction.extractTransactionTitle(),
|
|
||||||
transactionSubtitle = transaction.extractTransactionSubtitle(),
|
|
||||||
transactionAmount = transaction.extractAmount(),
|
|
||||||
transactionAmountColor = transaction.extractAmountColor(),
|
|
||||||
localTransactionText = transaction.extractLocalAmount(),
|
|
||||||
labelState = transaction.extractLabel(),
|
|
||||||
notification = transaction.extractNotification(),
|
|
||||||
buttons = value.extractButtonsState(),
|
|
||||||
dismiss = value.onDismiss,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractDate(): TextReference {
|
|
||||||
val date = DateTimeFormatters.formatDate(this.date, dateFormatter)
|
|
||||||
val time = DateTimeFormatters.formatDate(this.date, DateTimeFormatters.timeFormatter)
|
|
||||||
|
|
||||||
return stringReference("$date ${StringsSigns.DOT} $time")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractIcon(): ImageReference {
|
|
||||||
return when (this) {
|
|
||||||
is TangemPayTxHistoryItem.Collateral -> when (this.type) {
|
|
||||||
TangemPayTxHistoryItem.Type.Deposit -> ImageReference.Res(R.drawable.ic_arrow_down_24)
|
|
||||||
TangemPayTxHistoryItem.Type.Withdrawal -> ImageReference.Res(R.drawable.ic_arrow_up_24)
|
|
||||||
}
|
|
||||||
is TangemPayTxHistoryItem.Fee -> ImageReference.Res(R.drawable.ic_percent_24)
|
|
||||||
is TangemPayTxHistoryItem.Payment -> ImageReference.Res(R.drawable.ic_arrow_up_24)
|
|
||||||
is TangemPayTxHistoryItem.Spend -> {
|
|
||||||
val merchantIcon = this.enrichedMerchantIconUrl
|
|
||||||
if (!merchantIcon.isNullOrEmpty()) {
|
|
||||||
ImageReference.Url(merchantIcon)
|
|
||||||
} else {
|
|
||||||
ImageReference.Res(R.drawable.ic_category_24)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractTransactionTitle(): TextReference {
|
|
||||||
return when (this) {
|
|
||||||
is TangemPayTxHistoryItem.Spend -> stringReference(this.enrichedMerchantName ?: this.merchantName)
|
|
||||||
is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.tangem_pay_withdrawal)
|
|
||||||
is TangemPayTxHistoryItem.Collateral -> when (this.type) {
|
|
||||||
TangemPayTxHistoryItem.Type.Deposit -> resourceReference(R.string.tangem_pay_deposit)
|
|
||||||
TangemPayTxHistoryItem.Type.Withdrawal -> resourceReference(R.string.tangem_pay_withdrawal)
|
|
||||||
}
|
|
||||||
is TangemPayTxHistoryItem.Fee -> {
|
|
||||||
this.description?.let(::stringReference) ?: resourceReference(R.string.tangem_pay_fee_title)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractTransactionSubtitle(): TextReference {
|
|
||||||
return when (this) {
|
|
||||||
is TangemPayTxHistoryItem.Fee -> resourceReference(R.string.tangem_pay_fee_subtitle)
|
|
||||||
is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.common_transfer)
|
|
||||||
is TangemPayTxHistoryItem.Collateral -> resourceReference(R.string.common_transfer)
|
|
||||||
is TangemPayTxHistoryItem.Spend -> paySpendSubtitleConverter.convert(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractAmount(): String {
|
|
||||||
return when (this) {
|
|
||||||
is TangemPayTxHistoryItem.Fee,
|
|
||||||
is TangemPayTxHistoryItem.Payment,
|
|
||||||
-> {
|
|
||||||
val amount = this.amount.format {
|
|
||||||
fiat(
|
|
||||||
fiatCurrencyCode = this@extractAmount.currency.currencyCode,
|
|
||||||
fiatCurrencySymbol = this@extractAmount.currency.symbol,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
StringsSigns.MINUS + amount
|
|
||||||
}
|
|
||||||
is TangemPayTxHistoryItem.Spend -> {
|
|
||||||
val amountPrefix = when {
|
|
||||||
this.amount.isZero() -> ""
|
|
||||||
this.status == TangemPayTxHistoryItem.Status.REVERSED -> StringsSigns.MINUS
|
|
||||||
this.status == TangemPayTxHistoryItem.Status.DECLINED ||
|
|
||||||
this.amount.isPositive() -> StringsSigns.MINUS
|
|
||||||
else -> StringsSigns.PLUS
|
|
||||||
}
|
|
||||||
val amount = when (this.status) {
|
|
||||||
TangemPayTxHistoryItem.Status.DECLINED -> this.authorizedAmount
|
|
||||||
else -> this.amount
|
|
||||||
}
|
|
||||||
val formattedAmount = amount.abs().format {
|
|
||||||
fiat(
|
|
||||||
fiatCurrencyCode = this@extractAmount.currency.currencyCode,
|
|
||||||
fiatCurrencySymbol = this@extractAmount.currency.symbol,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
amountPrefix + formattedAmount
|
|
||||||
}
|
|
||||||
is TangemPayTxHistoryItem.Collateral -> {
|
|
||||||
val amountPrefix = when {
|
|
||||||
this.amount.isZero() -> ""
|
|
||||||
this.amount.isPositive() -> StringsSigns.PLUS
|
|
||||||
else -> StringsSigns.MINUS
|
|
||||||
}
|
|
||||||
val amount = this.amount.abs().format {
|
|
||||||
fiat(
|
|
||||||
fiatCurrencyCode = this@extractAmount.currency.currencyCode,
|
|
||||||
fiatCurrencySymbol = this@extractAmount.currency.symbol,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
amountPrefix + amount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractAmountColor(): ColorReference {
|
|
||||||
return when (this) {
|
|
||||||
is TangemPayTxHistoryItem.Fee,
|
|
||||||
is TangemPayTxHistoryItem.Payment,
|
|
||||||
-> themedColor { TangemTheme.colors.text.primary1 }
|
|
||||||
is TangemPayTxHistoryItem.Collateral -> when (this.type) {
|
|
||||||
TangemPayTxHistoryItem.Type.Deposit -> themedColor { TangemTheme.colors.text.accent }
|
|
||||||
TangemPayTxHistoryItem.Type.Withdrawal -> themedColor { TangemTheme.colors.text.primary1 }
|
|
||||||
}
|
|
||||||
is TangemPayTxHistoryItem.Spend -> when (this.status) {
|
|
||||||
TangemPayTxHistoryItem.Status.DECLINED -> themedColor { TangemTheme.colors.text.warning }
|
|
||||||
else -> themedColor { TangemTheme.colors.text.primary1 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractLocalAmount(): String? {
|
|
||||||
return when (this) {
|
|
||||||
is TangemPayTxHistoryItem.Collateral,
|
|
||||||
is TangemPayTxHistoryItem.Fee,
|
|
||||||
is TangemPayTxHistoryItem.Payment,
|
|
||||||
-> null
|
|
||||||
is TangemPayTxHistoryItem.Spend -> {
|
|
||||||
val localCurrency = this.localCurrency
|
|
||||||
val localAmount = this.localAmount
|
|
||||||
if (localCurrency != null && localAmount != null && localCurrency != currency) {
|
|
||||||
val amountPrefix = when {
|
|
||||||
localAmount.isZero() -> ""
|
|
||||||
this.status == TangemPayTxHistoryItem.Status.DECLINED ||
|
|
||||||
localAmount.isPositive() -> StringsSigns.MINUS
|
|
||||||
else -> StringsSigns.PLUS
|
|
||||||
}
|
|
||||||
val amount = localAmount.abs().format {
|
|
||||||
fiat(
|
|
||||||
fiatCurrencyCode = localCurrency.currencyCode,
|
|
||||||
fiatCurrencySymbol = localCurrency.symbol,
|
|
||||||
).price()
|
|
||||||
}
|
|
||||||
amountPrefix + amount
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractLabel(): LabelUM? {
|
|
||||||
return when (this) {
|
|
||||||
is TangemPayTxHistoryItem.Fee,
|
|
||||||
is TangemPayTxHistoryItem.Payment,
|
|
||||||
is TangemPayTxHistoryItem.Collateral,
|
|
||||||
-> null
|
|
||||||
is TangemPayTxHistoryItem.Spend -> when (this.status) {
|
|
||||||
TangemPayTxHistoryItem.Status.COMPLETED -> LabelUM(
|
|
||||||
text = resourceReference(R.string.tangem_pay_status_completed),
|
|
||||||
style = LabelStyle.ACCENT,
|
|
||||||
)
|
|
||||||
TangemPayTxHistoryItem.Status.PENDING -> LabelUM(
|
|
||||||
text = resourceReference(R.string.tangem_pay_status_pending),
|
|
||||||
style = LabelStyle.REGULAR,
|
|
||||||
icon = com.tangem.core.ui.R.drawable.ic_clock_24,
|
|
||||||
)
|
|
||||||
TangemPayTxHistoryItem.Status.DECLINED -> LabelUM(
|
|
||||||
text = resourceReference(R.string.tangem_pay_status_declined),
|
|
||||||
style = LabelStyle.WARNING,
|
|
||||||
)
|
|
||||||
TangemPayTxHistoryItem.Status.REVERSED -> LabelUM(
|
|
||||||
text = resourceReference(R.string.tangem_pay_status_reversed),
|
|
||||||
style = LabelStyle.REGULAR,
|
|
||||||
)
|
|
||||||
TangemPayTxHistoryItem.Status.RESERVED,
|
|
||||||
TangemPayTxHistoryItem.Status.UNKNOWN,
|
|
||||||
-> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TangemPayTxHistoryItem.extractNotification(): TangemPayTxHistoryDetailsUM.NotificationState? {
|
|
||||||
return when (this) {
|
|
||||||
is TangemPayTxHistoryItem.Payment -> null
|
|
||||||
is TangemPayTxHistoryItem.Collateral -> null
|
|
||||||
is TangemPayTxHistoryItem.Fee -> TangemPayTxHistoryDetailsUM.NotificationState(
|
|
||||||
config = NotificationConfig(
|
|
||||||
title = resourceReference(R.string.tangem_pay_transaction_fee_notification_text),
|
|
||||||
subtitle = TextReference.EMPTY,
|
|
||||||
iconResId = R.drawable.ic_token_info_24,
|
|
||||||
),
|
|
||||||
titleColor = themedColor { TangemTheme.colors.text.tertiary },
|
|
||||||
iconTint = themedColor { TangemTheme.colors.icon.secondary },
|
|
||||||
containerColor = null,
|
|
||||||
)
|
|
||||||
is TangemPayTxHistoryItem.Spend -> when (this.status) {
|
|
||||||
TangemPayTxHistoryItem.Status.DECLINED -> TangemPayTxHistoryDetailsUM.NotificationState(
|
|
||||||
config = NotificationConfig(
|
|
||||||
title = declinedReason.let { reason ->
|
|
||||||
if (reason.isNullOrEmpty()) {
|
|
||||||
resourceReference(R.string.tangem_pay_transaction_declined_notification_text)
|
|
||||||
} else {
|
|
||||||
resourceReference(
|
|
||||||
id = R.string.tangem_pay_history_item_spend_mc_declined_reason,
|
|
||||||
formatArgs = wrappedList(TangemPayDeclinedReasonMapper.map(reason)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
subtitle = TextReference.EMPTY,
|
|
||||||
iconResId = R.drawable.ic_token_info_24,
|
|
||||||
),
|
|
||||||
titleColor = themedColor { TangemTheme.colors.text.warning },
|
|
||||||
iconTint = themedColor { TangemTheme.colors.icon.warning },
|
|
||||||
containerColor = themedColor { TangemColorPalette.Amaranth.copy(alpha = 0.1F) },
|
|
||||||
)
|
|
||||||
TangemPayTxHistoryItem.Status.REVERSED -> TangemPayTxHistoryDetailsUM.NotificationState(
|
|
||||||
config = NotificationConfig(
|
|
||||||
title = resourceReference(R.string.tangem_pay_transaction_reversed_notification_text),
|
|
||||||
subtitle = TextReference.EMPTY,
|
|
||||||
iconResId = R.drawable.ic_token_info_24,
|
|
||||||
),
|
|
||||||
titleColor = themedColor { TangemTheme.colors.text.tertiary },
|
|
||||||
iconTint = themedColor { TangemTheme.colors.icon.secondary },
|
|
||||||
containerColor = null,
|
|
||||||
)
|
|
||||||
TangemPayTxHistoryItem.Status.PENDING,
|
|
||||||
TangemPayTxHistoryItem.Status.COMPLETED,
|
|
||||||
TangemPayTxHistoryItem.Status.RESERVED,
|
|
||||||
TangemPayTxHistoryItem.Status.UNKNOWN,
|
|
||||||
-> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Input.extractButtonsState(): ImmutableList<ButtonState> {
|
|
||||||
return when (this.item) {
|
|
||||||
is TangemPayTxHistoryItem.Fee -> persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_get_help),
|
|
||||||
onClick = this.onDisputeClick,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
is TangemPayTxHistoryItem.Spend -> persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_get_help),
|
|
||||||
onClick = this.onDisputeClick,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
is TangemPayTxHistoryItem.Payment -> persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_get_help),
|
|
||||||
onClick = this.onDisputeClick,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
is TangemPayTxHistoryItem.Collateral -> persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_get_help),
|
|
||||||
onClick = this.onDisputeClick,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Input(
|
|
||||||
val item: TangemPayTxHistoryItem,
|
|
||||||
val isBalanceHidden: Boolean,
|
|
||||||
val onExplorerClick: (String?) -> Unit,
|
|
||||||
val onDisputeClick: () -> Unit,
|
|
||||||
val onDismiss: () -> Unit,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.key
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.util.fastForEach
|
|
||||||
import com.tangem.core.ui.components.SpacerH16
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetContent
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
|
||||||
import com.tangem.core.ui.ds.image.TangemIcon
|
|
||||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
|
||||||
import com.tangem.core.ui.extensions.TextReference.Res
|
|
||||||
import com.tangem.core.ui.extensions.resolveReference
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsItemUM
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayAddFundsContent(state: TangemPayAddFundsUM) {
|
|
||||||
TangemModalBottomSheet<TangemBottomSheetConfigContent.Empty>(
|
|
||||||
config = TangemBottomSheetConfig(
|
|
||||||
isShown = true,
|
|
||||||
onDismissRequest = state.dismiss,
|
|
||||||
content = TangemBottomSheetConfigContent.Empty,
|
|
||||||
),
|
|
||||||
onBack = state.dismiss,
|
|
||||||
containerColor = TangemTheme.colors.background.tertiary,
|
|
||||||
title = {
|
|
||||||
TangemModalBottomSheetTitle(
|
|
||||||
title = resourceReference(R.string.tangempay_card_details_add_funds),
|
|
||||||
endIconRes = R.drawable.ic_close_24,
|
|
||||||
onEndClick = state.dismiss,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
if (state.errorMessage != null) {
|
|
||||||
MessageBottomSheetContent(state.errorMessage)
|
|
||||||
} else {
|
|
||||||
Surface(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
|
||||||
color = TangemTheme.colors.background.primary,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
horizontalAlignment = Alignment.Start,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(top = 12.dp, start = 16.dp, end = 16.dp),
|
|
||||||
text = resourceReference(R.string.tangempay_card_details_add_funds_subtitle).resolveReference(),
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
)
|
|
||||||
state.items.fastForEach {
|
|
||||||
key(it.title) {
|
|
||||||
TangemPayTopUpItem(state = it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SpacerH16()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayTopUpItem(state: TangemPayAddFundsItemUM, modifier: Modifier = Modifier) {
|
|
||||||
Row(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clickable(onClick = state.onClick)
|
|
||||||
.padding(horizontal = 12.dp, vertical = 16.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.background(
|
|
||||||
color = TangemTheme.colors.icon.accent.copy(alpha = 0.1f),
|
|
||||||
shape = CircleShape,
|
|
||||||
)
|
|
||||||
.size(36.dp),
|
|
||||||
) {
|
|
||||||
TangemIcon(
|
|
||||||
modifier = Modifier.size(16.dp),
|
|
||||||
tangemIconUM = state.icon,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = state.title.resolveReference(),
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = state.description.resolveReference(),
|
|
||||||
style = TangemTheme.typography.caption2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayAddFundsContentPreview() {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayAddFundsContent(
|
|
||||||
state = TangemPayAddFundsUM(
|
|
||||||
items = persistentListOf(
|
|
||||||
TangemPayAddFundsItemUM(
|
|
||||||
icon = TangemIconUM.Icon(
|
|
||||||
iconRes = R.drawable.ic_exchange_vertical_24,
|
|
||||||
tintReference = {
|
|
||||||
TangemTheme.colors.icon.accent
|
|
||||||
},
|
|
||||||
),
|
|
||||||
title = Res(R.string.common_exchange),
|
|
||||||
description = Res(R.string.exсhange_token_description),
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
TangemPayAddFundsItemUM(
|
|
||||||
icon = TangemIconUM.Icon(
|
|
||||||
iconRes = R.drawable.ic_arrow_down_24,
|
|
||||||
tintReference = {
|
|
||||||
TangemTheme.colors.icon.accent
|
|
||||||
},
|
|
||||||
),
|
|
||||||
title = Res(R.string.common_receive),
|
|
||||||
description = Res(R.string.receive_token_description),
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dismiss = {},
|
|
||||||
errorMessage = null,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,120 +1,19 @@
|
||||||
package com.tangem.features.tangempay.ui
|
package com.tangem.features.tangempay.ui
|
||||||
|
|
||||||
import android.content.res.Configuration
|
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.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
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.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.tangem.core.ui.ds.message.TangemMessage
|
import com.tangem.core.ui.ds.message.TangemMessage
|
||||||
import com.tangem.core.ui.ds.message.TangemMessageEffect
|
import com.tangem.core.ui.ds.message.TangemMessageEffect
|
||||||
import com.tangem.core.ui.extensions.clickableSingle
|
import com.tangem.core.ui.extensions.clickableSingle
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
|
||||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
import com.tangem.features.tangempay.details.impl.R
|
||||||
import com.tangem.features.tangempay.entity.AddToWalletBlockState
|
import com.tangem.features.tangempay.entity.AddToWalletBlockState
|
||||||
|
|
||||||
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
|
@Composable
|
||||||
internal fun TangemPayAddToWalletBlock(state: AddToWalletBlockState, modifier: Modifier = Modifier) {
|
internal fun TangemPayAddToWalletBlock(state: AddToWalletBlockState, modifier: Modifier = Modifier) {
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
|
||||||
TangemPayAddToWalletBlockV2(state = state, modifier = modifier)
|
|
||||||
} else {
|
|
||||||
TangemPayAddToWalletBlockV1(state = state, modifier = modifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayAddToWalletBlockV1(state: AddToWalletBlockState, 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),
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(IntrinsicSize.Min)
|
|
||||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Image(
|
|
||||||
painter = painterResource(R.drawable.img_google_wallet_48),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(36.dp)
|
|
||||||
.clip(CircleShape),
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(Modifier.width(12.dp))
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_notification_title),
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.constantWhite,
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(Modifier.height(6.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_notification_subtitle),
|
|
||||||
style = TangemTheme.typography.caption2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxHeight(),
|
|
||||||
contentAlignment = Alignment.TopEnd,
|
|
||||||
) {
|
|
||||||
Image(
|
|
||||||
modifier = Modifier
|
|
||||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
|
||||||
.clickable(onClick = state.onClickClose)
|
|
||||||
.padding(4.dp)
|
|
||||||
.size(12.dp),
|
|
||||||
painter = painterResource(id = R.drawable.ic_close_24),
|
|
||||||
colorFilter = ColorFilter.tint(TangemTheme.colors.icon.inactive),
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayAddToWalletBlockV2(state: AddToWalletBlockState, modifier: Modifier = Modifier) {
|
|
||||||
TangemMessage(
|
TangemMessage(
|
||||||
modifier = modifier.clickableSingle(onClick = state.onClick),
|
modifier = modifier.clickableSingle(onClick = state.onClick),
|
||||||
onCloseClick = state.onClickClose,
|
onCloseClick = state.onClickClose,
|
||||||
|
|
|
||||||
|
|
@ -1,193 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
|
||||||
import com.tangem.core.ui.components.SecondaryButton
|
|
||||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
|
||||||
import com.tangem.core.ui.extensions.resolveReference
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
|
||||||
import com.tangem.core.ui.res.TangemColorPalette
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.domain.models.pay.TangemPayCardFrozenState
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayAddToWalletUM
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayAddToWalletScreen(
|
|
||||||
state: TangemPayAddToWalletUM,
|
|
||||||
cardDetailsState: TangemPayCardDetailsUM,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
val listState = rememberLazyListState()
|
|
||||||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.navigationBarsPadding(),
|
|
||||||
) {
|
|
||||||
AppBarWithBackButton(
|
|
||||||
modifier = Modifier.statusBarsPadding(),
|
|
||||||
iconRes = R.drawable.ic_close_24,
|
|
||||||
onBackClick = state.onBackClick,
|
|
||||||
)
|
|
||||||
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.weight(1f),
|
|
||||||
state = listState,
|
|
||||||
contentPadding = PaddingValues(bottom = TangemTheme.dimens.spacing16 + bottomBarHeight),
|
|
||||||
) {
|
|
||||||
item(TangemPayCardDetailsUM::class.java) {
|
|
||||||
TangemPayCard(
|
|
||||||
state = cardDetailsState,
|
|
||||||
modifier = Modifier.padding(horizontal = 16.dp).padding(top = 8.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
item(key = TangemPayAddToWalletUM::class.java) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 16.dp, vertical = 24.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_open_wallet_title),
|
|
||||||
style = TangemTheme.typography.h2,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
itemsIndexed(
|
|
||||||
items = state.steps,
|
|
||||||
key = { _, step -> "${TangemPayAddToWalletStepItemUM::class.java}${step.count}" },
|
|
||||||
) { idx, step ->
|
|
||||||
StepItem(
|
|
||||||
modifier = Modifier.padding(bottom = if (idx < state.steps.lastIndex) 16.dp else 0.dp),
|
|
||||||
stepNumber = step.count,
|
|
||||||
title = step.text,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SecondaryButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.imePadding()
|
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 8.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
text = resourceReference(R.string.common_got_it).resolveReference(),
|
|
||||||
onClick = state.onBackClick,
|
|
||||||
|
|
||||||
)
|
|
||||||
if (state.showAddToWalletButton) {
|
|
||||||
PrimaryButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.imePadding()
|
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
text = resourceReference(R.string.tangempay_card_details_open_wallet_button).resolveReference(),
|
|
||||||
onClick = state.onClickOpenWallet,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun StepItem(stepNumber: Int, title: TextReference, modifier: Modifier = Modifier) {
|
|
||||||
Row(
|
|
||||||
modifier = modifier
|
|
||||||
.background(color = Color.Transparent, shape = TangemTheme.shapes.roundedCorners8)
|
|
||||||
.padding(horizontal = 24.dp),
|
|
||||||
verticalAlignment = Alignment.Top,
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.size(24.dp)
|
|
||||||
.background(color = TangemColorPalette.Azure, shape = CircleShape),
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stepNumber.toString(),
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.primary2,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(12.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = title.resolveReference(),
|
|
||||||
style = TangemTheme.typography.subtitle1,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun PreviewTangemPayAddToWalletScreen() {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayAddToWalletScreen(
|
|
||||||
state = TangemPayAddToWalletUM(
|
|
||||||
steps = persistentListOf(
|
|
||||||
TangemPayAddToWalletStepItemUM(
|
|
||||||
count = 1,
|
|
||||||
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_1),
|
|
||||||
),
|
|
||||||
TangemPayAddToWalletStepItemUM(
|
|
||||||
count = 2,
|
|
||||||
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_2),
|
|
||||||
),
|
|
||||||
TangemPayAddToWalletStepItemUM(
|
|
||||||
count = 3,
|
|
||||||
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_3),
|
|
||||||
),
|
|
||||||
TangemPayAddToWalletStepItemUM(
|
|
||||||
count = 4,
|
|
||||||
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_4),
|
|
||||||
),
|
|
||||||
TangemPayAddToWalletStepItemUM(
|
|
||||||
count = 5,
|
|
||||||
text = resourceReference(R.string.tangempay_card_details_open_wallet_step_5),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
showAddToWalletButton = true,
|
|
||||||
onBackClick = {},
|
|
||||||
onClickOpenWallet = {},
|
|
||||||
),
|
|
||||||
cardDetailsState = TangemPayCardDetailsUM(
|
|
||||||
number = "",
|
|
||||||
numberShort = "*1245",
|
|
||||||
expiry = "••/••",
|
|
||||||
cvv = "•••",
|
|
||||||
onCopy = { _, _ -> },
|
|
||||||
onClick = {},
|
|
||||||
buttonText = TextReference.Res(R.string.tangempay_card_details_hide_text),
|
|
||||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
|
||||||
displayNameState = null,
|
|
||||||
cardImageUrl = null,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -21,7 +21,6 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.graphics.Brush
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
|
|
@ -57,7 +56,6 @@ import com.tangem.core.ui.components.buttons.common.TangemButtonSize
|
||||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||||
import com.tangem.core.ui.ds2.button.TangemButton
|
import com.tangem.core.ui.ds2.button.TangemButton
|
||||||
import com.tangem.core.ui.extensions.conditional
|
import com.tangem.core.ui.extensions.conditional
|
||||||
import com.tangem.core.ui.extensions.conditionalCompose
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||||
import com.tangem.core.ui.res.*
|
import com.tangem.core.ui.res.*
|
||||||
|
|
@ -118,7 +116,6 @@ internal fun TangemPayCard(state: TangemPayCardDetailsUM, modifier: Modifier = M
|
||||||
@Suppress("LongMethod", "DestructuringDeclarationWithTooManyEntries")
|
@Suppress("LongMethod", "DestructuringDeclarationWithTooManyEntries")
|
||||||
@Composable
|
@Composable
|
||||||
private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modifier: Modifier = Modifier) {
|
private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modifier: Modifier = Modifier) {
|
||||||
val isRedesignEnabled = LocalVisaRedesignEnabled.current
|
|
||||||
Box(modifier = modifier.fillMaxSize()) {
|
Box(modifier = modifier.fillMaxSize()) {
|
||||||
TangemPayCardBackground(
|
TangemPayCardBackground(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -163,24 +160,7 @@ private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modif
|
||||||
)
|
)
|
||||||
|
|
||||||
when (state.cardFrozenState) {
|
when (state.cardFrozenState) {
|
||||||
TangemPayCardFrozenState.Frozen -> {
|
TangemPayCardFrozenState.Frozen -> Unit
|
||||||
if (!isRedesignEnabled) {
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier
|
|
||||||
.constrainAs(frozenIconRef) {
|
|
||||||
start.linkTo(cardNumberRef.end, margin = 4.dp)
|
|
||||||
top.linkTo(cardNumberRef.top)
|
|
||||||
bottom.linkTo(cardNumberRef.bottom)
|
|
||||||
}
|
|
||||||
.padding(bottom = 8.dp)
|
|
||||||
.size(16.dp)
|
|
||||||
.testTag(TangemPayTestTags.CARD_FROZEN_BADGE),
|
|
||||||
painter = painterResource(id = R.drawable.ic_snow_24),
|
|
||||||
contentDescription = null,
|
|
||||||
tint = TangemTheme.colors.icon.constant,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TangemPayCardFrozenState.Pending -> CircularProgressIndicator(
|
TangemPayCardFrozenState.Pending -> CircularProgressIndicator(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.constrainAs(frozenIconRef) {
|
.constrainAs(frozenIconRef) {
|
||||||
|
|
@ -203,9 +183,7 @@ private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modif
|
||||||
bottom.linkTo(parent.bottom)
|
bottom.linkTo(parent.bottom)
|
||||||
}
|
}
|
||||||
.testTag(TangemPayTestTags.CARD_DETAILS_SHOW_BUTTON),
|
.testTag(TangemPayTestTags.CARD_DETAILS_SHOW_BUTTON),
|
||||||
visible = !isRedesignEnabled ||
|
visible = state.isLoading || state.shouldShowCardDetailsButtonOnCard,
|
||||||
state.isLoading ||
|
|
||||||
state.shouldShowCardDetailsButtonOnCard,
|
|
||||||
) {
|
) {
|
||||||
TangemPayCardDetailsCustomButton(
|
TangemPayCardDetailsCustomButton(
|
||||||
text = stringResourceSafe(id = R.string.tangempay_card_details_show_details),
|
text = stringResourceSafe(id = R.string.tangempay_card_details_show_details),
|
||||||
|
|
@ -286,8 +264,7 @@ private fun CardBgWrapper(
|
||||||
back: @Composable () -> Unit,
|
back: @Composable () -> Unit,
|
||||||
front: @Composable () -> Unit,
|
front: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
val isRedesignEnabled = LocalVisaRedesignEnabled.current
|
val shouldShowDetailsBg = shouldShowDetails
|
||||||
val shouldShowDetailsBg = shouldShowDetails && isRedesignEnabled
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
@ -295,32 +272,13 @@ private fun CardBgWrapper(
|
||||||
rotationY = rotateCardY
|
rotationY = rotateCardY
|
||||||
cameraDistance = zAxisDistance
|
cameraDistance = zAxisDistance
|
||||||
}
|
}
|
||||||
.conditionalCompose(
|
.clip(RoundedCornerShape(TangemTheme.dimens2.x5))
|
||||||
condition = isRedesignEnabled,
|
.border(
|
||||||
modifier = {
|
width = 1.dp,
|
||||||
clip(RoundedCornerShape(TangemTheme.dimens2.x5))
|
shape = RoundedCornerShape(TangemTheme.dimens2.x5),
|
||||||
.border(
|
color = TangemTheme.colors3.border.secondary,
|
||||||
width = 1.dp,
|
)
|
||||||
shape = RoundedCornerShape(TangemTheme.dimens2.x5),
|
.background(CardBackgroundColor),
|
||||||
color = TangemTheme.colors3.border.secondary,
|
|
||||||
)
|
|
||||||
.background(CardBackgroundColor)
|
|
||||||
},
|
|
||||||
otherModifier = {
|
|
||||||
clip(RoundedCornerShape(16.dp))
|
|
||||||
.background(CardBackgroundColor)
|
|
||||||
.border(
|
|
||||||
width = 1.dp,
|
|
||||||
brush = Brush.linearGradient(
|
|
||||||
colors = listOf(
|
|
||||||
TangemTheme.colors.text.constantWhite.copy(alpha = 0.1F),
|
|
||||||
TangemTheme.colors.text.constantWhite.copy(alpha = 0f),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
shape = RoundedCornerShape(16.dp),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
) {
|
) {
|
||||||
EqualHeightCardSides(
|
EqualHeightCardSides(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
|
@ -400,30 +358,17 @@ private fun CardTopBlock(modifier: Modifier = Modifier) {
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
) {
|
) {
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
Text(
|
||||||
Text(
|
text = stringResourceSafe(R.string.tangempay_digital_card),
|
||||||
text = stringResourceSafe(R.string.tangempay_digital_card),
|
style = TangemTheme.typography3.body.medium,
|
||||||
style = TangemTheme.typography3.body.medium,
|
color = TangemTheme.colors3.text.staticDark.primary,
|
||||||
color = TangemTheme.colors3.text.staticDark.primary,
|
)
|
||||||
)
|
Icon(
|
||||||
Icon(
|
modifier = Modifier.size(TangemTheme.dimens2.x5),
|
||||||
modifier = Modifier.size(TangemTheme.dimens2.x5),
|
imageVector = ImageVector.vectorResource(R.drawable.ic_cloud_fill_16),
|
||||||
imageVector = ImageVector.vectorResource(R.drawable.ic_cloud_fill_16),
|
tint = TangemTheme.colors3.icon.staticDark,
|
||||||
tint = TangemTheme.colors3.icon.staticDark,
|
contentDescription = null,
|
||||||
contentDescription = null,
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(R.drawable.ic_cloud_fill_16),
|
|
||||||
tint = TangemTheme.colors.icon.constant,
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_digital_card),
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.constantWhite,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -434,36 +379,22 @@ private fun ConstraintLayoutScope.CardNumberBlock(
|
||||||
cardNumberRef: ConstrainedLayoutReference,
|
cardNumberRef: ConstrainedLayoutReference,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
Text(
|
||||||
Text(
|
text = numberShort,
|
||||||
text = numberShort,
|
style = TangemTheme.typography3.body.medium,
|
||||||
style = TangemTheme.typography3.body.medium,
|
color = if (isRenaming) {
|
||||||
color = if (isRenaming) {
|
TangemTheme.colors3.text.staticDark.secondary
|
||||||
TangemTheme.colors3.text.staticDark.secondary
|
} else {
|
||||||
} else {
|
TangemTheme.colors3.text.staticDark.primary
|
||||||
TangemTheme.colors3.text.staticDark.primary
|
},
|
||||||
},
|
modifier = modifier
|
||||||
modifier = modifier
|
.constrainAs(cardNumberRef) {
|
||||||
.constrainAs(cardNumberRef) {
|
start.linkTo(parent.start)
|
||||||
start.linkTo(parent.start)
|
bottom.linkTo(parent.bottom)
|
||||||
bottom.linkTo(parent.bottom)
|
}
|
||||||
}
|
.padding(bottom = 8.dp)
|
||||||
.padding(bottom = 8.dp)
|
.testTag(TangemPayTestTags.CARD_NUMBER_SHORT),
|
||||||
.testTag(TangemPayTestTags.CARD_NUMBER_SHORT),
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Text(
|
|
||||||
text = numberShort,
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.constantWhite,
|
|
||||||
modifier = modifier
|
|
||||||
.constrainAs(cardNumberRef) {
|
|
||||||
start.linkTo(parent.start)
|
|
||||||
bottom.linkTo(parent.bottom)
|
|
||||||
}
|
|
||||||
.padding(bottom = 8.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -476,67 +407,37 @@ private fun CardDisplayName(state: DisplayNameState, modifier: Modifier = Modifi
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DisplayOnlyCardDisplayName(state: DisplayNameState.Display, modifier: Modifier = Modifier) {
|
private fun DisplayOnlyCardDisplayName(state: DisplayNameState.Display, modifier: Modifier = Modifier) {
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
Row(
|
||||||
Row(
|
modifier = modifier.conditional(
|
||||||
modifier = modifier.conditional(
|
condition = state.isEditingEnabled,
|
||||||
condition = state.isEditingEnabled,
|
modifier = { clickable(onClick = state.onClick) },
|
||||||
modifier = { clickable(onClick = state.onClick) },
|
),
|
||||||
),
|
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
|
||||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
) {
|
||||||
) {
|
Text(
|
||||||
Text(
|
text = state.displayName,
|
||||||
text = state.displayName,
|
style = TangemTheme.typography3.body.medium,
|
||||||
style = TangemTheme.typography3.body.medium,
|
color = TangemTheme.colors3.text.staticDark.secondary,
|
||||||
color = TangemTheme.colors3.text.staticDark.secondary,
|
maxLines = 1,
|
||||||
maxLines = 1,
|
)
|
||||||
|
if (state.isEditingEnabled) {
|
||||||
|
Icon(
|
||||||
|
imageVector = ImageVector.vectorResource(id = R.drawable.ic_edit_card_20),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(TangemTheme.dimens2.x5),
|
||||||
|
tint = TangemTheme.colors3.icon.staticDark,
|
||||||
)
|
)
|
||||||
if (state.isEditingEnabled) {
|
|
||||||
Icon(
|
|
||||||
imageVector = ImageVector.vectorResource(id = R.drawable.ic_edit_card_20),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier.size(TangemTheme.dimens2.x5),
|
|
||||||
tint = TangemTheme.colors3.icon.staticDark,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Row(
|
|
||||||
modifier = modifier.conditional(
|
|
||||||
condition = state.isEditingEnabled,
|
|
||||||
modifier = { clickable(onClick = state.onClick) },
|
|
||||||
),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = state.displayName,
|
|
||||||
style = TangemTheme.typography.caption1.copy(color = TangemTheme.colors.text.constantWhite),
|
|
||||||
maxLines = 1,
|
|
||||||
)
|
|
||||||
if (state.isEditingEnabled) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_edit_new_12),
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier.size(10.dp),
|
|
||||||
tint = TangemTheme.colors.text.constantWhite,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Modifier = Modifier) {
|
private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Modifier = Modifier) {
|
||||||
val isRedesignEnabled = LocalVisaRedesignEnabled.current
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
val placeholder = stringResourceSafe(R.string.tangempay_card_edit_name_placeholder)
|
val placeholder = stringResourceSafe(R.string.tangempay_card_edit_name_placeholder)
|
||||||
|
|
||||||
val textStyle = if (isRedesignEnabled) {
|
val textStyle = TangemTheme.typography3.body.medium.copy(color = TangemTheme.colors3.text.staticDark.primary)
|
||||||
TangemTheme.typography3.body.medium.copy(color = TangemTheme.colors3.text.staticDark.primary)
|
|
||||||
} else {
|
|
||||||
TangemTheme.typography.caption1.copy(color = TangemTheme.colors.text.constantWhite)
|
|
||||||
}
|
|
||||||
val textMeasurer = rememberTextMeasurer()
|
val textMeasurer = rememberTextMeasurer()
|
||||||
val measuredText = state.editingValue.text.ifEmpty { placeholder }
|
val measuredText = state.editingValue.text.ifEmpty { placeholder }
|
||||||
val textWidthDp = with(LocalDensity.current) {
|
val textWidthDp = with(LocalDensity.current) {
|
||||||
|
|
@ -551,11 +452,7 @@ private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Mo
|
||||||
.focusRequester(focusRequester),
|
.focusRequester(focusRequester),
|
||||||
textStyle = textStyle,
|
textStyle = textStyle,
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
cursorBrush = if (isRedesignEnabled) {
|
cursorBrush = SolidColor(TangemTheme.colors3.text.staticDark.primary),
|
||||||
SolidColor(TangemTheme.colors3.text.staticDark.primary)
|
|
||||||
} else {
|
|
||||||
SolidColor(TangemTheme.colors.text.constantWhite)
|
|
||||||
},
|
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||||
keyboardActions = KeyboardActions(
|
keyboardActions = KeyboardActions(
|
||||||
onDone = if (state.isSubmitEnabled) {
|
onDone = if (state.isSubmitEnabled) {
|
||||||
|
|
@ -569,13 +466,7 @@ private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Mo
|
||||||
if (state.editingValue.text.isEmpty()) {
|
if (state.editingValue.text.isEmpty()) {
|
||||||
Text(
|
Text(
|
||||||
text = placeholder,
|
text = placeholder,
|
||||||
style = textStyle.copy(
|
style = textStyle.copy(color = TangemTheme.colors3.text.staticDark.secondary),
|
||||||
color = if (isRedesignEnabled) {
|
|
||||||
TangemTheme.colors3.text.staticDark.secondary
|
|
||||||
} else {
|
|
||||||
TangemTheme.colors.text.tertiary
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
innerTextField()
|
innerTextField()
|
||||||
|
|
@ -640,30 +531,19 @@ private fun TangemPayCardDetailsShownBlock(
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Row {
|
Row {
|
||||||
SpacerWMax()
|
SpacerWMax()
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
// Must use dark theme locally for button cause card is dark
|
||||||
// Must use dark theme locally for button cause card is dark
|
CompositionLocalProvider(LocalIsInDarkTheme provides true) {
|
||||||
CompositionLocalProvider(LocalIsInDarkTheme provides true) {
|
TangemThemeRedesign {
|
||||||
TangemThemeRedesign {
|
TangemButton(
|
||||||
TangemButton(
|
modifier = Modifier
|
||||||
modifier = Modifier
|
.padding(end = 16.dp, bottom = 8.dp)
|
||||||
.padding(end = 16.dp, bottom = 8.dp)
|
.testTag(TangemPayTestTags.CARD_DETAILS_HIDE_BUTTON),
|
||||||
.testTag(TangemPayTestTags.CARD_DETAILS_HIDE_BUTTON),
|
variant = TangemButton.Variant.Material,
|
||||||
variant = TangemButton.Variant.Material,
|
size = TangemButton.Size.X8,
|
||||||
size = TangemButton.Size.X8,
|
onClick = onHideDetails,
|
||||||
onClick = onHideDetails,
|
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_20),
|
||||||
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_20),
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
TangemPayCardDetailsCustomButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(end = 16.dp, bottom = 8.dp)
|
|
||||||
.testTag(TangemPayTestTags.CARD_DETAILS_HIDE_BUTTON),
|
|
||||||
text = stringResourceSafe(id = R.string.tangempay_card_details_hide_details),
|
|
||||||
onClick = onHideDetails,
|
|
||||||
showProgress = false,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ import androidx.compose.animation.core.MutableTransitionState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyItemScope
|
import androidx.compose.foundation.lazy.LazyItemScope
|
||||||
|
|
@ -16,7 +14,6 @@ import androidx.compose.foundation.pager.HorizontalPager
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.ScaffoldDefaults
|
import androidx.compose.material3.ScaffoldDefaults
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -25,9 +22,7 @@ import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastForEach
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
|
||||||
import com.tangem.core.ui.ds.TangemPagerIndicator
|
import com.tangem.core.ui.ds.TangemPagerIndicator
|
||||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||||
import com.tangem.core.ui.ds.topbar.TangemTopBar
|
import com.tangem.core.ui.ds.topbar.TangemTopBar
|
||||||
|
|
@ -74,7 +69,6 @@ private fun TangemPayCardPageScreen(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
cardSection: @Composable () -> Unit,
|
cardSection: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
val isRedesignEnabled = LocalVisaRedesignEnabled.current
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -84,15 +78,11 @@ private fun TangemPayCardPageScreen(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
|
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
|
||||||
containerColor = if (isRedesignEnabled) {
|
containerColor = TangemTheme.colors3.bg.primary,
|
||||||
TangemTheme.colors3.bg.primary
|
|
||||||
} else {
|
|
||||||
TangemTheme.colors.background.secondary
|
|
||||||
},
|
|
||||||
) { scaffoldPaddings ->
|
) { scaffoldPaddings ->
|
||||||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||||
val contentBottomPadding = TangemTheme.dimens.spacing16 + bottomBarHeight
|
val contentBottomPadding = TangemTheme.dimens.spacing16 + bottomBarHeight
|
||||||
val reissueTitle = reissueTitleOrNull(isRedesignEnabled = isRedesignEnabled, cardState = state.cardState)
|
val reissueTitle = reissueTitleOrNull(cardState = state.cardState)
|
||||||
|
|
||||||
if (reissueTitle != null) {
|
if (reissueTitle != null) {
|
||||||
ReissueCardLayout(
|
ReissueCardLayout(
|
||||||
|
|
@ -109,9 +99,7 @@ private fun TangemPayCardPageScreen(
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(scaffoldPaddings),
|
.padding(scaffoldPaddings),
|
||||||
contentPadding = PaddingValues(bottom = contentBottomPadding),
|
contentPadding = PaddingValues(bottom = contentBottomPadding),
|
||||||
verticalArrangement = Arrangement.spacedBy(
|
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||||
if (isRedesignEnabled) 0.dp else TangemTheme.dimens.spacing16,
|
|
||||||
),
|
|
||||||
) {
|
) {
|
||||||
item(key = "Card") {
|
item(key = "Card") {
|
||||||
Box(modifier = Modifier.padding(top = TangemTheme.dimens.spacing8)) {
|
Box(modifier = Modifier.padding(top = TangemTheme.dimens.spacing8)) {
|
||||||
|
|
@ -119,7 +107,6 @@ private fun TangemPayCardPageScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
isRedesignEnabled &&
|
|
||||||
state.settingsV2.isNotEmpty() &&
|
state.settingsV2.isNotEmpty() &&
|
||||||
state.cardState == TangemPayCardState.Active
|
state.cardState == TangemPayCardState.Active
|
||||||
) {
|
) {
|
||||||
|
|
@ -136,8 +123,7 @@ private fun TangemPayCardPageScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reissueTitleOrNull(isRedesignEnabled: Boolean, cardState: TangemPayCardState): TextReference? {
|
private fun reissueTitleOrNull(cardState: TangemPayCardState): TextReference? {
|
||||||
if (!isRedesignEnabled) return null
|
|
||||||
return when (cardState) {
|
return when (cardState) {
|
||||||
TangemPayCardState.Reissuing -> combinedReference(
|
TangemPayCardState.Reissuing -> combinedReference(
|
||||||
resourceReference(R.string.tangempay_reissue_card_in_progress),
|
resourceReference(R.string.tangempay_reissue_card_in_progress),
|
||||||
|
|
@ -243,95 +229,14 @@ private fun CardDetailsPage(controller: TangemPayCardDetailsController, modifier
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LazyListScope.cardState(state: TangemPayCardPageUM) {
|
private fun LazyListScope.cardState(state: TangemPayCardPageUM) {
|
||||||
when (state.cardState) {
|
if (state.cardState != TangemPayCardState.Active) return
|
||||||
TangemPayCardState.Active -> {
|
if (state.addToWalletBlockState != null) {
|
||||||
if (state.addToWalletBlockState != null) {
|
cardPageItem(key = "GooglePay") {
|
||||||
cardPageItem(key = "GooglePay") {
|
TangemPayAddToWalletBlock(state = state.addToWalletBlockState)
|
||||||
TangemPayAddToWalletBlock(state = state.addToWalletBlockState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cardPageItem(key = "Limit") {
|
|
||||||
TangemPayDailyLimitBlock(state = state.dailyLimitState)
|
|
||||||
}
|
|
||||||
if (state.dailyLimitState is TangemPayDailyLimitBlockState.Error) {
|
|
||||||
cardPageItem(key = "LimitError") {
|
|
||||||
TangemPayDailyLimitErrorBlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cardPageItem(key = "Settings") {
|
|
||||||
TangemPayCardPageSettingsBlock(settings = state.settings)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TangemPayCardState.Reissuing -> cardPageItem(key = "Reissue") {
|
|
||||||
TangemPayReplacingCardBlock()
|
|
||||||
}
|
|
||||||
TangemPayCardState.Closing -> cardPageItem(key = "Closing") {
|
|
||||||
TangemPayReplacingCardBlock(
|
|
||||||
title = resourceReference(R.string.tangempay_card_page_closing_banner_title),
|
|
||||||
subtitle = resourceReference(R.string.tangempay_card_page_closing_banner_description),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
TangemPayCardState.Issuing -> cardPageItem(key = "Issuing") {
|
|
||||||
TangemPayReplacingCardBlock(
|
|
||||||
title = resourceReference(R.string.tangempay_issuing_new_digital_card_title),
|
|
||||||
subtitle = resourceReference(R.string.tangempay_reissue_card_in_progress_description),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
cardPageItem(key = "Limit") {
|
||||||
|
TangemPayDailyLimitBlock(state = state.dailyLimitState)
|
||||||
@Composable
|
|
||||||
private fun TangemPayCardPageSettingsBlock(
|
|
||||||
settings: ImmutableList<TangemPayCardPageSetting>,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
if (LocalVisaRedesignEnabled.current) return
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(
|
|
||||||
color = TangemTheme.colors.background.primary,
|
|
||||||
shape = TangemTheme.shapes.roundedCornersMedium,
|
|
||||||
),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(
|
|
||||||
start = TangemTheme.dimens.spacing12,
|
|
||||||
top = TangemTheme.dimens.spacing12,
|
|
||||||
bottom = TangemTheme.dimens.spacing4,
|
|
||||||
),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_page_settings_title),
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
settings.fastForEach { item ->
|
|
||||||
TangemPayCardPageSettingRow(
|
|
||||||
item = item,
|
|
||||||
onClick = item.onSettingClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayCardPageSettingRow(
|
|
||||||
item: TangemPayCardPageSetting,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clickable(onClick = onClick)
|
|
||||||
.padding(TangemTheme.dimens.spacing12)
|
|
||||||
.then(if (item.testTag != null) Modifier.testTag(item.testTag) else Modifier),
|
|
||||||
contentAlignment = Alignment.CenterStart,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = item.title.resolveReference(),
|
|
||||||
style = TangemTheme.typography.subtitle1,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,41 +246,34 @@ private fun CardPageTopBar(
|
||||||
items: ImmutableList<TangemPayDropDownItemUM>,
|
items: ImmutableList<TangemPayDropDownItemUM>,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
var isDropdownMenuShown by rememberSaveable { mutableStateOf(false) }
|
||||||
var isDropdownMenuShown by rememberSaveable { mutableStateOf(false) }
|
TangemTopBar(
|
||||||
TangemTopBar(
|
modifier = modifier.statusBarsPadding(),
|
||||||
modifier = modifier.statusBarsPadding(),
|
startContent = {
|
||||||
startContent = {
|
TangemButton(
|
||||||
|
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_arrow_back_28),
|
||||||
|
onClick = onBackClick,
|
||||||
|
size = TangemButton.Size.X11,
|
||||||
|
variant = TangemButton.Variant.Material,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
endContent = {
|
||||||
|
Box {
|
||||||
TangemButton(
|
TangemButton(
|
||||||
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_arrow_back_28),
|
modifier = Modifier.testTag(TangemPayTestTags.CARD_PAGE_MORE_BUTTON),
|
||||||
onClick = onBackClick,
|
iconStart = TangemIconUM.Icon(iconRes = CoreUiR.drawable.ic_more_default_24),
|
||||||
|
onClick = { isDropdownMenuShown = true },
|
||||||
size = TangemButton.Size.X11,
|
size = TangemButton.Size.X11,
|
||||||
variant = TangemButton.Variant.Material,
|
variant = TangemButton.Variant.Material,
|
||||||
)
|
)
|
||||||
},
|
PayContextMenuBlock(
|
||||||
endContent = {
|
items = items,
|
||||||
Box {
|
onMenuDismiss = { isDropdownMenuShown = false },
|
||||||
TangemButton(
|
isDropdownMenuShown = isDropdownMenuShown,
|
||||||
modifier = Modifier.testTag(TangemPayTestTags.CARD_PAGE_MORE_BUTTON),
|
)
|
||||||
iconStart = TangemIconUM.Icon(iconRes = CoreUiR.drawable.ic_more_default_24),
|
}
|
||||||
onClick = { isDropdownMenuShown = true },
|
},
|
||||||
size = TangemButton.Size.X11,
|
)
|
||||||
variant = TangemButton.Variant.Material,
|
|
||||||
)
|
|
||||||
PayContextMenuBlock(
|
|
||||||
items = items,
|
|
||||||
onMenuDismiss = { isDropdownMenuShown = false },
|
|
||||||
isDropdownMenuShown = isDropdownMenuShown,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
AppBarWithBackButton(
|
|
||||||
modifier = modifier.statusBarsPadding(),
|
|
||||||
onBackClick = onBackClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LazyListScope.cardPageItem(
|
private fun LazyListScope.cardPageItem(
|
||||||
|
|
@ -400,23 +298,6 @@ private fun LazyListScope.cardPageItem(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayCardPageScreenPreviewV1() {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayCardPageScreen(
|
|
||||||
state = TangemPayCardPageUM.stub(),
|
|
||||||
cardSection = {
|
|
||||||
TangemPayCard(
|
|
||||||
state = previewCardDetailsState(),
|
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun previewCardDetailsState(): TangemPayCardDetailsUM = TangemPayCardDetailsUM(
|
private fun previewCardDetailsState(): TangemPayCardDetailsUM = TangemPayCardDetailsUM(
|
||||||
number = "•••• •••• •••• 1245",
|
number = "•••• •••• •••• 1245",
|
||||||
numberShort = "··1245",
|
numberShort = "··1245",
|
||||||
|
|
@ -440,7 +321,6 @@ private fun TangemPayCardPageScreenPreviewV2() {
|
||||||
TangemThemePreviewRedesign {
|
TangemThemePreviewRedesign {
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalRedesignEnabled provides true,
|
LocalRedesignEnabled provides true,
|
||||||
LocalVisaRedesignEnabled provides true,
|
|
||||||
) {
|
) {
|
||||||
TangemPayCardPageScreen(
|
TangemPayCardPageScreen(
|
||||||
state = TangemPayCardPageUM.stub(),
|
state = TangemPayCardPageUM.stub(),
|
||||||
|
|
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import androidx.compose.ui.platform.testTag
|
|
||||||
import androidx.compose.ui.res.vectorResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.airbnb.lottie.compose.LottieAnimation
|
|
||||||
import com.airbnb.lottie.compose.LottieCompositionSpec
|
|
||||||
import com.airbnb.lottie.compose.animateLottieCompositionAsState
|
|
||||||
import com.airbnb.lottie.compose.rememberLottieComposition
|
|
||||||
import com.tangem.core.ui.components.*
|
|
||||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
|
||||||
import com.tangem.core.ui.extensions.resolveReference
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.core.ui.test.TangemPayTestTags
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayChangePinCodeSuccessScreen(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
|
||||||
val composition by rememberLottieComposition(spec = LottieCompositionSpec.RawRes(R.raw.anim_confetti))
|
|
||||||
val progress by animateLottieCompositionAsState(composition)
|
|
||||||
var showConfetti by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.navigationBarsPadding(),
|
|
||||||
) {
|
|
||||||
TangemTopAppBar(
|
|
||||||
modifier = Modifier.statusBarsPadding(),
|
|
||||||
title = resourceReference(R.string.common_done).resolveReference(),
|
|
||||||
startButton = null,
|
|
||||||
titleAlignment = Alignment.CenterHorizontally,
|
|
||||||
)
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize(),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
SuccessContent(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.weight(1f),
|
|
||||||
)
|
|
||||||
|
|
||||||
PrimaryButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.padding(bottom = 16.dp)
|
|
||||||
.navigationBarsPadding()
|
|
||||||
.testTag(TangemPayTestTags.PIN_DONE_BUTTON),
|
|
||||||
text = stringResourceSafe(R.string.common_done),
|
|
||||||
onClick = onClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showConfetti) {
|
|
||||||
FullScreen(notTouchable = true) {
|
|
||||||
LottieAnimation(
|
|
||||||
composition = composition,
|
|
||||||
progress = { progress },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
showConfetti = true
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(progress == 1f) {
|
|
||||||
if (progress == 1f) {
|
|
||||||
showConfetti = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun SuccessContent(modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier,
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = ImageVector.vectorResource(R.drawable.ic_success_blue_76),
|
|
||||||
tint = Color.Unspecified,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(76.dp),
|
|
||||||
)
|
|
||||||
SpacerH32()
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 32.dp)
|
|
||||||
.testTag(TangemPayTestTags.PIN_SUCCESS_TITLE),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_change_pin_success_title),
|
|
||||||
style = TangemTheme.typography.h2,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
)
|
|
||||||
SpacerH12()
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 32.dp)
|
|
||||||
.testTag(TangemPayTestTags.PIN_SUCCESS_DESCRIPTION),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_change_pin_success_description),
|
|
||||||
style = TangemTheme.typography.body1,
|
|
||||||
color = TangemTheme.colors.text.secondary,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
SpacerH(72.dp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Composable
|
|
||||||
private fun Preview() {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayChangePinCodeSuccessScreen(onClick = {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,192 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
|
||||||
import androidx.compose.ui.focus.focusRequester
|
|
||||||
import androidx.compose.ui.graphics.Color.Companion.Transparent
|
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
|
||||||
import androidx.compose.ui.platform.testTag
|
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.tangem.common.ui.navigationButtons.NavigationButton
|
|
||||||
import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton
|
|
||||||
import com.tangem.core.ui.components.SpacerH
|
|
||||||
import com.tangem.core.ui.components.SpacerH16
|
|
||||||
import com.tangem.core.ui.components.SpacerH4
|
|
||||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
|
||||||
import com.tangem.core.ui.extensions.resolveReference
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.test.TangemPayTestTags
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayChangePinUM
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayChangePinScreen(
|
|
||||||
state: TangemPayChangePinUM,
|
|
||||||
onBackClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.navigationBarsPadding(),
|
|
||||||
) {
|
|
||||||
AppBarWithBackButton(
|
|
||||||
modifier = Modifier.statusBarsPadding(),
|
|
||||||
onBackClick = onBackClick,
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(top = 48.dp)
|
|
||||||
.padding(horizontal = 36.dp)
|
|
||||||
.weight(1f),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.visa_onboarding_pin_code_title),
|
|
||||||
style = TangemTheme.typography.h2,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
modifier = Modifier.testTag(TangemPayTestTags.PIN_SCREEN_TITLE),
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH16()
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.visa_onboarding_pin_code_description),
|
|
||||||
style = TangemTheme.typography.body1,
|
|
||||||
color = TangemTheme.colors.text.secondary,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
modifier = Modifier.testTag(TangemPayTestTags.PIN_SCREEN_DESCRIPTION),
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH(26.dp)
|
|
||||||
|
|
||||||
PinCodeSection(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
NavigationPrimaryButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.imePadding()
|
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.testTag(TangemPayTestTags.PIN_SUBMIT_BUTTON),
|
|
||||||
primaryButton = NavigationButton(
|
|
||||||
textReference = resourceReference(R.string.common_submit),
|
|
||||||
onClick = state.onSubmitClick,
|
|
||||||
shouldShowProgress = state.submitButtonLoading,
|
|
||||||
isEnabled = state.submitButtonEnabled,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PinCodeSection(state: TangemPayChangePinUM, modifier: Modifier = Modifier) {
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
|
||||||
PinCode(
|
|
||||||
modifier = modifier,
|
|
||||||
value = state.pinCode,
|
|
||||||
onValueChange = state.onPinCodeChange,
|
|
||||||
focusRequester = focusRequester,
|
|
||||||
)
|
|
||||||
|
|
||||||
AnimatedVisibility(
|
|
||||||
visible = state.error != null,
|
|
||||||
) {
|
|
||||||
val error = remember(this) { requireNotNull(state.error) }
|
|
||||||
Column {
|
|
||||||
SpacerH4()
|
|
||||||
Text(
|
|
||||||
text = error.resolveReference(),
|
|
||||||
style = TangemTheme.typography.caption2,
|
|
||||||
color = TangemTheme.colors.text.warning,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
modifier = Modifier.testTag(TangemPayTestTags.PIN_ERROR_MESSAGE),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
delay(timeMillis = 300)
|
|
||||||
focusRequester.requestFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PinCode(
|
|
||||||
value: String,
|
|
||||||
onValueChange: (String) -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
numbersCount: Int = 4,
|
|
||||||
focusRequester: FocusRequester = remember { FocusRequester() },
|
|
||||||
) {
|
|
||||||
val keyboardController = LocalSoftwareKeyboardController.current
|
|
||||||
|
|
||||||
BasicTextField(
|
|
||||||
value = value,
|
|
||||||
onValueChange = { text ->
|
|
||||||
if (text.length <= numbersCount) {
|
|
||||||
onValueChange(text)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modifier = modifier
|
|
||||||
.focusRequester(focusRequester)
|
|
||||||
.clickable {
|
|
||||||
focusRequester.requestFocus()
|
|
||||||
keyboardController?.show()
|
|
||||||
}
|
|
||||||
.testTag(TangemPayTestTags.PIN_INPUT_FIELD),
|
|
||||||
textStyle = TangemTheme.typography.h1.copy(color = Transparent),
|
|
||||||
keyboardOptions = KeyboardOptions(
|
|
||||||
keyboardType = KeyboardType.NumberPassword,
|
|
||||||
imeAction = ImeAction.Done,
|
|
||||||
),
|
|
||||||
keyboardActions = KeyboardActions(onDone = { keyboardController?.hide() }),
|
|
||||||
cursorBrush = SolidColor(Transparent),
|
|
||||||
decorationBox = { innerTextField ->
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
repeat(numbersCount) { index ->
|
|
||||||
val digit = value.getOrNull(index)?.toString()
|
|
||||||
PinDigitBox(
|
|
||||||
digit = digit,
|
|
||||||
backgroundColor = TangemTheme.colors.field.focused,
|
|
||||||
borderColor = TangemTheme.colors.stroke.primary,
|
|
||||||
textColor = TangemTheme.colors.text.primary1,
|
|
||||||
textStyle = TangemTheme.typography.h1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
innerTextField()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
|
@ -16,15 +15,10 @@ import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.layout.layoutId
|
import androidx.compose.ui.layout.layoutId
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.tangem.core.ui.components.*
|
import com.tangem.core.ui.components.*
|
||||||
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
|
|
||||||
import com.tangem.core.ui.components.notifications.Notification
|
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
|
||||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||||
import com.tangem.core.ui.ds.row.TangemRowContainer
|
import com.tangem.core.ui.ds.row.TangemRowContainer
|
||||||
import com.tangem.core.ui.ds.row.TangemRowLayoutId
|
import com.tangem.core.ui.ds.row.TangemRowLayoutId
|
||||||
|
|
@ -41,92 +35,7 @@ import com.tangem.features.tangempay.entity.TangemPayDailyLimitBlockState
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun TangemPayDailyLimitBlock(state: TangemPayDailyLimitBlockState, modifier: Modifier = Modifier) {
|
internal fun TangemPayDailyLimitBlock(state: TangemPayDailyLimitBlockState, modifier: Modifier = Modifier) {
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
CurrentLimitBlockV2(state, modifier.padding(top = TangemTheme.dimens2.x2))
|
||||||
CurrentLimitBlockV2(state, modifier.padding(top = TangemTheme.dimens2.x2))
|
|
||||||
} else {
|
|
||||||
TangemPayDailyLimitBlockV1(state, modifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayDailyLimitBlockV1(state: TangemPayDailyLimitBlockState, modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(
|
|
||||||
color = TangemTheme.colors.background.primary,
|
|
||||||
shape = TangemTheme.shapes.roundedCornersMedium,
|
|
||||||
)
|
|
||||||
.padding(TangemTheme.dimens.spacing12),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_title),
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
SpacerH4()
|
|
||||||
CurrentLimitBlockV1(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun CurrentLimitBlockV1(state: TangemPayDailyLimitBlockState) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.size(36.dp)
|
|
||||||
.background(
|
|
||||||
color = TangemTheme.colors.icon.accent.copy(alpha = 0.1f),
|
|
||||||
shape = CircleShape,
|
|
||||||
),
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(R.drawable.ic_limit_20),
|
|
||||||
contentDescription = null,
|
|
||||||
tint = TangemTheme.colors.icon.accent,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
SpacerW12()
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_current_limit),
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
when (state) {
|
|
||||||
is TangemPayDailyLimitBlockState.Error,
|
|
||||||
is TangemPayDailyLimitBlockState.Content,
|
|
||||||
-> Text(
|
|
||||||
text = if (state is TangemPayDailyLimitBlockState.Content) state.limit else "—",
|
|
||||||
style = TangemTheme.typography.subtitle1,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
)
|
|
||||||
TangemPayDailyLimitBlockState.Loading -> TextShimmer(
|
|
||||||
style = TangemTheme.typography.subtitle1,
|
|
||||||
text = "$50,000",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SpacerW8()
|
|
||||||
if (state is TangemPayDailyLimitBlockState.Content) {
|
|
||||||
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides 0.dp) {
|
|
||||||
SecondaryButton(
|
|
||||||
modifier = Modifier,
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_page_daily_limit_change),
|
|
||||||
onClick = state.onChangeClick,
|
|
||||||
size = TangemButtonSize.Small,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -279,36 +188,6 @@ private fun SubtitleLimit(state: TangemPayDailyLimitBlockState, modifier: Modifi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayDailyLimitErrorBlock(modifier: Modifier = Modifier) {
|
|
||||||
if (LocalVisaRedesignEnabled.current) return
|
|
||||||
Notification(
|
|
||||||
config = NotificationConfig(
|
|
||||||
title = resourceReference(R.string.tangempay_card_page_daily_limit_error_title),
|
|
||||||
subtitle = resourceReference(R.string.tangempay_card_page_daily_limit_error_description),
|
|
||||||
iconResId = R.drawable.img_attention_20,
|
|
||||||
),
|
|
||||||
containerColor = TangemTheme.colors.background.action,
|
|
||||||
modifier = modifier.fillMaxWidth(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun Preview() {
|
|
||||||
TangemThemePreview {
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
|
||||||
) {
|
|
||||||
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Content.stub())
|
|
||||||
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Error(onReloadClick = {}))
|
|
||||||
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Loading)
|
|
||||||
TangemPayDailyLimitErrorBlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -316,7 +195,6 @@ private fun PreviewV2() {
|
||||||
TangemThemePreviewRedesign {
|
TangemThemePreviewRedesign {
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalRedesignEnabled provides true,
|
LocalRedesignEnabled provides true,
|
||||||
LocalVisaRedesignEnabled provides true,
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
|
@ -324,7 +202,6 @@ private fun PreviewV2() {
|
||||||
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Content.stub())
|
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Content.stub())
|
||||||
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Error(onReloadClick = {}))
|
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Error(onReloadClick = {}))
|
||||||
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Loading)
|
TangemPayDailyLimitBlock(state = TangemPayDailyLimitBlockState.Loading)
|
||||||
TangemPayDailyLimitErrorBlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
package com.tangem.features.tangempay.ui
|
||||||
|
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||||
|
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
|
||||||
|
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
||||||
|
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||||
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import com.tangem.core.ui.extensions.combinedReference
|
||||||
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
import com.tangem.core.ui.extensions.styledStringReference
|
||||||
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
|
import com.tangem.features.tangempay.components.txHistory.PreviewTangemPayTxHistoryComponent
|
||||||
|
import com.tangem.features.tangempay.details.impl.R
|
||||||
|
import com.tangem.features.tangempay.entity.AddToWalletBlockState
|
||||||
|
import com.tangem.features.tangempay.entity.CardsProgressBannerUM
|
||||||
|
import com.tangem.features.tangempay.entity.TangemPayAction
|
||||||
|
import com.tangem.features.tangempay.entity.TangemPayActionButtonUM
|
||||||
|
import com.tangem.features.tangempay.entity.TangemPayCardUiState
|
||||||
|
import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState
|
||||||
|
import com.tangem.features.tangempay.entity.TangemPayDetailsTopBarConfig
|
||||||
|
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
|
||||||
|
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
|
internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<TangemPayDetailsUM>(
|
||||||
|
collection = listOf(
|
||||||
|
TangemPayDetailsUM(
|
||||||
|
topBarConfig = TangemPayDetailsTopBarConfig(
|
||||||
|
onBackClick = {},
|
||||||
|
onOpenMenu = {},
|
||||||
|
items = persistentListOf(),
|
||||||
|
itemsV2 = persistentListOf(),
|
||||||
|
),
|
||||||
|
pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}),
|
||||||
|
balanceBlockState = TangemPayDetailsBalanceBlockState.Content(
|
||||||
|
actionButtons = persistentListOf(
|
||||||
|
TangemPayActionButtonUM(
|
||||||
|
action = TangemPayAction.AddFunds,
|
||||||
|
config = ActionButtonConfig(
|
||||||
|
text = resourceReference(id = R.string.common_receive),
|
||||||
|
iconResId = R.drawable.ic_arrow_down_24,
|
||||||
|
onClick = {},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
fiatBalance = combinedReference(
|
||||||
|
stringReference("1,234"),
|
||||||
|
styledStringReference(
|
||||||
|
".56",
|
||||||
|
{ SpanStyle(color = TangemTheme.colors3.text.primary) },
|
||||||
|
),
|
||||||
|
stringReference(" $"),
|
||||||
|
),
|
||||||
|
isBalanceFlickering = false,
|
||||||
|
cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState(
|
||||||
|
cards = persistentListOf(
|
||||||
|
TangemPayDetailsBalanceBlockState.Card(
|
||||||
|
lastDigits = "1234",
|
||||||
|
imageUrl = null,
|
||||||
|
onClick = {},
|
||||||
|
isEnabled = false,
|
||||||
|
isFrozen = false,
|
||||||
|
state = TangemPayCardUiState.Active,
|
||||||
|
),
|
||||||
|
TangemPayDetailsBalanceBlockState.Card(
|
||||||
|
lastDigits = "3456",
|
||||||
|
imageUrl = null,
|
||||||
|
onClick = {},
|
||||||
|
isEnabled = true,
|
||||||
|
isFrozen = false,
|
||||||
|
state = TangemPayCardUiState.Active,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onAddCardClick = {},
|
||||||
|
isAddCardEnabled = true,
|
||||||
|
),
|
||||||
|
isNegative = false,
|
||||||
|
isInactive = false,
|
||||||
|
),
|
||||||
|
isBalanceHidden = false,
|
||||||
|
addToWalletBlockState = AddToWalletBlockState(
|
||||||
|
onClick = {},
|
||||||
|
onClickClose = {},
|
||||||
|
),
|
||||||
|
accountDeactivatedNotificationConfig = null,
|
||||||
|
errorNotificationConfig = null,
|
||||||
|
),
|
||||||
|
TangemPayDetailsUM(
|
||||||
|
topBarConfig = TangemPayDetailsTopBarConfig(
|
||||||
|
onBackClick = {},
|
||||||
|
onOpenMenu = {},
|
||||||
|
items = persistentListOf(),
|
||||||
|
itemsV2 = persistentListOf(),
|
||||||
|
),
|
||||||
|
pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}),
|
||||||
|
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(
|
||||||
|
actionButtons = persistentListOf(),
|
||||||
|
cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState(
|
||||||
|
cards = persistentListOf(
|
||||||
|
TangemPayDetailsBalanceBlockState.Card(
|
||||||
|
lastDigits = "1234",
|
||||||
|
imageUrl = null,
|
||||||
|
onClick = {},
|
||||||
|
isFrozen = false,
|
||||||
|
isEnabled = true,
|
||||||
|
state = TangemPayCardUiState.InProgress,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onAddCardClick = {},
|
||||||
|
isAddCardEnabled = true,
|
||||||
|
progressBanner = CardsProgressBannerUM.Reissuing,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
isBalanceHidden = false,
|
||||||
|
addToWalletBlockState = null,
|
||||||
|
accountDeactivatedNotificationConfig = null,
|
||||||
|
errorNotificationConfig = NotificationConfig(
|
||||||
|
title = TextReference.Str("Error title"),
|
||||||
|
subtitle = TextReference.Str("Error subtitle"),
|
||||||
|
iconResId = R.drawable.ic_alert_circle_24,
|
||||||
|
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||||
|
text = TextReference.Str("Error btn text"),
|
||||||
|
onClick = {},
|
||||||
|
iconResId = R.drawable.ic_tangem_24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
internal class TangemPayDetailsTxHistoryProvider : CollectionPreviewParameterProvider<TangemPayTxHistoryUM>(
|
||||||
|
collection = listOf(
|
||||||
|
PreviewTangemPayTxHistoryComponent.loadingUM,
|
||||||
|
PreviewTangemPayTxHistoryComponent.contentUM,
|
||||||
|
PreviewTangemPayTxHistoryComponent.emptyUM,
|
||||||
|
PreviewTangemPayTxHistoryComponent.errorUM,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
@ -1,587 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
|
||||||
import androidx.compose.foundation.Image
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.border
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material3.*
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.layout.ContentScale
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
|
||||||
import androidx.compose.ui.platform.testTag
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.text.SpanStyle
|
|
||||||
import androidx.compose.ui.tooling.preview.Devices
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
|
||||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.compose.ui.util.fastForEach
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|
||||||
import com.tangem.core.ui.components.RectangleShimmer
|
|
||||||
import com.tangem.core.ui.components.SpacerH12
|
|
||||||
import com.tangem.core.ui.components.buttons.HorizontalActionChips
|
|
||||||
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
|
|
||||||
import com.tangem.core.ui.components.buttons.small.TangemIconButton
|
|
||||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
|
||||||
import com.tangem.core.ui.components.containers.pullToRefresh.TangemPullToRefreshContainer
|
|
||||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownItem
|
|
||||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenu
|
|
||||||
import com.tangem.core.ui.components.notifications.Notification
|
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
|
||||||
import com.tangem.core.ui.components.text.applyBladeBrush
|
|
||||||
import com.tangem.core.ui.extensions.*
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.core.ui.test.TangemPayTestTags
|
|
||||||
import com.tangem.core.ui.test.TokenDetailsTopBarTestTags
|
|
||||||
import com.tangem.core.ui.test.WalletConnectBottomSheetTestTags
|
|
||||||
import com.tangem.features.tangempay.components.express.PreviewEmptyExpressTransactionsComponent
|
|
||||||
import com.tangem.features.tangempay.components.txHistory.PreviewTangemPayTxHistoryComponent
|
|
||||||
import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryComponent
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import com.tangem.features.tangempay.entity.*
|
|
||||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
|
||||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
|
||||||
|
|
||||||
private const val DISABLED_ALPHA = 0.5f
|
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayDetailsScreen(
|
|
||||||
state: TangemPayDetailsUM,
|
|
||||||
txHistoryComponent: TangemPayTxHistoryComponent,
|
|
||||||
expressTransactionsComponent: ExpressTransactionsComponent,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Scaffold(
|
|
||||||
modifier = modifier,
|
|
||||||
topBar = { TangemPayDetailsTopAppBar(config = state.topBarConfig) },
|
|
||||||
contentWindowInsets = ScaffoldDefaults.contentWindowInsets.exclude(WindowInsets.navigationBars),
|
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
|
||||||
) { scaffoldPaddings ->
|
|
||||||
val listState = rememberLazyListState()
|
|
||||||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
|
||||||
val txHistoryState by txHistoryComponent.state.collectAsStateWithLifecycle()
|
|
||||||
val expressState by expressTransactionsComponent.state.collectAsStateWithLifecycle()
|
|
||||||
val expressTransactionsBottomSheetState = expressState.bottomSheetSlot
|
|
||||||
|
|
||||||
TangemPullToRefreshContainer(
|
|
||||||
config = state.pullToRefreshConfig,
|
|
||||||
modifier = Modifier.padding(scaffoldPaddings),
|
|
||||||
) {
|
|
||||||
LazyColumn(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
state = listState,
|
|
||||||
contentPadding = PaddingValues(
|
|
||||||
bottom = TangemTheme.dimens.spacing16 + bottomBarHeight,
|
|
||||||
),
|
|
||||||
) {
|
|
||||||
item(key = "title") {
|
|
||||||
TangemPayTitle(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
|
||||||
.padding(top = 4.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (state.errorNotificationConfig != null) {
|
|
||||||
item(
|
|
||||||
key = "error_message",
|
|
||||||
content = {
|
|
||||||
Notification(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
|
||||||
.padding(top = 12.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
config = state.errorNotificationConfig,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
item(
|
|
||||||
key = TangemPayDetailsBalanceBlockState::class.java,
|
|
||||||
content = {
|
|
||||||
TangemPayDetailsBalanceBlock(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
|
||||||
.padding(top = 12.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
state = state.balanceBlockState,
|
|
||||||
isBalanceHidden = state.isBalanceHidden,
|
|
||||||
)
|
|
||||||
SpacerH12()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
val progressBanner = state.balanceBlockState.cardsBlockState?.progressBanner
|
|
||||||
if (progressBanner == CardsProgressBannerUM.Reissuing) {
|
|
||||||
item(
|
|
||||||
key = "REISSUE_MESSAGE",
|
|
||||||
content = {
|
|
||||||
TangemPayReplacingCardBlock(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
)
|
|
||||||
SpacerH12()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
if (state.addToWalletBlockState != null) {
|
|
||||||
item(
|
|
||||||
key = AddToWalletBlockState::class.java,
|
|
||||||
content = {
|
|
||||||
TangemPayAddToWalletBlock(
|
|
||||||
state = state.addToWalletBlockState,
|
|
||||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (state.accountDeactivatedNotificationConfig != null) {
|
|
||||||
item(
|
|
||||||
key = "DEACTIVATION_MESSAGE",
|
|
||||||
content = {
|
|
||||||
Notification(
|
|
||||||
modifier = modifier
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
config = state.accountDeactivatedNotificationConfig,
|
|
||||||
)
|
|
||||||
SpacerH12()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state.accountDeactivatedNotificationConfig == null) {
|
|
||||||
with(expressTransactionsComponent) {
|
|
||||||
expressTransactionsContentLegacy(
|
|
||||||
state = expressState.transactionsToDisplay,
|
|
||||||
modifier = modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.padding(top = 12.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryState) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expressTransactionsBottomSheetState?.content(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayTitle(modifier: Modifier = Modifier) {
|
|
||||||
Column(modifier = modifier) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_payment_account),
|
|
||||||
style = TangemTheme.typography.head,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
maxLines = 1,
|
|
||||||
)
|
|
||||||
TangemPaySubtitle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("MagicNumber")
|
|
||||||
@Composable
|
|
||||||
private fun TangemPaySubtitle(modifier: Modifier = Modifier) {
|
|
||||||
Row(
|
|
||||||
modifier = modifier,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
|
||||||
) {
|
|
||||||
Box(modifier = Modifier.wrapContentWidth()) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_polygon_22),
|
|
||||||
contentDescription = null,
|
|
||||||
tint = TangemTheme.colors.text.constantWhite,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(start = TangemTheme.dimens.spacing12)
|
|
||||||
.border(width = 2.dp, color = TangemTheme.colors.background.secondary, shape = CircleShape)
|
|
||||||
.padding(2.dp)
|
|
||||||
.clip(CircleShape)
|
|
||||||
.background(Color(0xFF8247E5))
|
|
||||||
.size(16.dp)
|
|
||||||
.testTag(WalletConnectBottomSheetTestTags.NETWORKS_ICONS),
|
|
||||||
)
|
|
||||||
Image(
|
|
||||||
painter = painterResource(id = R.drawable.img_usdc_16),
|
|
||||||
contentDescription = null,
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
modifier = Modifier
|
|
||||||
.border(width = 2.dp, color = TangemTheme.colors.background.secondary, shape = CircleShape)
|
|
||||||
.padding(2.dp)
|
|
||||||
.clip(CircleShape)
|
|
||||||
.size(16.dp)
|
|
||||||
.testTag(WalletConnectBottomSheetTestTags.NETWORKS_ICONS),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.align(Alignment.CenterVertically),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_usdc_on_polygon_network),
|
|
||||||
style = TangemTheme.typography.caption2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
maxLines = 1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// region Balance block
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayDetailsBalanceBlock(
|
|
||||||
state: TangemPayDetailsBalanceBlockState,
|
|
||||||
isBalanceHidden: Boolean,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.background(
|
|
||||||
color = TangemTheme.colors.background.primary,
|
|
||||||
shape = TangemTheme.shapes.roundedCornersMedium,
|
|
||||||
)
|
|
||||||
.padding(vertical = 12.dp),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(start = 12.dp),
|
|
||||||
text = stringResourceSafe(R.string.common_balance_title),
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
)
|
|
||||||
FiatBalance(
|
|
||||||
modifier = Modifier.padding(start = 12.dp, top = 8.dp),
|
|
||||||
state = state,
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
)
|
|
||||||
state.cardsBlockState?.let { cardsBlockState ->
|
|
||||||
CardsBlockRow(
|
|
||||||
modifier = Modifier
|
|
||||||
.wrapContentSize()
|
|
||||||
.padding(horizontal = 12.dp, vertical = 8.dp),
|
|
||||||
cardsBlockState = cardsBlockState,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (state.actionButtons.isNotEmpty()) {
|
|
||||||
HorizontalActionChips(
|
|
||||||
modifier = Modifier.padding(top = 12.dp),
|
|
||||||
buttons = state.actionButtons.map { it.config }.toImmutableList(),
|
|
||||||
containerColor = TangemTheme.colors.background.primary,
|
|
||||||
contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing12),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun CardsBlockRow(
|
|
||||||
cardsBlockState: TangemPayDetailsBalanceBlockState.CardsBlockState,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = modifier,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
|
||||||
) {
|
|
||||||
val itemsModifier = Modifier.size(width = 48.dp, height = 32.dp)
|
|
||||||
cardsBlockState.cards.fastForEach { card ->
|
|
||||||
TangemPayCardItem(modifier = itemsModifier, card = card)
|
|
||||||
}
|
|
||||||
TangemIconButton(
|
|
||||||
modifier = itemsModifier.alpha(if (cardsBlockState.isAddCardEnabled) 1f else DISABLED_ALPHA),
|
|
||||||
onClick = cardsBlockState.onAddCardClick,
|
|
||||||
iconRes = R.drawable.ic_plus_24,
|
|
||||||
shape = RoundedCornerShape(4.dp),
|
|
||||||
enabled = cardsBlockState.isAddCardEnabled,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayCardItem(card: TangemPayDetailsBalanceBlockState.Card, modifier: Modifier = Modifier) {
|
|
||||||
val isCardInProcess = card.state == TangemPayCardUiState.InProgress
|
|
||||||
Box(
|
|
||||||
modifier = modifier
|
|
||||||
.clip(RoundedCornerShape(4.dp))
|
|
||||||
.clickable(
|
|
||||||
onClick = card.onClick,
|
|
||||||
enabled = card.isEnabled,
|
|
||||||
)
|
|
||||||
.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_CARD_BUTTON),
|
|
||||||
) {
|
|
||||||
Image(
|
|
||||||
modifier = Modifier
|
|
||||||
.alpha(if (card.isEnabled) 1f else DISABLED_ALPHA)
|
|
||||||
.fillMaxSize(),
|
|
||||||
painter = painterResource(
|
|
||||||
if (isCardInProcess) {
|
|
||||||
R.drawable.img_visa_card_inactive_48_32
|
|
||||||
} else {
|
|
||||||
R.drawable.img_visa_card_48_32
|
|
||||||
},
|
|
||||||
),
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
if (!isCardInProcess) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomStart)
|
|
||||||
.padding(4.dp, bottom = 2.dp),
|
|
||||||
text = card.lastDigits,
|
|
||||||
style = TangemTheme.typography.overline.copy(letterSpacing = 0.sp),
|
|
||||||
color = TangemTheme.colors.text.constantWhite,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun FiatBalance(
|
|
||||||
state: TangemPayDetailsBalanceBlockState,
|
|
||||||
isBalanceHidden: Boolean,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayDetailsBalanceBlockState.Loading -> RectangleShimmer(
|
|
||||||
modifier = modifier.size(
|
|
||||||
width = TangemTheme.dimens.size102,
|
|
||||||
height = TangemTheme.dimens.size32,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
is TangemPayDetailsBalanceBlockState.Content -> Text(
|
|
||||||
modifier = modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE),
|
|
||||||
text = state.fiatBalance.orMaskWithStars(isBalanceHidden).resolveReference(),
|
|
||||||
style = TangemTheme.typography.h2.applyBladeBrush(
|
|
||||||
isEnabled = state.isBalanceFlickering,
|
|
||||||
textColor = TangemTheme.colors.text.primary1,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
is TangemPayDetailsBalanceBlockState.Error -> Text(
|
|
||||||
modifier = modifier.testTag(TangemPayTestTags.PAYMENT_ACCOUNT_BALANCE),
|
|
||||||
text = DASH_SIGN.orMaskWithStars(isBalanceHidden),
|
|
||||||
style = TangemTheme.typography.h2,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// endregion
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayDetailsTopAppBar(config: TangemPayDetailsTopBarConfig, modifier: Modifier = Modifier) {
|
|
||||||
var showDropdownMenu by rememberSaveable { mutableStateOf(false) }
|
|
||||||
TopAppBar(
|
|
||||||
modifier = modifier,
|
|
||||||
navigationIcon = {
|
|
||||||
IconButton(onClick = config.onBackClick) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_back_24),
|
|
||||||
tint = TangemTheme.colors.icon.primary1,
|
|
||||||
contentDescription = "Back",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title = {},
|
|
||||||
actions = {
|
|
||||||
AnimatedVisibility(visible = config.items.isNotEmpty()) {
|
|
||||||
IconButton(
|
|
||||||
onClick = {
|
|
||||||
config.onOpenMenu()
|
|
||||||
showDropdownMenu = true
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_more_vertical_24),
|
|
||||||
tint = TangemTheme.colors.icon.primary1,
|
|
||||||
contentDescription = "More",
|
|
||||||
modifier = Modifier.testTag(TokenDetailsTopBarTestTags.MORE_BUTTON),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TangemDropdownMenu(
|
|
||||||
expanded = showDropdownMenu,
|
|
||||||
modifier = Modifier.background(TangemTheme.colors.background.primary),
|
|
||||||
onDismissRequest = { showDropdownMenu = false },
|
|
||||||
content = {
|
|
||||||
config.items.fastForEach { item ->
|
|
||||||
TangemDropdownItem(
|
|
||||||
item = item,
|
|
||||||
dismissParent = { showDropdownMenu = false },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
|
||||||
containerColor = TangemTheme.colors.background.secondary,
|
|
||||||
titleContentColor = TangemTheme.colors.icon.primary1,
|
|
||||||
actionIconContentColor = TangemTheme.colors.icon.primary1,
|
|
||||||
),
|
|
||||||
scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(device = Devices.PIXEL_7_PRO)
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_7_PRO)
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayDetailsScreenPreview(
|
|
||||||
@PreviewParameter(TangemPayDetailsUMProvider::class) state: TangemPayDetailsUM,
|
|
||||||
) {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayDetailsScreen(
|
|
||||||
state = state,
|
|
||||||
txHistoryComponent = PreviewTangemPayTxHistoryComponent(
|
|
||||||
txHistoryUM = PreviewTangemPayTxHistoryComponent.contentUM,
|
|
||||||
),
|
|
||||||
expressTransactionsComponent = PreviewEmptyExpressTransactionsComponent(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<TangemPayDetailsUM>(
|
|
||||||
collection = listOf(
|
|
||||||
TangemPayDetailsUM(
|
|
||||||
topBarConfig = TangemPayDetailsTopBarConfig(
|
|
||||||
onBackClick = {},
|
|
||||||
onOpenMenu = {},
|
|
||||||
items = persistentListOf(),
|
|
||||||
itemsV2 = persistentListOf(),
|
|
||||||
),
|
|
||||||
pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}),
|
|
||||||
balanceBlockState = TangemPayDetailsBalanceBlockState.Content(
|
|
||||||
actionButtons = persistentListOf(
|
|
||||||
TangemPayActionButtonUM(
|
|
||||||
action = TangemPayAction.AddFunds,
|
|
||||||
config = ActionButtonConfig(
|
|
||||||
text = resourceReference(id = R.string.common_receive),
|
|
||||||
iconResId = R.drawable.ic_arrow_down_24,
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
fiatBalance = combinedReference(
|
|
||||||
stringReference("1,234"),
|
|
||||||
styledStringReference(
|
|
||||||
".56",
|
|
||||||
{ SpanStyle(color = TangemTheme.colors3.text.primary) },
|
|
||||||
),
|
|
||||||
stringReference(" $"),
|
|
||||||
),
|
|
||||||
isBalanceFlickering = false,
|
|
||||||
cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState(
|
|
||||||
cards = persistentListOf(
|
|
||||||
TangemPayDetailsBalanceBlockState.Card(
|
|
||||||
lastDigits = "1234",
|
|
||||||
imageUrl = null,
|
|
||||||
onClick = {},
|
|
||||||
isEnabled = false,
|
|
||||||
isFrozen = false,
|
|
||||||
state = TangemPayCardUiState.Active,
|
|
||||||
),
|
|
||||||
TangemPayDetailsBalanceBlockState.Card(
|
|
||||||
lastDigits = "3456",
|
|
||||||
imageUrl = null,
|
|
||||||
onClick = {},
|
|
||||||
isEnabled = true,
|
|
||||||
isFrozen = false,
|
|
||||||
state = TangemPayCardUiState.Active,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onAddCardClick = {},
|
|
||||||
isAddCardEnabled = true,
|
|
||||||
),
|
|
||||||
isNegative = false,
|
|
||||||
isInactive = false,
|
|
||||||
),
|
|
||||||
isBalanceHidden = false,
|
|
||||||
addToWalletBlockState = AddToWalletBlockState(
|
|
||||||
onClick = {},
|
|
||||||
onClickClose = {},
|
|
||||||
),
|
|
||||||
accountDeactivatedNotificationConfig = null,
|
|
||||||
errorNotificationConfig = null,
|
|
||||||
),
|
|
||||||
TangemPayDetailsUM(
|
|
||||||
topBarConfig = TangemPayDetailsTopBarConfig(
|
|
||||||
onBackClick = {},
|
|
||||||
onOpenMenu = {},
|
|
||||||
items = persistentListOf(),
|
|
||||||
itemsV2 = persistentListOf(),
|
|
||||||
),
|
|
||||||
pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}),
|
|
||||||
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(
|
|
||||||
actionButtons = persistentListOf(),
|
|
||||||
cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState(
|
|
||||||
cards = persistentListOf(
|
|
||||||
TangemPayDetailsBalanceBlockState.Card(
|
|
||||||
lastDigits = "1234",
|
|
||||||
imageUrl = null,
|
|
||||||
onClick = {},
|
|
||||||
isFrozen = false,
|
|
||||||
isEnabled = true,
|
|
||||||
state = TangemPayCardUiState.InProgress,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onAddCardClick = {},
|
|
||||||
isAddCardEnabled = true,
|
|
||||||
progressBanner = CardsProgressBannerUM.Reissuing,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
isBalanceHidden = false,
|
|
||||||
addToWalletBlockState = null,
|
|
||||||
accountDeactivatedNotificationConfig = null,
|
|
||||||
errorNotificationConfig = NotificationConfig(
|
|
||||||
title = TextReference.Str("Error title"),
|
|
||||||
subtitle = TextReference.Str("Error subtitle"),
|
|
||||||
iconResId = R.drawable.ic_alert_circle_24,
|
|
||||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
|
||||||
text = TextReference.Str("Error btn text"),
|
|
||||||
onClick = {},
|
|
||||||
iconResId = R.drawable.ic_tangem_24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
@Preview(device = Devices.PIXEL_7_PRO)
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayDetailsTxHistoryScreenPreview(
|
|
||||||
@PreviewParameter(TangemPayDetailsTxHistoryProvider::class) state: TangemPayTxHistoryUM,
|
|
||||||
) {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayDetailsScreen(
|
|
||||||
state = TangemPayDetailsUMProvider().values.first(),
|
|
||||||
txHistoryComponent = PreviewTangemPayTxHistoryComponent(txHistoryUM = state),
|
|
||||||
expressTransactionsComponent = PreviewEmptyExpressTransactionsComponent(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class TangemPayDetailsTxHistoryProvider : CollectionPreviewParameterProvider<TangemPayTxHistoryUM>(
|
|
||||||
collection = listOf(
|
|
||||||
PreviewTangemPayTxHistoryComponent.loadingUM,
|
|
||||||
PreviewTangemPayTxHistoryComponent.contentUM,
|
|
||||||
PreviewTangemPayTxHistoryComponent.emptyUM,
|
|
||||||
PreviewTangemPayTxHistoryComponent.errorUM,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
@ -4,18 +4,12 @@ import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
|
||||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||||
import com.tangem.core.ui.ds.topbar.TangemTopBar
|
import com.tangem.core.ui.ds.topbar.TangemTopBar
|
||||||
import com.tangem.core.ui.ds2.button.TangemButton
|
import com.tangem.core.ui.ds2.button.TangemButton
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.core.ui.res.generated.icons.Icons
|
import com.tangem.core.ui.res.generated.icons.Icons
|
||||||
import com.tangem.core.ui.res.generated.icons.ic_cross_20
|
import com.tangem.core.ui.res.generated.icons.ic_cross_20
|
||||||
|
|
@ -23,80 +17,6 @@ import com.tangem.features.tangempay.details.impl.R
|
||||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||||
import com.tangem.features.tangempay.entity.TangemPayEditDisplayNameUM
|
import com.tangem.features.tangempay.entity.TangemPayEditDisplayNameUM
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayEditDisplayNameScreen(
|
|
||||||
isRedesignEnabled: Boolean,
|
|
||||||
state: TangemPayEditDisplayNameUM,
|
|
||||||
cardDetailsState: TangemPayCardDetailsUM,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
if (isRedesignEnabled) {
|
|
||||||
TangemPayEditDisplayNameScreenV2(
|
|
||||||
state = state,
|
|
||||||
cardDetailsState = cardDetailsState,
|
|
||||||
modifier = modifier,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TangemPayEditDisplayNameScreenV1(
|
|
||||||
state = state,
|
|
||||||
cardDetailsState = cardDetailsState,
|
|
||||||
modifier = modifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayEditDisplayNameScreenV1(
|
|
||||||
state: TangemPayEditDisplayNameUM,
|
|
||||||
cardDetailsState: TangemPayCardDetailsUM,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.background(TangemTheme.colors.background.secondary)
|
|
||||||
.navigationBarsPadding(),
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.statusBarsPadding()
|
|
||||||
.height(56.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
) {
|
|
||||||
IconButton(
|
|
||||||
modifier = Modifier.padding(start = 4.dp, top = 4.dp),
|
|
||||||
onClick = state.onDismiss,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = com.tangem.core.ui.R.drawable.ic_close_24),
|
|
||||||
contentDescription = null,
|
|
||||||
tint = TangemTheme.colors.icon.primary1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TangemPayCard(
|
|
||||||
state = cardDetailsState,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.padding(top = 8.dp),
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
|
||||||
|
|
||||||
PrimaryButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.imePadding()
|
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
text = stringResourceSafe(R.string.common_done),
|
|
||||||
onClick = state.onDoneClick,
|
|
||||||
showProgress = state.isLoading,
|
|
||||||
enabled = !state.isLoading && state.isDoneEnabled,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun TangemPayEditDisplayNameScreenV2(
|
internal fun TangemPayEditDisplayNameScreenV2(
|
||||||
state: TangemPayEditDisplayNameUM,
|
state: TangemPayEditDisplayNameUM,
|
||||||
|
|
|
||||||
|
|
@ -1,218 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
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.core.ui.components.PrimaryButton
|
|
||||||
import com.tangem.core.ui.components.SpacerH16
|
|
||||||
import com.tangem.core.ui.components.SpacerH24
|
|
||||||
import com.tangem.core.ui.components.SpacerH8
|
|
||||||
import com.tangem.core.ui.components.TextShimmer
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
|
||||||
import com.tangem.core.ui.components.notifications.Notification
|
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayReissueCardError
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayReissueCardUM
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayReissueCardContent(state: TangemPayReissueCardUM) {
|
|
||||||
TangemModalBottomSheet<TangemBottomSheetConfigContent.Empty>(
|
|
||||||
config = TangemBottomSheetConfig(
|
|
||||||
isShown = true,
|
|
||||||
onDismissRequest = state.onDismissRequest,
|
|
||||||
content = TangemBottomSheetConfigContent.Empty,
|
|
||||||
),
|
|
||||||
containerColor = TangemTheme.colors.background.tertiary,
|
|
||||||
onBack = state.onDismissRequest,
|
|
||||||
title = {
|
|
||||||
TangemModalBottomSheetTitle(
|
|
||||||
title = TextReference.EMPTY,
|
|
||||||
endIconRes = R.drawable.ic_close_24,
|
|
||||||
onEndClick = state.onDismissRequest,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Content(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Content(state: TangemPayReissueCardUM) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.size(TangemTheme.dimens.spacing56)
|
|
||||||
.clip(CircleShape)
|
|
||||||
.background(TangemTheme.colors.icon.accent.copy(alpha = 0.1f)),
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.ic_update_32),
|
|
||||||
contentDescription = null,
|
|
||||||
tint = TangemTheme.colors.icon.accent,
|
|
||||||
modifier = Modifier.size(32.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SpacerH24()
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_reissue_card_title),
|
|
||||||
style = TangemTheme.typography.h3,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp),
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH8()
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_reissue_card_description),
|
|
||||||
style = TangemTheme.typography.body2,
|
|
||||||
color = TangemTheme.colors.text.secondary,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 16.dp),
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH24()
|
|
||||||
|
|
||||||
FeeBlock(state)
|
|
||||||
|
|
||||||
if (state.error != null) {
|
|
||||||
SpacerH16()
|
|
||||||
ErrorBlock(
|
|
||||||
error = state.error,
|
|
||||||
onRetryFee = state.onRetryFee,
|
|
||||||
onAddFundsClick = state.onAddFundsClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SpacerH24()
|
|
||||||
|
|
||||||
PrimaryButton(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_reissue_card_confirm),
|
|
||||||
enabled = state.error == null && !state.isFeeLoading,
|
|
||||||
showProgress = state.isReissuingInProgress,
|
|
||||||
onClick = state.onConfirmClick,
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH16()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun FeeBlock(state: TangemPayReissueCardUM) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(
|
|
||||||
color = TangemTheme.colors.background.action,
|
|
||||||
shape = TangemTheme.shapes.roundedCornersMedium,
|
|
||||||
)
|
|
||||||
.padding(TangemTheme.dimens.spacing12),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_reissue_card_fee_label),
|
|
||||||
style = TangemTheme.typography.body1,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
)
|
|
||||||
AnimatedContent(
|
|
||||||
targetState = when {
|
|
||||||
state.isFeeLoading -> null
|
|
||||||
state.error == TangemPayReissueCardError.InitialDataLoading -> "—"
|
|
||||||
else -> state.feeAmount
|
|
||||||
},
|
|
||||||
) { fee ->
|
|
||||||
if (fee != null) {
|
|
||||||
Text(
|
|
||||||
text = fee,
|
|
||||||
style = TangemTheme.typography.body1,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TextShimmer(style = TangemTheme.typography.body1, text = "$0.00")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun ErrorBlock(error: TangemPayReissueCardError, onAddFundsClick: () -> Unit, onRetryFee: () -> Unit) {
|
|
||||||
when (error) {
|
|
||||||
TangemPayReissueCardError.InsufficientFunds -> Notification(
|
|
||||||
config = NotificationConfig(
|
|
||||||
title = resourceReference(R.string.tangempay_reissue_card_insufficient_funds_title),
|
|
||||||
subtitle = resourceReference(R.string.tangempay_reissue_card_insufficient_funds_subtitle),
|
|
||||||
iconResId = R.drawable.img_usdc_16,
|
|
||||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
|
||||||
text = resourceReference(R.string.tangempay_card_details_add_funds),
|
|
||||||
iconResId = R.drawable.ic_plus_24,
|
|
||||||
onClick = onAddFundsClick,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
containerColor = TangemTheme.colors.background.action,
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
)
|
|
||||||
TangemPayReissueCardError.InitialDataLoading -> Notification(
|
|
||||||
config = NotificationConfig(
|
|
||||||
title = resourceReference(R.string.tangempay_reissue_card_fee_unreachable_error_title),
|
|
||||||
subtitle = resourceReference(R.string.send_fee_unreachable_error_text),
|
|
||||||
iconResId = R.drawable.img_attention_20,
|
|
||||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
|
||||||
text = resourceReference(R.string.warning_button_refresh),
|
|
||||||
onClick = onRetryFee,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
containerColor = TangemTheme.colors.background.action,
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun preview() = TangemThemePreview {
|
|
||||||
TangemPayReissueCardContent(
|
|
||||||
state = TangemPayReissueCardUM.stub(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import com.tangem.core.ui.components.SpacerH24
|
|
||||||
import com.tangem.core.ui.components.notifications.Notification
|
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayReplacingCardBlock(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
title: TextReference? = resourceReference(R.string.tangempay_reissue_card_in_progress),
|
|
||||||
subtitle: TextReference = resourceReference(R.string.tangempay_reissue_card_in_progress_description),
|
|
||||||
) {
|
|
||||||
if (LocalVisaRedesignEnabled.current) {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
Block(title = title, subtitle = subtitle, modifier = modifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Block(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
title: TextReference? = resourceReference(R.string.tangempay_reissue_card_in_progress),
|
|
||||||
subtitle: TextReference = resourceReference(R.string.tangempay_reissue_card_in_progress_description),
|
|
||||||
) {
|
|
||||||
Notification(
|
|
||||||
modifier = modifier,
|
|
||||||
config = NotificationConfig(
|
|
||||||
iconResId = R.drawable.ic_update_32,
|
|
||||||
iconTint = NotificationConfig.IconTint.Accent,
|
|
||||||
title = title,
|
|
||||||
subtitle = subtitle,
|
|
||||||
),
|
|
||||||
containerColor = TangemTheme.colors.background.primary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun Preview() {
|
|
||||||
Column {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayReplacingCardBlock()
|
|
||||||
}
|
|
||||||
SpacerH24()
|
|
||||||
CompositionLocalProvider(LocalVisaRedesignEnabled provides true) {
|
|
||||||
TangemThemePreviewRedesign {
|
|
||||||
TangemPayReplacingCardBlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,408 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.lazy.LazyListScope
|
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
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.draw.clip
|
|
||||||
import androidx.compose.ui.platform.testTag
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.constraintlayout.compose.ChainStyle
|
|
||||||
import androidx.constraintlayout.compose.ConstraintLayout
|
|
||||||
import androidx.constraintlayout.compose.Dimension
|
|
||||||
import com.tangem.core.ui.R
|
|
||||||
import com.tangem.core.ui.components.CircleShimmer
|
|
||||||
import com.tangem.core.ui.components.RectangleShimmer
|
|
||||||
import com.tangem.core.ui.components.buttons.actions.ActionButton
|
|
||||||
import com.tangem.core.ui.components.list.InfiniteListHandler
|
|
||||||
import com.tangem.core.ui.components.transactions.TxHistoryGroupTitle
|
|
||||||
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
|
||||||
import com.tangem.core.ui.extensions.ImageReference
|
|
||||||
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.test.EmptyTransactionBlockTestTags
|
|
||||||
import com.tangem.core.ui.test.TransactionHistoryBlockTestTags
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayEmptyTransactionHistoryState
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTransactionState
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
|
||||||
|
|
||||||
private const val LOAD_ITEMS_BUFFER = 20
|
|
||||||
|
|
||||||
internal fun LazyListScope.tangemPayTxHistoryItems(listState: LazyListState, state: TangemPayTxHistoryUM) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayTxHistoryUM.Content -> contentItems(listState = listState, state = state)
|
|
||||||
is TangemPayTxHistoryUM.Empty -> nonContentItem(state = TangemPayEmptyTransactionHistoryState.Empty)
|
|
||||||
is TangemPayTxHistoryUM.Error -> nonContentItem(
|
|
||||||
state = TangemPayEmptyTransactionHistoryState.FailedToLoad(onReload = state.onReload),
|
|
||||||
)
|
|
||||||
is TangemPayTxHistoryUM.Loading -> loadingItems(state = state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun LazyListScope.nonContentItem(state: TangemPayEmptyTransactionHistoryState, modifier: Modifier = Modifier) {
|
|
||||||
item(key = state::class.java, contentType = state::class.java) {
|
|
||||||
TangemPayEmptyTransactionBlock(
|
|
||||||
state = state,
|
|
||||||
modifier = modifier
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing16, vertical = TangemTheme.dimens.spacing12)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun LazyListScope.contentItems(listState: LazyListState, state: TangemPayTxHistoryUM.Content) {
|
|
||||||
itemsIndexed(
|
|
||||||
items = state.items,
|
|
||||||
key = { index, item ->
|
|
||||||
when (item) {
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> item.itemKey
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> index + item.hashCode()
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction ->
|
|
||||||
item.transaction.id + (item.transaction as? TangemPayTransactionState.Content)?.hashCode()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
contentType = { _, item -> item::class.java },
|
|
||||||
itemContent = { index, item ->
|
|
||||||
TangemPayTxHistoryListItem(
|
|
||||||
state = item,
|
|
||||||
isBalanceHidden = state.isBalanceHidden,
|
|
||||||
modifier = Modifier.roundedShapeItemDecoration(
|
|
||||||
currentIndex = index,
|
|
||||||
lastIndex = state.items.lastIndex,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
item {
|
|
||||||
InfiniteListHandler(
|
|
||||||
listState = listState,
|
|
||||||
buffer = LOAD_ITEMS_BUFFER,
|
|
||||||
onLoadMore = state.loadMore,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun LazyListScope.loadingItems(state: TangemPayTxHistoryUM.Loading) {
|
|
||||||
itemsIndexed(
|
|
||||||
items = state.items,
|
|
||||||
key = { _, item ->
|
|
||||||
when (item) {
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> item.itemKey
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> item.hashCode()
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction ->
|
|
||||||
item.transaction.id + (item.transaction as? TangemPayTransactionState.Content)?.hashCode()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
contentType = { _, item -> item::class.java },
|
|
||||||
itemContent = { index, item ->
|
|
||||||
TangemPayTxHistoryListItem(
|
|
||||||
state = item,
|
|
||||||
isBalanceHidden = true,
|
|
||||||
modifier = Modifier.roundedShapeItemDecoration(
|
|
||||||
currentIndex = index,
|
|
||||||
lastIndex = state.items.lastIndex,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayTxHistoryListItem(
|
|
||||||
state: TangemPayTxHistoryUM.TangemPayTxHistoryItemUM,
|
|
||||||
isBalanceHidden: Boolean,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> {
|
|
||||||
if (state.isLoading) {
|
|
||||||
RectangleShimmer(
|
|
||||||
modifier = modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(
|
|
||||||
vertical = TangemTheme.dimens.spacing8,
|
|
||||||
horizontal = TangemTheme.dimens.spacing12,
|
|
||||||
)
|
|
||||||
.height(TangemTheme.dimens.size12),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TxHistoryGroupTitle(config = state.legacyGroupTitle, modifier = modifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> {
|
|
||||||
TangemPayTxHistoryTitle(modifier = modifier)
|
|
||||||
}
|
|
||||||
is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction -> {
|
|
||||||
TangemPayTransaction(
|
|
||||||
transactionState = state.transaction,
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
modifier = modifier,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayTxHistoryTitle(modifier: Modifier = Modifier) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(id = R.string.common_transactions),
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
modifier = modifier
|
|
||||||
.background(TangemTheme.colors.background.primary)
|
|
||||||
.padding(top = TangemTheme.dimens.spacing12)
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing12)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.heightIn(min = TangemTheme.dimens.size24)
|
|
||||||
.testTag(TransactionHistoryBlockTestTags.TITLE_TEXT),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayTransaction(
|
|
||||||
transactionState: TangemPayTransactionState,
|
|
||||||
isBalanceHidden: Boolean,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Surface(
|
|
||||||
modifier = modifier
|
|
||||||
.background(TangemTheme.colors.background.primary)
|
|
||||||
.clickable(
|
|
||||||
enabled = transactionState is TangemPayTransactionState.Content,
|
|
||||||
onClick = (transactionState as? TangemPayTransactionState.Content)?.onClick ?: {},
|
|
||||||
)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.heightIn(min = TangemTheme.dimens.size56)
|
|
||||||
.padding(
|
|
||||||
vertical = TangemTheme.dimens.spacing8,
|
|
||||||
horizontal = TangemTheme.dimens.spacing12,
|
|
||||||
),
|
|
||||||
color = TangemTheme.colors.background.primary,
|
|
||||||
) {
|
|
||||||
@Suppress("DestructuringDeclarationWithTooManyEntries")
|
|
||||||
ConstraintLayout(modifier = Modifier.fillMaxWidth()) {
|
|
||||||
val (iconItem, titleItem, subtitleItem, amountItem, timestampItem) = createRefs()
|
|
||||||
|
|
||||||
createVerticalChain(titleItem, subtitleItem, chainStyle = ChainStyle.Spread)
|
|
||||||
createVerticalChain(amountItem, timestampItem, chainStyle = ChainStyle.Spread)
|
|
||||||
|
|
||||||
Icon(
|
|
||||||
state = transactionState,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(TangemTheme.dimens.size40)
|
|
||||||
.constrainAs(iconItem) {
|
|
||||||
start.linkTo(parent.start)
|
|
||||||
centerVerticallyTo(parent)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
Title(
|
|
||||||
state = transactionState,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(
|
|
||||||
start = TangemTheme.dimens.spacing12,
|
|
||||||
end = TangemTheme.dimens.spacing4,
|
|
||||||
)
|
|
||||||
.constrainAs(titleItem) {
|
|
||||||
top.linkTo(parent.top)
|
|
||||||
bottom.linkTo(subtitleItem.top)
|
|
||||||
start.linkTo(iconItem.end)
|
|
||||||
end.linkTo(amountItem.start)
|
|
||||||
width = Dimension.fillToConstraints
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
Subtitle(
|
|
||||||
state = transactionState,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(
|
|
||||||
start = TangemTheme.dimens.spacing12,
|
|
||||||
end = TangemTheme.dimens.spacing4,
|
|
||||||
)
|
|
||||||
.constrainAs(subtitleItem) {
|
|
||||||
top.linkTo(titleItem.bottom)
|
|
||||||
bottom.linkTo(parent.bottom)
|
|
||||||
start.linkTo(iconItem.end)
|
|
||||||
end.linkTo(timestampItem.start)
|
|
||||||
width = Dimension.fillToConstraints
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
Amount(
|
|
||||||
state = transactionState,
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
modifier = Modifier.constrainAs(amountItem) {
|
|
||||||
top.linkTo(parent.top)
|
|
||||||
bottom.linkTo(timestampItem.top)
|
|
||||||
start.linkTo(titleItem.end)
|
|
||||||
end.linkTo(parent.end)
|
|
||||||
width = Dimension.preferredWrapContent
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
Timestamp(
|
|
||||||
state = transactionState,
|
|
||||||
modifier = Modifier.constrainAs(timestampItem) {
|
|
||||||
top.linkTo(amountItem.bottom)
|
|
||||||
bottom.linkTo(parent.bottom)
|
|
||||||
end.linkTo(parent.end)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Icon(state: TangemPayTransactionState, modifier: Modifier = Modifier) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayTransactionState.Content -> when (val iconReference = state.icon) {
|
|
||||||
is ImageReference.Url -> RemoteIcon(modifier = modifier, url = iconReference.url)
|
|
||||||
is ImageReference.Res -> LocalStaticIcon(
|
|
||||||
modifier = modifier,
|
|
||||||
id = iconReference.resId,
|
|
||||||
iconSize = TangemTheme.dimens.size20,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is TangemPayTransactionState.Loading -> CircleShimmer(modifier = modifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Title(state: TangemPayTransactionState, modifier: Modifier = Modifier) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayTransactionState.Content -> {
|
|
||||||
Text(
|
|
||||||
modifier = modifier,
|
|
||||||
text = state.title.resolveReference(),
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
style = TangemTheme.typography.subtitle2,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
maxLines = 1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is TangemPayTransactionState.Loading -> {
|
|
||||||
RectangleShimmer(
|
|
||||||
modifier = modifier.size(width = TangemTheme.dimens.size70, height = TangemTheme.dimens.size12),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Subtitle(state: TangemPayTransactionState, modifier: Modifier = Modifier) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayTransactionState.Content -> {
|
|
||||||
Text(
|
|
||||||
text = state.subtitle.resolveReference(),
|
|
||||||
modifier = modifier,
|
|
||||||
textAlign = TextAlign.Start,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
style = TangemTheme.typography.caption2,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is TangemPayTransactionState.Loading -> {
|
|
||||||
RectangleShimmer(
|
|
||||||
modifier = modifier.size(width = TangemTheme.dimens.size52, height = TangemTheme.dimens.size12),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Amount(state: TangemPayTransactionState, isBalanceHidden: Boolean, modifier: Modifier = Modifier) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayTransactionState.Content -> {
|
|
||||||
Text(
|
|
||||||
text = state.amount.orMaskWithStars(isBalanceHidden),
|
|
||||||
modifier = modifier,
|
|
||||||
textAlign = TextAlign.End,
|
|
||||||
color = state.amountColor.resolveReference(),
|
|
||||||
style = TangemTheme.typography.body2,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is TangemPayTransactionState.Loading -> {
|
|
||||||
RectangleShimmer(
|
|
||||||
modifier = modifier.size(width = TangemTheme.dimens.size72, height = TangemTheme.dimens.size12),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Timestamp(state: TangemPayTransactionState, modifier: Modifier = Modifier) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayTransactionState.Content -> {
|
|
||||||
Text(
|
|
||||||
text = state.time,
|
|
||||||
modifier = modifier,
|
|
||||||
textAlign = TextAlign.End,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
style = TangemTheme.typography.caption2,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is TangemPayTransactionState.Loading -> {
|
|
||||||
RectangleShimmer(
|
|
||||||
modifier = modifier.size(width = TangemTheme.dimens.size40, height = TangemTheme.dimens.size12),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayEmptyTransactionBlock(
|
|
||||||
state: TangemPayEmptyTransactionHistoryState,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
|
||||||
.background(color = TangemTheme.colors.background.primary)
|
|
||||||
.padding(vertical = TangemTheme.dimens.spacing24)
|
|
||||||
.testTag(EmptyTransactionBlockTestTags.BLOCK),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing24),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier
|
|
||||||
.size(TangemTheme.dimens.size64)
|
|
||||||
.testTag(EmptyTransactionBlockTestTags.ICON),
|
|
||||||
painter = painterResource(id = state.iconRes),
|
|
||||||
tint = TangemTheme.colors.icon.inactive,
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = TangemTheme.dimens.spacing32)
|
|
||||||
.testTag(EmptyTransactionBlockTestTags.TEXT),
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
text = state.text.resolveReference(),
|
|
||||||
style = TangemTheme.typography.body2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
|
|
||||||
when (state) {
|
|
||||||
is TangemPayEmptyTransactionHistoryState.Empty -> Unit
|
|
||||||
is TangemPayEmptyTransactionHistoryState.FailedToLoad -> ActionButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 24.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
config = state.actionButtonConfig,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,204 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color.Companion.Transparent
|
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import com.tangem.core.ui.components.SecondaryButton
|
|
||||||
import com.tangem.core.ui.components.SpacerH12
|
|
||||||
import com.tangem.core.ui.components.SpacerH24
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetContent
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
|
||||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayViewPinUM
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayViewPinContent(state: TangemPayViewPinUM) {
|
|
||||||
TangemModalBottomSheet<TangemBottomSheetConfigContent.Empty>(
|
|
||||||
config = TangemBottomSheetConfig(
|
|
||||||
isShown = true,
|
|
||||||
onDismissRequest = state.onDismiss,
|
|
||||||
content = TangemBottomSheetConfigContent.Empty,
|
|
||||||
),
|
|
||||||
onBack = state.onDismiss,
|
|
||||||
containerColor = TangemTheme.colors.background.tertiary,
|
|
||||||
title = {
|
|
||||||
TangemModalBottomSheetTitle(
|
|
||||||
title = TextReference.EMPTY,
|
|
||||||
endIconRes = R.drawable.ic_close_24,
|
|
||||||
onEndClick = state.onDismiss,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
when (state) {
|
|
||||||
is TangemPayViewPinUM.Content -> {
|
|
||||||
PinSuccessContent(state)
|
|
||||||
}
|
|
||||||
is TangemPayViewPinUM.Error -> {
|
|
||||||
MessageBottomSheetContent(state.errorMessage)
|
|
||||||
}
|
|
||||||
is TangemPayViewPinUM.Loading -> {
|
|
||||||
PinLoadingContent()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PinSuccessContent(state: TangemPayViewPinUM.Content, modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_view_pin_code_title),
|
|
||||||
style = TangemTheme.typography.h2,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH12()
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_view_pin_code_description),
|
|
||||||
style = TangemTheme.typography.body1,
|
|
||||||
color = TangemTheme.colors.text.secondary,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH24()
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(200.dp),
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
PinCode(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopCenter),
|
|
||||||
value = state.pin,
|
|
||||||
)
|
|
||||||
|
|
||||||
SecondaryButton(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.BottomCenter)
|
|
||||||
.imePadding()
|
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
text = stringResourceSafe(R.string.tangempay_change_pin_code),
|
|
||||||
onClick = state.onClickChangePin,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PinLoadingContent(modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_view_pin_code_title),
|
|
||||||
style = TangemTheme.typography.h2,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH12()
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.tangempay_card_details_view_pin_code_description),
|
|
||||||
style = TangemTheme.typography.body1,
|
|
||||||
color = TangemTheme.colors.text.secondary,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
|
|
||||||
SpacerH24()
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(200.dp),
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
CircularProgressIndicator(
|
|
||||||
color = TangemTheme.colors.text.disabled,
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopCenter)
|
|
||||||
.padding(top = 16.dp)
|
|
||||||
.size(TangemTheme.dimens.size24),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PinCode(value: String, modifier: Modifier = Modifier, numbersCount: Int = 4) {
|
|
||||||
BasicTextField(
|
|
||||||
value = value,
|
|
||||||
onValueChange = {},
|
|
||||||
modifier = modifier,
|
|
||||||
textStyle = TangemTheme.typography.h1.copy(color = Transparent),
|
|
||||||
cursorBrush = SolidColor(Transparent),
|
|
||||||
decorationBox = { innerTextField ->
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
contentAlignment = Alignment.Center,
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
repeat(numbersCount) { index ->
|
|
||||||
val digit = value.getOrNull(index)?.toString()
|
|
||||||
PinDigitBox(
|
|
||||||
digit = digit,
|
|
||||||
backgroundColor = TangemTheme.colors.background.action,
|
|
||||||
borderColor = TangemTheme.colors.stroke.primary,
|
|
||||||
textColor = TangemTheme.colors.text.primary1,
|
|
||||||
textStyle = TangemTheme.typography.h1,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
innerTextField()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayViewPinContentPreview() {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayViewPinContent(
|
|
||||||
state = TangemPayViewPinUM.Content(
|
|
||||||
pin = "1234",
|
|
||||||
onClickChangePin = {},
|
|
||||||
onDismiss = {},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,307 +0,0 @@
|
||||||
package com.tangem.features.tangempay.ui
|
|
||||||
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.tooling.preview.Devices
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
|
||||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.util.fastForEach
|
|
||||||
import com.tangem.core.ui.components.SecondaryButton
|
|
||||||
import com.tangem.core.ui.components.SecondaryButtonIconStart
|
|
||||||
import com.tangem.core.ui.components.SpacerH32
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
|
||||||
import com.tangem.core.ui.components.label.Label
|
|
||||||
import com.tangem.core.ui.components.label.entity.LabelStyle
|
|
||||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
|
||||||
import com.tangem.core.ui.components.notifications.Notification
|
|
||||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
|
||||||
import com.tangem.core.ui.extensions.*
|
|
||||||
import com.tangem.core.ui.res.TangemColorPalette
|
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
|
||||||
import com.tangem.core.ui.res.TangemThemePreview
|
|
||||||
import com.tangem.features.tangempay.details.impl.R
|
|
||||||
import com.tangem.features.tangempay.entity.ButtonState
|
|
||||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
|
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
|
||||||
@Composable
|
|
||||||
internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM) {
|
|
||||||
TangemModalBottomSheet<TangemBottomSheetConfigContent.Empty>(
|
|
||||||
config = TangemBottomSheetConfig(
|
|
||||||
isShown = true,
|
|
||||||
onDismissRequest = state.dismiss,
|
|
||||||
content = TangemBottomSheetConfigContent.Empty,
|
|
||||||
),
|
|
||||||
onBack = state.dismiss,
|
|
||||||
containerColor = TangemTheme.colors.background.tertiary,
|
|
||||||
title = {
|
|
||||||
TangemModalBottomSheetTitle(
|
|
||||||
title = state.title,
|
|
||||||
endIconRes = R.drawable.ic_close_24,
|
|
||||||
onEndClick = state.dismiss,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = 24.dp)
|
|
||||||
.size(88.dp),
|
|
||||||
iconState = state.iconState,
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(top = 32.dp),
|
|
||||||
text = state.transactionTitle.resolveReference(),
|
|
||||||
style = TangemTheme.typography.subtitle1,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(top = 2.dp),
|
|
||||||
text = state.transactionSubtitle.resolveReference(),
|
|
||||||
style = TangemTheme.typography.body2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(top = 8.dp),
|
|
||||||
text = state.transactionAmount.orMaskWithStars(state.isBalanceHidden),
|
|
||||||
style = TangemTheme.typography.head,
|
|
||||||
color = state.transactionAmountColor.resolveReference(),
|
|
||||||
)
|
|
||||||
if (state.localTransactionText != null) {
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(top = 4.dp),
|
|
||||||
text = state.localTransactionText.orMaskWithStars(state.isBalanceHidden),
|
|
||||||
style = TangemTheme.typography.body2,
|
|
||||||
color = TangemTheme.colors.text.tertiary,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (state.labelState != null) {
|
|
||||||
Label(state = state.labelState, modifier = Modifier.padding(top = 12.dp))
|
|
||||||
}
|
|
||||||
SpacerH32()
|
|
||||||
if (state.notification != null) {
|
|
||||||
Notification(
|
|
||||||
config = state.notification.config,
|
|
||||||
titleColor = state.notification.titleColor.resolveReference(),
|
|
||||||
iconTint = state.notification.iconTint.resolveReference(),
|
|
||||||
containerColor = state.notification.containerColor?.resolveReference(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ButtonsContainer(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(vertical = 16.dp)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
buttons = state.buttons,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun ButtonsContainer(buttons: ImmutableList<ButtonState>, modifier: Modifier = Modifier) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier,
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
|
||||||
) {
|
|
||||||
buttons.fastForEach { buttonState ->
|
|
||||||
if (buttonState.startIcon != null) {
|
|
||||||
SecondaryButtonIconStart(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = buttonState.text.resolveReference(),
|
|
||||||
iconResId = buttonState.startIcon.resId,
|
|
||||||
onClick = buttonState.onClick,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
SecondaryButton(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = buttonState.text.resolveReference(),
|
|
||||||
onClick = buttonState.onClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Icon(iconState: ImageReference, modifier: Modifier = Modifier) {
|
|
||||||
when (iconState) {
|
|
||||||
is ImageReference.Res -> LocalStaticIcon(modifier = modifier, id = iconState.resId, iconSize = 40.dp)
|
|
||||||
is ImageReference.Url -> RemoteIcon(modifier = modifier, url = iconState.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(device = Devices.PIXEL_7_PRO)
|
|
||||||
@Preview(device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
|
||||||
@Composable
|
|
||||||
private fun TangemPayTxHistoryDetailsContentPreview(
|
|
||||||
@PreviewParameter(TangemPayTxHistoryDetailsUMProvider::class) state: TangemPayTxHistoryDetailsUM,
|
|
||||||
) {
|
|
||||||
TangemThemePreview {
|
|
||||||
TangemPayTxHistoryDetailsContent(state = state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterProvider<TangemPayTxHistoryDetailsUM>(
|
|
||||||
listOf(
|
|
||||||
TangemPayTxHistoryDetailsUM(
|
|
||||||
isBalanceHidden = true,
|
|
||||||
title = stringReference("12 June • 12:40"),
|
|
||||||
iconState = ImageReference.Res(R.drawable.ic_category_24),
|
|
||||||
transactionTitle = stringReference("Starbucks"),
|
|
||||||
transactionSubtitle = stringReference("Food and drinks"),
|
|
||||||
transactionAmount = "-$5.86",
|
|
||||||
transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 },
|
|
||||||
localTransactionText = null,
|
|
||||||
labelState = LabelUM(
|
|
||||||
text = resourceReference(R.string.tangem_pay_status_pending),
|
|
||||||
style = LabelStyle.REGULAR,
|
|
||||||
icon = R.drawable.ic_clock_24,
|
|
||||||
),
|
|
||||||
notification = null,
|
|
||||||
buttons = persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_dispute),
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dismiss = {},
|
|
||||||
),
|
|
||||||
TangemPayTxHistoryDetailsUM(
|
|
||||||
isBalanceHidden = true,
|
|
||||||
title = stringReference("12 June • 12:40"),
|
|
||||||
iconState = ImageReference.Res(R.drawable.ic_category_24),
|
|
||||||
transactionTitle = stringReference("Starbucks"),
|
|
||||||
transactionSubtitle = stringReference("Food and drinks"),
|
|
||||||
transactionAmount = "-$5.86",
|
|
||||||
transactionAmountColor = themedColor { TangemTheme.colors.text.warning },
|
|
||||||
localTransactionText = null,
|
|
||||||
labelState = LabelUM(
|
|
||||||
text = resourceReference(R.string.tangem_pay_status_declined),
|
|
||||||
style = LabelStyle.WARNING,
|
|
||||||
),
|
|
||||||
notification = TangemPayTxHistoryDetailsUM.NotificationState(
|
|
||||||
config = NotificationConfig(
|
|
||||||
title = stringReference("The bank rejected this transaction request."),
|
|
||||||
subtitle = TextReference.EMPTY,
|
|
||||||
iconResId = R.drawable.ic_token_info_24,
|
|
||||||
),
|
|
||||||
titleColor = themedColor { TangemTheme.colors.text.warning },
|
|
||||||
iconTint = themedColor { TangemTheme.colors.icon.warning },
|
|
||||||
containerColor = themedColor { TangemColorPalette.Amaranth.copy(alpha = 0.1F) },
|
|
||||||
),
|
|
||||||
buttons = persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_dispute),
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dismiss = {},
|
|
||||||
),
|
|
||||||
TangemPayTxHistoryDetailsUM(
|
|
||||||
isBalanceHidden = true,
|
|
||||||
title = stringReference("12 June • 12:40"),
|
|
||||||
iconState = ImageReference.Res(R.drawable.ic_category_24),
|
|
||||||
transactionTitle = stringReference("Starbucks"),
|
|
||||||
transactionSubtitle = stringReference("Food and drinks Food and drinks Food and drinks Food and drinks"),
|
|
||||||
transactionAmount = "-$5.86",
|
|
||||||
transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 },
|
|
||||||
localTransactionText = "€ 5.36",
|
|
||||||
labelState = LabelUM(
|
|
||||||
text = resourceReference(R.string.tangem_pay_status_completed),
|
|
||||||
style = LabelStyle.ACCENT,
|
|
||||||
),
|
|
||||||
notification = null,
|
|
||||||
buttons = persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_dispute),
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dismiss = {},
|
|
||||||
),
|
|
||||||
TangemPayTxHistoryDetailsUM(
|
|
||||||
isBalanceHidden = false,
|
|
||||||
title = stringReference("12 June • 12:40"),
|
|
||||||
iconState = ImageReference.Res(R.drawable.ic_percent_24),
|
|
||||||
transactionTitle = stringReference("Fee"),
|
|
||||||
transactionSubtitle = stringReference("Service fee"),
|
|
||||||
transactionAmount = "-$5.86",
|
|
||||||
transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 },
|
|
||||||
localTransactionText = null,
|
|
||||||
labelState = null,
|
|
||||||
notification = TangemPayTxHistoryDetailsUM.NotificationState(
|
|
||||||
config = NotificationConfig(
|
|
||||||
title = stringReference("This fee goes to cover the cost of handling your transfer."),
|
|
||||||
subtitle = TextReference.EMPTY,
|
|
||||||
iconResId = R.drawable.ic_token_info_24,
|
|
||||||
),
|
|
||||||
titleColor = themedColor { TangemTheme.colors.text.tertiary },
|
|
||||||
iconTint = themedColor { TangemTheme.colors.icon.secondary },
|
|
||||||
containerColor = null,
|
|
||||||
),
|
|
||||||
buttons = persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_dispute),
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dismiss = {},
|
|
||||||
),
|
|
||||||
TangemPayTxHistoryDetailsUM(
|
|
||||||
isBalanceHidden = false,
|
|
||||||
title = stringReference("12 June • 12:40"),
|
|
||||||
iconState = ImageReference.Res(R.drawable.ic_arrow_down_24),
|
|
||||||
transactionTitle = stringReference("Deposit"),
|
|
||||||
transactionSubtitle = stringReference("Transfers"),
|
|
||||||
transactionAmount = "+$20",
|
|
||||||
transactionAmountColor = themedColor { TangemTheme.colors.text.accent },
|
|
||||||
localTransactionText = null,
|
|
||||||
labelState = null,
|
|
||||||
notification = null,
|
|
||||||
buttons = persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_get_help),
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dismiss = {},
|
|
||||||
),
|
|
||||||
TangemPayTxHistoryDetailsUM(
|
|
||||||
isBalanceHidden = false,
|
|
||||||
title = stringReference("12 June • 12:40"),
|
|
||||||
iconState = ImageReference.Res(R.drawable.ic_arrow_up_24),
|
|
||||||
transactionTitle = stringReference("Withdrawal"),
|
|
||||||
transactionSubtitle = stringReference("Transfers"),
|
|
||||||
transactionAmount = "-$5.86",
|
|
||||||
transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 },
|
|
||||||
localTransactionText = null,
|
|
||||||
labelState = null,
|
|
||||||
notification = null,
|
|
||||||
buttons = persistentListOf(
|
|
||||||
ButtonState(
|
|
||||||
text = resourceReference(R.string.tangem_pay_get_help),
|
|
||||||
onClick = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dismiss = {},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
@ -60,29 +60,20 @@ internal object TangemPayMessagesFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createFreezeCardMessage(isRedesignEnabled: Boolean, onFreezeClicked: () -> Unit): BottomSheetMessage {
|
fun createFreezeCardMessage(onFreezeClicked: () -> Unit): BottomSheetMessage {
|
||||||
return bottomSheetMessage {
|
return bottomSheetMessage {
|
||||||
infoBlock {
|
infoBlock {
|
||||||
if (isRedesignEnabled) {
|
vector(Icons.ic_snowflake_20) {
|
||||||
vector(Icons.ic_snowflake_20) {
|
type = MessageBottomSheetUM.Vector.Type.Informative
|
||||||
type = MessageBottomSheetUM.Vector.Type.Informative
|
backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Informative
|
||||||
backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Informative
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
icon(R.drawable.ic_snow_24) {
|
|
||||||
type = MessageBottomSheetUM.Icon.Type.Accent
|
|
||||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.Accent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
title = TextReference.Res(R.string.tangem_pay_freeze_card_alert_title)
|
title = TextReference.Res(R.string.tangem_pay_freeze_card_alert_title)
|
||||||
body = TextReference.Res(R.string.tangem_pay_freeze_card_alert_body)
|
body = TextReference.Res(R.string.tangem_pay_freeze_card_alert_body)
|
||||||
}
|
}
|
||||||
if (isRedesignEnabled) {
|
secondaryButton {
|
||||||
secondaryButton {
|
text = resourceReference(R.string.common_cancel)
|
||||||
text = resourceReference(R.string.common_cancel)
|
onClick {
|
||||||
onClick {
|
closeBs()
|
||||||
closeBs()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
primaryButton {
|
primaryButton {
|
||||||
|
|
@ -95,29 +86,20 @@ internal object TangemPayMessagesFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createUnfreezeCardMessage(isRedesignEnabled: Boolean, onUnfreezeClicked: () -> Unit): BottomSheetMessage {
|
fun createUnfreezeCardMessage(onUnfreezeClicked: () -> Unit): BottomSheetMessage {
|
||||||
return bottomSheetMessage {
|
return bottomSheetMessage {
|
||||||
infoBlock {
|
infoBlock {
|
||||||
if (isRedesignEnabled) {
|
vector(Icons.ic_sun_20) {
|
||||||
vector(Icons.ic_sun_20) {
|
type = MessageBottomSheetUM.Vector.Type.Attention
|
||||||
type = MessageBottomSheetUM.Vector.Type.Attention
|
backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Attention
|
||||||
backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Attention
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
icon(R.drawable.ic_snow_24) {
|
|
||||||
type = MessageBottomSheetUM.Icon.Type.Accent
|
|
||||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.Accent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
title = TextReference.Res(R.string.tangem_pay_unfreeze_card_alert_title)
|
title = TextReference.Res(R.string.tangem_pay_unfreeze_card_alert_title)
|
||||||
body = TextReference.Res(R.string.tangem_pay_unfreeze_card_alert_body)
|
body = TextReference.Res(R.string.tangem_pay_unfreeze_card_alert_body)
|
||||||
}
|
}
|
||||||
if (isRedesignEnabled) {
|
secondaryButton {
|
||||||
secondaryButton {
|
text = resourceReference(R.string.common_cancel)
|
||||||
text = resourceReference(R.string.common_cancel)
|
onClick {
|
||||||
onClick {
|
closeBs()
|
||||||
closeBs()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
primaryButton {
|
primaryButton {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ internal class TangemPayDetailsStateFactoryTest {
|
||||||
onBack = {},
|
onBack = {},
|
||||||
onOpenMenu = {},
|
onOpenMenu = {},
|
||||||
intents = intents,
|
intents = intents,
|
||||||
isRedesignEnabled = true,
|
|
||||||
isRemoveAccountEnabled = true,
|
isRemoveAccountEnabled = true,
|
||||||
isTiersPlusPlanEnabled = true,
|
isTiersPlusPlanEnabled = true,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||||
import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase
|
import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase
|
||||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
|
@ -36,7 +35,6 @@ internal class TangemPayCardLimitSetupModelTest {
|
||||||
private val setLimitUseCase: SetTangemPayCardLimitUseCase = mockk(relaxed = true)
|
private val setLimitUseCase: SetTangemPayCardLimitUseCase = mockk(relaxed = true)
|
||||||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier = mockk()
|
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier = mockk()
|
||||||
private val analytics: AnalyticsEventHandler = mockk(relaxed = true)
|
private val analytics: AnalyticsEventHandler = mockk(relaxed = true)
|
||||||
private val featureToggles: TangemPayFeatureToggles = mockk()
|
|
||||||
|
|
||||||
private val initialCard = TangemPayCard(
|
private val initialCard = TangemPayCard(
|
||||||
id = cardId,
|
id = cardId,
|
||||||
|
|
@ -98,7 +96,6 @@ internal class TangemPayCardLimitSetupModelTest {
|
||||||
setTangemPayCardLimitUseCase = setLimitUseCase,
|
setTangemPayCardLimitUseCase = setLimitUseCase,
|
||||||
uiMessageSender = uiMessageSender,
|
uiMessageSender = uiMessageSender,
|
||||||
analytics = analytics,
|
analytics = analytics,
|
||||||
featureToggles = featureToggles,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import com.tangem.domain.models.pay.TangemPayCardState
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||||
import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase
|
import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase
|
||||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|
||||||
import com.tangem.features.tangempay.components.TangemPayEditDisplayNameComponent
|
import com.tangem.features.tangempay.components.TangemPayEditDisplayNameComponent
|
||||||
import com.tangem.features.tangempay.model.controller.TangemPayCardDetailsController
|
import com.tangem.features.tangempay.model.controller.TangemPayCardDetailsController
|
||||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||||
|
|
@ -36,7 +35,6 @@ internal class TangemPayEditDisplayNameModelTest {
|
||||||
private val updateCardNameUseCase: UpdateTangemPayCardNameUseCase = mockk()
|
private val updateCardNameUseCase: UpdateTangemPayCardNameUseCase = mockk()
|
||||||
private val uiMessageSender: UiMessageSender = mockk(relaxed = true)
|
private val uiMessageSender: UiMessageSender = mockk(relaxed = true)
|
||||||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier = mockk()
|
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier = mockk()
|
||||||
private val featureToggles: TangemPayFeatureToggles = mockk(relaxed = true)
|
|
||||||
private val cardDetailsControllerFactory: TangemPayCardDetailsController.Factory = mockk(relaxed = true)
|
private val cardDetailsControllerFactory: TangemPayCardDetailsController.Factory = mockk(relaxed = true)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
@ -55,7 +53,6 @@ internal class TangemPayEditDisplayNameModelTest {
|
||||||
updateCardNameUseCase = updateCardNameUseCase,
|
updateCardNameUseCase = updateCardNameUseCase,
|
||||||
uiMessageSender = uiMessageSender,
|
uiMessageSender = uiMessageSender,
|
||||||
paymentAccountStatusSupplier = paymentAccountStatusSupplier,
|
paymentAccountStatusSupplier = paymentAccountStatusSupplier,
|
||||||
featureToggles = featureToggles,
|
|
||||||
cardDetailsControllerFactory = cardDetailsControllerFactory,
|
cardDetailsControllerFactory = cardDetailsControllerFactory,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ internal class TangemPayTxHistoryDetailsModelTest {
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertThat(model.uiState.value.redesign.detail).isEqualTo(TransactionDetailUM.Loading)
|
assertThat(model.uiState.value.detail).isEqualTo(TransactionDetailUM.Loading)
|
||||||
model.onDestroy()
|
model.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ internal class TangemPayTxHistoryDetailsModelTest {
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertThat(model.uiState.value.redesign.detail)
|
assertThat(model.uiState.value.detail)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
TransactionDetailUM.Content(
|
TransactionDetailUM.Content(
|
||||||
cardNumber = stringReference("*4321"),
|
cardNumber = stringReference("*4321"),
|
||||||
|
|
@ -106,7 +106,7 @@ internal class TangemPayTxHistoryDetailsModelTest {
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertThat(model.uiState.value.redesign.detail).isNull()
|
assertThat(model.uiState.value.detail).isNull()
|
||||||
model.onDestroy()
|
model.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ internal class TangemPayTxHistoryDetailsModelTest {
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertThat(model.uiState.value.redesign.detail).isInstanceOf(TransactionDetailUM.Error::class.java)
|
assertThat(model.uiState.value.detail).isInstanceOf(TransactionDetailUM.Error::class.java)
|
||||||
model.onDestroy()
|
model.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,7 +136,7 @@ internal class TangemPayTxHistoryDetailsModelTest {
|
||||||
)
|
)
|
||||||
val model = createModel(testScope = this, transaction = spendTransaction())
|
val model = createModel(testScope = this, transaction = spendTransaction())
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
val errorState = model.uiState.value.redesign.detail
|
val errorState = model.uiState.value.detail
|
||||||
assertThat(errorState).isInstanceOf(TransactionDetailUM.Error::class.java)
|
assertThat(errorState).isInstanceOf(TransactionDetailUM.Error::class.java)
|
||||||
|
|
||||||
// Act — tap refresh
|
// Act — tap refresh
|
||||||
|
|
@ -144,7 +144,7 @@ internal class TangemPayTxHistoryDetailsModelTest {
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertThat(model.uiState.value.redesign.detail)
|
assertThat(model.uiState.value.detail)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
TransactionDetailUM.Content(
|
TransactionDetailUM.Content(
|
||||||
cardNumber = stringReference("*4321"),
|
cardNumber = stringReference("*4321"),
|
||||||
|
|
@ -164,7 +164,7 @@ internal class TangemPayTxHistoryDetailsModelTest {
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertThat(model.uiState.value.redesign.detail).isNull()
|
assertThat(model.uiState.value.detail).isNull()
|
||||||
coVerify(exactly = 0) { repository.getTransaction(any(), any()) }
|
coVerify(exactly = 0) { repository.getTransaction(any(), any()) }
|
||||||
model.onDestroy()
|
model.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue