Updated on 2026-08-14
This commit is contained in:
parent
3b1e642150
commit
27820ec8ad
24 changed files with 356 additions and 142 deletions
|
|
@ -1690,6 +1690,7 @@
|
|||
<string name="tangempay_card_details_withdraw_error_title">Withdraw unavailable now</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">You can\'t initiate swap or new withdrawal till the current one is finished</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">Withdrawal in progress</string>
|
||||
<string name="tangempay_card_edit_name_placeholder">Card name</string>
|
||||
<string name="tangempay_card_limit_setup_amount_subtitle">Set a limit from %s</string>
|
||||
<string name="tangempay_card_limit_setup_error_message">We couldn’t set the limit. Please try again</string>
|
||||
<string name="tangempay_card_page_daily_limit_change">Change</string>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import com.tangem.domain.pay.repository.*
|
|||
import com.tangem.domain.pay.usecase.GetPaymentAccountCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
|
||||
import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase
|
||||
import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase
|
||||
import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase
|
||||
import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
|
||||
|
|
@ -148,6 +149,14 @@ internal interface TangemPayDataModule {
|
|||
return SetTangemPayCardLimitUseCase(cardDetailsRepository, paymentAccountStatusFetcher)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideUpdateTangemPayCardNameUseCase(
|
||||
cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||
paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
): UpdateTangemPayCardNameUseCase {
|
||||
return UpdateTangemPayCardNameUseCase(cardDetailsRepository, paymentAccountStatusFetcher)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetTangemPayCryptoCurrencyStatusUseCase(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
package com.tangem.domain.pay.flow
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.core.flow.FlowFetcher
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface PaymentAccountStatusFetcher : FlowFetcher<PaymentAccountStatusFetcher.Params> {
|
||||
|
||||
suspend operator fun invoke(userWalletId: UserWalletId): Either<Throwable, Unit> {
|
||||
return invoke(Params(userWalletId))
|
||||
}
|
||||
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -17,9 +17,6 @@ class SetTangemPayCardLimitUseCase(
|
|||
amount: BigDecimal,
|
||||
): Either<UniversalError, Unit> {
|
||||
return cardDetailsRepository.updateCardLimit(cardId, userWalletId, amount.toPlainString())
|
||||
.onRight {
|
||||
val params = PaymentAccountStatusFetcher.Params(userWalletId)
|
||||
paymentAccountStatusFetcher.invoke(params)
|
||||
}
|
||||
.onRight { paymentAccountStatusFetcher.invoke(userWalletId) }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.domain.pay.usecase
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
|
||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||
|
||||
class UpdateTangemPayCardNameUseCase(
|
||||
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
) {
|
||||
suspend operator fun invoke(
|
||||
cardId: String,
|
||||
userWalletId: UserWalletId,
|
||||
displayName: CardDisplayName,
|
||||
): Either<UniversalError, Unit> {
|
||||
return cardDetailsRepository.updateCardDisplayName(cardId, userWalletId, displayName)
|
||||
.onRight { paymentAccountStatusFetcher(userWalletId) }
|
||||
}
|
||||
}
|
||||
|
|
@ -69,6 +69,10 @@ internal class DefaultTangemPayDetailsContainerComponent @AssistedInject constru
|
|||
context = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
params = TangemPayCardPageComponent.Params(userWalletId = params.userWalletId, config = params.config),
|
||||
)
|
||||
TangemPayAccountDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent(
|
||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
params = params,
|
||||
)
|
||||
}
|
||||
|
||||
private fun onChildBack() {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ internal class TangemPayAddToWalletComponent(
|
|||
appComponentContext = child("cardDetailsBlockComponent"),
|
||||
params = TangemPayCardDetailsBlockComponent.Params(
|
||||
params = params,
|
||||
isDisplayCardNameEnabled = false,
|
||||
isEditingNameEnabled = false,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ internal class TangemPayCardPageScreenComponent(
|
|||
appComponentContext = child("cardDetailsBlockComponent"),
|
||||
params = TangemPayCardDetailsBlockComponent.Params(
|
||||
params = containerParams,
|
||||
isDisplayCardNameEnabled = true,
|
||||
isEditingNameEnabled = true,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ internal class TangemPayEditDisplayNameComponent(
|
|||
|
||||
private val cardDetailsBlockComponent = DefaultTangemPayCardDetailsBlockComponent(
|
||||
appComponentContext = child("editDisplayNameCardDetails"),
|
||||
params = TangemPayCardDetailsBlockComponent.Params(params = params, isDisplayCardNameEnabled = true),
|
||||
params = TangemPayCardDetailsBlockComponent.Params(params = params, isEditingNameEnabled = false),
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
@ -33,7 +33,7 @@ internal class TangemPayEditDisplayNameComponent(
|
|||
val cardDetailsState by cardDetailsBlockComponent.state.collectAsStateWithLifecycle()
|
||||
val editingCardDetailsState = cardDetailsState.copy(
|
||||
displayNameState = DisplayNameState.Editing(
|
||||
displayName = state.editingValue,
|
||||
displayName = state.editingValue.text,
|
||||
editingValue = state.editingValue,
|
||||
onValueChanged = state.onValueChanged,
|
||||
onSubmit = state.onDoneClick,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ internal interface TangemPayCardDetailsBlockComponent {
|
|||
|
||||
data class Params(
|
||||
val params: TangemPayDetailsContainerComponent.Params,
|
||||
val isDisplayCardNameEnabled: Boolean,
|
||||
val isEditingNameEnabled: Boolean,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.tangempay.entity
|
||||
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import com.tangem.domain.visa.model.TangemPayCardFrozenState
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.model.CardDataType
|
||||
|
|
@ -8,21 +9,33 @@ import com.tangem.utils.StringsSigns
|
|||
|
||||
internal class TangemPayCardDetailsBlockStateFactory(
|
||||
private val cardNumberEnd: String,
|
||||
private val displayNameState: DisplayNameState?,
|
||||
private val displayName: CardDisplayName?,
|
||||
private val isEditingNameEnabled: Boolean,
|
||||
private val onEditNameClick: () -> Unit,
|
||||
private val onReveal: () -> Unit,
|
||||
private val onCopy: (String, CardDataType) -> Unit,
|
||||
) {
|
||||
|
||||
fun getInitialState() = TangemPayCardDetailsUM(
|
||||
number = "",
|
||||
numberShort = "${StringsSigns.ASTERISK}$cardNumberEnd",
|
||||
expiry = "",
|
||||
cvv = "",
|
||||
buttonText = resourceReference(R.string.tangempay_card_details_reveal_text),
|
||||
onClick = onReveal,
|
||||
onCopy = onCopy,
|
||||
isHidden = true,
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
displayNameState = displayNameState,
|
||||
)
|
||||
fun getInitialState(): TangemPayCardDetailsUM {
|
||||
return TangemPayCardDetailsUM(
|
||||
number = "",
|
||||
numberShort = "${StringsSigns.ASTERISK}$cardNumberEnd",
|
||||
expiry = "",
|
||||
cvv = "",
|
||||
buttonText = resourceReference(R.string.tangempay_card_details_reveal_text),
|
||||
onClick = onReveal,
|
||||
onCopy = onCopy,
|
||||
isHidden = true,
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
displayNameState = if (displayName != null) {
|
||||
DisplayNameState.Display(
|
||||
displayName = displayName.value,
|
||||
onClick = onEditNameClick,
|
||||
isEditingEnabled = isEditingNameEnabled,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -59,6 +59,7 @@ internal class TangemPayDetailsStateFactory(
|
|||
),
|
||||
isBalanceHidden = false,
|
||||
addFundsEnabled = true,
|
||||
addToWalletBlockState = null,
|
||||
accountDeactivatedNotificationConfig = NotificationConfig(
|
||||
title = resourceReference(R.string.tangempay_account_deactivated_message_title),
|
||||
subtitle = resourceReference(R.string.tangempay_account_deactivated_message_subtitle),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.tangempay.entity
|
||||
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
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
|
||||
|
|
@ -12,6 +13,7 @@ internal data class TangemPayDetailsUM(
|
|||
val topBarConfig: TangemPayDetailsTopBarConfig,
|
||||
val pullToRefreshConfig: PullToRefreshConfig,
|
||||
val balanceBlockState: TangemPayDetailsBalanceBlockState,
|
||||
val addToWalletBlockState: AddToWalletBlockState?,
|
||||
val isBalanceHidden: Boolean,
|
||||
val addFundsEnabled: Boolean,
|
||||
val accountDeactivatedNotificationConfig: NotificationConfig?,
|
||||
|
|
@ -39,15 +41,23 @@ internal sealed interface DisplayNameState {
|
|||
data class Display(
|
||||
override val displayName: String,
|
||||
val onClick: () -> Unit,
|
||||
val isEditingEnabled: Boolean,
|
||||
) : DisplayNameState
|
||||
|
||||
data class Editing(
|
||||
override val displayName: String,
|
||||
val editingValue: String,
|
||||
val onValueChanged: (String) -> Unit,
|
||||
val editingValue: TextFieldValue,
|
||||
val onValueChanged: (TextFieldValue) -> Unit,
|
||||
val onSubmit: () -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
) : DisplayNameState
|
||||
|
||||
fun copySealed(displayName: String): DisplayNameState {
|
||||
return when (this) {
|
||||
is Display -> copy(displayName = displayName)
|
||||
is Editing -> copy(displayName = displayName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class TangemPayDetailsBalanceBlockState {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package com.tangem.features.tangempay.entity
|
||||
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
|
||||
internal data class TangemPayEditDisplayNameUM(
|
||||
val editingValue: String,
|
||||
val editingValue: TextFieldValue,
|
||||
val isLoading: Boolean,
|
||||
val onValueChanged: (String) -> Unit,
|
||||
val onValueChanged: (TextFieldValue) -> Unit,
|
||||
val onDoneClick: () -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
|
|
@ -10,11 +10,16 @@ import com.tangem.core.decompose.ui.UiMessageSender
|
|||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.account.hasCardWithId
|
||||
import com.tangem.domain.models.account.requireCardWithId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.DisplayNameState
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsBlockStateFactory
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||
import com.tangem.features.tangempay.model.listener.CardDetailsEvent
|
||||
|
|
@ -22,10 +27,12 @@ import com.tangem.features.tangempay.model.listener.CardDetailsEventListener
|
|||
import com.tangem.features.tangempay.model.transformers.DetailsHiddenStateTransformer
|
||||
import com.tangem.features.tangempay.model.transformers.DetailsRevealProgressStateTransformer
|
||||
import com.tangem.features.tangempay.model.transformers.DetailsRevealedStateTransformer
|
||||
import com.tangem.features.tangempay.model.transformers.TangemPayCardDetailsUpdateNameTransformer
|
||||
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -46,20 +53,16 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor(
|
|||
private val cardDetailsEventListener: CardDetailsEventListener,
|
||||
private val analytics: AnalyticsEventHandler,
|
||||
private val router: Router,
|
||||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||
) : Model() {
|
||||
|
||||
private val params: TangemPayCardDetailsBlockComponent.Params = paramsContainer.require()
|
||||
|
||||
private val stateFactory = TangemPayCardDetailsBlockStateFactory(
|
||||
cardNumberEnd = params.params.config.cardNumberEnd,
|
||||
displayNameState = if (params.isDisplayCardNameEnabled && params.params.config.displayName != null) {
|
||||
DisplayNameState.Display(
|
||||
displayName = requireNotNull(params.params.config.displayName).value,
|
||||
onClick = ::startEditingDisplayName,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
displayName = params.params.config.displayName,
|
||||
isEditingNameEnabled = params.isEditingNameEnabled,
|
||||
onEditNameClick = ::startEditingDisplayName,
|
||||
onReveal = ::revealCardDetails,
|
||||
onCopy = ::copyData,
|
||||
)
|
||||
|
|
@ -71,6 +74,7 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor(
|
|||
private val showCardDetailsTimerJobHolder = JobHolder()
|
||||
|
||||
init {
|
||||
subscribeToCardNameChanges(cardId = params.params.config.cardId, userWalletId = params.params.userWalletId)
|
||||
subscribeToCardFrozenState()
|
||||
modelScope.launch {
|
||||
cardDetailsEventListener.event.collectLatest { event ->
|
||||
|
|
@ -82,6 +86,23 @@ internal class TangemPayCardDetailsBlockModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun subscribeToCardNameChanges(cardId: String, userWalletId: UserWalletId) {
|
||||
paymentAccountStatusSupplier.invoke(userWalletId)
|
||||
.onEach { state ->
|
||||
val status = state.value
|
||||
if (status is PaymentAccountStatusValue.Loaded &&
|
||||
status.source == StatusSource.ACTUAL &&
|
||||
status.hasCardWithId(cardId)
|
||||
) {
|
||||
val card = status.requireCardWithId(cardId)
|
||||
val displayName = card.displayName ?: return@onEach
|
||||
|
||||
uiState.update(TangemPayCardDetailsUpdateNameTransformer(displayName))
|
||||
}
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun subscribeToCardFrozenState() {
|
||||
cardDetailsRepository
|
||||
.cardFrozenState(params.params.config.cardId)
|
||||
|
|
|
|||
|
|
@ -39,10 +39,7 @@ import com.tangem.features.tangempay.entity.TangemPayDetailsStateFactory
|
|||
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
|
||||
import com.tangem.features.tangempay.model.listener.CardDetailsEvent
|
||||
import com.tangem.features.tangempay.model.listener.CardDetailsEventListener
|
||||
import com.tangem.features.tangempay.model.transformers.DetailBalanceVisibilityTransformer
|
||||
import com.tangem.features.tangempay.model.transformers.DetailsBalanceTransformer
|
||||
import com.tangem.features.tangempay.model.transformers.TangemPayDetailsRefreshTransformer
|
||||
import com.tangem.features.tangempay.model.transformers.TangemPayFreezeUnfreezeStateTransformer
|
||||
import com.tangem.features.tangempay.model.transformers.*
|
||||
import com.tangem.features.tangempay.navigation.TangemPayAccountDetailsInnerRoute
|
||||
import com.tangem.features.tangempay.utils.TangemPayDetailIntents
|
||||
import com.tangem.features.tangempay.utils.TangemPayMessagesFactory
|
||||
|
|
@ -56,7 +53,10 @@ import com.tangem.utils.coroutines.saveIn
|
|||
import com.tangem.utils.logging.TangemLogger
|
||||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -100,6 +100,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
|
||||
private val refreshStateJobHolder = JobHolder()
|
||||
private val fetchBalanceJobHolder = JobHolder()
|
||||
private val addToWalletBannerJobHolder = JobHolder()
|
||||
|
||||
private var balance: TangemPayCardBalance? = null
|
||||
|
||||
|
|
@ -116,6 +117,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
fetchBalance()
|
||||
if (!params.config.isTangemPayDeactivated) {
|
||||
subscribeToCardFrozenState()
|
||||
fetchAddToWalletBanner()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,6 +233,24 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
}.saveIn(fetchBalanceJobHolder)
|
||||
}
|
||||
|
||||
private fun fetchAddToWalletBanner() {
|
||||
modelScope.launch {
|
||||
val isDone = try {
|
||||
cardDetailsRepository.isAddToWalletDone(params.userWalletId).getOrNull() == true
|
||||
} catch (e: Exception) {
|
||||
TangemLogger.e("Error", e)
|
||||
return@launch
|
||||
}
|
||||
uiState.update(
|
||||
transformer = DetailsAddToWalletBannerTransformer(
|
||||
onClickBanner = ::onClickAddToWalletBlock,
|
||||
onClickCloseBanner = ::onClickCloseAddToWalletBlock,
|
||||
isDone = isDone,
|
||||
),
|
||||
)
|
||||
}.saveIn(addToWalletBannerJobHolder)
|
||||
}
|
||||
|
||||
private fun handleBalanceHiding() {
|
||||
getBalanceHidingSettingsUseCase().onEach {
|
||||
uiState.update(DetailBalanceVisibilityTransformer(isHidden = it.isBalanceHidden))
|
||||
|
|
@ -260,6 +280,28 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
}.saveIn(refreshStateJobHolder)
|
||||
}
|
||||
|
||||
private fun onClickAddToWalletBlock() {
|
||||
analytics.send(TangemPayAnalyticsEvents.AddToWalletClicked())
|
||||
router.push(TangemPayAccountDetailsInnerRoute.AddToWallet)
|
||||
}
|
||||
|
||||
private fun onClickCloseAddToWalletBlock() {
|
||||
modelScope.launch {
|
||||
try {
|
||||
cardDetailsRepository.setAddToWalletAsDone(params.userWalletId)
|
||||
} catch (e: Exception) {
|
||||
TangemLogger.e("Error", e)
|
||||
}
|
||||
uiState.update(
|
||||
transformer = DetailsAddToWalletBannerTransformer(
|
||||
onClickBanner = ::onClickAddToWalletBlock,
|
||||
onClickCloseBanner = ::onClickCloseAddToWalletBlock,
|
||||
isDone = true,
|
||||
),
|
||||
)
|
||||
}.saveIn(addToWalletBannerJobHolder)
|
||||
}
|
||||
|
||||
private fun onOpenMenu() {
|
||||
analytics.send(TangemPayAnalyticsEvents.CardSettingsClicked())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.features.tangempay.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
|
|
@ -8,15 +10,19 @@ import com.tangem.core.decompose.navigation.Router
|
|||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.account.hasCardWithId
|
||||
import com.tangem.domain.models.account.requireCardWithId
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase
|
||||
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.TangemPayEditDisplayNameUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -26,8 +32,9 @@ internal class TangemPayEditDisplayNameModel @Inject constructor(
|
|||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||
private val updateCardNameUseCase: UpdateTangemPayCardNameUseCase,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||
) : Model() {
|
||||
|
||||
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
|
||||
|
|
@ -37,7 +44,10 @@ internal class TangemPayEditDisplayNameModel @Inject constructor(
|
|||
val uiState: StateFlow<TangemPayEditDisplayNameUM>
|
||||
field = MutableStateFlow(
|
||||
TangemPayEditDisplayNameUM(
|
||||
editingValue = originalDisplayName,
|
||||
editingValue = TextFieldValue(
|
||||
text = originalDisplayName,
|
||||
selection = TextRange(originalDisplayName.length),
|
||||
),
|
||||
isLoading = false,
|
||||
onValueChanged = ::onValueChanged,
|
||||
onDoneClick = ::onDoneClick,
|
||||
|
|
@ -45,23 +55,51 @@ internal class TangemPayEditDisplayNameModel @Inject constructor(
|
|||
),
|
||||
)
|
||||
|
||||
private fun onValueChanged(value: String) {
|
||||
if (value.length <= CardDisplayName.MAX_LENGTH) {
|
||||
init {
|
||||
subscribeToCardNameChanges(params.config.cardId, params.userWalletId)
|
||||
}
|
||||
|
||||
private fun subscribeToCardNameChanges(cardId: String, userWalletId: UserWalletId) {
|
||||
paymentAccountStatusSupplier.invoke(userWalletId)
|
||||
.onEach { state ->
|
||||
val status = state.value
|
||||
if (status is PaymentAccountStatusValue.Loaded &&
|
||||
status.source == StatusSource.ACTUAL &&
|
||||
status.hasCardWithId(cardId)
|
||||
) {
|
||||
val card = status.requireCardWithId(cardId)
|
||||
val displayName = card.displayName ?: return@onEach
|
||||
|
||||
uiState.update { uiState ->
|
||||
uiState.copy(
|
||||
editingValue = TextFieldValue(
|
||||
text = displayName.value,
|
||||
selection = TextRange(displayName.value.length),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun onValueChanged(value: TextFieldValue) {
|
||||
if (value.text.length <= CardDisplayName.MAX_LENGTH) {
|
||||
uiState.update { it.copy(editingValue = value) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun onDoneClick() {
|
||||
val currentValue = uiState.value.editingValue
|
||||
val currentValue = uiState.value.editingValue.text
|
||||
if (currentValue.trim() == originalDisplayName.trim()) {
|
||||
router.pop()
|
||||
return
|
||||
}
|
||||
CardDisplayName(currentValue)
|
||||
.onRight { cardDisplayName ->
|
||||
uiState.update { it.copy(isLoading = true) }
|
||||
modelScope.launch {
|
||||
cardDetailsRepository.updateCardDisplayName(
|
||||
uiState.update { it.copy(isLoading = true) }
|
||||
updateCardNameUseCase(
|
||||
cardId = params.config.cardId,
|
||||
userWalletId = params.userWalletId,
|
||||
displayName = cardDisplayName,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.features.tangempay.model.transformers
|
||||
|
||||
import com.tangem.features.tangempay.entity.AddToWalletBlockState
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class DetailsAddToWalletBannerTransformer(
|
||||
private val onClickBanner: () -> Unit,
|
||||
private val onClickCloseBanner: () -> Unit,
|
||||
private val isDone: Boolean,
|
||||
) : Transformer<TangemPayDetailsUM> {
|
||||
|
||||
override fun transform(prevState: TangemPayDetailsUM): TangemPayDetailsUM {
|
||||
return prevState.copy(
|
||||
addToWalletBlockState = if (isDone) {
|
||||
null
|
||||
} else {
|
||||
AddToWalletBlockState(onClick = onClickBanner, onClickClose = onClickCloseBanner)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.features.tangempay.model.transformers
|
||||
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class TangemPayCardDetailsUpdateNameTransformer(
|
||||
private val displayName: CardDisplayName,
|
||||
) : Transformer<TangemPayCardDetailsUM> {
|
||||
|
||||
override fun transform(prevState: TangemPayCardDetailsUM): TangemPayCardDetailsUM {
|
||||
val displayNameState = prevState.displayNameState ?: return prevState
|
||||
return prevState.copy(displayNameState = displayNameState.copySealed(displayName = displayName.value))
|
||||
}
|
||||
}
|
||||
|
|
@ -10,4 +10,7 @@ internal sealed class TangemPayAccountDetailsInnerRoute : Route {
|
|||
|
||||
@Serializable
|
||||
data object CardDetails : TangemPayAccountDetailsInnerRoute()
|
||||
|
||||
@Serializable
|
||||
data object AddToWallet : TangemPayAccountDetailsInnerRoute()
|
||||
}
|
||||
|
|
@ -1,24 +1,22 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.EaseInOut
|
||||
import androidx.compose.animation.core.MutableTransitionState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -46,6 +44,7 @@ import com.tangem.core.ui.components.SpacerWMax
|
|||
import com.tangem.core.ui.components.buttons.common.TangemButton
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
|
||||
import com.tangem.core.ui.extensions.conditional
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
|
@ -58,7 +57,7 @@ import com.tangem.features.tangempay.entity.DisplayNameState
|
|||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||
import com.tangem.features.tangempay.model.CardDataType
|
||||
|
||||
private const val ICON_FADE_DURATION_MS = 300
|
||||
private const val TEXT_WIDTH_PADDING = 2
|
||||
private val CustomCardBlockColor = Color(0x1F828282)
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
|
|
@ -228,80 +227,55 @@ private fun TangemPayCardDetailsHiddenBlock(state: TangemPayCardDetailsUM, modif
|
|||
|
||||
@Composable
|
||||
private fun CardDisplayName(state: DisplayNameState, modifier: Modifier = Modifier) {
|
||||
val isDisplayMode = state is DisplayNameState.Display
|
||||
|
||||
Row(
|
||||
modifier = modifier.then(
|
||||
if (state is DisplayNameState.Display) {
|
||||
Modifier.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = state.onClick,
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
},
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
when (state) {
|
||||
is DisplayNameState.Display -> DisplayOnlyCardDisplayName(state = state)
|
||||
is DisplayNameState.Editing -> EditingCardDisplayName(state = state)
|
||||
}
|
||||
val iconVisibleState = remember {
|
||||
MutableTransitionState(initialState = !isDisplayMode).apply {
|
||||
targetState = isDisplayMode
|
||||
}
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visibleState = iconVisibleState,
|
||||
enter = fadeIn(animationSpec = tween(durationMillis = ICON_FADE_DURATION_MS)),
|
||||
exit = fadeOut(animationSpec = tween(durationMillis = ICON_FADE_DURATION_MS)),
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
Icon(
|
||||
painter = painterResource(id = com.tangem.core.ui.R.drawable.ic_edit_new_12),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(10.dp),
|
||||
tint = TangemTheme.colors.text.constantWhite,
|
||||
)
|
||||
}
|
||||
}
|
||||
when (state) {
|
||||
is DisplayNameState.Display -> DisplayOnlyCardDisplayName(modifier = modifier, state = state)
|
||||
is DisplayNameState.Editing -> EditingCardDisplayName(modifier = modifier, state = state)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DisplayOnlyCardDisplayName(state: DisplayNameState.Display, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = state.displayName,
|
||||
style = TangemTheme.typography.caption1.copy(color = TangemTheme.colors.text.constantWhite),
|
||||
maxLines = 1,
|
||||
modifier = modifier,
|
||||
)
|
||||
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
|
||||
private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Modifier = Modifier) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
var textFieldValue by remember(state.editingValue) {
|
||||
mutableStateOf(
|
||||
TextFieldValue(text = state.editingValue, selection = TextRange(state.editingValue.length)),
|
||||
)
|
||||
}
|
||||
val placeholder = stringResourceSafe(R.string.tangempay_card_edit_name_placeholder)
|
||||
|
||||
val textStyle = TangemTheme.typography.caption1.copy(color = TangemTheme.colors.text.constantWhite)
|
||||
val textMeasurer = rememberTextMeasurer()
|
||||
val measuredText = state.editingValue.text.ifEmpty { placeholder }
|
||||
val textWidthDp = with(LocalDensity.current) {
|
||||
textMeasurer.measure(textFieldValue.text, textStyle).size.width.toDp() + 2.dp
|
||||
textMeasurer.measure(measuredText, textStyle).size.width.toDp() + TEXT_WIDTH_PADDING.dp
|
||||
}
|
||||
|
||||
BasicTextField(
|
||||
value = textFieldValue,
|
||||
value = state.editingValue,
|
||||
onValueChange = { newValue ->
|
||||
if (newValue.text.length in 0..CardDisplayName.MAX_LENGTH) {
|
||||
textFieldValue = newValue
|
||||
state.onValueChanged(newValue.text)
|
||||
if (newValue.text.length <= CardDisplayName.MAX_LENGTH) {
|
||||
state.onValueChanged(newValue)
|
||||
}
|
||||
},
|
||||
modifier = modifier
|
||||
|
|
@ -312,6 +286,17 @@ private fun EditingCardDisplayName(state: DisplayNameState.Editing, modifier: Mo
|
|||
cursorBrush = SolidColor(TangemTheme.colors.text.constantWhite),
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { state.onSubmit() }),
|
||||
decorationBox = { innerTextField ->
|
||||
Box {
|
||||
if (state.editingValue.text.isEmpty()) {
|
||||
Text(
|
||||
text = placeholder,
|
||||
style = textStyle.copy(color = TangemTheme.colors.text.tertiary),
|
||||
)
|
||||
}
|
||||
innerTextField()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
||||
|
|
@ -492,7 +477,13 @@ private class TangemPayCardDetailsUMProvider : CollectionPreviewParameterProvide
|
|||
onCopy = { _, _ -> },
|
||||
isHidden = true,
|
||||
cardFrozenState = TangemPayCardFrozenState.Frozen,
|
||||
displayNameState = DisplayNameState.Display(displayName = "Tangem", onClick = {}),
|
||||
displayNameState = DisplayNameState.Editing(
|
||||
displayName = "Tangem",
|
||||
editingValue = TextFieldValue(text = "movet", selection = TextRange("movet".length)),
|
||||
onValueChanged = {},
|
||||
onSubmit = {},
|
||||
onDismiss = {},
|
||||
),
|
||||
),
|
||||
TangemPayCardDetailsUM(
|
||||
isLoading = false,
|
||||
|
|
@ -505,7 +496,13 @@ private class TangemPayCardDetailsUMProvider : CollectionPreviewParameterProvide
|
|||
onCopy = { _, _ -> },
|
||||
isHidden = true,
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
displayNameState = DisplayNameState.Display(displayName = "Tangem Pay Card", onClick = {}),
|
||||
displayNameState = DisplayNameState.Editing(
|
||||
displayName = "Tangem",
|
||||
editingValue = TextFieldValue(text = ""),
|
||||
onValueChanged = {},
|
||||
onSubmit = {},
|
||||
onDismiss = {},
|
||||
),
|
||||
),
|
||||
TangemPayCardDetailsUM(
|
||||
isLoading = false,
|
||||
|
|
@ -518,7 +515,11 @@ private class TangemPayCardDetailsUMProvider : CollectionPreviewParameterProvide
|
|||
onCopy = { _, _ -> },
|
||||
isHidden = true,
|
||||
cardFrozenState = TangemPayCardFrozenState.Pending,
|
||||
displayNameState = DisplayNameState.Display(displayName = "Tangem Pay Card", onClick = {}),
|
||||
displayNameState = DisplayNameState.Display(
|
||||
displayName = "Tangem Pay Card",
|
||||
onClick = {},
|
||||
isEditingEnabled = true,
|
||||
),
|
||||
),
|
||||
TangemPayCardDetailsUM(
|
||||
isLoading = false,
|
||||
|
|
@ -531,7 +532,11 @@ private class TangemPayCardDetailsUMProvider : CollectionPreviewParameterProvide
|
|||
expiry = "12/34",
|
||||
cvv = "123",
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
displayNameState = DisplayNameState.Display(displayName = "Tangem Pay Card", onClick = {}),
|
||||
displayNameState = DisplayNameState.Display(
|
||||
displayName = "Tangem Pay Card",
|
||||
onClick = {},
|
||||
isEditingEnabled = false,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -8,18 +8,7 @@ import androidx.compose.animation.fadeIn
|
|||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.exclude
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.navigationBars
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyItemScope
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
|
|
@ -46,11 +35,7 @@ import com.tangem.domain.visa.model.TangemPayCardFrozenState
|
|||
import com.tangem.features.tangempay.components.cardDetails.PreviewTangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.DisplayNameState
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardPageSetting
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardPageUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayDailyLimitBlockState
|
||||
import com.tangem.features.tangempay.entity.*
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
private const val CONTENT_FADE_DURATION_MS = 300
|
||||
|
|
@ -217,7 +202,11 @@ private fun preview() = TangemThemePreview {
|
|||
onCopy = { _, _ -> },
|
||||
onClick = {},
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
displayNameState = DisplayNameState.Display(displayName = "Tangem Pay Card", onClick = {}),
|
||||
displayNameState = DisplayNameState.Display(
|
||||
displayName = "Tangem Pay Card",
|
||||
onClick = {},
|
||||
isEditingEnabled = true,
|
||||
),
|
||||
),
|
||||
),
|
||||
cardDetailsState = TangemPayCardDetailsUM(
|
||||
|
|
@ -228,7 +217,11 @@ private fun preview() = TangemThemePreview {
|
|||
onCopy = { _, _ -> },
|
||||
onClick = {},
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
displayNameState = DisplayNameState.Display(displayName = "Tangem Pay Card", onClick = {}),
|
||||
displayNameState = DisplayNameState.Display(
|
||||
displayName = "Tangem Pay Card",
|
||||
onClick = {},
|
||||
isEditingEnabled = false,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -56,10 +56,7 @@ import com.tangem.features.tangempay.components.express.PreviewEmptyExpressTrans
|
|||
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.TangemPayDetailsBalanceBlockState
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsTopBarConfig
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
|
||||
import com.tangem.features.tangempay.entity.*
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -116,6 +113,17 @@ internal fun TangemPayDetailsScreen(
|
|||
SpacerH12()
|
||||
},
|
||||
)
|
||||
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",
|
||||
|
|
@ -420,6 +428,7 @@ private class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<Ta
|
|||
),
|
||||
isBalanceHidden = false,
|
||||
addFundsEnabled = true,
|
||||
addToWalletBlockState = AddToWalletBlockState(onClick = {}, onClickClose = {}),
|
||||
accountDeactivatedNotificationConfig = null,
|
||||
),
|
||||
TangemPayDetailsUM(
|
||||
|
|
@ -434,6 +443,7 @@ private class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<Ta
|
|||
),
|
||||
isBalanceHidden = false,
|
||||
addFundsEnabled = true,
|
||||
addToWalletBlockState = null,
|
||||
accountDeactivatedNotificationConfig = null,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ internal fun TangemPayEditDisplayNameScreen(
|
|||
textReference = resourceReference(R.string.common_done),
|
||||
onClick = state.onDoneClick,
|
||||
shouldShowProgress = state.isLoading,
|
||||
isEnabled = !state.isLoading && state.editingValue.isNotBlank(),
|
||||
isEnabled = !state.isLoading && state.editingValue.text.isNotBlank(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue