Updated on 2026-08-14
This commit is contained in:
parent
03c65b35cf
commit
931cb4d20b
9 changed files with 161 additions and 390 deletions
|
|
@ -7,6 +7,7 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
|
|||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
|
|
@ -100,6 +101,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
private val accountDependencies: AccountDependencies,
|
||||
private val yieldSupplySetShouldShowMainPromoUseCase: YieldSupplySetShouldShowMainPromoUseCase,
|
||||
private val tokenListAnalyticsSender: TokenListAnalyticsSender,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
) : BaseWalletClickIntents(), WalletContentClickIntents {
|
||||
|
||||
override fun onDetailsClick() {
|
||||
|
|
@ -311,15 +313,12 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onConfirmDisposeExpressStatus() {
|
||||
walletEventSender.send(
|
||||
WalletEvent.ShowAlert(
|
||||
WalletAlertState.ConfirmExpressStatusHide(
|
||||
onConfirmClick = {
|
||||
walletEventSender.onConsume()
|
||||
onDisposeExpressStatus()
|
||||
},
|
||||
onCancelClick = walletEventSender::onConsume,
|
||||
),
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.confirmExpressStatusHide(
|
||||
onConfirmClick = {
|
||||
walletEventSender.onConsume()
|
||||
onDisposeExpressStatus()
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,14 @@ import com.tangem.core.analytics.models.AnalyticsEvent
|
|||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.WrappedList
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.haptic.TangemHapticEffect
|
||||
import com.tangem.core.ui.haptic.VibratorHapticManager
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
|
||||
|
|
@ -56,7 +57,7 @@ import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
|
|||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.unwrap
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState
|
||||
|
|
@ -150,6 +151,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
) : BaseWalletClickIntents(), WalletCurrencyActionsClickIntents {
|
||||
|
||||
override fun onSendClick(
|
||||
|
|
@ -269,48 +271,19 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
)
|
||||
|
||||
modelScope.launch(dispatchers.main) {
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = getHideTokeAlertConfig(userWalletId, cryptoCurrencyStatus),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
val currency = cryptoCurrencyStatus.currency
|
||||
val isCryptoCurrencyCoinCouldHide = currency is CryptoCurrency.Coin &&
|
||||
!isCryptoCurrencyCoinCouldHide(userWalletId = userWalletId, cryptoCurrencyCoin = currency)
|
||||
|
||||
private suspend fun getHideTokeAlertConfig(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): WalletAlertState.DefaultAlert {
|
||||
val currency = cryptoCurrencyStatus.currency
|
||||
val isCryptoCurrencyCoinCouldHide = currency is CryptoCurrency.Coin &&
|
||||
!isCryptoCurrencyCoinCouldHide(userWalletId = userWalletId, cryptoCurrencyCoin = currency)
|
||||
return if (isCryptoCurrencyCoinCouldHide) {
|
||||
WalletAlertState.DefaultAlert(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_title,
|
||||
formatArgs = WrappedList(listOf(cryptoCurrencyStatus.currency.name)),
|
||||
),
|
||||
message = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_message,
|
||||
formatArgs = WrappedList(
|
||||
listOf(
|
||||
cryptoCurrencyStatus.currency.name,
|
||||
cryptoCurrencyStatus.currency.symbol,
|
||||
cryptoCurrencyStatus.currency.network.name,
|
||||
),
|
||||
),
|
||||
),
|
||||
onConfirmClick = null,
|
||||
)
|
||||
} else {
|
||||
WalletAlertState.DefaultAlert(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_hide_alert_title,
|
||||
formatArgs = WrappedList(listOf(cryptoCurrencyStatus.currency.name)),
|
||||
),
|
||||
message = resourceReference(R.string.token_details_hide_alert_message),
|
||||
onConfirmClick = { onPerformHideToken(userWalletId, cryptoCurrencyStatus) },
|
||||
)
|
||||
if (isCryptoCurrencyCoinCouldHide) {
|
||||
uiMessageSender.send(WalletAlertUM.unableHideToken(cryptoCurrency = cryptoCurrencyStatus.currency))
|
||||
} else {
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.hideTokenConfirm(cryptoCurrency = cryptoCurrencyStatus.currency) {
|
||||
onPerformHideToken(userWalletId, cryptoCurrencyStatus)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -618,17 +591,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
private fun handleUnavailabilityReason(unavailabilityReason: ScenarioUnavailabilityReason): Boolean {
|
||||
if (unavailabilityReason == ScenarioUnavailabilityReason.None) return false
|
||||
|
||||
modelScope.launch(dispatchers.main) {
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.DefaultAlert(
|
||||
title = null,
|
||||
message = unavailabilityReason.getUnavailabilityReasonText(),
|
||||
onConfirmClick = null,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
uiMessageSender.send(DialogMessage(message = unavailabilityReason.getUnavailabilityReasonText()))
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -641,7 +604,10 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
modelScope.launch {
|
||||
statusFlow.foldStatus(
|
||||
onContent = { handleContent(route, eventCreator) },
|
||||
onError = { handleError(eventCreator = eventCreator) },
|
||||
onError = {
|
||||
analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Error))
|
||||
uiMessageSender.send(WalletAlertUM.unavailableOperation())
|
||||
},
|
||||
onLoading = { handleLoading(eventCreator) },
|
||||
)
|
||||
}
|
||||
|
|
@ -667,21 +633,10 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
appRouter.push(route = route)
|
||||
}
|
||||
|
||||
private fun handleError(
|
||||
alertState: WalletAlertState = WalletAlertState.UnavailableOperation,
|
||||
eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent,
|
||||
) {
|
||||
analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Error))
|
||||
|
||||
walletEventSender.send(event = WalletEvent.ShowAlert(state = alertState))
|
||||
}
|
||||
|
||||
private fun handleLoading(eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent) {
|
||||
analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Pending))
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(state = WalletAlertState.ProvidersStillLoading),
|
||||
)
|
||||
uiMessageSender.send(WalletAlertUM.providersStillLoading())
|
||||
}
|
||||
|
||||
private suspend fun getSwapRoute(targetRoute: AppRoute): AppRoute {
|
||||
|
|
@ -743,12 +698,8 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
private fun checkSwapCryptoAvailability(tokenCount: Int) {
|
||||
if (tokenCount < 2) {
|
||||
handleError(
|
||||
alertState = WalletAlertState.InsufficientTokensCountForSwapping,
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonSwap,
|
||||
)
|
||||
|
||||
return
|
||||
analyticsEventHandler.send(event = MainScreenAnalyticsEvent.ButtonSwap(AnalyticsParam.Status.Error))
|
||||
uiMessageSender.send(WalletAlertUM.insufficientTokensCountForSwapping())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ import com.tangem.core.analytics.models.AnalyticsParam
|
|||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.navigation.review.ReviewManager
|
||||
import com.tangem.domain.card.SetCardWasScannedUseCase
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
||||
|
|
@ -38,14 +38,11 @@ import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.Program
|
|||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.PromotionBannerClicked
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.Basic
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWalletClickHandler
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWalletError
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
|
||||
import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents
|
||||
|
|
@ -70,8 +67,6 @@ internal interface WalletWarningsClickIntents {
|
|||
|
||||
fun onOpenUnlockWalletsBottomSheetClick()
|
||||
|
||||
fun onUnlockVisaAccessClick()
|
||||
|
||||
fun onLikeAppClick()
|
||||
|
||||
fun onDislikeAppClick()
|
||||
|
|
@ -113,7 +108,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
private val neverToSuggestRateAppUseCase: NeverToSuggestRateAppUseCase,
|
||||
private val remindToRateAppLaterUseCase: RemindToRateAppLaterUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val scanCardToUnlockWalletClickHandler: ScanCardToUnlockWalletClickHandler,
|
||||
private val nonBiometricUnlockWalletUseCase: NonBiometricUnlockWalletUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
|
|
@ -133,6 +127,7 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase,
|
||||
private val getWalletsListForEnablingUseCase: GetWalletsForAutomaticallyPushEnablingUseCase,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val reviewManager: ReviewManager,
|
||||
) : BaseWalletClickIntents(), WalletWarningsClickIntents {
|
||||
|
||||
override fun onAddBackupCardClick() {
|
||||
|
|
@ -212,38 +207,14 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onUnlockVisaAccessClick() {
|
||||
openScanCardDialog()
|
||||
}
|
||||
|
||||
private fun openScanCardDialog() {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
scanCardToUnlockWalletClickHandler(walletId = stateHolder.getSelectedWalletId())
|
||||
.onLeft { error ->
|
||||
when (error) {
|
||||
ScanCardToUnlockWalletError.WrongCardIsScanned -> {
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(WalletAlertState.WrongCardIsScanned),
|
||||
)
|
||||
}
|
||||
ScanCardToUnlockWalletError.ManyScanFails -> router.openScanFailedDialog(::openScanCardDialog)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLikeAppClick() {
|
||||
analyticsEventHandler.send(MainScreen.NoticeRateAppButton(AnalyticsParam.RateApp.Liked))
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.RateApp(
|
||||
onDismissClick = {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
neverToSuggestRateAppUseCase()
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
reviewManager.request {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
neverToSuggestRateAppUseCase()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDislikeAppClick() {
|
||||
|
|
@ -293,7 +264,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
action = PromotionBannerClicked.BannerAction.Closed(),
|
||||
)
|
||||
},
|
||||
|
||||
)
|
||||
modelScope.launch(dispatchers.main) {
|
||||
shouldShowPromoWalletUseCase.neverToShow(promoId)
|
||||
|
|
@ -374,21 +344,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
analyticsEventHandler.send(MainScreen.NoticeSeedPhraseSupportButtonYes())
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.SimpleOkAlert(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_yes),
|
||||
onOkClick = {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.confirm(userWalletId = userWallet.walletId)
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.seedPhraseConfirm {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.confirm(userWalletId = userWallet.walletId)
|
||||
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotify),
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotify),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -397,17 +362,12 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
analyticsEventHandler.send(MainScreen.NoticeSeedPhraseSupportButtonNo())
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.SimpleOkAlert(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_no),
|
||||
onOkClick = {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.decline(userWalletId = userWallet.walletId)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.seedPhraseDismiss {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.decline(userWalletId = userWallet.walletId)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -416,21 +376,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
analyticsEventHandler.send(MainScreen.NoticeSeedPhraseSupportButtonUsed())
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.SimpleOkAlert(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_yes),
|
||||
onOkClick = {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.acceptSecond(userWalletId = userWallet.walletId)
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.seedPhraseConfirm {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.acceptSecond(userWalletId = userWallet.walletId)
|
||||
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotifySecond),
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotifySecond),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,106 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.model
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
|
||||
@Immutable
|
||||
internal sealed interface WalletAlertState {
|
||||
|
||||
@Immutable
|
||||
sealed class Basic : WalletAlertState {
|
||||
abstract val title: TextReference?
|
||||
abstract val message: TextReference
|
||||
open val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
|
||||
open val isWarningConfirmButton: Boolean = false
|
||||
abstract val onConfirmClick: (() -> Unit)?
|
||||
open val cancelButtonText: TextReference? = null
|
||||
open val onCancelClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
@Immutable
|
||||
sealed class TextInput : WalletAlertState {
|
||||
abstract val title: TextReference
|
||||
abstract val label: TextReference
|
||||
open val text: String = ""
|
||||
open val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
|
||||
abstract val onConfirmClick: (String) -> Unit
|
||||
abstract val errorTextProvider: (String) -> TextReference?
|
||||
}
|
||||
|
||||
data class SimpleOkAlert(val message: TextReference, val onOkClick: () -> Unit) : WalletAlertState
|
||||
|
||||
data class DefaultAlert(
|
||||
override val title: TextReference?,
|
||||
override val message: TextReference,
|
||||
override val onConfirmClick: (() -> Unit)?,
|
||||
) : Basic()
|
||||
|
||||
data class VisaLimitsInfo(
|
||||
val totalLimit: String,
|
||||
val otherLimit: String,
|
||||
) : Basic() {
|
||||
override val title: TextReference? = null
|
||||
override val message: TextReference = stringReference(
|
||||
value = "Limits are needed to control costs, improve security, manage risk. " +
|
||||
"You can spend $totalLimit during the week for card payments in shops and " +
|
||||
"$otherLimit for other transactions, e. g. subscriptions or debts.",
|
||||
)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object WrongCardIsScanned : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.common_warning)
|
||||
override val message: TextReference = resourceReference(R.string.error_wrong_wallet_tapped)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object RescanWallets : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.common_attention)
|
||||
override val message: TextReference = resourceReference(R.string.key_invalidated_warning_description)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object VisaBalancesInfo : Basic() {
|
||||
override val title: TextReference? = null
|
||||
override val message: TextReference = stringReference(
|
||||
value = "Available balance is actual funds available, considering pending transactions, " +
|
||||
"blocked amounts, and debit balance to prevent overdrafts.",
|
||||
)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object ProvidersStillLoading : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.action_buttons_service_loading_alert_title)
|
||||
override val message: TextReference = resourceReference(R.string.action_buttons_service_loading_alert_message)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object UnavailableOperation : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.action_buttons_something_wrong_alert_title)
|
||||
override val message: TextReference = resourceReference(R.string.action_buttons_something_wrong_alert_message)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object InsufficientTokensCountForSwapping : Basic() {
|
||||
override val title: TextReference =
|
||||
resourceReference(id = R.string.action_buttons_swap_no_tokens_added_alert_title)
|
||||
|
||||
override val message: TextReference =
|
||||
resourceReference(id = R.string.action_buttons_swap_no_tokens_added_alert_message)
|
||||
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data class ConfirmExpressStatusHide(
|
||||
override val onConfirmClick: (() -> Unit),
|
||||
override val onCancelClick: (() -> Unit),
|
||||
) : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.express_status_hide_dialog_title)
|
||||
override val message: TextReference = resourceReference(R.string.express_status_hide_dialog_text)
|
||||
override val confirmButtonText: TextReference = resourceReference(R.string.common_hide)
|
||||
override val cancelButtonText: TextReference = resourceReference(R.string.common_cancel)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.model
|
||||
|
||||
import com.tangem.core.ui.extensions.WrappedList
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
|
||||
internal object WalletAlertUM {
|
||||
|
||||
fun seedPhraseConfirm(onClick: () -> Unit): DialogMessage {
|
||||
return DialogMessage(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_yes),
|
||||
firstActionBuilder = {
|
||||
okAction(onClick = onClick)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun seedPhraseDismiss(onClick: () -> Unit): DialogMessage {
|
||||
return DialogMessage(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_no),
|
||||
firstActionBuilder = {
|
||||
okAction(onClick = onClick)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun unableHideToken(cryptoCurrency: CryptoCurrency): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_title,
|
||||
formatArgs = WrappedList(listOf(cryptoCurrency.name)),
|
||||
),
|
||||
message = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_message,
|
||||
formatArgs = WrappedList(
|
||||
listOf(
|
||||
cryptoCurrency.name,
|
||||
cryptoCurrency.symbol,
|
||||
cryptoCurrency.network.name,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun hideTokenConfirm(cryptoCurrency: CryptoCurrency, onClick: () -> Unit): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_hide_alert_title,
|
||||
formatArgs = WrappedList(listOf(cryptoCurrency.name)),
|
||||
),
|
||||
message = resourceReference(R.string.token_details_hide_alert_message),
|
||||
firstActionBuilder = {
|
||||
okAction(onClick)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun providersStillLoading(): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(R.string.action_buttons_service_loading_alert_title),
|
||||
message = resourceReference(R.string.action_buttons_service_loading_alert_message),
|
||||
)
|
||||
}
|
||||
|
||||
fun unavailableOperation(): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(R.string.action_buttons_something_wrong_alert_title),
|
||||
message = resourceReference(R.string.action_buttons_something_wrong_alert_message),
|
||||
)
|
||||
}
|
||||
|
||||
fun insufficientTokensCountForSwapping(): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(R.string.action_buttons_swap_no_tokens_added_alert_title),
|
||||
message = resourceReference(R.string.action_buttons_swap_no_tokens_added_alert_message),
|
||||
)
|
||||
}
|
||||
|
||||
fun confirmExpressStatusHide(onConfirmClick: () -> Unit): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(R.string.express_status_hide_dialog_title),
|
||||
message = resourceReference(R.string.express_status_hide_dialog_text),
|
||||
firstActionBuilder = {
|
||||
EventMessageAction(
|
||||
title = resourceReference(R.string.common_hide),
|
||||
onClick = onConfirmClick,
|
||||
)
|
||||
},
|
||||
secondActionBuilder = { cancelAction() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -13,12 +13,8 @@ internal sealed class WalletEvent {
|
|||
|
||||
data class ShowError(val text: TextReference) : WalletEvent()
|
||||
|
||||
data class ShowAlert(val state: WalletAlertState) : WalletEvent()
|
||||
|
||||
data object CopyAddress : WalletEvent()
|
||||
|
||||
data class RateApp(val onDismissClick: () -> Unit) : WalletEvent()
|
||||
|
||||
data class DemonstrateWalletsScrollPreview(val direction: Direction) : WalletEvent() {
|
||||
|
||||
enum class Direction {
|
||||
|
|
|
|||
|
|
@ -1,98 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import com.tangem.core.ui.components.AdditionalTextInputDialogUM
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.components.TextInputDialog
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState
|
||||
|
||||
@Composable
|
||||
internal fun WalletAlert(state: WalletAlertState, onDismiss: () -> Unit) {
|
||||
when (state) {
|
||||
is WalletAlertState.Basic -> BasicAlert(state, onDismiss)
|
||||
is WalletAlertState.TextInput -> TextInputAlert(state, onDismiss)
|
||||
is WalletAlertState.SimpleOkAlert -> {
|
||||
BasicDialog(
|
||||
message = state.message.resolveReference(),
|
||||
confirmButton = DialogButtonUM(
|
||||
onClick = {
|
||||
state.onOkClick()
|
||||
onDismiss()
|
||||
},
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
isDismissable = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BasicAlert(state: WalletAlertState.Basic, onDismiss: () -> Unit) {
|
||||
val confirmButton: DialogButtonUM
|
||||
val dismissButton: DialogButtonUM?
|
||||
|
||||
val onActionClick = state.onConfirmClick
|
||||
if (onActionClick != null) {
|
||||
confirmButton = DialogButtonUM(
|
||||
title = state.confirmButtonText.resolveReference(),
|
||||
isWarning = state.isWarningConfirmButton,
|
||||
onClick = {
|
||||
onActionClick()
|
||||
onDismiss()
|
||||
},
|
||||
)
|
||||
dismissButton = DialogButtonUM(
|
||||
title = stringResourceSafe(id = R.string.common_cancel),
|
||||
onClick = onDismiss,
|
||||
)
|
||||
} else {
|
||||
confirmButton = DialogButtonUM(
|
||||
title = state.confirmButtonText.resolveReference(),
|
||||
isWarning = state.isWarningConfirmButton,
|
||||
onClick = onDismiss,
|
||||
)
|
||||
dismissButton = null
|
||||
}
|
||||
|
||||
BasicDialog(
|
||||
message = state.message.resolveReference(),
|
||||
confirmButton = confirmButton,
|
||||
onDismissDialog = onDismiss,
|
||||
title = state.title?.resolveReference(),
|
||||
dismissButton = dismissButton,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TextInputAlert(state: WalletAlertState.TextInput, onDismiss: () -> Unit) {
|
||||
var value by remember { mutableStateOf(TextFieldValue(text = state.text)) }
|
||||
|
||||
TextInputDialog(
|
||||
fieldValue = value,
|
||||
confirmButton = DialogButtonUM(
|
||||
title = state.confirmButtonText.resolveReference(),
|
||||
isEnabled = value.text.isNotEmpty() &&
|
||||
value.text != state.text &&
|
||||
state.errorTextProvider(value.text) == null,
|
||||
onClick = {
|
||||
state.onConfirmClick(value.text)
|
||||
onDismiss()
|
||||
},
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
onValueChange = { value = it },
|
||||
title = state.title.resolveReference(),
|
||||
dismissButton = DialogButtonUM(title = stringResourceSafe(id = R.string.common_cancel), onClick = onDismiss),
|
||||
textFieldParams = AdditionalTextInputDialogUM(
|
||||
label = state.label.resolveReference(),
|
||||
isError = state.errorTextProvider(value.text) != null,
|
||||
caption = state.errorTextProvider(value.text)?.resolveReference(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -11,9 +11,7 @@ import com.tangem.core.ui.event.StateEvent
|
|||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.utils.requestPermission
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.utils.ReviewManagerRequester
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.utils.animateScrollByIndex
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.utils.demonstrateScrolling
|
||||
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
||||
|
|
@ -24,10 +22,8 @@ internal fun WalletEventEffect(
|
|||
snackbarHostState: SnackbarHostState,
|
||||
event: StateEvent<WalletEvent>,
|
||||
onAutoScrollSet: () -> Unit,
|
||||
onAlertConfigSet: (WalletAlertState) -> Unit,
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val resources = LocalContext.current.resources
|
||||
|
||||
var showPermissionRequest by remember { mutableStateOf<Pair<() -> Unit, () -> Unit>?>(null) }
|
||||
|
|
@ -57,10 +53,6 @@ internal fun WalletEventEffect(
|
|||
duration = SnackbarDuration.Short,
|
||||
)
|
||||
}
|
||||
is WalletEvent.ShowAlert -> onAlertConfigSet(value.state)
|
||||
is WalletEvent.RateApp -> {
|
||||
ReviewManagerRequester.request(context = context, onDismissClick = value.onDismissClick)
|
||||
}
|
||||
is WalletEvent.DemonstrateWalletsScrollPreview -> {
|
||||
walletsListState.demonstrateScrolling(coroutineScope = coroutineScope, direction = value.direction)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,13 +100,6 @@ internal fun WalletScreen(
|
|||
val snackbarHostState = remember(::SnackbarHostState)
|
||||
val isAutoScroll = remember { mutableStateOf(value = false) }
|
||||
|
||||
var alertConfig by remember { mutableStateOf<WalletAlertState?>(value = null) }
|
||||
|
||||
val config = alertConfig
|
||||
if (config != null) {
|
||||
WalletAlert(state = config, onDismiss = { alertConfig = null })
|
||||
}
|
||||
|
||||
WalletContent(
|
||||
state = state,
|
||||
walletsListState = walletsListState,
|
||||
|
|
@ -114,7 +107,6 @@ internal fun WalletScreen(
|
|||
isAutoScroll = isAutoScroll,
|
||||
onAutoScrollReset = { isAutoScroll.value = false },
|
||||
bottomSheetContent = bottomSheetContent,
|
||||
alertConfig = alertConfig,
|
||||
bottomSheetHeaderHeightProvider = bottomSheetHeaderHeightProvider,
|
||||
onBottomSheetStateChange = onBottomSheetStateChange,
|
||||
)
|
||||
|
|
@ -124,7 +116,6 @@ internal fun WalletScreen(
|
|||
snackbarHostState = snackbarHostState,
|
||||
event = state.event,
|
||||
onAutoScrollSet = { isAutoScroll.value = true },
|
||||
onAlertConfigSet = { alertConfig = it },
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +126,6 @@ private fun WalletContent(
|
|||
walletsListState: LazyListState,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
isAutoScroll: State<Boolean>,
|
||||
alertConfig: WalletAlertState?,
|
||||
onAutoScrollReset: () -> Unit,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
|
|
@ -279,7 +269,6 @@ private fun WalletContent(
|
|||
selectedWallet = selectedWallet,
|
||||
snackbarHostState = snackbarHostState,
|
||||
bottomSheetHeaderHeightProvider = bottomSheetHeaderHeightProvider,
|
||||
alertConfig = alertConfig,
|
||||
onBottomSheetStateChange = onBottomSheetStateChange,
|
||||
bottomSheetContent = bottomSheetContent,
|
||||
content = scaffoldContent,
|
||||
|
|
@ -294,7 +283,6 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
listState: LazyListState,
|
||||
selectedWallet: WalletState,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
alertConfig: WalletAlertState?,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
noinline onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
crossinline bottomSheetContent: @Composable () -> Unit,
|
||||
|
|
@ -341,7 +329,6 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
|
||||
BottomSheetStateEffects(
|
||||
bottomSheetState = bottomSheetState,
|
||||
alertConfig = alertConfig,
|
||||
onBottomSheetStateChange = onBottomSheetStateChange,
|
||||
navigationBarVisible = isNavBarVisible,
|
||||
isSearchFieldFocused = isSearchFieldFocused,
|
||||
|
|
@ -615,7 +602,6 @@ private fun BottomSheetScrim(color: Color, visible: Boolean, onDismissRequest: (
|
|||
@Composable
|
||||
private fun BottomSheetStateEffects(
|
||||
bottomSheetState: TangemSheetState,
|
||||
alertConfig: WalletAlertState?,
|
||||
navigationBarVisible: MutableState<Boolean>,
|
||||
onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
isSearchFieldFocused: Boolean,
|
||||
|
|
@ -634,7 +620,7 @@ private fun BottomSheetStateEffects(
|
|||
val isKeyboardVisible by rememberIsKeyboardVisible()
|
||||
|
||||
LaunchedEffect(isKeyboardVisible) {
|
||||
if (isKeyboardVisible && alertConfig == null && isSearchFieldFocused) {
|
||||
if (isKeyboardVisible && isSearchFieldFocused) {
|
||||
bottomSheetState.expand()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue