Updated on 2026-08-14
This commit is contained in:
parent
9378e4fa31
commit
d7d50b086a
23 changed files with 291 additions and 74 deletions
|
|
@ -1,13 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string name="action_buttons_buy_empty_search_message">Token nicht in Deinem Portfolio gefunden? Überprüfe die Märkte, um es zu finden und zum Kauf hinzuzufügen</string>
|
||||
<string name="action_buttons_sell_empty_search_message">Token nicht in Deinem Portfolio gefunden? Überprüfe die Märkte, um es zu finden und zum Verkauf hinzuzufügen</string>
|
||||
<string name="action_buttons_sell_empty_search_message">Token nicht in Ihrem Portfolio gefunden? Überprüfe die Märkte, um es zu finden und zum Verkauf hinzuzufügen</string>
|
||||
<string name="action_buttons_swap_choose_token">Wähle den Token</string>
|
||||
<string name="action_buttons_swap_empty_search_message">Token nicht in Deinem Portfolio gefunden? Überprüfe die Märkte, um es für Swaps zu finden und hinzuzufügen</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_message">Es gibt keine verfügbaren Token, die mit dem ausgewählten Token getauscht werden können. Bitte wähle einen anderen.</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_title">Kein verfügbares Paar</string>
|
||||
<string name="action_buttons_you_want_to_receive">Du möchtest erhalten</string>
|
||||
<string name="action_buttons_you_want_to_swap">Du möchtest tauschen</string>
|
||||
<string name="action_buttons_you_want_to_receive">Wähle den Token aus, das Du erhalten möchtest</string>
|
||||
<string name="action_buttons_you_want_to_swap">Wähle den Token, den Du tauschen möchtest</string>
|
||||
<string name="add_custom_token_choose_network">Netzwerk wählen</string>
|
||||
<string name="add_custom_token_title">Token anlegen</string>
|
||||
<string name="add_tokens_title">Token verwalten</string>
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
<string name="action_buttons_swap_empty_search_message">¿No encuentras el token en tu billetera? Consulte los mercados para encontrarlo y agregarlo al intercambio</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_message">No hay tokens disponibles para intercambiar con el token seleccionado. Por favor elige otro.</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_title">No hay par disponible</string>
|
||||
<string name="action_buttons_you_want_to_receive">Desea recibir</string>
|
||||
<string name="action_buttons_you_want_to_swap">Quiere intercambiar</string>
|
||||
<string name="add_custom_token_choose_network">Elige red</string>
|
||||
<string name="add_custom_token_title">Agregue un token personalizado</string>
|
||||
<string name="add_tokens_title">Gestionar tokens</string>
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
<string name="action_buttons_swap_empty_search_message">Jeton non trouvé dans votre portefeuille ? Consultez les marchés pour le trouver et l\'ajouter à l\'échange</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_message">Il n\'y a pas de token disponible pour échanger avec le token sélectionné. Veuillez en choisir un autre.</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_title">Aucune paire disponible</string>
|
||||
<string name="action_buttons_you_want_to_receive">Vous souhaitez recevoir</string>
|
||||
<string name="action_buttons_you_want_to_swap">Vous souhaitez échanger</string>
|
||||
<string name="add_custom_token_choose_network">Choisissez le réseau</string>
|
||||
<string name="add_custom_token_title">Ajouter un jeton personnalisé</string>
|
||||
<string name="add_tokens_title">Gérer les jetons</string>
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
<resources>
|
||||
<string name="action_buttons_buy_empty_search_message">ポートフォリオにトークンが見つかりませんか?マーケットから見つけ、買付のために追加してください</string>
|
||||
<string name="action_buttons_sell_empty_search_message">ポートフォリオにトークンが見つかりませんか?マーケットから見つけ、売却のために追加してください</string>
|
||||
<string name="action_buttons_sell_navigation_bar_title">暗号資産を売却</string>
|
||||
<string name="action_buttons_swap_choose_token">トークンを選択</string>
|
||||
<string name="action_buttons_swap_empty_search_message">ポートフォリオにトークンが見つかりませんか?マーケットから見つけ、スワップのために追加してください</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_message">選択したトークンと交換できるトークンがありません。別のトークンを選択してください。</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_title">利用可能なペアがありません</string>
|
||||
<string name="action_buttons_you_want_to_receive">受け取りたい</string>
|
||||
<string name="action_buttons_you_want_to_swap">交換したい</string>
|
||||
<string name="action_buttons_you_want_to_receive">受け取りたいトークンを選択します</string>
|
||||
<string name="action_buttons_you_want_to_swap">スワップしたいトークンを選択します</string>
|
||||
<string name="add_custom_token_choose_network">ネットワークを選択</string>
|
||||
<string name="add_custom_token_title">カスタムトークンの追加</string>
|
||||
<string name="add_tokens_title">トークンの管理</string>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string name="action_buttons_buy_empty_search_message">Не нашли свой токен? Перейдите в раздел «Рынок» на главной странице и добавьте его в свой портфель для покупки.</string>
|
||||
<string name="action_buttons_sell_empty_search_message">Не нашли свой токен? Перейдите в раздел «Рынок» на главной странице и добавьте его в свой портфель для продажи.</string>
|
||||
<string name="action_buttons_sell_navigation_bar_title">Продать криптовалюту</string>
|
||||
<string name="action_buttons_swap_choose_token">Выберите токен</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_message">Нет доступных токенов для обмена с выбранным токеном, пожалуйста, выберите другой.</string>
|
||||
<string name="action_buttons_swap_empty_search_message">Не нашли свой токен? Перейдите в раздел «Рынок» на главной странице и добавьте его в свой портфель для обмена.</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_message">Нет доступных вариантов для обмена с выбранным токеном, пожалуйста, выберите другой.</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_title">Нет доступных пар</string>
|
||||
<string name="action_buttons_you_want_to_receive">Вы хотите получить</string>
|
||||
<string name="action_buttons_you_want_to_swap">Вы хотите обменять</string>
|
||||
<string name="action_buttons_you_want_to_receive">Выберите токен для получения</string>
|
||||
<string name="action_buttons_you_want_to_swap">Выберите токен для обмена</string>
|
||||
<string name="add_custom_token_choose_network">Выберите сеть</string>
|
||||
<string name="add_custom_token_title">Добавить токен</string>
|
||||
<string name="add_tokens_title">Валюты</string>
|
||||
|
|
@ -652,6 +656,10 @@
|
|||
<string name="scan_card_settings_button">Сканировать</string>
|
||||
<string name="scan_card_settings_message">Отсканируйте карту или кольцо, чтобы изменить ее настройки. Изменения затронут только ту карту или кольцо, которые вы отсканировали, и не повлияют на другие устройства, привязанные к вашему кошельку.</string>
|
||||
<string name="scan_card_settings_title">Приготовьте свой Tangem!</string>
|
||||
<string name="selling_insufficient_balance_alert_message">На вашем балансе недостаточно средств для продажи этой криптовалюты. Пожалуйста, пополните нужный актив, чтобы продолжить.</string>
|
||||
<string name="selling_insufficient_balance_alert_title">Недостаточно средств</string>
|
||||
<string name="selling_regional_restriction_alert_message">Продажа криптовалюты в вашем регионе временно недоступна. Мы активно работаем над тем, чтобы добавить эту возможность. Следите за нашими новостями!</string>
|
||||
<string name="selling_regional_restriction_alert_title">Региональные ограничения</string>
|
||||
<string name="send_additional_field_already_included">Уже содержится во введенном адресе</string>
|
||||
<string name="send_alert_fee_too_high_text">Сумма комиссии в %s раз превышает рекомендованную. Убедитесь, что указанная комиссия верна.</string>
|
||||
<string name="send_alert_fee_too_low_text">Вы указали комиссию ниже рекомендуемой, это может привести к задержке исполнения вашей транзакции. Продолжить?</string>
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
<string name="action_buttons_swap_empty_search_message">Токен не знайдено у вашому портфелі? Перевірте ринки, щоб знайти та додати його для обміну</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_message">Немає доступних токенів для обміну з обраним токеном. Будь ласка, оберіть інший.</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_title">Немає вільної пари</string>
|
||||
<string name="action_buttons_you_want_to_receive">Ви хочете отримати</string>
|
||||
<string name="action_buttons_you_want_to_swap">Ви хочете обміняти</string>
|
||||
<string name="add_custom_token_choose_network">Оберіть мережу</string>
|
||||
<string name="add_custom_token_title">Додати токен</string>
|
||||
<string name="add_tokens_title">Токени</string>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string name="action_buttons_buy_empty_search_message">Token not found in your portfolio? Check the Markets to find and add it for purchase</string>
|
||||
<string name="action_buttons_sell_empty_search_message">Token not found in your portfolio? Check the Markets to find and add it for selling</string>
|
||||
<string name="action_buttons_buy_empty_search_message">Can’t find your token? Go to the Market section on the main page and add it to your portfolio for purchase</string>
|
||||
<string name="action_buttons_sell_empty_search_message">Can’t find your token? Go to the Market section on the main page and add it to your portfolio for selling.</string>
|
||||
<string name="action_buttons_sell_navigation_bar_title">Sell crypto</string>
|
||||
<string name="action_buttons_swap_choose_token">Choose the Token</string>
|
||||
<string name="action_buttons_swap_empty_search_message">Token not found in your portfolio? Check the Markets to find and add it for swap</string>
|
||||
<string name="action_buttons_swap_empty_search_message">Can’t find your token? Go to the Market section on the main page and add it to your portfolio for swapping.</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_message">There are no available tokens to swap with the selected token. Please choose another one.</string>
|
||||
<string name="action_buttons_swap_no_available_pair_notification_title">No available pair</string>
|
||||
<string name="action_buttons_you_want_to_receive">You want to Receive</string>
|
||||
<string name="action_buttons_you_want_to_swap">You want to Swap</string>
|
||||
<string name="action_buttons_you_want_to_receive">Choose the token you want to receive</string>
|
||||
<string name="action_buttons_you_want_to_swap">Choose the token you want to swap</string>
|
||||
<string name="add_custom_token_choose_network">Choose network</string>
|
||||
<string name="add_custom_token_title">Add custom token</string>
|
||||
<string name="add_tokens_title">Manage tokens</string>
|
||||
|
|
@ -647,6 +648,10 @@
|
|||
<string name="scan_card_settings_button">Scan card or ring</string>
|
||||
<string name="scan_card_settings_message">Scan the card or ring to change its settings. The changes will impact only the card or ring you\'ve scanned and will not affect other devices tied to your wallet.</string>
|
||||
<string name="scan_card_settings_title">Get your Tangem ready!</string>
|
||||
<string name="selling_insufficient_balance_alert_message">You don’t have enough funds in your balance to sell this cryptocurrency. Please deposit the desired asset to proceed.</string>
|
||||
<string name="selling_insufficient_balance_alert_title">Insufficient Balance</string>
|
||||
<string name="selling_regional_restriction_alert_message">Selling cryptocurrency is unavailable in your region at the moment. We’re actively working to bring this option to you soon—stay tuned!</string>
|
||||
<string name="selling_regional_restriction_alert_title">Regional Restriction</string>
|
||||
<string name="send_additional_field_already_included">Already included in the entered address</string>
|
||||
<string name="send_alert_fee_too_high_text">Your commission amount is %s times higher than the recommended amount. Please review and adjust your custom settings.</string>
|
||||
<string name="send_alert_fee_too_low_text">You specified a commission below the recommended amount, which could cause a delay in your transaction. Continue?</string>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ internal object WalletPreviewData {
|
|||
onRenameClick = { _ -> },
|
||||
onDeleteClick = {},
|
||||
cardCount = 1,
|
||||
isZeroBalance = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ internal object WalletScreenPreviewData {
|
|||
balance = DASH_SIGN,
|
||||
onRenameClick = { _ -> },
|
||||
onDeleteClick = {},
|
||||
isZeroBalance = false,
|
||||
)
|
||||
}
|
||||
private val multiWalletState by lazy {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
||||
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
|
||||
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -11,12 +10,10 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarnin
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletActionsSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletTokenListSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletWarningsSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
|
||||
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class MultiWalletContentLoader(
|
||||
|
|
@ -31,8 +28,6 @@ internal class MultiWalletContentLoader(
|
|||
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
|
||||
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
|
||||
private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase,
|
||||
private val rampStateManager: RampStateManager,
|
||||
private val walletFeatureToggles: WalletFeatureToggles,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
||||
override fun create(): List<WalletSubscriber> {
|
||||
|
|
@ -55,16 +50,6 @@ internal class MultiWalletContentLoader(
|
|||
getMultiWalletWarningsFactory = getMultiWalletWarningsFactory,
|
||||
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
|
||||
),
|
||||
createMultiWalletButtonsSubscriber(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createMultiWalletButtonsSubscriber(): MultiWalletActionsSubscriber? {
|
||||
return MultiWalletActionsSubscriber(
|
||||
userWallet = userWallet,
|
||||
rampStateManager = rampStateManager,
|
||||
stateController = stateHolder,
|
||||
)
|
||||
.takeIf { walletFeatureToggles.isMainActionButtonsEnabled }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
||||
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
|
||||
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -12,7 +11,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenList
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
|
||||
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
|
||||
import dagger.hilt.android.scopes.ViewModelScoped
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -28,8 +26,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
|
|||
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
|
||||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase,
|
||||
private val rampStateManager: RampStateManager,
|
||||
private val walletFeatureToggles: WalletFeatureToggles,
|
||||
) {
|
||||
|
||||
fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): WalletContentLoader {
|
||||
|
|
@ -45,8 +41,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
|
|||
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
|
||||
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
|
||||
runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase,
|
||||
rampStateManager = rampStateManager,
|
||||
walletFeatureToggles = walletFeatureToggles,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -83,4 +83,32 @@ internal sealed interface WalletAlertState {
|
|||
)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object ProvidersStillLoading : Basic() {
|
||||
override val title: TextReference = stringReference(value = "Providers are still loading")
|
||||
override val message: TextReference = resourceReference(R.string.wallet_connect_toast_awaiting_session_proposal)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object UnavailableOperation : Basic() {
|
||||
override val title: TextReference = stringReference(value = "This operation is currently unavailable")
|
||||
override val message: TextReference = resourceReference(R.string.warning_some_networks_unreachable_message)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object SellingRegionalRestriction : Basic() {
|
||||
override val title: TextReference = resourceReference(id = R.string.selling_regional_restriction_alert_title)
|
||||
override val message: TextReference =
|
||||
resourceReference(id = R.string.selling_regional_restriction_alert_message)
|
||||
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object InsufficientBalanceForSelling : Basic() {
|
||||
override val title: TextReference = resourceReference(id = R.string.selling_insufficient_balance_alert_title)
|
||||
override val message: TextReference =
|
||||
resourceReference(id = R.string.selling_insufficient_balance_alert_message)
|
||||
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
}
|
||||
|
|
@ -50,6 +50,7 @@ internal sealed interface WalletCardState {
|
|||
override val onDeleteClick: (UserWalletId) -> Unit,
|
||||
val cardCount: Int?,
|
||||
val balance: String,
|
||||
val isZeroBalance: Boolean?,
|
||||
) : WalletCardState
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletManageButton
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import timber.log.Timber
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Transformer for disabling action of multi-currency wallet
|
||||
*
|
||||
* @param userWalletId user wallet id
|
||||
* @property actionClass action class that must be disabled
|
||||
*/
|
||||
internal class DisableActionTransformer(
|
||||
userWalletId: UserWalletId,
|
||||
private val actionClass: KClass<out WalletManageButton>,
|
||||
) : WalletStateTransformer(userWalletId = userWalletId) {
|
||||
|
||||
override fun transform(prevState: WalletState): WalletState {
|
||||
return when (prevState) {
|
||||
is WalletState.MultiCurrency.Content -> {
|
||||
prevState.copy(buttons = prevState.buttons.updateButtons())
|
||||
}
|
||||
is WalletState.MultiCurrency.Locked -> {
|
||||
Timber.w("Impossible to disable action for locked wallet")
|
||||
prevState
|
||||
}
|
||||
is WalletState.SingleCurrency -> {
|
||||
Timber.w("Impossible to disable action for single-currency wallet")
|
||||
prevState
|
||||
}
|
||||
is WalletState.Visa -> {
|
||||
Timber.w("Impossible to disable action for VISA wallet")
|
||||
prevState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun PersistentList<WalletManageButton>.updateButtons(): PersistentList<WalletManageButton> {
|
||||
return map { action ->
|
||||
if (action::class == actionClass) {
|
||||
when (action) {
|
||||
is WalletManageButton.Buy -> action.copy(enabled = false)
|
||||
is WalletManageButton.Swap -> action.copy(enabled = false)
|
||||
is WalletManageButton.Sell -> action.copy(enabled = false)
|
||||
else -> action
|
||||
}
|
||||
} else {
|
||||
action
|
||||
}
|
||||
}
|
||||
.toPersistentList()
|
||||
}
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ internal class InitializeWalletsTransformer(
|
|||
multiCurrencyCreator = {
|
||||
WalletState.MultiCurrency.Locked(
|
||||
walletCardState = userWallet.toLockedWalletCardState(),
|
||||
buttons = createMultiWalletDisabledButtons(),
|
||||
buttons = createMultiWalletEnabledButtons(),
|
||||
bottomSheetConfig = null,
|
||||
onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick,
|
||||
)
|
||||
|
|
@ -67,7 +67,7 @@ internal class InitializeWalletsTransformer(
|
|||
WalletState.SingleCurrency.Locked(
|
||||
walletCardState = userWallet.toLockedWalletCardState(),
|
||||
bottomSheetConfig = null,
|
||||
buttons = createDisabledButtons(),
|
||||
buttons = createSingleWalletDisabledButtons(),
|
||||
onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick,
|
||||
onExploreClick = clickIntents::onExploreClick,
|
||||
)
|
||||
|
|
@ -75,7 +75,7 @@ internal class InitializeWalletsTransformer(
|
|||
visaWalletCreator = {
|
||||
WalletState.Visa.Locked(
|
||||
walletCardState = userWallet.toLockedWalletCardState(),
|
||||
buttons = createMultiWalletDisabledButtons(),
|
||||
buttons = createMultiWalletEnabledButtons(),
|
||||
bottomSheetConfig = null,
|
||||
onUnlockNotificationClick = clickIntents::onOpenUnlockWalletsBottomSheetClick,
|
||||
onExploreClick = clickIntents::onExploreClick,
|
||||
|
|
@ -95,18 +95,17 @@ internal class InitializeWalletsTransformer(
|
|||
)
|
||||
}
|
||||
|
||||
private fun createMultiWalletDisabledButtons(): PersistentList<WalletManageButton> {
|
||||
private fun createMultiWalletEnabledButtons(): PersistentList<WalletManageButton> {
|
||||
if (!walletFeatureToggles.isMainActionButtonsEnabled) return persistentListOf()
|
||||
|
||||
return persistentListOf(
|
||||
WalletManageButton.Receive(enabled = false, dimContent = false, onClick = {}, onLongClick = null),
|
||||
WalletManageButton.Send(enabled = false, dimContent = false, onClick = {}),
|
||||
WalletManageButton.Buy(enabled = false, dimContent = false, onClick = {}),
|
||||
WalletManageButton.Swap(enabled = false, dimContent = false, onClick = {}),
|
||||
WalletManageButton.Sell(enabled = false, dimContent = false, onClick = {}),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createDisabledButtons(): PersistentList<WalletManageButton> {
|
||||
private fun createSingleWalletDisabledButtons(): PersistentList<WalletManageButton> {
|
||||
return persistentListOf(
|
||||
WalletManageButton.Receive(enabled = false, dimContent = false, onClick = {}, onLongClick = null),
|
||||
WalletManageButton.Send(enabled = false, dimContent = false, onClick = {}),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditiona
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
|
||||
import com.tangem.utils.extensions.isZero
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.Days
|
||||
|
||||
|
|
@ -76,6 +77,7 @@ internal class SetBalancesAndLimitsTransformer(
|
|||
crypto(visaCurrency.symbol, visaCurrency.decimals)
|
||||
},
|
||||
cardCount = userWallet.getCardsCount(),
|
||||
isZeroBalance = visaCurrency.balances.available.isZero(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfo
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.disableButtons
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -26,6 +27,11 @@ internal class SetTokenListErrorTransformer(
|
|||
prevState.copy(
|
||||
walletCardState = prevState.walletCardState.toLoadedState(),
|
||||
tokensListState = WalletTokensListState.Empty,
|
||||
buttons = if (error == TokenListError.EmptyTokens) {
|
||||
prevState.disableButtons()
|
||||
} else {
|
||||
prevState.buttons
|
||||
},
|
||||
)
|
||||
}
|
||||
is WalletState.MultiCurrency.Locked -> {
|
||||
|
|
@ -62,6 +68,7 @@ internal class SetTokenListErrorTransformer(
|
|||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
),
|
||||
cardCount = selectedWallet.getCardsCount(),
|
||||
isZeroBalance = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletCardStateConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.TokenListStateConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.enableButtons
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ internal class SetTokenListTransformer(
|
|||
prevState.copy(
|
||||
walletCardState = prevState.walletCardState.toLoadedState(),
|
||||
tokensListState = prevState.tokensListState.toLoadedState(),
|
||||
buttons = prevState.enableButtons(),
|
||||
)
|
||||
}
|
||||
is WalletState.MultiCurrency.Locked -> {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.domain.wallets.models.UserWallet
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.utils.extensions.isZero
|
||||
|
||||
internal class MultiWalletCardStateConverter(
|
||||
private val fiatBalance: TotalFiatBalance,
|
||||
|
|
@ -58,6 +59,7 @@ internal class MultiWalletCardStateConverter(
|
|||
fiatCurrencyCode = appCurrency.code,
|
||||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
),
|
||||
isZeroBalance = fiatBalance.amount.isZero(),
|
||||
cardCount = selectedWallet.getCardsCount(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.domain.wallets.models.UserWallet
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
|
||||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.utils.extensions.isZero
|
||||
|
||||
internal class SingleWalletCardStateConverter(
|
||||
private val status: CryptoCurrencyStatus.Value,
|
||||
|
|
@ -63,6 +64,7 @@ internal class SingleWalletCardStateConverter(
|
|||
onDeleteClick = onDeleteClick,
|
||||
balance = formatFiatAmount(status = status, appCurrency = appCurrency),
|
||||
cardCount = selectedWallet.getCardsCount(),
|
||||
isZeroBalance = status.fiatAmount?.isZero(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.utils
|
||||
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletManageButton
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
internal fun WalletState.MultiCurrency.Content.enableButtons(): PersistentList<WalletManageButton> {
|
||||
return changeAvailability(enabled = true)
|
||||
}
|
||||
|
||||
internal fun WalletState.MultiCurrency.Content.disableButtons(): PersistentList<WalletManageButton> {
|
||||
return changeAvailability(enabled = false)
|
||||
}
|
||||
|
||||
private fun WalletState.MultiCurrency.Content.changeAvailability(enabled: Boolean): PersistentList<WalletManageButton> {
|
||||
return buttons
|
||||
.map { action ->
|
||||
when (action) {
|
||||
is WalletManageButton.Buy -> action.copy(enabled = enabled)
|
||||
is WalletManageButton.Sell -> action.copy(enabled = enabled)
|
||||
is WalletManageButton.Swap -> action.copy(enabled = enabled)
|
||||
else -> action
|
||||
}
|
||||
}
|
||||
.toPersistentList()
|
||||
}
|
||||
|
|
@ -98,18 +98,18 @@ internal class WalletLoadingStateFactory(
|
|||
|
||||
return persistentListOf(
|
||||
WalletManageButton.Buy(
|
||||
enabled = false,
|
||||
dimContent = true,
|
||||
enabled = true,
|
||||
dimContent = false,
|
||||
onClick = { clickIntents.onMultiWalletBuyClick(userWalletId = userWallet.walletId) },
|
||||
),
|
||||
WalletManageButton.Swap(
|
||||
enabled = false,
|
||||
dimContent = true,
|
||||
enabled = true,
|
||||
dimContent = false,
|
||||
onClick = { clickIntents.onMultiWalletSwapClick(userWalletId = userWallet.walletId) },
|
||||
),
|
||||
WalletManageButton.Sell(
|
||||
enabled = false,
|
||||
dimContent = true,
|
||||
enabled = true,
|
||||
dimContent = false,
|
||||
onClick = { clickIntents.onMultiWalletSellClick(userWalletId = userWallet.walletId) },
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,9 +21,14 @@ import com.tangem.core.ui.haptic.VibratorHapticManager
|
|||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.extenstions.unwrap
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.utils.lceError
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.markets.TokenMarketParams
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||
import com.tangem.domain.staking.model.stakekit.Yield
|
||||
import com.tangem.domain.tokens.*
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
|
|
@ -42,17 +47,23 @@ 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.WalletCardState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletManageButton
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.DisableActionTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.scopes.ViewModelScoped
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.launch
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
interface WalletCurrencyActionsClickIntents {
|
||||
|
||||
|
|
@ -112,6 +123,8 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
private val vibratorHapticManager: VibratorHapticManager,
|
||||
private val clipboardManager: ClipboardManager,
|
||||
private val appRouter: AppRouter,
|
||||
private val rampStateManager: RampStateManager,
|
||||
private val getUserCountryUseCase: GetUserCountryUseCase,
|
||||
) : BaseWalletClickIntents(), WalletCurrencyActionsClickIntents {
|
||||
|
||||
override fun onSendClick(
|
||||
|
|
@ -441,36 +454,59 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onMultiWalletSellClick(userWalletId: UserWalletId) {
|
||||
analyticsEventHandler.send(
|
||||
event = MainScreenAnalyticsEvent.ButtonSell(
|
||||
status = AnalyticsParam.Status.Success, // TODO [REDACTED_JIRA]
|
||||
),
|
||||
)
|
||||
viewModelScope.launch {
|
||||
val userCountry = getUserCountryUseCase().getOrNull()
|
||||
if (userCountry is UserCountry.Russia) {
|
||||
handleError(
|
||||
userWalletId = userWalletId,
|
||||
actionKClass = WalletManageButton.Sell::class,
|
||||
alertState = WalletAlertState.SellingRegionalRestriction,
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonSell,
|
||||
)
|
||||
|
||||
// TODO [REDACTED_JIRA]
|
||||
appRouter.push(route = AppRoute.SellCrypto(userWalletId = userWalletId))
|
||||
return@launch
|
||||
}
|
||||
|
||||
val selectedWallet = stateHolder.getSelectedWallet().walletCardState as? WalletCardState.Content
|
||||
if (selectedWallet?.isZeroBalance == true) {
|
||||
handleError(
|
||||
userWalletId = userWalletId,
|
||||
actionKClass = WalletManageButton.Sell::class,
|
||||
alertState = WalletAlertState.InsufficientBalanceForSelling,
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonSell,
|
||||
)
|
||||
|
||||
return@launch
|
||||
}
|
||||
|
||||
onMultiWalletActionClick(
|
||||
userWalletId = userWalletId,
|
||||
statusFlow = rampStateManager.getSellInitializationStatus(),
|
||||
route = AppRoute.SellCrypto(userWalletId = userWalletId),
|
||||
actionKClass = WalletManageButton.Sell::class,
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonSell,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMultiWalletSwapClick(userWalletId: UserWalletId) {
|
||||
analyticsEventHandler.send(
|
||||
event = MainScreenAnalyticsEvent.ButtonSwap(
|
||||
status = AnalyticsParam.Status.Success, // TODO [REDACTED_JIRA]
|
||||
),
|
||||
onMultiWalletActionClick(
|
||||
userWalletId = userWalletId,
|
||||
statusFlow = rampStateManager.getSwapInitializationStatus(userWalletId),
|
||||
route = AppRoute.SwapCrypto(userWalletId = userWalletId),
|
||||
actionKClass = WalletManageButton.Swap::class,
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonSwap,
|
||||
)
|
||||
|
||||
// TODO [REDACTED_JIRA]
|
||||
appRouter.push(route = AppRoute.SwapCrypto(userWalletId = userWalletId))
|
||||
}
|
||||
|
||||
override fun onMultiWalletBuyClick(userWalletId: UserWalletId) {
|
||||
analyticsEventHandler.send(
|
||||
event = MainScreenAnalyticsEvent.ButtonBuy(
|
||||
status = AnalyticsParam.Status.Success, // TODO [REDACTED_JIRA]
|
||||
),
|
||||
onMultiWalletActionClick(
|
||||
userWalletId = userWalletId,
|
||||
statusFlow = rampStateManager.getBuyInitializationStatus(),
|
||||
route = AppRoute.BuyCrypto(userWalletId = userWalletId),
|
||||
actionKClass = WalletManageButton.Buy::class,
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonBuy,
|
||||
)
|
||||
|
||||
// TODO [REDACTED_JIRA]
|
||||
appRouter.push(route = AppRoute.BuyCrypto(userWalletId = userWalletId))
|
||||
}
|
||||
|
||||
private fun openExplorer() {
|
||||
|
|
@ -570,4 +606,69 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun onMultiWalletActionClick(
|
||||
userWalletId: UserWalletId,
|
||||
statusFlow: Flow<Lce<Throwable, Any>>,
|
||||
route: AppRoute,
|
||||
actionKClass: KClass<out WalletManageButton>,
|
||||
eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent,
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
statusFlow.foldStatus(
|
||||
onContent = { handleContent(route, eventCreator) },
|
||||
onError = {
|
||||
handleError(
|
||||
userWalletId = userWalletId,
|
||||
actionKClass = actionKClass,
|
||||
eventCreator = eventCreator,
|
||||
)
|
||||
},
|
||||
onLoading = { handleLoading(eventCreator) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun Flow<Lce<Throwable, Any>>.foldStatus(
|
||||
onContent: () -> Unit,
|
||||
onError: () -> Unit,
|
||||
onLoading: () -> Unit,
|
||||
) {
|
||||
val status = firstOrNull() ?: IllegalStateException("Status is null").lceError()
|
||||
|
||||
when (status) {
|
||||
is Lce.Content -> onContent()
|
||||
is Lce.Error -> onError()
|
||||
is Lce.Loading -> onLoading()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleContent(route: AppRoute, eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent) {
|
||||
analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Success))
|
||||
|
||||
appRouter.push(route = route)
|
||||
}
|
||||
|
||||
private fun handleError(
|
||||
userWalletId: UserWalletId,
|
||||
actionKClass: KClass<out WalletManageButton>,
|
||||
alertState: WalletAlertState = WalletAlertState.UnavailableOperation,
|
||||
eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent,
|
||||
) {
|
||||
analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Error))
|
||||
|
||||
stateHolder.update(
|
||||
transformer = DisableActionTransformer(userWalletId = userWalletId, actionClass = actionKClass),
|
||||
)
|
||||
|
||||
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),
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue