Updated on 2026-08-14
This commit is contained in:
parent
507b608807
commit
768422ea7c
34 changed files with 661 additions and 80 deletions
|
|
@ -320,6 +320,13 @@ internal class ChildFactory @Inject constructor(
|
|||
userWalletId = route.userWalletId,
|
||||
isInitialReverseOrder = route.isInitialReverseOrder,
|
||||
screenSource = route.screenSource,
|
||||
tangemPayInput = route.tangemPayInput?.let { tangemPayInput ->
|
||||
SwapComponent.Params.TangemPayInput(
|
||||
cryptoAmount = tangemPayInput.cryptoAmount,
|
||||
fiatAmount = tangemPayInput.fiatAmount,
|
||||
depositAddress = tangemPayInput.depositAddress,
|
||||
)
|
||||
},
|
||||
),
|
||||
componentFactory = swapComponentFactory,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import com.tangem.domain.models.PortfolioId
|
|||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
import com.tangem.domain.onramp.model.OnrampSource
|
||||
|
|
@ -181,13 +182,21 @@ sealed class AppRoute(val path: String) : Route {
|
|||
val userWalletId: UserWalletId,
|
||||
val isInitialReverseOrder: Boolean = false,
|
||||
val screenSource: String,
|
||||
val tangemPayInput: TangemPayInput? = null,
|
||||
) : AppRoute(
|
||||
path = "/swap" +
|
||||
"/${currencyFrom.id.value}" +
|
||||
"/${currencyTo?.id?.value}" +
|
||||
"/${userWalletId.stringValue}" +
|
||||
"/$isInitialReverseOrder",
|
||||
)
|
||||
) {
|
||||
@Serializable
|
||||
data class TangemPayInput(
|
||||
val cryptoAmount: SerializedBigDecimal,
|
||||
val fiatAmount: SerializedBigDecimal,
|
||||
val depositAddress: String,
|
||||
)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data object AppCurrencySelector : AppRoute(path = "/app_currency_selector")
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ sealed class AnalyticsParam {
|
|||
data object LongTap : ScreensSources("Long Tap")
|
||||
data object Markets : ScreensSources("Markets")
|
||||
data object HotWallet : ScreensSources("Hot Wallet")
|
||||
data object TangemPay : ScreensSources("Tangem Pay")
|
||||
}
|
||||
|
||||
sealed class TxSentFrom(val value: String) {
|
||||
|
|
|
|||
|
|
@ -760,6 +760,8 @@
|
|||
<string name="notification_sepa_button">Krypto kaufen</string>
|
||||
<string name="notification_sepa_text">Profitiere von **0 % Gebühren** beim Kauf von Kryptowährungen per SEPA-Überweisung.</string>
|
||||
<string name="notification_sepa_title">Krypto mit SEPA kaufen</string>
|
||||
<string name="notification_visa_waitlist_promo_text">Trage dich in die Warteliste ein und erhalte eine Zahlungskarte, die es so noch nie gab.</string>
|
||||
<string name="notification_visa_waitlist_promo_title">Tangem Visa Card</string>
|
||||
<string name="onboarding_access_code_feature_1_description">Du musst einen einzigen Zugangscode einrichten, um alle deine Geräte zu schützen</string>
|
||||
<string name="onboarding_access_code_feature_1_title">Schützen</string>
|
||||
<string name="onboarding_access_code_feature_2_description">Du kannst später auf jeder Karte oder Ring einen individuellen Zugangscode einrichten</string>
|
||||
|
|
@ -1711,7 +1713,7 @@
|
|||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem erhebt außerdem eine Servicegebühr von 15% auf den erzielten Ertrag.</string>
|
||||
<string name="yield_module_high_fee_error">Deine Gelder werden automatisch an Aave überwiesen, sobald die Netzwerkgebühren niedriger sind oder Dein Guthaben den erforderlichen Mindestbetrag erreicht.</string>
|
||||
<string name="yield_module_historical_returns">Historische Renditen</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Die Freigabe für Deine Token im Yield-Modus wurde widerrufen. Öffne den Token, um die Berechtigung erneut zu erteilen.</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Die Genehmigung für Deine Token im Yield-Modus wurde widerrufen. Öffne den Token, um die Berechtigung erneut zu erteilen.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Token-Genehmigung erforderlich</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Prüfe Deine Netzwerkverbindung</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_title">Informationen zu den Netzwerkgebühren nicht erreichbar</string>
|
||||
|
|
@ -1743,6 +1745,7 @@
|
|||
<string name="yield_module_stop_earning_sheet_fee_note">Die Netzwerkgebühr wird von dem Betrag, den Du abhebst, abgezogen.</string>
|
||||
<string name="yield_module_supply_apr">Effektiver Jahreszins für Versorgung</string>
|
||||
<string name="yield_module_token_details_earn_notification_apy">Effektiver Jahreszins</string>
|
||||
<string name="yield_module_token_details_earn_notification_description">Zinsen fallen automatisch an</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_subtitle">Zinsen fallen automatisch an</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Ertragsmodus</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Bearbeitung Deiner Einzahlung</string>
|
||||
|
|
|
|||
|
|
@ -653,6 +653,8 @@
|
|||
<string name="notification_sepa_button">Comprar cripto</string>
|
||||
<string name="notification_sepa_text">Disfrute de unas comisiones del **0%** al comprar criptomonedas mediante transferencias SEPA.</string>
|
||||
<string name="notification_sepa_title">Comprar criptomonedas con SEPA</string>
|
||||
<string name="notification_visa_waitlist_promo_text">Únete a la lista de espera y consigue una tarjeta de pago como ninguna otra.</string>
|
||||
<string name="notification_visa_waitlist_promo_title">Tangem Visa Card</string>
|
||||
<string name="onboarding_access_code_feature_1_description">Configure un código de acceso único para proteger todos sus dispositivos.</string>
|
||||
<string name="onboarding_access_code_feature_1_title">Proteger</string>
|
||||
<string name="onboarding_access_code_feature_2_description">Puede configurar un código de acceso individual en cada tarjeta más adelante</string>
|
||||
|
|
@ -1544,9 +1546,11 @@
|
|||
<string name="yield_module_stop_earning_sheet_fee_note">La comisión de red se deducirá del importe que retire.</string>
|
||||
<string name="yield_module_supply_apr">Suministro APY</string>
|
||||
<string name="yield_module_token_details_earn_notification_apy">APY</string>
|
||||
<string name="yield_module_token_details_earn_notification_description">Los intereses se devengan automáticamente</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_subtitle">Los intereses se devengan automáticamente</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Modo de rendimiento</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Procesando su depósito</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Modo Rendimiento</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Automático</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Deposite algo de %1$s %2$s para cubrir la tarifa de red para las transacciones</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">No se puede cubrir la tarifa %s</string>
|
||||
|
|
|
|||
|
|
@ -626,6 +626,8 @@
|
|||
<string name="notification_sepa_button">Acheter crypto</string>
|
||||
<string name="notification_sepa_text">Profitez de **0% de frais** lors de l\'achat de cryptomonnaies via des virements SEPA.</string>
|
||||
<string name="notification_sepa_title">Acheter des cryptomonnaies avec SEPA</string>
|
||||
<string name="notification_visa_waitlist_promo_text">Rejoignez la liste d’attente et obtenez une carte de paiement pas comme les autres.</string>
|
||||
<string name="notification_visa_waitlist_promo_title">Tangem Visa Card</string>
|
||||
<string name="onboarding_access_code_feature_1_description">Vous devez définir un seul code d\'accès pour protéger tous vos appareils.</string>
|
||||
<string name="onboarding_access_code_feature_1_title">Protéger</string>
|
||||
<string name="onboarding_access_code_feature_2_description">Vous pourrez définir un code d\'accès individuel sur chaque carte plus tard</string>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
<string name="account_details_archive">アカウントをアーカイブする</string>
|
||||
<string name="account_details_archive_action">アーカイブ</string>
|
||||
<string name="account_details_archive_description">このアカウントをアーカイブしますが、いつでも復元できます。</string>
|
||||
<string name="account_details_archiving">アーカイブ中・・・</string>
|
||||
<string name="account_details_title">アカウント</string>
|
||||
<string name="account_edit_success_message">アカウントが保存されました</string>
|
||||
<string name="account_for_rewards">報酬用のアカウント</string>
|
||||
|
|
@ -156,6 +157,13 @@
|
|||
<plurals name="card_label_token_count">
|
||||
<item quantity="other">%1$dトークン</item>
|
||||
</plurals>
|
||||
<string name="card_reset_alert_continue_message">続行するには次のデバイスをリセットしてください。</string>
|
||||
<string name="card_reset_alert_continue_title">ウォレットのリセット</string>
|
||||
<string name="card_reset_alert_finish_message">すべてのTangemデバイスがリセットされました。ウォレットのアップグレードを続行できます。</string>
|
||||
<string name="card_reset_alert_finish_ok_button">もう一度アップグレードしてください</string>
|
||||
<string name="card_reset_alert_finish_title">リセット完了</string>
|
||||
<string name="card_reset_alert_incomplete_message">すべてのTangemデバイスをリセットしていません</string>
|
||||
<string name="card_reset_alert_incomplete_title">すべてのTangemデバイスをリセットしていません</string>
|
||||
<string name="card_settings_access_code_recovery_disabled_description">このカードを使用して、このウォレット内の他のカードまたはリングのアクセスコードをリセットしたくない場合は、このオプションを無効にしてください。これにより、このカードのアクセスコードもリセットできなくなりますのでご注意ください。</string>
|
||||
<string name="card_settings_access_code_recovery_enabled_description">このカードを使用して、このウォレット内の他のカードのアクセスコードをリセットできます。</string>
|
||||
<string name="card_settings_access_code_recovery_title">アクセスコードの復元</string>
|
||||
|
|
@ -307,6 +315,7 @@
|
|||
<string name="common_reload">リロード</string>
|
||||
<string name="common_rename">名前を変更</string>
|
||||
<string name="common_required">必須</string>
|
||||
<string name="common_reset">リセット</string>
|
||||
<string name="common_save">保存</string>
|
||||
<string name="common_save_changes">変更内容を保存</string>
|
||||
<string name="common_search">検索</string>
|
||||
|
|
@ -423,6 +432,7 @@
|
|||
<string name="email_subject_wc_error">WalletConnectエラー</string>
|
||||
<string name="error_wrong_wallet_tapped">別のウォレットのカードまたはリングを使用しました。このウォレットにリンクしているカードまたはリングをタップしてください。</string>
|
||||
<string name="eth_gas_required_exceeds_allowance">取引に必要な資金が不足しています。アカウントに入金してください。</string>
|
||||
<string name="exchange_token_description">ポートフォリオ内のアセットをこのトークンと交換します</string>
|
||||
<string name="exchange_tokens_available_tokens_header">マイトークン</string>
|
||||
<string name="exchange_tokens_empty_tokens">まだトークンを追加していません。マーケットからトークンを追加して交換してください。</string>
|
||||
<string name="exchange_tokens_unavailable_tokens_header">%sとの交換はできません</string>
|
||||
|
|
@ -779,6 +789,8 @@
|
|||
<string name="notification_sepa_button">暗号資産を買い付ける</string>
|
||||
<string name="notification_sepa_text">SEPA送金で暗号資産を買い付けると、**手数料 0% ** になります。</string>
|
||||
<string name="notification_sepa_title">SEPAで暗号資産を購入</string>
|
||||
<string name="notification_visa_waitlist_promo_text">事前申し込み受付中。他にない特別なカードを、いち早く体験しよう。</string>
|
||||
<string name="notification_visa_waitlist_promo_title">Tangem Visaカード</string>
|
||||
<string name="onboarding_access_code_feature_1_description">すべてのデバイスを保護するには、単一のアクセスコードを設定してください。</string>
|
||||
<string name="onboarding_access_code_feature_1_title">保護する</string>
|
||||
<string name="onboarding_access_code_feature_2_description">後で各カードおよびリングに個別のアクセスコードを設定できます。</string>
|
||||
|
|
@ -1303,6 +1315,7 @@
|
|||
<string name="tangem_pay_explore_transaction">取引を表示</string>
|
||||
<string name="tangem_pay_fee_subtitle">サービス手数料</string>
|
||||
<string name="tangem_pay_fee_title">手数料</string>
|
||||
<string name="tangem_pay_get_help">サポートを受ける</string>
|
||||
<string name="tangem_pay_status_completed">完了</string>
|
||||
<string name="tangem_pay_status_declined">拒否</string>
|
||||
<string name="tangem_pay_status_pending">保留中</string>
|
||||
|
|
@ -1315,6 +1328,15 @@
|
|||
<string name="tangempay_card_details_error_text">データの読み込みに失敗しました。しばらくしてからもう一度お試しください。</string>
|
||||
<string name="tangempay_card_details_freeze_card">カードの一時停止</string>
|
||||
<string name="tangempay_card_details_hide_text">非表示</string>
|
||||
<string name="tangempay_card_details_open_wallet_button">Googleウォレットを開く</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_subtitle">数回タップするだけでTangem Payの設定完了。Google Payですぐに支払いを始めましょう。</string>
|
||||
<string name="tangempay_card_details_open_wallet_notification_title">Google Payにカードを追加する</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_1">Googleウォレットを開く</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_2">「カードを追加」をタップします</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_3">カードの詳細を手動で入力してください</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_4">お使いの端末に送信されたワンタイムパスワード(OTP)でカードを認証してください。</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">準備完了!カードはすぐに使用できます。</string>
|
||||
<string name="tangempay_card_details_open_wallet_title">Google Payにカードを追加する</string>
|
||||
<string name="tangempay_card_details_receive_error_description">技術的な問題が検出されました。しばらくしてからもう一度お試しいただくか、サポートにお問い合わせください。</string>
|
||||
<string name="tangempay_card_details_receive_error_title">現在、受け取りは利用できません</string>
|
||||
<string name="tangempay_card_details_reveal_text">表示</string>
|
||||
|
|
|
|||
|
|
@ -701,6 +701,8 @@
|
|||
<string name="notification_sepa_button">Купить криптовалюту</string>
|
||||
<string name="notification_sepa_text">Наслаждайтесь **нулевой комиссией** при покупке криптовалюты через SEPA-переводы.</string>
|
||||
<string name="notification_sepa_title">Покупайте крипту через SEPA</string>
|
||||
<string name="notification_visa_waitlist_promo_text">Присоединяйтесь к списку ожидания и получите уникальную платёжную карту, не похожую ни на одну другую.</string>
|
||||
<string name="notification_visa_waitlist_promo_title">Tangem Visa Card</string>
|
||||
<string name="onboarding_access_code_feature_1_description">Установите единый код доступа для защиты всех ваших карт или колец</string>
|
||||
<string name="onboarding_access_code_feature_1_title">Защита</string>
|
||||
<string name="onboarding_access_code_feature_2_description">Установите индивидуальный код доступа для каждой карты или кольца позже.</string>
|
||||
|
|
@ -1631,7 +1633,7 @@
|
|||
<string name="yield_module_start_earning_sheet_next_deposits">Следующие пополнения вашего счёта автоматически поступят в Aave.</string>
|
||||
<string name="yield_module_status_active">Активен</string>
|
||||
<string name="yield_module_status_paused">На паузе</string>
|
||||
<string name="yield_module_stop_earning">Завершить заработок</string>
|
||||
<string name="yield_module_stop_earning">Завершение режима доходности</string>
|
||||
<string name="yield_module_stop_earning_sheet_description">Выключив эту функцию, вы выведёте средства из Aave, получите их обратно в %s в своем кошельке и перестанете зарабатывать награды.</string>
|
||||
<string name="yield_module_stop_earning_sheet_fee_note">Комиссия сети будет вычтена из суммы вашего вывода.</string>
|
||||
<string name="yield_module_supply_apr">Годовая доходность (APY)</string>
|
||||
|
|
|
|||
|
|
@ -629,6 +629,8 @@
|
|||
<string name="notification_sepa_button">Купити криптовалюту</string>
|
||||
<string name="notification_sepa_text">Насолоджуйтесь **нульовою комісією** при купівлі криптовалюти через перекази SEPA.</string>
|
||||
<string name="notification_sepa_title">Купуйте криптовалюту через SEPA</string>
|
||||
<string name="notification_visa_waitlist_promo_text">Приєднуйтесь до списку очікування та отримайте унікальну платіжну картку, якої ще не було.</string>
|
||||
<string name="notification_visa_waitlist_promo_title">Tangem Visa Card</string>
|
||||
<string name="onboarding_access_code_feature_1_description">Налаштуйте єдиний код доступу для захисту всіх ваших карток або кілець</string>
|
||||
<string name="onboarding_access_code_feature_1_title">Захист</string>
|
||||
<string name="onboarding_access_code_feature_2_description">Встановіть індивідуальний код доступу для кожної картки або кільця пізніше.</string>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
<string name="account_details_archive">Archive account</string>
|
||||
<string name="account_details_archive_action">Archive</string>
|
||||
<string name="account_details_archive_description">You are archiving this account, but you can always get it back.</string>
|
||||
<string name="account_details_archiving">Archiving...</string>
|
||||
<string name="account_details_title">Account</string>
|
||||
<string name="account_edit_success_message">Account saved</string>
|
||||
<string name="account_for_rewards">Account for rewards</string>
|
||||
|
|
@ -159,6 +160,13 @@
|
|||
<item quantity="one">%d token</item>
|
||||
<item quantity="other">%d tokens</item>
|
||||
</plurals>
|
||||
<string name="card_reset_alert_continue_message">Please reset the next device to continue.</string>
|
||||
<string name="card_reset_alert_continue_title">Wallet reset</string>
|
||||
<string name="card_reset_alert_finish_message">All Tangem devices have been reset. You can now continue upgrading your wallet.</string>
|
||||
<string name="card_reset_alert_finish_ok_button">Upgrade again</string>
|
||||
<string name="card_reset_alert_finish_title">Reset complete</string>
|
||||
<string name="card_reset_alert_incomplete_message">You haven’t reset all your Tangem devices</string>
|
||||
<string name="card_reset_alert_incomplete_title">You haven’t reset all your Tangem devices</string>
|
||||
<string name="card_settings_access_code_recovery_disabled_description">Disable this option if you don\'t want this card to be used to reset access codes on other cards or rings in this wallet. Please note that this will also prevent you from resetting the access code on this card.</string>
|
||||
<string name="card_settings_access_code_recovery_enabled_description">Allows you to use this card to reset access code on other cards in this wallet</string>
|
||||
<string name="card_settings_access_code_recovery_title">Access code recovery</string>
|
||||
|
|
@ -313,6 +321,7 @@
|
|||
<string name="common_reload">Reload</string>
|
||||
<string name="common_rename">Rename</string>
|
||||
<string name="common_required">Required</string>
|
||||
<string name="common_reset">Reset</string>
|
||||
<string name="common_save">Save</string>
|
||||
<string name="common_save_changes">Save changes</string>
|
||||
<string name="common_search">Search</string>
|
||||
|
|
@ -431,6 +440,7 @@
|
|||
<string name="email_subject_wc_error">WalletConnect error</string>
|
||||
<string name="error_wrong_wallet_tapped">You have used a card or ring from another wallet. Tap the card or ring associated with this wallet</string>
|
||||
<string name="eth_gas_required_exceeds_allowance">Not enough funds for the transaction. Please top up your account.</string>
|
||||
<string name="exchange_token_description">Swap any asset in your portfolio for this token</string>
|
||||
<string name="exchange_tokens_available_tokens_header">My tokens</string>
|
||||
<string name="exchange_tokens_empty_tokens">You haven\'t added any tokens yet. Add tokens via Market to swap</string>
|
||||
<string name="exchange_tokens_unavailable_tokens_header">Cannot be swapped for %s</string>
|
||||
|
|
@ -795,6 +805,8 @@
|
|||
<string name="notification_sepa_button">Buy crypto</string>
|
||||
<string name="notification_sepa_text">Enjoy **0% fees** when purchasing crypto via SEPA transfers.</string>
|
||||
<string name="notification_sepa_title">Buy Crypto with SEPA</string>
|
||||
<string name="notification_visa_waitlist_promo_text">Join the waitlist and get a payment card unlike any other</string>
|
||||
<string name="notification_visa_waitlist_promo_title">Tangem Visa Card</string>
|
||||
<string name="onboarding_access_code_feature_1_description">Set up a single access code to protect all your devices.</string>
|
||||
<string name="onboarding_access_code_feature_1_title">Protect</string>
|
||||
<string name="onboarding_access_code_feature_2_description">Set an individual access code for each card or ring later.</string>
|
||||
|
|
@ -1326,6 +1338,9 @@
|
|||
<string name="tangem_pay_explore_transaction">Explore transaction</string>
|
||||
<string name="tangem_pay_fee_subtitle">Service fees</string>
|
||||
<string name="tangem_pay_fee_title">Fee</string>
|
||||
<string name="tangem_pay_freeze_card_alert_body">Keep your money safe if your card is lost or stolen. You can unfreeze anytime.</string>
|
||||
<string name="tangem_pay_freeze_card_alert_title">Freeze your card?</string>
|
||||
<string name="tangem_pay_freeze_card_freeze">Freeze</string>
|
||||
<string name="tangem_pay_get_help">Get Help</string>
|
||||
<string name="tangem_pay_status_completed">Completed</string>
|
||||
<string name="tangem_pay_status_declined">Declined</string>
|
||||
|
|
@ -1333,6 +1348,8 @@
|
|||
<string name="tangem_pay_transaction_declined_notification_text">The bank rejected this transaction request.</string>
|
||||
<string name="tangem_pay_transaction_fee_notification_text">This fee goes to cover the cost of handling your transfer.</string>
|
||||
<string name="tangem_pay_withdrawal">Withdrawal</string>
|
||||
<string name="tangempay_card_details_add_funds">Add funds</string>
|
||||
<string name="tangempay_card_details_add_funds_subtitle">Top-up options</string>
|
||||
<string name="tangempay_card_details_change_pin">Change PIN</string>
|
||||
<string name="tangempay_card_details_change_pin_success_description">The card is fully ready for payments.</string>
|
||||
<string name="tangempay_card_details_change_pin_success_title">PIN code created</string>
|
||||
|
|
@ -1348,9 +1365,11 @@
|
|||
<string name="tangempay_card_details_open_wallet_step_4">Verify card using the OTP sent to your device.</string>
|
||||
<string name="tangempay_card_details_open_wallet_step_5">All set! Your card is ready to use.</string>
|
||||
<string name="tangempay_card_details_open_wallet_title">Add card to Google Pay</string>
|
||||
<string name="tangempay_card_details_receive_description">Share your address or show QR-code</string>
|
||||
<string name="tangempay_card_details_receive_error_description">Technical issues detected. Please try again later or contact support.</string>
|
||||
<string name="tangempay_card_details_receive_error_title">Receive unavailable now</string>
|
||||
<string name="tangempay_card_details_reveal_text">Reveal</string>
|
||||
<string name="tangempay_card_details_swap_description">Swap any asset in your portfolio for card</string>
|
||||
<string name="tangempay_card_details_title">Card details</string>
|
||||
<string name="tangempay_issue_card_notification_title">Create account and issue a card</string>
|
||||
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
|
||||
|
|
@ -1869,7 +1888,7 @@
|
|||
<string name="yield_module_promo_screen_cash_out_subtitle">Send, swap, or sell your funds instantly, anytime you want.</string>
|
||||
<string name="yield_module_promo_screen_cash_out_title">Access your funds anytime</string>
|
||||
<string name="yield_module_promo_screen_how_it_works_button_title">How it works?</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_subtitle">Aave is a decentralized protocol managing over $61 billion in total value.</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_subtitle">Aave is a decentralized protocol managing over $61 billion in total value.</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_title">Decentralized and self-custodial</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">By using this service, you agree with provider\n%1$s and %2$s</string>
|
||||
<string name="yield_module_promo_screen_title">Connect Aave</string>
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ dependencies {
|
|||
implementation(projects.domain.tokens)
|
||||
implementation(projects.domain.networks)
|
||||
implementation(projects.domain.walletManager)
|
||||
implementation(projects.domain.quotes)
|
||||
|
||||
/** Feature API - remove after removing [HotWalletFeatureToggles] */
|
||||
implementation(projects.features.hotWallet.api)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.data.pay
|
|||
import arrow.core.Either
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.blockchain.blockchains.ethereum.Chain
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
||||
|
|
@ -14,13 +13,15 @@ import com.tangem.datasource.di.NetworkMoshi
|
|||
import com.tangem.domain.models.ReceiveAddressModel
|
||||
import com.tangem.domain.models.ReceiveAddressModel.NameService
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.pay.DataForReceive
|
||||
import com.tangem.domain.pay.DataForReceiveFactory
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.pay.TangemPayTopUpData
|
||||
import com.tangem.domain.pay.TangemPayTopUpDataFactory
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val TAG = "TangemPay: TokenReceiveConfigFactory"
|
||||
private const val TAG = "TangemPay: DefaultDataForTopUpFactory"
|
||||
/**
|
||||
* Custom token parameters. Will be used only for F&F.
|
||||
*/
|
||||
|
|
@ -29,11 +30,11 @@ private const val TOKEN_NAME = "USDC"
|
|||
private const val TOKEN_CONTRACT_ADDRESS = "0x3c499c542cef5e3811e1192ce70d8cc03d5c3359"
|
||||
private const val TOKEN_DECIMALS = 6
|
||||
|
||||
internal class DefaultDataForReceiveFactory @Inject constructor(
|
||||
internal class DefaultTangemPayTopUpDataFactory @Inject constructor(
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
private val tangemPayWalletsManager: TangemPayWalletsManager,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
) : DataForReceiveFactory {
|
||||
) : TangemPayTopUpDataFactory {
|
||||
|
||||
private val cryptoCurrencyFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
CryptoCurrencyFactory(excludedBlockchains)
|
||||
|
|
@ -43,26 +44,39 @@ internal class DefaultDataForReceiveFactory @Inject constructor(
|
|||
}
|
||||
private val errorConverter by lazy(mode = LazyThreadSafetyMode.NONE) { TangemPayErrorConverter(moshi) }
|
||||
|
||||
override fun getDataForReceive(depositAddress: String, chainId: Int): Either<UniversalError, DataForReceive> {
|
||||
private fun getCurrency(userWallet: UserWallet, chainId: Int): CryptoCurrency {
|
||||
val chain = requireNotNull(Chain.entries.find { it.id == chainId }) { "Can not find chain with $chainId" }
|
||||
val blockchain = requireNotNull(chain.blockchain)
|
||||
val network = networkFactory.create(
|
||||
blockchain = blockchain,
|
||||
extraDerivationPath = null,
|
||||
userWallet = userWallet,
|
||||
)
|
||||
return cryptoCurrencyFactory.createToken(
|
||||
network = requireNotNull(network),
|
||||
rawId = CryptoCurrency.RawID(TOKEN_ID),
|
||||
name = TOKEN_NAME,
|
||||
symbol = TOKEN_NAME,
|
||||
contractAddress = TOKEN_CONTRACT_ADDRESS,
|
||||
decimals = TOKEN_DECIMALS,
|
||||
)
|
||||
}
|
||||
|
||||
override fun create(
|
||||
depositAddress: String,
|
||||
chainId: Int,
|
||||
cryptoBalance: BigDecimal,
|
||||
fiatBalance: BigDecimal,
|
||||
): Either<UniversalError, TangemPayTopUpData> {
|
||||
return try {
|
||||
val wallet = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking()
|
||||
val blockchain: Blockchain? = Chain.entries.find { it.id == chainId }?.blockchain
|
||||
val network = networkFactory.create(
|
||||
blockchain = requireNotNull(blockchain),
|
||||
extraDerivationPath = null,
|
||||
userWallet = wallet,
|
||||
)
|
||||
val currency = cryptoCurrencyFactory.createToken(
|
||||
network = requireNotNull(network),
|
||||
rawId = CryptoCurrency.RawID(TOKEN_ID),
|
||||
name = TOKEN_NAME,
|
||||
symbol = TOKEN_NAME,
|
||||
contractAddress = TOKEN_CONTRACT_ADDRESS,
|
||||
decimals = TOKEN_DECIMALS,
|
||||
)
|
||||
val result = DataForReceive(
|
||||
val currency = getCurrency(wallet, chainId)
|
||||
val result = TangemPayTopUpData(
|
||||
currency = currency,
|
||||
walletId = wallet.walletId,
|
||||
cryptoBalance = cryptoBalance,
|
||||
fiatBalance = fiatBalance,
|
||||
depositAddress = depositAddress,
|
||||
receiveAddress = listOf(ReceiveAddressModel(nameService = NameService.Default, value = depositAddress)),
|
||||
)
|
||||
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
package com.tangem.data.pay.di
|
||||
|
||||
import com.tangem.data.pay.DefaultDataForReceiveFactory
|
||||
import com.tangem.data.pay.DefaultTangemPayTopUpDataFactory
|
||||
import com.tangem.data.pay.repository.DefaultCardDetailsRepository
|
||||
import com.tangem.data.pay.repository.DefaultKycRepository
|
||||
import com.tangem.data.pay.repository.DefaultTangemPayTxHistoryRepository
|
||||
import com.tangem.data.pay.repository.DefaultOnboardingRepository
|
||||
import com.tangem.domain.pay.DataForReceiveFactory
|
||||
import com.tangem.data.pay.usecase.DefaultGetTangemPayCurrencyStatusUseCase
|
||||
import com.tangem.domain.pay.TangemPayTopUpDataFactory
|
||||
import com.tangem.domain.pay.repository.CardDetailsRepository
|
||||
import com.tangem.domain.pay.repository.KycRepository
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
|
||||
import com.tangem.domain.pay.usecase.TangemPayIssueOrderUseCase
|
||||
import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase
|
||||
import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase
|
||||
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
|
|
@ -42,7 +44,13 @@ internal interface TangemPayDataModule {
|
|||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindDataForReceiveFactory(factory: DefaultDataForReceiveFactory): DataForReceiveFactory
|
||||
fun bindDataForReceiveFactory(factory: DefaultTangemPayTopUpDataFactory): TangemPayTopUpDataFactory
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindGetTangemPayCurrencyStatusUseCase(
|
||||
impl: DefaultGetTangemPayCurrencyStatusUseCase,
|
||||
): GetTangemPayCurrencyStatusUseCase
|
||||
|
||||
companion object {
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package com.tangem.data.pay.usecase
|
||||
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.domain.quotes.single.SingleQuoteStatusFetcher
|
||||
import com.tangem.domain.quotes.single.SingleQuoteStatusProducer
|
||||
import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier
|
||||
import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultGetTangemPayCurrencyStatusUseCase @Inject constructor(
|
||||
private val singleQuoteStatusSupplier: SingleQuoteStatusSupplier,
|
||||
private val singleQuoteStatusFetcher: SingleQuoteStatusFetcher,
|
||||
) : GetTangemPayCurrencyStatusUseCase {
|
||||
|
||||
override suspend fun invoke(
|
||||
currency: CryptoCurrency,
|
||||
cryptoAmount: BigDecimal,
|
||||
fiatAmount: BigDecimal,
|
||||
depositAddress: String,
|
||||
): CryptoCurrencyStatus? {
|
||||
val rawCurrencyId = currency.id.rawCurrencyId ?: return null
|
||||
val quoteStatus = singleQuoteStatusSupplier.getSyncOrNull(
|
||||
params = SingleQuoteStatusProducer.Params(rawCurrencyId = rawCurrencyId),
|
||||
)?.value
|
||||
val quoteStatusData: QuoteStatus.Data = when (quoteStatus) {
|
||||
is QuoteStatus.Data -> quoteStatus
|
||||
else -> {
|
||||
singleQuoteStatusFetcher.invoke(
|
||||
params = SingleQuoteStatusFetcher.Params(rawCurrencyId = rawCurrencyId, appCurrencyId = null),
|
||||
)
|
||||
singleQuoteStatusSupplier.getSyncOrNull(
|
||||
params = SingleQuoteStatusProducer.Params(rawCurrencyId = rawCurrencyId),
|
||||
)?.value as? QuoteStatus.Data
|
||||
}
|
||||
} ?: return null
|
||||
|
||||
return CryptoCurrencyStatus(
|
||||
currency = currency,
|
||||
value = CryptoCurrencyStatus.Loaded(
|
||||
amount = cryptoAmount,
|
||||
fiatRate = quoteStatusData.fiatRate,
|
||||
priceChange = quoteStatusData.priceChange,
|
||||
fiatAmount = fiatAmount,
|
||||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(
|
||||
type = NetworkAddress.Address.Type.Primary,
|
||||
value = depositAddress,
|
||||
),
|
||||
),
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
pendingTransactions = emptySet(),
|
||||
yieldBalance = null,
|
||||
yieldSupplyStatus = null,
|
||||
hasCurrentNetworkTransactions = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package com.tangem.domain.pay
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.domain.models.ReceiveAddressModel
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface DataForReceiveFactory {
|
||||
|
||||
fun getDataForReceive(depositAddress: String, chainId: Int): Either<UniversalError, DataForReceive>
|
||||
}
|
||||
|
||||
data class DataForReceive(
|
||||
val walletId: UserWalletId,
|
||||
val currency: CryptoCurrency,
|
||||
val receiveAddress: List<ReceiveAddressModel>,
|
||||
)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.domain.pay
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.domain.models.ReceiveAddressModel
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import java.math.BigDecimal
|
||||
|
||||
interface TangemPayTopUpDataFactory {
|
||||
|
||||
fun create(
|
||||
depositAddress: String,
|
||||
chainId: Int,
|
||||
cryptoBalance: BigDecimal,
|
||||
fiatBalance: BigDecimal,
|
||||
): Either<UniversalError, TangemPayTopUpData>
|
||||
}
|
||||
|
||||
data class TangemPayTopUpData(
|
||||
val walletId: UserWalletId,
|
||||
val currency: CryptoCurrency,
|
||||
val cryptoBalance: BigDecimal,
|
||||
val fiatBalance: BigDecimal,
|
||||
val depositAddress: String,
|
||||
val receiveAddress: List<ReceiveAddressModel>,
|
||||
)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.domain.tangempay
|
||||
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import java.math.BigDecimal
|
||||
|
||||
interface GetTangemPayCurrencyStatusUseCase {
|
||||
|
||||
suspend operator fun invoke(
|
||||
currency: CryptoCurrency,
|
||||
cryptoAmount: BigDecimal,
|
||||
fiatAmount: BigDecimal,
|
||||
depositAddress: String,
|
||||
): CryptoCurrencyStatus?
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.tangem.core.decompose.factory.ComponentFactory
|
|||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import java.math.BigDecimal
|
||||
|
||||
interface SwapComponent : ComposableContentComponent {
|
||||
|
||||
|
|
@ -13,7 +14,14 @@ interface SwapComponent : ComposableContentComponent {
|
|||
val userWalletId: UserWalletId,
|
||||
val isInitialReverseOrder: Boolean = false,
|
||||
val screenSource: String,
|
||||
)
|
||||
val tangemPayInput: TangemPayInput? = null,
|
||||
) {
|
||||
data class TangemPayInput(
|
||||
val cryptoAmount: BigDecimal,
|
||||
val fiatAmount: BigDecimal,
|
||||
val depositAddress: String,
|
||||
)
|
||||
}
|
||||
|
||||
interface Factory : ComponentFactory<Params, SwapComponent>
|
||||
}
|
||||
|
|
@ -46,6 +46,7 @@ dependencies {
|
|||
implementation(projects.domain.express.models)
|
||||
implementation(projects.domain.account)
|
||||
implementation(projects.domain.account.status)
|
||||
implementation(projects.domain.visa)
|
||||
|
||||
/** Feature modules */
|
||||
implementation(projects.features.swap.domain)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import com.tangem.domain.promo.models.StoryContentIds
|
|||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||
import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions
|
||||
import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase
|
||||
import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
|
|
@ -113,6 +114,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
private val getTangemPayCurrencyStatusUseCase: GetTangemPayCurrencyStatusUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<SwapComponent.Params>()
|
||||
|
|
@ -121,6 +123,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val initialCurrencyTo = params.currencyTo
|
||||
private val userWalletId = params.userWalletId
|
||||
private val isInitiallyReversed = params.isInitialReverseOrder
|
||||
private val tangemPayInput = params.tangemPayInput
|
||||
|
||||
private val userWallet by lazy {
|
||||
requireNotNull(
|
||||
|
|
@ -196,7 +199,7 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
|
||||
modelScope.launch(dispatchers.io) {
|
||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
if (accountsFeatureToggles.isFeatureEnabled && tangemPayInput == null) {
|
||||
isAccountsMode = isAccountsModeEnabledUseCase.invokeSync()
|
||||
|
||||
val fromAccountStatus = getAccountCurrencyStatusUseCase.invokeSync(
|
||||
|
|
@ -220,10 +223,19 @@ internal class SwapModel @Inject constructor(
|
|||
initTokens(isInitiallyReversed)
|
||||
}
|
||||
} else {
|
||||
val fromStatus = getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = initialCurrencyFrom.id,
|
||||
).getOrNull()
|
||||
val fromStatus = if (tangemPayInput != null) {
|
||||
getTangemPayCurrencyStatusUseCase(
|
||||
currency = initialCurrencyFrom,
|
||||
cryptoAmount = tangemPayInput.cryptoAmount,
|
||||
fiatAmount = tangemPayInput.fiatAmount,
|
||||
depositAddress = tangemPayInput.depositAddress,
|
||||
)
|
||||
} else {
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = initialCurrencyFrom.id,
|
||||
).getOrNull()
|
||||
}
|
||||
val toStatus = initialCurrencyTo?.let {
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
||||
userWalletId = userWalletId,
|
||||
|
|
@ -555,6 +567,7 @@ internal class SwapModel @Inject constructor(
|
|||
selectedFeeType = dataState.selectedFee?.feeType ?: FeeType.NORMAL,
|
||||
isReverseSwapPossible = isReverseSwapPossible(),
|
||||
needApplyFCARestrictions = userCountry.needApplyFCARestrictions(),
|
||||
isForTangemPaySwap = tangemPayInput != null,
|
||||
)
|
||||
if (uiState.notifications.any { it is SwapNotificationUM.Error.UnableToCoverFeeWarning }) {
|
||||
analyticsEventHandler.send(
|
||||
|
|
@ -574,6 +587,7 @@ internal class SwapModel @Inject constructor(
|
|||
toTokenStatus = toTokenStatus,
|
||||
isReverseSwapPossible = isReverseSwapPossible(),
|
||||
toAccount = dataState.toAccount,
|
||||
isForTangemPaySwap = tangemPayInput != null,
|
||||
)
|
||||
}
|
||||
is SwapState.SwapError -> {
|
||||
|
|
@ -588,6 +602,7 @@ internal class SwapModel @Inject constructor(
|
|||
isReverseSwapPossible = isReverseSwapPossible(),
|
||||
needApplyFCARestrictions = userCountry.needApplyFCARestrictions(),
|
||||
toAccount = dataState.toAccount,
|
||||
isForTangemPaySwap = tangemPayInput != null,
|
||||
)
|
||||
sendErrorAnalyticsEvent(state.error, provider)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ internal class StateBuilder(
|
|||
selectedFeeType: FeeType,
|
||||
isReverseSwapPossible: Boolean,
|
||||
needApplyFCARestrictions: Boolean,
|
||||
isForTangemPaySwap: Boolean,
|
||||
): SwapStateHolder {
|
||||
if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
|
|
@ -369,7 +370,7 @@ internal class StateBuilder(
|
|||
enabled = getSwapButtonEnabled(notifications),
|
||||
onClick = actions.onSwapClick,
|
||||
),
|
||||
changeCardsButtonState = if (isReverseSwapPossible) {
|
||||
changeCardsButtonState = if (isReverseSwapPossible && !isForTangemPaySwap) {
|
||||
ChangeCardsButtonState.ENABLED
|
||||
} else {
|
||||
ChangeCardsButtonState.DISABLED
|
||||
|
|
@ -442,6 +443,7 @@ internal class StateBuilder(
|
|||
expressDataError: ExpressDataError,
|
||||
isReverseSwapPossible: Boolean,
|
||||
needApplyFCARestrictions: Boolean,
|
||||
isForTangemPaySwap: Boolean,
|
||||
): SwapStateHolder {
|
||||
if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
|
|
@ -500,7 +502,7 @@ internal class StateBuilder(
|
|||
enabled = false,
|
||||
onClick = actions.onSwapClick,
|
||||
),
|
||||
changeCardsButtonState = if (isReverseSwapPossible) {
|
||||
changeCardsButtonState = if (isReverseSwapPossible && !isForTangemPaySwap) {
|
||||
ChangeCardsButtonState.ENABLED
|
||||
} else {
|
||||
ChangeCardsButtonState.DISABLED
|
||||
|
|
@ -559,6 +561,7 @@ internal class StateBuilder(
|
|||
toTokenStatus: CryptoCurrencyStatus?,
|
||||
toAccount: Account.CryptoPortfolio?,
|
||||
isReverseSwapPossible: Boolean,
|
||||
isForTangemPaySwap: Boolean,
|
||||
): SwapStateHolder {
|
||||
if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
|
|
@ -601,7 +604,7 @@ internal class StateBuilder(
|
|||
enabled = false,
|
||||
onClick = { },
|
||||
),
|
||||
changeCardsButtonState = if (isReverseSwapPossible) {
|
||||
changeCardsButtonState = if (isReverseSwapPossible && !isForTangemPaySwap) {
|
||||
ChangeCardsButtonState.ENABLED
|
||||
} else {
|
||||
ChangeCardsButtonState.DISABLED
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ dependencies {
|
|||
implementation(projects.core.error)
|
||||
implementation(projects.core.navigation)
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.analytics.models)
|
||||
|
||||
/** Common */
|
||||
implementation(projects.common.ui)
|
||||
implementation(projects.common.routing)
|
||||
|
||||
/** Features api */
|
||||
implementation(projects.features.tangempay.details.api)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package com.tangem.features.tangempay.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.TangemPayTopUpData
|
||||
import com.tangem.features.tangempay.model.TangemPayAddFundsModel
|
||||
import com.tangem.features.tangempay.ui.TangemPayAddFundsContent
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal class TangemPayAddFundsComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: Params,
|
||||
) : ComposableBottomSheetComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
private val model: TangemPayAddFundsModel = getOrCreateModel(params = params)
|
||||
|
||||
override fun dismiss() {
|
||||
model.onDismiss()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun BottomSheet() {
|
||||
TangemPayAddFundsContent(state = model.uiState)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val listener: AddFundsListener,
|
||||
val walletId: UserWalletId,
|
||||
val cryptoBalance: BigDecimal,
|
||||
val fiatBalance: BigDecimal,
|
||||
val depositAddress: String,
|
||||
val chainId: Int,
|
||||
)
|
||||
}
|
||||
|
||||
internal interface AddFundsListener {
|
||||
fun onClickReceive(data: TangemPayTopUpData)
|
||||
fun onClickSwap(data: TangemPayTopUpData)
|
||||
fun onDismissAddFunds()
|
||||
}
|
||||
|
|
@ -87,6 +87,17 @@ internal class TangemPayDetailsComponent(
|
|||
onDismiss = model.bottomSheetNavigation::dismiss,
|
||||
),
|
||||
)
|
||||
is TangemPayDetailsNavigation.AddFunds -> TangemPayAddFundsComponent(
|
||||
appComponentContext = context,
|
||||
params = TangemPayAddFundsComponent.Params(
|
||||
walletId = navigation.walletId,
|
||||
cryptoBalance = navigation.cryptoBalance,
|
||||
fiatBalance = navigation.fiatBalance,
|
||||
depositAddress = navigation.depositAddress,
|
||||
chainId = navigation.chainId,
|
||||
listener = model,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.tangempay.di
|
|||
|
||||
import com.tangem.core.decompose.di.ModelComponent
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.features.tangempay.model.TangemPayAddFundsModel
|
||||
import com.tangem.features.tangempay.model.TangemPayAddToWalletModel
|
||||
import com.tangem.features.tangempay.model.TangemPayCardDetailsBlockModel
|
||||
import com.tangem.features.tangempay.model.TangemPayChangePinModel
|
||||
|
|
@ -47,4 +48,9 @@ internal interface TangemPayModelModule {
|
|||
@IntoMap
|
||||
@ClassKey(TangemPayAddToWalletModel::class)
|
||||
fun bindTangemPayAddToWalletModel(model: TangemPayAddToWalletModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(TangemPayAddFundsModel::class)
|
||||
fun bindTangemPayAddFundsModel(model: TangemPayAddFundsModel): Model
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.tangem.features.tangempay.entity
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
internal data class TangemPayAddFundsUM(
|
||||
val items: ImmutableList<TangemPayAddFundsItemUM>,
|
||||
val dismiss: () -> Unit,
|
||||
val errorMessage: MessageBottomSheetUMV2?,
|
||||
)
|
||||
|
||||
internal data class TangemPayAddFundsItemUM(
|
||||
@DrawableRes val iconRes: Int,
|
||||
val title: TextReference,
|
||||
val description: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
)
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.features.tangempay.entity
|
||||
|
||||
import com.tangem.domain.models.TokenReceiveConfig
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
|
@ -10,6 +12,15 @@ internal sealed class TangemPayDetailsNavigation {
|
|||
@Serializable
|
||||
data class Receive(val config: TokenReceiveConfig) : TangemPayDetailsNavigation()
|
||||
|
||||
@Serializable
|
||||
data class AddFunds(
|
||||
val walletId: UserWalletId,
|
||||
val cryptoBalance: SerializedBigDecimal,
|
||||
val fiatBalance: SerializedBigDecimal,
|
||||
val depositAddress: String,
|
||||
val chainId: Int,
|
||||
) : TangemPayDetailsNavigation()
|
||||
|
||||
@Serializable
|
||||
data class TransactionDetails(val transaction: TangemPayTxHistoryItem) : TangemPayDetailsNavigation()
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
internal class TangemPayDetailsStateFactory(
|
||||
private val onBack: () -> Unit,
|
||||
private val onRefresh: (ShowRefreshState) -> Unit,
|
||||
private val onReceive: () -> Unit,
|
||||
private val onAddFunds: () -> Unit,
|
||||
private val onClickChangePin: () -> Unit,
|
||||
private val onClickFreezeCard: () -> Unit,
|
||||
) {
|
||||
|
|
@ -39,13 +39,14 @@ internal class TangemPayDetailsStateFactory(
|
|||
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(
|
||||
actionButtons = persistentListOf(
|
||||
ActionButtonConfig(
|
||||
text = resourceReference(id = R.string.common_receive),
|
||||
text = resourceReference(id = R.string.tangempay_card_details_add_funds),
|
||||
iconResId = R.drawable.ic_arrow_down_24,
|
||||
onClick = onReceive,
|
||||
onClick = onAddFunds,
|
||||
),
|
||||
),
|
||||
),
|
||||
addToWalletBlockState = null,
|
||||
isBalanceHidden = false,
|
||||
addFundsEnabled = true,
|
||||
)
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ internal data class TangemPayDetailsUM(
|
|||
val balanceBlockState: TangemPayDetailsBalanceBlockState,
|
||||
val addToWalletBlockState: AddToWalletBlockState?,
|
||||
val isBalanceHidden: Boolean,
|
||||
val addFundsEnabled: Boolean,
|
||||
)
|
||||
|
||||
internal data class TangemPayCardDetailsUM(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.features.tangempay.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.domain.pay.TangemPayTopUpDataFactory
|
||||
import com.tangem.features.tangempay.components.TangemPayAddFundsComponent
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
|
||||
import com.tangem.features.tangempay.model.transformers.TangemPayAddFundsUMConverter
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class TangemPayAddFundsModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val tangemPayTopUpDataFactory: TangemPayTopUpDataFactory,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<TangemPayAddFundsComponent.Params>()
|
||||
|
||||
val uiState: TangemPayAddFundsUM = getInitialState()
|
||||
|
||||
private fun getInitialState(): TangemPayAddFundsUM {
|
||||
val data = tangemPayTopUpDataFactory.create(
|
||||
depositAddress = params.depositAddress,
|
||||
chainId = params.chainId,
|
||||
cryptoBalance = params.cryptoBalance,
|
||||
fiatBalance = params.fiatBalance,
|
||||
).getOrNull()
|
||||
|
||||
return TangemPayAddFundsUMConverter(listener = params.listener).convert(data)
|
||||
}
|
||||
|
||||
fun onDismiss() {
|
||||
params.listener.onDismissAddFunds()
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,9 @@ package com.tangem.features.tangempay.model
|
|||
import androidx.compose.runtime.Stable
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
|
|
@ -10,9 +13,11 @@ import com.tangem.core.decompose.navigation.Router
|
|||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig.ShowRefreshState
|
||||
import com.tangem.domain.models.TokenReceiveConfig
|
||||
import com.tangem.domain.pay.DataForReceiveFactory
|
||||
import com.tangem.domain.pay.TangemPayTopUpData
|
||||
import com.tangem.domain.pay.model.TangemPayCardBalance
|
||||
import com.tangem.domain.pay.repository.CardDetailsRepository
|
||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
||||
import com.tangem.features.tangempay.components.AddFundsListener
|
||||
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsErrorType
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsNavigation
|
||||
|
|
@ -44,17 +49,16 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val cardDetailsRepository: CardDetailsRepository,
|
||||
private val dataForReceiveFactory: DataForReceiveFactory,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val cardDetailsEventListener: CardDetailsEventListener,
|
||||
) : Model(), TangemPayTxHistoryUiActions {
|
||||
) : Model(), TangemPayTxHistoryUiActions, AddFundsListener {
|
||||
|
||||
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
|
||||
|
||||
private val stateFactory = TangemPayDetailsStateFactory(
|
||||
onBack = router::pop,
|
||||
onRefresh = ::onRefreshSwipe,
|
||||
onReceive = ::onClickReceive,
|
||||
onAddFunds = ::onClickAddFunds,
|
||||
onClickChangePin = ::onClickChangePin,
|
||||
onClickFreezeCard = ::onClickFreezeCard,
|
||||
)
|
||||
|
|
@ -66,6 +70,8 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
private val fetchBalanceJobHolder = JobHolder()
|
||||
private val addToWalletBannerJobHolder = JobHolder()
|
||||
|
||||
private var balance: TangemPayCardBalance? = null
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<TangemPayDetailsNavigation> = SlotNavigation()
|
||||
|
||||
init {
|
||||
|
|
@ -81,30 +87,27 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
// TODO [REDACTED_JIRA]
|
||||
}
|
||||
|
||||
private fun onClickReceive() {
|
||||
val depositAddress = params.config.depositAddress
|
||||
if (depositAddress == null) {
|
||||
private fun onClickAddFunds() {
|
||||
if (params.config.depositAddress == null || balance == null) {
|
||||
showBottomSheetError(TangemPayDetailsErrorType.Receive)
|
||||
} else {
|
||||
dataForReceiveFactory.getDataForReceive(depositAddress = depositAddress, chainId = params.config.chainId)
|
||||
.onRight {
|
||||
val config = TokenReceiveConfig(
|
||||
shouldShowWarning = false,
|
||||
cryptoCurrency = it.currency,
|
||||
userWalletId = it.walletId,
|
||||
showMemoDisclaimer = false,
|
||||
receiveAddress = it.receiveAddress,
|
||||
)
|
||||
bottomSheetNavigation.activate(TangemPayDetailsNavigation.Receive(config))
|
||||
}
|
||||
.onLeft { showBottomSheetError(TangemPayDetailsErrorType.Receive) }
|
||||
bottomSheetNavigation.activate(
|
||||
TangemPayDetailsNavigation.AddFunds(
|
||||
walletId = params.userWalletId,
|
||||
fiatBalance = requireNotNull(balance).balance,
|
||||
// Using the fiat balance as crypto balance. This will be changed when back returns crypto balance
|
||||
cryptoBalance = requireNotNull(balance).balance,
|
||||
depositAddress = requireNotNull(params.config.depositAddress),
|
||||
chainId = params.config.chainId,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchBalance(): Job {
|
||||
return modelScope.launch {
|
||||
val result = cardDetailsRepository.getCardBalance()
|
||||
uiState.update(DetailsBalanceTransformer(result))
|
||||
val result = cardDetailsRepository.getCardBalance().onRight { balance = it }
|
||||
uiState.update(DetailsBalanceTransformer(balance = result))
|
||||
}.saveIn(fetchBalanceJobHolder)
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +150,39 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
}.saveIn(addToWalletBannerJobHolder)
|
||||
}
|
||||
|
||||
override fun onClickSwap(data: TangemPayTopUpData) {
|
||||
bottomSheetNavigation.dismiss()
|
||||
router.push(
|
||||
AppRoute.Swap(
|
||||
currencyFrom = data.currency,
|
||||
userWalletId = data.walletId,
|
||||
isInitialReverseOrder = true,
|
||||
screenSource = AnalyticsParam.ScreensSources.TangemPay.value,
|
||||
tangemPayInput = AppRoute.Swap.TangemPayInput(
|
||||
cryptoAmount = data.cryptoBalance,
|
||||
fiatAmount = data.fiatBalance,
|
||||
depositAddress = data.depositAddress,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onClickReceive(data: TangemPayTopUpData) {
|
||||
bottomSheetNavigation.dismiss()
|
||||
val config = TokenReceiveConfig(
|
||||
shouldShowWarning = false,
|
||||
cryptoCurrency = data.currency,
|
||||
userWalletId = data.walletId,
|
||||
showMemoDisclaimer = false,
|
||||
receiveAddress = data.receiveAddress,
|
||||
)
|
||||
bottomSheetNavigation.activate(TangemPayDetailsNavigation.Receive(config))
|
||||
}
|
||||
|
||||
override fun onDismissAddFunds() {
|
||||
bottomSheetNavigation.dismiss()
|
||||
}
|
||||
|
||||
override fun onTransactionClick(item: TangemPayTxHistoryItem) {
|
||||
bottomSheetNavigation.activate(TangemPayDetailsNavigation.TransactionDetails(item))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
package com.tangem.features.tangempay.model.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.pay.TangemPayTopUpData
|
||||
import com.tangem.features.tangempay.components.AddFundsListener
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsItemUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsErrorType
|
||||
import com.tangem.features.tangempay.utils.TangemPayErrorMessageFactory
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal class TangemPayAddFundsUMConverter(
|
||||
val listener: AddFundsListener,
|
||||
) : Converter<TangemPayTopUpData?, TangemPayAddFundsUM> {
|
||||
|
||||
override fun convert(value: TangemPayTopUpData?): TangemPayAddFundsUM {
|
||||
return if (value == null) {
|
||||
TangemPayAddFundsUM(
|
||||
items = persistentListOf(),
|
||||
dismiss = listener::onDismissAddFunds,
|
||||
errorMessage = TangemPayErrorMessageFactory.createErrorMessage(
|
||||
type = TangemPayDetailsErrorType.Receive,
|
||||
).messageBottomSheetUMV2,
|
||||
)
|
||||
} else {
|
||||
TangemPayAddFundsUM(
|
||||
items = persistentListOf(
|
||||
TangemPayAddFundsItemUM(
|
||||
iconRes = R.drawable.ic_exchange_vertical_24,
|
||||
title = TextReference.Res(R.string.common_exchange),
|
||||
description = TextReference.Res(R.string.tangempay_card_details_swap_description),
|
||||
onClick = { listener.onClickSwap(value) },
|
||||
),
|
||||
TangemPayAddFundsItemUM(
|
||||
iconRes = R.drawable.ic_arrow_down_24,
|
||||
title = TextReference.Res(R.string.common_receive),
|
||||
description = TextReference.Res(R.string.tangempay_card_details_receive_description),
|
||||
onClick = { listener.onClickReceive(value) },
|
||||
),
|
||||
),
|
||||
dismiss = listener::onDismissAddFunds,
|
||||
errorMessage = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetV2Content
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.extensions.TextReference.Res
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsItemUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
internal fun TangemPayAddFundsContent(state: TangemPayAddFundsUM) {
|
||||
TangemModalBottomSheet<TangemBottomSheetConfigContent.Empty>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = state.dismiss,
|
||||
content = TangemBottomSheetConfigContent.Empty,
|
||||
),
|
||||
onBack = state.dismiss,
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
title = {
|
||||
TangemModalBottomSheetTitle(
|
||||
title = resourceReference(R.string.tangempay_card_details_add_funds),
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = state.dismiss,
|
||||
)
|
||||
},
|
||||
) {
|
||||
if (state.errorMessage != null) {
|
||||
MessageBottomSheetV2Content(state.errorMessage)
|
||||
} else {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
color = TangemTheme.colors.background.primary,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 12.dp, start = 16.dp, end = 16.dp),
|
||||
text = resourceReference(R.string.tangempay_card_details_add_funds_subtitle).resolveReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
)
|
||||
state.items.forEach {
|
||||
key(it.title) {
|
||||
TangemPayTopUpItem(state = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SpacerH16()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TangemPayTopUpItem(state: TangemPayAddFundsItemUM, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = state.onClick)
|
||||
.padding(horizontal = 12.dp, vertical = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = TangemTheme.colors.icon.accent.copy(alpha = 0.1f),
|
||||
shape = CircleShape,
|
||||
)
|
||||
.size(36.dp),
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(16.dp),
|
||||
imageVector = ImageVector.vectorResource(id = state.iconRes),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
Text(
|
||||
text = state.title.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
text = state.description.resolveReference(),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TangemPayAddFundsContentPreview() {
|
||||
TangemThemePreview {
|
||||
TangemPayAddFundsContent(
|
||||
state = TangemPayAddFundsUM(
|
||||
items = persistentListOf(
|
||||
TangemPayAddFundsItemUM(
|
||||
iconRes = R.drawable.ic_exchange_vertical_24,
|
||||
title = Res(R.string.common_exchange),
|
||||
description = Res(R.string.exсhange_token_description),
|
||||
onClick = {},
|
||||
),
|
||||
TangemPayAddFundsItemUM(
|
||||
iconRes = R.drawable.ic_arrow_down_24,
|
||||
title = Res(R.string.common_receive),
|
||||
description = Res(R.string.receive_token_description),
|
||||
onClick = {},
|
||||
),
|
||||
),
|
||||
dismiss = {},
|
||||
errorMessage = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -313,6 +313,7 @@ private class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<Ta
|
|||
),
|
||||
addToWalletBlockState = AddToWalletBlockState({}, {}),
|
||||
isBalanceHidden = false,
|
||||
addFundsEnabled = true,
|
||||
),
|
||||
TangemPayDetailsUM(
|
||||
topBarConfig = TangemPayDetailsTopBarConfig(onBackClick = {}, items = null),
|
||||
|
|
@ -320,6 +321,7 @@ private class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<Ta
|
|||
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(actionButtons = persistentListOf()),
|
||||
addToWalletBlockState = AddToWalletBlockState({}, {}),
|
||||
isBalanceHidden = false,
|
||||
addFundsEnabled = true,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue