Updated on 2026-08-14
This commit is contained in:
parent
822b82d1da
commit
c36ba85816
28 changed files with 846 additions and 21 deletions
|
|
@ -313,6 +313,7 @@
|
|||
<item quantity="other">%dStunden her</item>
|
||||
</plurals>
|
||||
<string name="common_import">Importieren</string>
|
||||
<string name="common_in">in</string>
|
||||
<string name="common_in_progress">In Arbeit</string>
|
||||
<string name="common_insufficient_balance">Unzureichende Mittel</string>
|
||||
<string name="common_later">Später</string>
|
||||
|
|
@ -398,6 +399,7 @@
|
|||
<string name="common_to">An</string>
|
||||
<string name="common_to_wallet_name">Zu %s</string>
|
||||
<string name="common_today">Heute</string>
|
||||
<string name="common_token">Token</string>
|
||||
<string name="common_token_send">Zu sendendes Token</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d Token</item>
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@
|
|||
<item quantity="other">Hace %dh</item>
|
||||
</plurals>
|
||||
<string name="common_import">Importe</string>
|
||||
<string name="common_in">en</string>
|
||||
<string name="common_in_progress">En progreso</string>
|
||||
<string name="common_insufficient_balance">Fondos insuficientes</string>
|
||||
<string name="common_later">Más tarde</string>
|
||||
|
|
@ -394,6 +395,7 @@
|
|||
<string name="common_to">A</string>
|
||||
<string name="common_to_wallet_name">A %s</string>
|
||||
<string name="common_today">Hoy</string>
|
||||
<string name="common_token">Token</string>
|
||||
<string name="common_token_send">Token para enviar</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d token</item>
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@
|
|||
<item quantity="other">Il y a %dh</item>
|
||||
</plurals>
|
||||
<string name="common_import">Importez</string>
|
||||
<string name="common_in">dans</string>
|
||||
<string name="common_in_progress">En cours</string>
|
||||
<string name="common_later">Plus tard</string>
|
||||
<string name="common_learn_more">En savoir plus</string>
|
||||
|
|
@ -392,6 +393,7 @@
|
|||
<string name="common_to">À</string>
|
||||
<string name="common_to_wallet_name">À %s</string>
|
||||
<string name="common_today">Aujourd\'hui</string>
|
||||
<string name="common_token">Token</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d token</item>
|
||||
<item quantity="other">%d tokens</item>
|
||||
|
|
|
|||
|
|
@ -16,12 +16,14 @@
|
|||
<string name="common_done">Fatto</string>
|
||||
<string name="common_error">Errore</string>
|
||||
<string name="common_fee_error">Impossibile ottenere la commissione</string>
|
||||
<string name="common_in">in</string>
|
||||
<string name="common_network_fee_title">Costi della rete</string>
|
||||
<string name="common_ok">OK</string>
|
||||
<string name="common_save_changes">Mantieni le modifiche</string>
|
||||
<string name="common_send">Invia</string>
|
||||
<string name="common_send_tx_error">Impossibile inviare la transazione</string>
|
||||
<string name="common_success">Con successo</string>
|
||||
<string name="common_token">Token</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d gettone</item>
|
||||
<item quantity="other">%d gettoni</item>
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@
|
|||
<string name="common_access_denied">アクセスが拒否されました</string>
|
||||
<string name="common_account">アカウント</string>
|
||||
<string name="common_accounts">アカウント</string>
|
||||
<string name="common_action_failed">%s に失敗しました</string>
|
||||
<string name="common_activate">有効化</string>
|
||||
<string name="common_add">追加</string>
|
||||
<string name="common_add_funds">資金を追加</string>
|
||||
|
|
@ -230,6 +231,8 @@
|
|||
<string name="common_apply">適用する</string>
|
||||
<string name="common_approval">承認</string>
|
||||
<string name="common_approve">承認</string>
|
||||
<string name="common_approved">承認済み</string>
|
||||
<string name="common_approving">承認中</string>
|
||||
<string name="common_attention">注意</string>
|
||||
<string name="common_available_networks">利用可能なネットワーク</string>
|
||||
<string name="common_backup">バックアップ</string>
|
||||
|
|
@ -309,10 +312,14 @@
|
|||
<string name="common_hide">非表示</string>
|
||||
<string name="common_hold_to">%sまで長押し</string>
|
||||
<string name="common_hour">時間</string>
|
||||
<plurals name="common_hours">
|
||||
<item quantity="other">%d 時間</item>
|
||||
</plurals>
|
||||
<plurals name="common_hours_time_ago">
|
||||
<item quantity="other">%d時間前</item>
|
||||
</plurals>
|
||||
<string name="common_import">インポート</string>
|
||||
<string name="common_in">で</string>
|
||||
<string name="common_in_progress">進行中</string>
|
||||
<string name="common_insufficient_balance">残高不足</string>
|
||||
<string name="common_later">後で</string>
|
||||
|
|
@ -355,6 +362,8 @@
|
|||
<string name="common_range_with_space">%1$s — %2$s</string>
|
||||
<string name="common_read_more">続きを読む</string>
|
||||
<string name="common_receive">受け取る</string>
|
||||
<string name="common_received">受け取り済み</string>
|
||||
<string name="common_receiving">受け取り中</string>
|
||||
<string name="common_recommended">おすすめ</string>
|
||||
<string name="common_reject">拒否</string>
|
||||
<string name="common_reload">リロード</string>
|
||||
|
|
@ -373,6 +382,8 @@
|
|||
<string name="common_send">送る</string>
|
||||
<string name="common_send_colon">送金:</string>
|
||||
<string name="common_send_tx_error">取引の送信に失敗しました</string>
|
||||
<string name="common_sending">送金中</string>
|
||||
<string name="common_sent">送金済み</string>
|
||||
<string name="common_server_unavailable">サーバーが利用できません。しばらくしてからもう一度お試しください。</string>
|
||||
<string name="common_share">共有</string>
|
||||
<string name="common_share_link">リンクを共有</string>
|
||||
|
|
@ -383,6 +394,7 @@
|
|||
<string name="common_skip">スキップ</string>
|
||||
<string name="common_something_went_wrong">問題が発生しました</string>
|
||||
<string name="common_stake">ステーキング</string>
|
||||
<string name="common_staked">ステーキング済み</string>
|
||||
<string name="common_staking">ステーキング</string>
|
||||
<string name="common_start">始める</string>
|
||||
<string name="common_submit">送信</string>
|
||||
|
|
@ -390,6 +402,8 @@
|
|||
<string name="common_support">サポート</string>
|
||||
<string name="common_supported_networks">対応ネットワーク</string>
|
||||
<string name="common_swap">スワップ</string>
|
||||
<string name="common_swapped">スワップ済み</string>
|
||||
<string name="common_swapping">スワップ中</string>
|
||||
<string name="common_tangem">Tangem</string>
|
||||
<string name="common_tangem_wallet">Tangem Wallet</string>
|
||||
<string name="common_tap_and_hold_hint">タップして長押し</string>
|
||||
|
|
@ -398,6 +412,7 @@
|
|||
<string name="common_to">宛先</string>
|
||||
<string name="common_to_wallet_name">%sへ</string>
|
||||
<string name="common_today">今日</string>
|
||||
<string name="common_token">トークン</string>
|
||||
<string name="common_token_send">送信するトークン</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="other">%d トークン</item>
|
||||
|
|
@ -406,6 +421,7 @@
|
|||
<string name="common_transaction_status">取引状況</string>
|
||||
<string name="common_transactions">取引</string>
|
||||
<string name="common_transfer">送金</string>
|
||||
<string name="common_transferred">送金済み</string>
|
||||
<string name="common_unable_to_load">データを読み込めません…</string>
|
||||
<string name="common_understand">わかりました</string>
|
||||
<string name="common_understand_continue">理解して続行</string>
|
||||
|
|
@ -415,10 +431,12 @@
|
|||
<string name="common_unstake">ステーキング解除</string>
|
||||
<string name="common_utxo_validate_withdrawal_message_warning">%1$sの制限により、1つのトランザクションに収まるUTXOは%2$d個のみです。つまり、 %3$s以下しか送信できません。量を減らす必要があります。</string>
|
||||
<string name="common_value_copied">値がコピーされました</string>
|
||||
<string name="common_voting">投票</string>
|
||||
<string name="common_wallets">ウォレット</string>
|
||||
<string name="common_warning">警告</string>
|
||||
<string name="common_week">週</string>
|
||||
<string name="common_with">で</string>
|
||||
<string name="common_withdrawing">引き出し中</string>
|
||||
<string name="common_yes">はい</string>
|
||||
<string name="common_yield_mode">利息モード</string>
|
||||
<string name="contract_address_copied_message">コントラクトアドレスをコピーしました!</string>
|
||||
|
|
@ -580,12 +598,14 @@
|
|||
<string name="express_provider_best_rate">ベストレート</string>
|
||||
<string name="express_provider_fca_warning_list">FCA警告リスト</string>
|
||||
<string name="express_provider_fixed_rate_is_unavailable">固定レートは利用できません</string>
|
||||
<string name="express_provider_for_swap">スワッププロバイダー</string>
|
||||
<string name="express_provider_great_rate">お得なレート</string>
|
||||
<string name="express_provider_in_fca_warning_list">FCA警告リストに掲載されたプロバイダー</string>
|
||||
<string name="express_provider_max_amount">最大 %s まで使用可能</string>
|
||||
<string name="express_provider_min_amount">%s 以上で利用可能</string>
|
||||
<string name="express_provider_not_available">このペアは利用できません</string>
|
||||
<string name="express_provider_permission_needed">許可が必要です</string>
|
||||
<string name="express_provider_permission_needed_v2">権限が必要です</string>
|
||||
<string name="express_provider_recommended">推奨</string>
|
||||
<string name="express_status_bought">%sを買い付けました</string>
|
||||
<string name="express_status_buying">%sを買い付けています</string>
|
||||
|
|
@ -633,6 +653,7 @@
|
|||
<string name="give_permission_staking_footer">承認機能は、別のアドレスに特定の量のトークンを使用する許可を与えるために必要です。設計上スマートコントラクトは、承認しない限りトークンにアクセスできません。トークンを「ロック解除」すると、StakeKitスマート コントラクトがトークンを使用する権限が与えられます。ネットワークのマイナーは、このアクションをブロックチェーンに記録するためにガス料金(あなたが支払う)を受け取ります。承認後、トークンをステーキングできます。</string>
|
||||
<string name="give_permission_staking_subtitle">続行するには、Polygonスマートコントラクトが%sを使用することを許可する必要があります</string>
|
||||
<string name="give_permission_swap_subtitle" formatted="false">続行するには、%1sスマートコントラクトに%2sを使用する権限を付与してください</string>
|
||||
<string name="give_permission_swap_subtitle_v2">分散型取引所がウォレットと連携するには、許可が必要です。%1s</string>
|
||||
<string name="give_permission_title">許可を与える</string>
|
||||
<string name="give_permission_unlimited">無制限</string>
|
||||
<string name="hardware_wallet_backup_feature_description">アドレスはTangemハードウェアウォレット上で直接生成され、そのまま安全に使用できます。</string>
|
||||
|
|
@ -660,6 +681,8 @@
|
|||
<string name="hw_backup_banner_description">暗号資産をオフラインで厳重保管。カードサイズで、金庫以上の安心を。</string>
|
||||
<string name="hw_backup_close_description">実行すると、最初からやり直す必要があります。</string>
|
||||
<string name="hw_backup_google_drive_description">Googleドライブのバックアップから既存のウォレットを復元する</string>
|
||||
<string name="hw_backup_google_drive_dialog_message">ウォレットの復元をさらに簡単にするため、Googleドライブバックアップ機能を準備しています。</string>
|
||||
<string name="hw_backup_google_drive_dialog_title">Googleドライブバックアップは近日対応予定です</string>
|
||||
<string name="hw_backup_google_drive_title">Googleドライブのバックアップ</string>
|
||||
<string name="hw_backup_hardware_create_description">さらに強固なセキュリティのために、新しいウォレットを作成して資産を移動しましょう。</string>
|
||||
<string name="hw_backup_hardware_create_title">新しいウォレットを作成</string>
|
||||
|
|
@ -1103,6 +1126,8 @@
|
|||
<string name="onramp_kyc_verification_choose_another">別の方法を選択してください。</string>
|
||||
<string name="onramp_kyc_verification_subtitle">現地の規制要件に準拠するため、%@の利用には本人確認が必要です。</string>
|
||||
<string name="onramp_kyc_verification_title">決済プロバイダーによる本人確認が必要です。</string>
|
||||
<string name="onramp_kyc_verification_verify_button">認証する</string>
|
||||
<string name="onramp_kyc_verification_whats_important">重要事項</string>
|
||||
<string name="onramp_legal">オンランプ機能を使用することにより、プロバイダの%1$sおよび%2$sに同意するものとします</string>
|
||||
<string name="onramp_legal_text">サービスは外部プロバイダーによって提供されます。 \nTangemは責任を負いません。</string>
|
||||
<string name="onramp_max_amount_restriction">買付金額は%s以下にしてください</string>
|
||||
|
|
@ -1166,7 +1191,11 @@
|
|||
<string name="qr_scanner_warning_unknown_parameters_title">不明なパラメータ</string>
|
||||
<string name="quick_action_buy_description">クレジットカードまたは銀行口座</string>
|
||||
<string name="quick_action_receive_description">アドレスまたはQRコードを共有してください</string>
|
||||
<string name="quick_action_sell_description">暗号資産を安全に売却</string>
|
||||
<string name="quick_action_send_description">別のウォレットに送信</string>
|
||||
<string name="quick_action_swap_description">ポートフォリオ間で</string>
|
||||
<string name="quick_top_up_chip_other">その他</string>
|
||||
<string name="quick_top_up_title">クイック入金</string>
|
||||
<string name="receive_bottom_sheet_no_memo_required_message">メモ不要</string>
|
||||
<string name="receive_bottom_sheet_warning_message">%3$sネットワーク上の%1$s ( %2$s )</string>
|
||||
<string name="receive_bottom_sheet_warning_message_compact">%2$sネットワーク上の%1$s</string>
|
||||
|
|
@ -1522,6 +1551,7 @@
|
|||
<string name="swap_approve_description">承認すると、このスマートコントラクトが今後の取引でトークンを利用できるようになります。</string>
|
||||
<string name="swap_fixed_rate">固定レート</string>
|
||||
<string name="swap_give_permission_fee_footer">ネットワークは、あなたがトークンのスワップを承認していることを確認するために、トークン承認手数料を請求します。</string>
|
||||
<string name="swap_in_progress">スワップ中</string>
|
||||
<string name="swap_promo_text">より多くのトークンをより良いレートで、ウォレット内にて直接交換します。</string>
|
||||
<string name="swap_promo_title">新しいスワッププロバイダーが利用可能になりました!</string>
|
||||
<string name="swap_search_suggestion_hint">他のものをお探しですか?\n検索してみるか、別の暗号資産をチェックしてみましょう!</string>
|
||||
|
|
@ -1530,11 +1560,11 @@
|
|||
<string name="swap_story_fifth_subtitle">24時間体制のサポートであらゆる問題に対応します。</string>
|
||||
<string name="swap_story_fifth_title">いつもここに</string>
|
||||
<string name="swap_story_first_subtitle">複数の信頼できるプロバイダーが一箇所に集結。ウォレット内で様々な暗号資産を簡単に交換できます。</string>
|
||||
<string name="swap_story_first_subtitle_v2">Tangem内で暗号資産を直接交換\n追加の送金は不要\n取引所に資産を移す必要なし</string>
|
||||
<string name="swap_story_first_subtitle_v2">Tangem内で暗号資産を直接交換できます\n追加の送金は不要です\n取引所に資金を移す必要もありません</string>
|
||||
<string name="swap_story_first_title">ぜひスワップしてください</string>
|
||||
<string name="swap_story_first_title_v2">ウォレット内でスワップ</string>
|
||||
<string name="swap_story_forth_subtitle">失敗も死角もありません。取引は常に保護されます。</string>
|
||||
<string name="swap_story_forth_subtitle_v2">スワップは信頼できるプロバイダーを通じて実行されます。秘密鍵は常にTangemウォレット内に保持されます。シンプル。透明。自己管理。</string>
|
||||
<string name="swap_story_forth_subtitle_v2">スワップは信頼できるプロバイダーを通じて実行されます。秘密鍵は常にTangemウォレット内に保持されます。明確で、透明性が高く、自己管理型です。</string>
|
||||
<string name="swap_story_forth_title">難攻不落の防御</string>
|
||||
<string name="swap_story_forth_title_v2">主導権はあなたの手にあります</string>
|
||||
<string name="swap_story_second_subtitle">幅広いネットワークの中から、常に最適なプロバイダーと料金レートを選択します</string>
|
||||
|
|
@ -1555,7 +1585,9 @@
|
|||
<string name="swapping_approve_information_text">すべての分散型取引所は、スマートコントラクトがあなたの許可なくウォレットにアクセスするのを防ぐために承認を必要とします。設計上、スマートコントラクトは承認なしでトークンにアクセスできません。トークンを「ロック解除」することで、あなたは1-inchのスマートコントラクトがトークンを使うことを承認します。ネットワークのマイナーは、このアクションをブロックチェーンに記録するためのガス料金(あなたが支払う)を受け取ります。承認後、トークンを交換することができます。</string>
|
||||
<string name="swapping_approve_information_title">承認</string>
|
||||
<string name="swapping_fee_estimation_error_text">手数料見積りエラーです。サポートにフィードバックをお送りください。</string>
|
||||
<string name="swapping_from_account_title">送信元</string>
|
||||
<string name="swapping_from_title">スワップする</string>
|
||||
<string name="swapping_from_title_v2">送信</string>
|
||||
<string name="swapping_high_price_impact_description">選択したトークンをこの量を交換すると、価格に大きな影響が生じ、結果が減少します。</string>
|
||||
<string name="swapping_high_price_impact_text">流動性が低いため、受取額が大幅に少なくなる可能性があります。金額を減らすか、別のプロバイダーをお試しください。</string>
|
||||
<string name="swapping_high_price_impact_title">価格への影響が甚大です</string>
|
||||
|
|
@ -1564,11 +1596,14 @@
|
|||
<string name="swapping_permission_header">許可を与える</string>
|
||||
<string name="swapping_swap_action">スワップ</string>
|
||||
<string name="swapping_swap_action_in_progress">スワップ中…</string>
|
||||
<string name="swapping_to_account_title">受け取り先</string>
|
||||
<string name="swapping_to_title">受け取る</string>
|
||||
<string name="swapping_token_list_title">トークンを選択</string>
|
||||
<string name="swapping_token_not_available">利用不可</string>
|
||||
<string name="swapping_trade_too_large_text">この取引に十分な流動性がありません。\n金額を減らすか、別のプロバイダーを選択してください。</string>
|
||||
<string name="swapping_trade_too_large_title">取引額が大きすぎます</string>
|
||||
<string name="swapping_transfer_action">送金</string>
|
||||
<string name="swapping_transfer_action_in_progress">送金...</string>
|
||||
<string name="tangem_pay_beta_notification_subtitle">皆様からのフィードバックをお待ちしております</string>
|
||||
<string name="tangem_pay_beta_notification_title">Tangem Payのベータ版を公開しました</string>
|
||||
<string name="tangem_pay_card_details_unable_to_rename_card_title">カード名を変更できません</string>
|
||||
|
|
@ -1657,6 +1692,7 @@
|
|||
<string name="tangempay_card_details_withdraw_error_title">現在、出金ができません</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_description">現在の処理が完了するまでは、スワップや新しい出金を開始することはできません。</string>
|
||||
<string name="tangempay_card_details_withdraw_in_progress_title">出金処理中です</string>
|
||||
<string name="tangempay_card_edit_name_placeholder">カード名</string>
|
||||
<string name="tangempay_card_limit_setup_amount_subtitle">%s以上の金額を設定してください</string>
|
||||
<string name="tangempay_card_limit_setup_error_message">限度額を設定できませんでした。もう一度お試しください</string>
|
||||
<string name="tangempay_card_page_daily_limit_change">変更</string>
|
||||
|
|
@ -1708,6 +1744,8 @@
|
|||
<string name="tangempay_onboarding_purchases_title">余計な費用なしで、表示金額のみを支払う</string>
|
||||
<string name="tangempay_onboarding_security_description">あなたの住所や資産を開示することなく、個別の支払い用アカウントが作成されます。</string>
|
||||
<string name="tangempay_onboarding_security_title">他に類を見ないプライバシー</string>
|
||||
<string name="tangempay_onboarding_setup_wallet_description">そして支払いカードを連携します</string>
|
||||
<string name="tangempay_onboarding_setup_wallet_title">ウォレットを設定します</string>
|
||||
<string name="tangempay_onboarding_title">無料のTangem Payカードを数分でゲットしましょう</string>
|
||||
<string name="tangempay_pay_support">Payサポート</string>
|
||||
<string name="tangempay_payment_account">支払いアカウント</string>
|
||||
|
|
@ -1757,7 +1795,7 @@
|
|||
<string name="token_button_unavailability_reason_yield_supply_approval">承認が取り消されましたが、あなたの資金は引き続き利息モードです。操作を行うには、利息モードに移動し、再度承認を付与してください。</string>
|
||||
<string name="token_details_balance_available">利用可能残高</string>
|
||||
<string name="token_details_balance_total">合計残高</string>
|
||||
<string name="token_details_earn_staking_subtitle">年間で最大%sを獲得</string>
|
||||
<string name="token_details_earn_staking_subtitle">年利最大%s</string>
|
||||
<string name="token_details_generate_xpub">XPUBを生成する</string>
|
||||
<string name="token_details_hide_alert_hide">非表示</string>
|
||||
<string name="token_details_hide_alert_message">このトークンをメイン画面から非表示にします。トークンの管理ページからいつでも再度追加できます。</string>
|
||||
|
|
@ -1783,12 +1821,21 @@
|
|||
<string name="tokens_list_unavailable_to_sell_header">売却できません</string>
|
||||
<string name="tokens_list_unavailable_to_swap_header">%sからのスワップは利用できません</string>
|
||||
<string name="tokens_list_unavailable_to_swap_source_header">スワップはできません</string>
|
||||
<string name="transaction_history_claiming_reward">報酬を請求中</string>
|
||||
<string name="transaction_history_contract_address">コントラクト: %s</string>
|
||||
<string name="transaction_history_disabling_yield_mode">利息モードを無効化中</string>
|
||||
<string name="transaction_history_earned_from_stake">ステーキングで獲得した金額</string>
|
||||
<string name="transaction_history_empty_transactions">まだ取引はありません</string>
|
||||
<string name="transaction_history_error_failed_to_load">取引履歴の読み込みに失敗しました。\n情報を更新するには、リロードボタンをクリックしてください。</string>
|
||||
<string name="transaction_history_from_inline_address">%%image%% %s から</string>
|
||||
<string name="transaction_history_multiple_addresses">複数のアドレス</string>
|
||||
<string name="transaction_history_not_supported_description">現在、このブロックチェーンでは取引履歴はサポートされていません。しかしご心配なく!弊社で対応中です。その間、エクスプローラーで確認することができます。</string>
|
||||
<string name="transaction_history_operation">オペレーション</string>
|
||||
<string name="transaction_history_pending">保留中</string>
|
||||
<string name="transaction_history_rewards_restaked">報酬を再ステーキングしました</string>
|
||||
<string name="transaction_history_rewards_restaking">報酬の再ステーキング</string>
|
||||
<string name="transaction_history_staking_reward">ステーキング報酬</string>
|
||||
<string name="transaction_history_to_inline_address">%%image%% %s へ</string>
|
||||
<string name="transaction_history_transaction_for_address">対象:%s</string>
|
||||
<string name="transaction_history_transaction_from_address">送金元: %s</string>
|
||||
<string name="transaction_history_transaction_to_address">送金先: %s</string>
|
||||
|
|
@ -2064,7 +2111,7 @@
|
|||
<string name="warning_matic_migration_message">MATICはPOLに移行中です。ただし、期限は設定されておらず、MATICはまだ廃止されていません。MATICトークンを引き続き安全に使用することも、POLに交換することもできます。</string>
|
||||
<string name="warning_matic_migration_title">MATICからPOLへの移行</string>
|
||||
<plurals name="warning_missing_derivation_message">
|
||||
<item quantity="other">%d ネットワークのアドレスを取得するために、カードまたはリングを利用してください</item>
|
||||
<item quantity="other">カードまたはリングを使って、[%i}ネットワークのアドレスを取得します</item>
|
||||
</plurals>
|
||||
<string name="warning_missing_derivation_title">一部のアドレスが見つかりません</string>
|
||||
<string name="warning_network_unreachable_message">現在、ネットワークにアクセスできません。しばらくしてからもう一度お試しください。</string>
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@
|
|||
<item quantity="other">OUTRO</item>
|
||||
</plurals>
|
||||
<string name="common_import">Importar</string>
|
||||
<string name="common_in">em</string>
|
||||
<string name="common_in_progress">Em andamento</string>
|
||||
<string name="common_insufficient_balance">Saldo insuficiente</string>
|
||||
<string name="common_later">Mais tarde</string>
|
||||
|
|
@ -407,6 +408,7 @@
|
|||
<string name="common_to">Para</string>
|
||||
<string name="common_to_wallet_name">Para %s</string>
|
||||
<string name="common_today">Hoje</string>
|
||||
<string name="common_token">Token</string>
|
||||
<string name="common_token_send">Token a ser enviado</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">token</item>
|
||||
|
|
|
|||
|
|
@ -339,6 +339,7 @@
|
|||
<item quantity="other">%dч назад</item>
|
||||
</plurals>
|
||||
<string name="common_import">Импортировать</string>
|
||||
<string name="common_in">в</string>
|
||||
<string name="common_in_progress">В процессе</string>
|
||||
<string name="common_insufficient_balance">Недостаточный баланс</string>
|
||||
<string name="common_later">Позже</string>
|
||||
|
|
@ -429,6 +430,7 @@
|
|||
<string name="common_to">На</string>
|
||||
<string name="common_to_wallet_name">На %s</string>
|
||||
<string name="common_today">Сегодня</string>
|
||||
<string name="common_token">Токен</string>
|
||||
<string name="common_token_send">Токен к отправке</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d токен</item>
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@
|
|||
<item quantity="other">%d годин тому</item>
|
||||
</plurals>
|
||||
<string name="common_import">Імпортувати</string>
|
||||
<string name="common_in">у</string>
|
||||
<string name="common_in_progress">В процесі</string>
|
||||
<string name="common_later">Пізніше</string>
|
||||
<string name="common_learn_more">Дізнатися більше</string>
|
||||
|
|
@ -408,6 +409,7 @@
|
|||
<string name="common_to">До</string>
|
||||
<string name="common_to_wallet_name">На %s</string>
|
||||
<string name="common_today">Сьогодні</string>
|
||||
<string name="common_token">Токен</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d токен</item>
|
||||
<item quantity="few">%d токени</item>
|
||||
|
|
|
|||
|
|
@ -312,6 +312,7 @@
|
|||
<item quantity="other">小时之前</item>
|
||||
</plurals>
|
||||
<string name="common_import">导入</string>
|
||||
<string name="common_in">在</string>
|
||||
<string name="common_in_progress">进行中</string>
|
||||
<string name="common_insufficient_balance">余额不足</string>
|
||||
<string name="common_later">稍后</string>
|
||||
|
|
@ -397,6 +398,7 @@
|
|||
<string name="common_to">至</string>
|
||||
<string name="common_to_wallet_name">到 %s</string>
|
||||
<string name="common_today">今天</string>
|
||||
<string name="common_token">代币</string>
|
||||
<string name="common_token_send">要发送的代币</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="other">%d代币</item>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
<string name="common_error">錯誤</string>
|
||||
<string name="common_fee_error">獲取費用失敗</string>
|
||||
<string name="common_import">導入</string>
|
||||
<string name="common_in">在</string>
|
||||
<string name="common_in_progress">進行中</string>
|
||||
<string name="common_network_fee_title">網路費</string>
|
||||
<string name="common_no">否</string>
|
||||
|
|
@ -92,6 +93,7 @@
|
|||
<string name="common_success">成功</string>
|
||||
<string name="common_swap">交換</string>
|
||||
<string name="common_terms_and_conditions">條款和條件</string>
|
||||
<string name="common_token">代幣</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="other">%d 代幣</item>
|
||||
</plurals>
|
||||
|
|
|
|||
|
|
@ -327,6 +327,7 @@
|
|||
<item quantity="other">%dh ago</item>
|
||||
</plurals>
|
||||
<string name="common_import">Import</string>
|
||||
<string name="common_in">in</string>
|
||||
<string name="common_in_progress">In progress</string>
|
||||
<string name="common_insufficient_balance">Insufficient balance</string>
|
||||
<string name="common_later">Later</string>
|
||||
|
|
@ -421,6 +422,7 @@
|
|||
<string name="common_to">To</string>
|
||||
<string name="common_to_wallet_name">To %s</string>
|
||||
<string name="common_today">Today</string>
|
||||
<string name="common_token">Token</string>
|
||||
<string name="common_token_send">Token to send</string>
|
||||
<plurals name="common_tokens_count">
|
||||
<item quantity="one">%d token</item>
|
||||
|
|
@ -1578,8 +1580,10 @@
|
|||
<string name="swap_give_permission_fee_footer">The network will charge a token approval fee to verify that you are authorizing the use of your token for the swap.</string>
|
||||
<string name="swap_in_progress">Swap in progress</string>
|
||||
<string name="swap_promo_text">Exchange more tokens at better rates directly in your wallet.</string>
|
||||
<string name="swap_detailed_mode">Detailed mode</string>
|
||||
<string name="swap_promo_title">New Swap Provider Available!</string>
|
||||
<string name="swap_search_suggestion_hint">Looking for something else?\nTry searching or explore another crypto!</string>
|
||||
<string name="swap_simple_mode">Simple mode</string>
|
||||
<string name="swap_search_tooltip_description">Search for any token, even if it’s not in your list yet.</string>
|
||||
<string name="swap_search_tooltip_title">Use search to find what you need</string>
|
||||
<string name="swap_story_fifth_subtitle">Feel confident with round-the-clock support to help with any issues</string>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.tangem.datasource.exchangeservice.swap.ExpressUtils
|
|||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.express.models.ExpressOperationType
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
|
|
@ -419,4 +420,8 @@ internal class DefaultSwapRepository(
|
|||
override suspend fun getStoredSwapUiMode(): SwapUIMode? {
|
||||
return appPreferencesStore.getObjectSyncOrNull(PreferencesKeys.SWAP_UI_MODE_KEY)
|
||||
}
|
||||
|
||||
override suspend fun storeSwapUiMode(mode: SwapUIMode) {
|
||||
appPreferencesStore.storeObject(PreferencesKeys.SWAP_UI_MODE_KEY, mode)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
|
||||
class SetSwapUiModeUseCase(
|
||||
private val swapRepository: SwapRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(mode: SwapUIMode) {
|
||||
swapRepository.storeSwapUiMode(mode)
|
||||
}
|
||||
}
|
||||
|
|
@ -77,4 +77,6 @@ interface SwapRepository {
|
|||
): Either<ExpressDataError, Unit>
|
||||
|
||||
suspend fun getStoredSwapUiMode(): SwapUIMode?
|
||||
|
||||
suspend fun storeSwapUiMode(mode: SwapUIMode)
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.feature.swap.domain.di
|
|||
import com.tangem.feature.swap.domain.AllowPermissionsHandler
|
||||
import com.tangem.feature.swap.domain.AllowPermissionsHandlerImpl
|
||||
import com.tangem.feature.swap.domain.GetSwapUiModeUseCase
|
||||
import com.tangem.feature.swap.domain.SetSwapUiModeUseCase
|
||||
import com.tangem.feature.swap.domain.SwapInteractor
|
||||
import com.tangem.feature.swap.domain.SwapInteractorImpl
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
|
|
@ -35,6 +36,11 @@ internal class SwapDomainModule {
|
|||
swapFeatureToggles = swapFeatureToggles,
|
||||
swapRepository = swapRepository,
|
||||
)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSetSwapUiModeUseCase(swapRepository: SwapRepository): SetSwapUiModeUseCase =
|
||||
SetSwapUiModeUseCase(swapRepository = swapRepository)
|
||||
}
|
||||
|
||||
@Module
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.feature.swap.domain
|
||||
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class SetSwapUiModeUseCaseTest {
|
||||
|
||||
private val swapRepository: SwapRepository = mockk(relaxUnitFun = true)
|
||||
|
||||
private val useCase = SetSwapUiModeUseCase(swapRepository = swapRepository)
|
||||
|
||||
@Test
|
||||
fun `GIVEN Simple mode WHEN invoke THEN delegates to repository`() = runTest {
|
||||
useCase.invoke(SwapUIMode.Simple)
|
||||
|
||||
coVerify(exactly = 1) { swapRepository.storeSwapUiMode(SwapUIMode.Simple) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN Detailed mode WHEN invoke THEN delegates to repository`() = runTest {
|
||||
useCase.invoke(SwapUIMode.Detailed)
|
||||
|
||||
coVerify(exactly = 1) { swapRepository.storeSwapUiMode(SwapUIMode.Detailed) }
|
||||
}
|
||||
}
|
||||
|
|
@ -74,6 +74,7 @@ import com.tangem.feature.swap.component.SwapFeeSelectorBlockComponent
|
|||
import com.tangem.feature.swap.converters.SwapTransactionErrorStateConverter
|
||||
import com.tangem.feature.swap.domain.AllowPermissionsHandler
|
||||
import com.tangem.feature.swap.domain.GetSwapUiModeUseCase
|
||||
import com.tangem.feature.swap.domain.SetSwapUiModeUseCase
|
||||
import com.tangem.feature.swap.domain.SwapInteractor
|
||||
import com.tangem.feature.swap.domain.TransactionFeeResult
|
||||
import com.tangem.feature.swap.domain.TxFeeSealedState
|
||||
|
|
@ -83,6 +84,7 @@ import com.tangem.feature.swap.domain.models.domain.ExchangeProviderType
|
|||
import com.tangem.feature.swap.domain.models.domain.SwapDataModel
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapPairLeast
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapProvider
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.feature.swap.domain.models.ui.*
|
||||
import com.tangem.feature.swap.domain.transfer.SwapTransferInteractor
|
||||
import com.tangem.feature.swap.models.*
|
||||
|
|
@ -157,6 +159,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val allowPermissionsHandler: AllowPermissionsHandler,
|
||||
private val swapFeatureToggles: SwapFeatureToggles,
|
||||
private val getSwapUiModeUseCase: GetSwapUiModeUseCase,
|
||||
private val setSwapUiModeUseCase: SetSwapUiModeUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<SwapComponent.Params>()
|
||||
|
|
@ -192,6 +195,7 @@ internal class SwapModel @Inject constructor(
|
|||
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
||||
isAccountsModeProvider = Provider { isAccountsMode },
|
||||
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
|
||||
shouldShowAbMenu = swapFeatureToggles.isSwapAbEnabled,
|
||||
)
|
||||
|
||||
private val inputNumberFormatter = InputNumberFormatter(
|
||||
|
|
@ -1621,9 +1625,16 @@ internal class SwapModel @Inject constructor(
|
|||
onSuccess = {
|
||||
router.replaceAll(SwapRoute.Success)
|
||||
},
|
||||
onSwapUIModeChange = ::onSwapUIModeChange,
|
||||
)
|
||||
}
|
||||
|
||||
private fun onSwapUIModeChange(mode: SwapUIMode) {
|
||||
if (uiState.swapUIMode == mode) return
|
||||
uiState = uiState.copy(swapUIMode = mode)
|
||||
modelScope.launch { setSwapUiModeUseCase(mode) }
|
||||
}
|
||||
|
||||
private fun selectWalletInSelector(
|
||||
fromSwapCurrencyStatus: SwapCurrencyStatus?,
|
||||
toSwapCurrencyStatus: SwapCurrencyStatus?,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ internal data class SwapStateHolder(
|
|||
val shouldShowMaxAmount: Boolean,
|
||||
val tosState: TosState? = null,
|
||||
val swapUIMode: SwapUIMode = SwapUIMode.Detailed,
|
||||
val shouldShowAbMenu: Boolean = false,
|
||||
|
||||
val onRefresh: () -> Unit,
|
||||
val onBackClicked: () -> Unit,
|
||||
|
|
@ -41,6 +42,7 @@ internal data class SwapStateHolder(
|
|||
val onSuccess: (() -> Unit),
|
||||
val onMaxAmountSelected: (() -> Unit)? = null,
|
||||
val onShowPermissionBottomSheet: () -> Unit = {},
|
||||
val onSwapUIModeChange: (SwapUIMode) -> Unit = {},
|
||||
)
|
||||
|
||||
@Immutable
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.feature.swap.models
|
||||
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.feature.swap.domain.models.ui.TxFee
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -26,4 +27,5 @@ internal data class UiActions(
|
|||
val onSuccess: () -> Unit,
|
||||
val onLinkClick: (String) -> Unit,
|
||||
val onReceiveCardWarningClick: () -> Unit,
|
||||
val onSwapUIModeChange: (SwapUIMode) -> Unit,
|
||||
)
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
package com.tangem.feature.swap.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.SubcomposeAsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
import com.tangem.core.ui.components.SpacerW8
|
||||
import com.tangem.core.ui.components.SpacerWMax
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.swap.models.states.PercentDifference
|
||||
import com.tangem.feature.swap.models.states.ProviderState
|
||||
|
||||
// TODO: [REDACTED_TASK_KEY] — remove this UI after swap migrates to swap-v2.
|
||||
// Layout copied from V2 `SwapChooseProviderContent`:
|
||||
// features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/chooseprovider/ui/SwapChooseProviderContent.kt
|
||||
@Composable
|
||||
internal fun ProviderItemBlockSimple(state: ProviderState, modifier: Modifier = Modifier) {
|
||||
if (state is ProviderState.Empty) return
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius16))
|
||||
.background(TangemTheme.colors.background.primary)
|
||||
.clickable(
|
||||
enabled = state.onProviderClick != null,
|
||||
onClick = { state.onProviderClick?.invoke(state.id) },
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.padding(TangemTheme.dimens.spacing12),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_stack_new_24),
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
)
|
||||
SpacerW8()
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.express_provider),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
SpacerWMax()
|
||||
SimpleProviderTrailing(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SimpleProviderTrailing(state: ProviderState) {
|
||||
when (state) {
|
||||
is ProviderState.Content -> {
|
||||
SubcomposeAsyncImage(
|
||||
model = ImageRequest.Builder(context = LocalContext.current)
|
||||
.data(state.iconUrl)
|
||||
.crossfade(enable = true)
|
||||
.allowHardware(false)
|
||||
.build(),
|
||||
loading = { RectangleShimmer(radius = 4.dp) },
|
||||
error = { RectangleShimmer(radius = 4.dp) },
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size20)
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius4)),
|
||||
)
|
||||
Text(
|
||||
text = state.name,
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(start = TangemTheme.dimens.spacing6),
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_chevron_24),
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
)
|
||||
}
|
||||
is ProviderState.Loading -> {
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
.size(width = TangemTheme.dimens.size80, height = TangemTheme.dimens.size20),
|
||||
radius = TangemTheme.dimens.radius4,
|
||||
)
|
||||
}
|
||||
is ProviderState.Unavailable -> {
|
||||
Text(
|
||||
text = state.alertText.resolveReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.warning,
|
||||
)
|
||||
}
|
||||
is ProviderState.Empty -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun ProviderItemBlockSimple_Preview(@PreviewParameter(SimpleProviderPreview::class) state: ProviderState) {
|
||||
TangemThemePreview {
|
||||
ProviderItemBlockSimple(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private class SimpleProviderPreview : PreviewParameterProvider<ProviderState> {
|
||||
override val values: Sequence<ProviderState> = sequenceOf(
|
||||
ProviderState.Content(
|
||||
id = "1",
|
||||
name = "Changelly",
|
||||
type = "CEX",
|
||||
iconUrl = "",
|
||||
subtitle = stringReference("1 SOL ≈ 0.0011337 BTC"),
|
||||
selectionType = ProviderState.SelectionType.CLICK,
|
||||
additionalBadge = ProviderState.AdditionalBadge.Empty,
|
||||
percentLowerThenBest = PercentDifference.Empty,
|
||||
namePrefix = ProviderState.PrefixType.NONE,
|
||||
onProviderClick = {},
|
||||
),
|
||||
ProviderState.Loading(),
|
||||
ProviderState.Unavailable(
|
||||
id = "2",
|
||||
name = "1inch",
|
||||
type = "DEX",
|
||||
iconUrl = "",
|
||||
alertText = stringReference("Unavailable"),
|
||||
selectionType = ProviderState.SelectionType.NONE,
|
||||
),
|
||||
)
|
||||
}
|
||||
// endregion
|
||||
|
|
@ -59,6 +59,7 @@ internal class StateBuilder(
|
|||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val isAccountsModeProvider: Provider<Boolean>,
|
||||
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork,
|
||||
private val shouldShowAbMenu: Boolean,
|
||||
) {
|
||||
private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter)
|
||||
|
||||
|
|
@ -97,6 +98,8 @@ internal class StateBuilder(
|
|||
priceImpact = PriceImpact.Empty,
|
||||
isInsufficientFunds = false,
|
||||
swapUIMode = swapUIMode,
|
||||
onSwapUIModeChange = actions.onSwapUIModeChange,
|
||||
shouldShowAbMenu = shouldShowAbMenu,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,39 @@ package com.tangem.feature.swap.ui
|
|||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon
|
||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenu
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.test.SwapTokenScreenTestTags
|
||||
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||
import com.tangem.feature.swap.component.SwapFeeSelectorBlockComponent
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.feature.swap.models.SwapStateHolder
|
||||
import com.tangem.feature.swap.models.states.ChooseFeeBottomSheetConfig
|
||||
import com.tangem.feature.swap.models.states.ChooseProviderBottomSheetConfig
|
||||
|
|
@ -26,13 +46,7 @@ internal fun SwapScreen(stateHolder: SwapStateHolder, feeSelectorBlockComponent:
|
|||
|
||||
Scaffold(
|
||||
modifier = Modifier.systemBarsPadding(),
|
||||
topBar = {
|
||||
AppBarWithBackButton(
|
||||
text = stringResourceSafe(R.string.common_swap),
|
||||
onBackClick = stateHolder.onBackClicked,
|
||||
iconRes = R.drawable.ic_close_24,
|
||||
)
|
||||
},
|
||||
topBar = { SwapTopBar(stateHolder = stateHolder) },
|
||||
contentWindowInsets = WindowInsetsZero,
|
||||
containerColor = TangemTheme.colors.background.secondary,
|
||||
) { scaffoldPaddings ->
|
||||
|
|
@ -64,4 +78,79 @@ internal fun SwapScreen(stateHolder: SwapStateHolder, feeSelectorBlockComponent:
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SwapTopBar(stateHolder: SwapStateHolder) {
|
||||
var shouldShowModeMenu by rememberSaveable { mutableStateOf(false) }
|
||||
Box(modifier = Modifier.fillMaxWidth()) {
|
||||
AppBarWithBackButtonAndIcon(
|
||||
text = stringResourceSafe(R.string.common_swap),
|
||||
backIconRes = R.drawable.ic_close_24,
|
||||
iconRes = if (stateHolder.shouldShowAbMenu) R.drawable.ic_more_vertical_24 else null,
|
||||
onIconClick = if (stateHolder.shouldShowAbMenu) {
|
||||
{ shouldShowModeMenu = true }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
onBackClick = stateHolder.onBackClicked,
|
||||
)
|
||||
if (stateHolder.shouldShowAbMenu) {
|
||||
Box(modifier = Modifier.align(Alignment.TopEnd)) {
|
||||
TangemDropdownMenu(
|
||||
expanded = shouldShowModeMenu,
|
||||
modifier = Modifier.background(TangemTheme.colors.background.primary),
|
||||
offset = DpOffset(x = TangemTheme.dimens.spacing20, y = 44.dp),
|
||||
onDismissRequest = { shouldShowModeMenu = false },
|
||||
content = {
|
||||
SwapUiModeMenuItem(
|
||||
title = stringResourceSafe(R.string.swap_simple_mode),
|
||||
isSelected = stateHolder.swapUIMode == SwapUIMode.Simple,
|
||||
onClick = {
|
||||
shouldShowModeMenu = false
|
||||
stateHolder.onSwapUIModeChange(SwapUIMode.Simple)
|
||||
},
|
||||
)
|
||||
SwapUiModeMenuItem(
|
||||
title = stringResourceSafe(R.string.swap_detailed_mode),
|
||||
isSelected = stateHolder.swapUIMode == SwapUIMode.Detailed,
|
||||
onClick = {
|
||||
shouldShowModeMenu = false
|
||||
stateHolder.onSwapUIModeChange(SwapUIMode.Detailed)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SwapUiModeMenuItem(title: String, isSelected: Boolean, onClick: () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = TangemTheme.typography.button,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
if (isSelected) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_check_24),
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
)
|
||||
} else {
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ import com.tangem.core.ui.extensions.stringResourceSafe
|
|||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.SwapTokenScreenTestTags
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
|
||||
import com.tangem.feature.swap.domain.models.ui.FeeType
|
||||
import com.tangem.feature.swap.domain.models.ui.PriceImpact
|
||||
import com.tangem.feature.swap.models.*
|
||||
|
|
@ -79,7 +80,11 @@ internal fun SwapScreenContent(
|
|||
) {
|
||||
MainInfo(state)
|
||||
|
||||
ProviderItemBlock(state = state.providerState)
|
||||
if (state.swapUIMode == SwapUIMode.Simple) {
|
||||
ProviderItemBlockSimple(state = state.providerState)
|
||||
} else {
|
||||
ProviderItemBlock(state = state.providerState)
|
||||
}
|
||||
|
||||
if (feeBlock != null) {
|
||||
feeBlock(Modifier.fillMaxWidth())
|
||||
|
|
@ -139,14 +144,25 @@ private fun MainInfo(state: SwapStateHolder) {
|
|||
onSelectTokenClick = { state.onSelectTokenClick(TokenSelectionDirection.FROM) },
|
||||
)
|
||||
val marginCard = TangemTheme.dimens.spacing12
|
||||
TransactionCard(
|
||||
priceImpact = priceImpact,
|
||||
swapCardState = state.receiveCardData,
|
||||
modifier = Modifier.constrainAs(bottomCard) {
|
||||
top.linkTo(topCard.bottom, margin = marginCard)
|
||||
},
|
||||
onSelectTokenClick = { state.onSelectTokenClick(TokenSelectionDirection.TO) },
|
||||
)
|
||||
if (state.swapUIMode == SwapUIMode.Simple) {
|
||||
TransactionCardSimple(
|
||||
priceImpact = priceImpact,
|
||||
swapCardState = state.receiveCardData,
|
||||
modifier = Modifier.constrainAs(bottomCard) {
|
||||
top.linkTo(topCard.bottom, margin = marginCard)
|
||||
},
|
||||
onSelectTokenClick = { state.onSelectTokenClick(TokenSelectionDirection.TO) },
|
||||
)
|
||||
} else {
|
||||
TransactionCard(
|
||||
priceImpact = priceImpact,
|
||||
swapCardState = state.receiveCardData,
|
||||
modifier = Modifier.constrainAs(bottomCard) {
|
||||
top.linkTo(topCard.bottom, margin = marginCard)
|
||||
},
|
||||
onSelectTokenClick = { state.onSelectTokenClick(TokenSelectionDirection.TO) },
|
||||
)
|
||||
}
|
||||
val marginButton = TangemTheme.dimens.spacing30
|
||||
SwapButton(
|
||||
state,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,418 @@
|
|||
package com.tangem.feature.swap.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.TextAutoSize
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.common.ui.account.AccountTitle
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
import com.tangem.core.ui.components.SpacerH4
|
||||
import com.tangem.core.ui.components.SpacerW16
|
||||
import com.tangem.core.ui.components.TextShimmer
|
||||
import com.tangem.core.ui.components.buttons.SecondarySmallButton
|
||||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
||||
import com.tangem.core.ui.extensions.orMaskWithStars
|
||||
import com.tangem.core.ui.extensions.resolveAnnotatedReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.SwapTokenScreenTestTags
|
||||
import com.tangem.feature.swap.domain.models.ui.PriceImpact
|
||||
import com.tangem.feature.swap.models.SwapCardState
|
||||
import com.tangem.feature.swap.models.TransactionCardType
|
||||
import com.tangem.feature.swap.ui.preview.SwapTransactionCardPreview
|
||||
|
||||
@Composable
|
||||
internal fun TransactionCardSimple(
|
||||
priceImpact: PriceImpact,
|
||||
swapCardState: SwapCardState,
|
||||
onSelectTokenClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val cardTag = when (swapCardState.type) {
|
||||
is TransactionCardType.Inputtable -> SwapTokenScreenTestTags.SWAP_CARD
|
||||
is TransactionCardType.ReadOnly -> SwapTokenScreenTestTags.RECEIVE_CARD
|
||||
}
|
||||
|
||||
when (swapCardState) {
|
||||
is SwapCardState.Empty -> SimpleTransactionCardEmpty(
|
||||
cardState = swapCardState,
|
||||
onChangeTokenClick = onSelectTokenClick,
|
||||
modifier = modifier.testTag(cardTag),
|
||||
)
|
||||
is SwapCardState.SwapCardData -> SimpleTransactionCardData(
|
||||
cardState = swapCardState,
|
||||
priceImpact = priceImpact,
|
||||
onChangeTokenClick = onSelectTokenClick,
|
||||
modifier = modifier.testTag(cardTag),
|
||||
)
|
||||
is SwapCardState.Loading -> SimpleTransactionCardLoading(modifier = modifier.testTag(cardTag))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SimpleTransactionCardData(
|
||||
cardState: SwapCardState.SwapCardData,
|
||||
priceImpact: PriceImpact,
|
||||
modifier: Modifier = Modifier,
|
||||
onChangeTokenClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.background(
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius16),
|
||||
color = TangemTheme.colors.background.primary,
|
||||
)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.Top,
|
||||
horizontalAlignment = Alignment.Start,
|
||||
) {
|
||||
SimpleHeader(
|
||||
balance = stringResourceSafe(
|
||||
R.string.common_balance,
|
||||
cardState.balance,
|
||||
).orMaskWithStars(cardState.isBalanceHidden),
|
||||
type = cardState.type,
|
||||
)
|
||||
|
||||
SimpleContent(
|
||||
type = cardState.type,
|
||||
textFieldValue = cardState.amountTextFieldValue,
|
||||
priceImpact = priceImpact,
|
||||
)
|
||||
}
|
||||
|
||||
Box(modifier = Modifier.align(Alignment.BottomEnd)) {
|
||||
Token(
|
||||
currencyIconState = cardState.currencyIconState,
|
||||
tokenSymbol = cardState.tokenSymbol,
|
||||
)
|
||||
}
|
||||
|
||||
if (onChangeTokenClick != null) {
|
||||
Box(modifier = Modifier.align(Alignment.CenterEnd)) {
|
||||
ChangeTokenSelector()
|
||||
}
|
||||
Box(
|
||||
Modifier
|
||||
.align(Alignment.CenterEnd)
|
||||
.height(TangemTheme.dimens.size116)
|
||||
.width(TangemTheme.dimens.size102)
|
||||
.clickable(
|
||||
indication = ripple(bounded = false),
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
) { onChangeTokenClick() },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SimpleTransactionCardEmpty(
|
||||
cardState: SwapCardState.Empty,
|
||||
modifier: Modifier = Modifier,
|
||||
onChangeTokenClick: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius12),
|
||||
color = TangemTheme.colors.background.primary,
|
||||
)
|
||||
.padding(
|
||||
top = 12.dp,
|
||||
start = 12.dp,
|
||||
end = 12.dp,
|
||||
bottom = 16.dp,
|
||||
)
|
||||
.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
AccountTitle(
|
||||
accountTitleUM = cardState.type.accountTitleUM,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
text = cardState.amountTextFieldValue?.text.orEmpty(),
|
||||
color = TangemTheme.colors.text.disabled,
|
||||
style = TangemTheme.typography.h2,
|
||||
autoSize = TextAutoSize.StepBased(
|
||||
minFontSize = 16.sp,
|
||||
maxFontSize = TangemTheme.typography.h2.fontSize,
|
||||
),
|
||||
maxLines = 1,
|
||||
modifier = Modifier.testTag(SwapTokenScreenTestTags.SWAP_TEXT_FIELD),
|
||||
)
|
||||
Text(
|
||||
text = cardState.amountEquivalent.resolveAnnotatedReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.body2,
|
||||
modifier = Modifier
|
||||
.defaultMinSize(minHeight = TangemTheme.dimens.size20)
|
||||
.testTag(SwapTokenScreenTestTags.SWAP_FIAT_AMOUNT),
|
||||
)
|
||||
}
|
||||
SecondarySmallButton(
|
||||
config = SmallButtonConfig(
|
||||
text = resourceReference(R.string.common_choose_token),
|
||||
icon = TangemButtonIconPosition.End(R.drawable.ic_chevron_24),
|
||||
onClick = onChangeTokenClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SimpleTransactionCardLoading(modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius12),
|
||||
color = TangemTheme.colors.background.primary,
|
||||
)
|
||||
.padding(
|
||||
top = 12.dp,
|
||||
start = 12.dp,
|
||||
end = 12.dp,
|
||||
bottom = 16.dp,
|
||||
)
|
||||
.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
TextShimmer(
|
||||
text = stringResourceSafe(R.string.swapping_to_title),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
)
|
||||
TextShimmer(
|
||||
style = TangemTheme.typography.body2,
|
||||
modifier = Modifier
|
||||
.testTag(SwapTokenScreenTestTags.BALANCE)
|
||||
.width(60.dp),
|
||||
)
|
||||
}
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
TextShimmer(
|
||||
style = TangemTheme.typography.h2,
|
||||
modifier = Modifier
|
||||
.width(100.dp)
|
||||
.testTag(SwapTokenScreenTestTags.SWAP_TEXT_FIELD),
|
||||
)
|
||||
TextShimmer(
|
||||
style = TangemTheme.typography.body2,
|
||||
modifier = Modifier
|
||||
.defaultMinSize(minHeight = 20.dp, minWidth = 40.dp)
|
||||
.testTag(SwapTokenScreenTestTags.SWAP_FIAT_AMOUNT),
|
||||
)
|
||||
}
|
||||
SecondarySmallButton(
|
||||
config = SmallButtonConfig(
|
||||
text = resourceReference(R.string.common_choose_token),
|
||||
icon = TangemButtonIconPosition.End(R.drawable.ic_chevron_24),
|
||||
isEnabled = false,
|
||||
onClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SimpleHeader(type: TransactionCardType, balance: String, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
bottom = TangemTheme.dimens.spacing8,
|
||||
top = TangemTheme.dimens.spacing14,
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
end = TangemTheme.dimens.spacing12,
|
||||
)
|
||||
.testTag(SwapTokenScreenTestTags.SWAP_BLOCK_HEADER),
|
||||
) {
|
||||
val titleColor = if (type.inputError is TransactionCardType.InputError.Empty) {
|
||||
TangemTheme.colors.text.tertiary
|
||||
} else {
|
||||
TangemTheme.colors.text.warning
|
||||
}
|
||||
AccountTitle(
|
||||
accountTitleUM = type.accountTitleUM,
|
||||
textColor = titleColor,
|
||||
)
|
||||
SpacerW16()
|
||||
if (balance.isNotBlank()) {
|
||||
AnimatedContent(targetState = balance, label = "") { balanceText ->
|
||||
Text(
|
||||
text = balanceText,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.body2,
|
||||
modifier = Modifier.testTag(SwapTokenScreenTestTags.BALANCE),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
.width(TangemTheme.dimens.size80)
|
||||
.height(TangemTheme.dimens.size12),
|
||||
radius = TangemTheme.dimens.radius3,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun SimpleContent(type: TransactionCardType, priceImpact: PriceImpact, textFieldValue: TextFieldValue?) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
bottom = TangemTheme.dimens.spacing16,
|
||||
),
|
||||
horizontalArrangement = Arrangement.Start,
|
||||
verticalAlignment = Alignment.Top,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(end = TangemTheme.dimens.spacing92),
|
||||
verticalArrangement = Arrangement.Top,
|
||||
horizontalAlignment = Alignment.Start,
|
||||
) {
|
||||
val sumTextModifier = Modifier.defaultMinSize(minHeight = TangemTheme.dimens.size32)
|
||||
when (type) {
|
||||
is TransactionCardType.ReadOnly -> {
|
||||
if (textFieldValue != null) {
|
||||
Text(
|
||||
text = textFieldValue.text,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.h2,
|
||||
autoSize = TextAutoSize.StepBased(
|
||||
minFontSize = 16.sp,
|
||||
maxFontSize = TangemTheme.typography.h2.fontSize,
|
||||
),
|
||||
maxLines = 1,
|
||||
modifier = sumTextModifier.testTag(SwapTokenScreenTestTags.RECEIVE_TEXT_FIELD),
|
||||
)
|
||||
} else {
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
.padding(vertical = TangemTheme.dimens.spacing4)
|
||||
.width(TangemTheme.dimens.size102)
|
||||
.height(TangemTheme.dimens.size24),
|
||||
)
|
||||
}
|
||||
}
|
||||
is TransactionCardType.Inputtable -> {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
AutoSizeTextField(
|
||||
modifier = sumTextModifier.testTag(SwapTokenScreenTestTags.SWAP_TEXT_FIELD),
|
||||
focusRequester = focusRequester,
|
||||
textFieldValue = textFieldValue ?: TextFieldValue(),
|
||||
isEnabled = type.isEnabled,
|
||||
onAmountChange = { type.onAmountChanged(it) },
|
||||
onFocusChange = type.onFocusChanged,
|
||||
)
|
||||
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
||||
}
|
||||
}
|
||||
SpacerH4()
|
||||
// Keep the same 20dp slot as Detailed (where fiat/shimmer lives)
|
||||
// so that Token (BottomEnd) does not shift when switching modes.
|
||||
Box(modifier = Modifier.defaultMinSize(minHeight = TangemTheme.dimens.size20)) {
|
||||
if (type is TransactionCardType.ReadOnly && type.shouldShowWarning) {
|
||||
WarningIcon(priceImpact = priceImpact, onClick = type.onWarningClick)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WarningIcon(priceImpact: PriceImpact, onClick: (() -> Unit)?) {
|
||||
IconButton(
|
||||
onClick = { onClick?.invoke() },
|
||||
modifier = Modifier.size(TangemTheme.dimens.size20),
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_information_24),
|
||||
contentDescription = null,
|
||||
tint = when (priceImpact.type) {
|
||||
PriceImpact.Type.HIGH -> TangemTheme.colors.text.warning
|
||||
PriceImpact.Type.MEDIUM -> TangemTheme.colors.text.attention
|
||||
else -> TangemTheme.colors.text.tertiary
|
||||
},
|
||||
modifier = Modifier.testTag(SwapTokenScreenTestTags.RECEIVE_FIAT_AMOUNT_INFORMATION_ICON),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TransactionCardSimple_Preview(@PreviewParameter(SimplePreviewProvider::class) params: SwapCardState) {
|
||||
TangemThemePreview {
|
||||
TransactionCardSimple(
|
||||
priceImpact = PriceImpact.Empty,
|
||||
swapCardState = params,
|
||||
onSelectTokenClick = {},
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class SimplePreviewProvider : PreviewParameterProvider<SwapCardState> {
|
||||
override val values: Sequence<SwapCardState> = sequenceOf(
|
||||
SwapTransactionCardPreview.sendCard,
|
||||
SwapTransactionCardPreview.receiveCard,
|
||||
SwapTransactionCardPreview.emptyReadOnlyCard,
|
||||
SwapTransactionCardPreview.emptyInputtableCard,
|
||||
SwapTransactionCardPreview.loadingCard,
|
||||
)
|
||||
}
|
||||
// endregion
|
||||
|
|
@ -48,6 +48,7 @@ internal class StateBuilderInitialStateTest {
|
|||
appCurrencyProvider = appCurrencyProvider,
|
||||
isAccountsModeProvider = isAccountsModeProvider,
|
||||
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
|
||||
shouldShowAbMenu = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ internal class StateBuilderPairsTest {
|
|||
appCurrencyProvider = appCurrencyProvider,
|
||||
isAccountsModeProvider = isAccountsModeProvider,
|
||||
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
|
||||
shouldShowAbMenu = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ internal class StateBuilderQuotesTest {
|
|||
appCurrencyProvider = appCurrencyProvider,
|
||||
isAccountsModeProvider = isAccountsModeProvider,
|
||||
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
|
||||
shouldShowAbMenu = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ internal class StateBuilderSwapDataTest {
|
|||
appCurrencyProvider = appCurrencyProvider,
|
||||
isAccountsModeProvider = isAccountsModeProvider,
|
||||
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
|
||||
shouldShowAbMenu = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue