Updated on 2026-08-14
This commit is contained in:
commit
c61e317229
25 changed files with 370 additions and 207 deletions
|
|
@ -104,8 +104,8 @@ data class TokenMarketInfoResponse(
|
|||
val marketCap: BigDecimal?,
|
||||
@Json(name = "volume_24h")
|
||||
val volume24h: BigDecimal?,
|
||||
@Json(name = "total_supply")
|
||||
val totalSupply: BigDecimal?,
|
||||
@Json(name = "max_supply")
|
||||
val maxSupply: BigDecimal?,
|
||||
@Json(name = "fully_diluted_valuation")
|
||||
val fullyDilutedValuation: BigDecimal?,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -414,7 +414,8 @@
|
|||
<string name="markets_token_details_market_rating_description">Position im Krypto-Rating zwischen allen Coins basierend auf der Marktkapitalisierung</string>
|
||||
<string name="markets_token_details_market_rating_full">Marktbewertung</string>
|
||||
<string name="markets_token_details_max_supply">Maximale Versorgung</string>
|
||||
<string name="markets_token_details_max_supply_description">Leer</string>
|
||||
<string name="markets_token_details_max_supply_description">Die maximale Anzahl von Coins oder Tokens, die jemals für eine bestimmte Kryptowährung existieren können</string>
|
||||
<string name="markets_token_details_max_supply_full">Maximale Versorgung</string>
|
||||
<string name="markets_token_details_metrics">Metriken</string>
|
||||
<string name="markets_token_details_official_links">Offizielle Links</string>
|
||||
<string name="markets_token_details_price_performance">Preisleistung</string>
|
||||
|
|
@ -700,6 +701,7 @@
|
|||
<string name="staking_notification_earn_rewards_text_period_week">Mit dem Staking kannst Du %1$s verdienen. Deine Staking-Belohnungen erhältst Du jede Woche.</string>
|
||||
<string name="staking_notification_earn_rewards_text_weekly">Sicher staken und wöchentliche Belohnungen verdienen.</string>
|
||||
<string name="staking_notification_earn_rewards_title">Verdiene Staking-Belohnungen</string>
|
||||
<string name="staking_notification_network_error_text">Aufgrund von Netzwerkproblemen ist Staking derzeit nicht verfügbar. Bitte versuche es später erneut.</string>
|
||||
<string name="staking_notification_new_validator_funds_transfer">Beim Staking im %1$s -Netzwerk mit einem neuen Validator werden alle zuvor eingesetzten Kryptos automatisch an diesen Validator übertragen</string>
|
||||
<string name="staking_notification_restake_rewards_text">Reinvestiert Deine verdienten Prämien in Deinen Einsatzbetrag und erhöht so den potenziellen Gewinn.</string>
|
||||
<string name="staking_notification_unlock_text">Entsperre dein Geld, um es aus dem Staking-Prozess abzuheben. Das Freischalten nimmt %s.</string>
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@
|
|||
<string name="common_approval">Aprobación</string>
|
||||
<string name="common_approve">Aprobar</string>
|
||||
<string name="common_attention">Atención</string>
|
||||
<string name="common_balance">Soldo: %s</string>
|
||||
<string name="common_balance_title">Soldo</string>
|
||||
<string name="common_balance">Saldo: %s</string>
|
||||
<string name="common_balance_title">Saldo</string>
|
||||
<string name="common_biometric_authentication">autenticación biométrica</string>
|
||||
<string name="common_biometrics">biometría</string>
|
||||
<string name="common_buy">Comprar</string>
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
<string name="common_enable">Activar</string>
|
||||
<string name="common_enabled">Activado</string>
|
||||
<string name="common_error">Error</string>
|
||||
<string name="common_exchange">Intercambie</string>
|
||||
<string name="common_exchange">Intercambiar</string>
|
||||
<string name="common_explore">Explore</string>
|
||||
<string name="common_explore_transaction_history">Explore historial de transacciones</string>
|
||||
<string name="common_explorer">Explorador(a)</string>
|
||||
|
|
@ -211,7 +211,7 @@
|
|||
<string name="details_row_description_flip_to_hide">Gire la pantalla de su dispositivo hacia abajo para ocultar y mostrar rápidamente los saldos</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">%s hashes</string>
|
||||
<string name="details_row_title_cid">ID de la tarjeta</string>
|
||||
<string name="details_row_title_contact_to_support">Contacta con el equipo de soporte</string>
|
||||
<string name="details_row_title_contact_to_support">Contactar con el equipo de soporte</string>
|
||||
<string name="details_row_title_create_backup">Vincular más tarjetas</string>
|
||||
<string name="details_row_title_currency">Moneda de la aplicación</string>
|
||||
<string name="details_row_title_flip_to_hide">Girar para ocultar saldos</string>
|
||||
|
|
@ -351,7 +351,7 @@
|
|||
<string name="markets_common_my_portfolio">Mi portafolio</string>
|
||||
<string name="markets_common_title">Mercado</string>
|
||||
<string name="markets_generate_addresses_notification">Para generar direcciones para las redes seleccionadas, debe escanear su tarjeta Tangem</string>
|
||||
<string name="markets_hint">Para agregar tokens, abra esta página o toque la barra de búsqueda</string>
|
||||
<string name="markets_hint">Para agregar tokens, abra esta página o pulse sobre la barra de búsqueda</string>
|
||||
<string name="markets_insights_info_description_message">Los datos de este apartado proceden de las siguientes redes: %s</string>
|
||||
<string name="markets_loading_error_title">No se pueden cargar los datos…</string>
|
||||
<string name="markets_loading_no_data_title">Sin datos</string>
|
||||
|
|
@ -363,11 +363,11 @@
|
|||
<string name="markets_search_token_no_result_title">Sin resultado</string>
|
||||
<string name="markets_select_network">Seleccione una red</string>
|
||||
<string name="markets_select_wallet">Seleccione una billetera</string>
|
||||
<string name="markets_selector_interval_1m_title">1 mo</string>
|
||||
<string name="markets_selector_interval_1y_title">1 año</string>
|
||||
<string name="markets_selector_interval_1m_title">1m</string>
|
||||
<string name="markets_selector_interval_1y_title">1a</string>
|
||||
<string name="markets_selector_interval_24h_title">24h</string>
|
||||
<string name="markets_selector_interval_3m_title">3mos</string>
|
||||
<string name="markets_selector_interval_6m_title">6mos</string>
|
||||
<string name="markets_selector_interval_3m_title">3m</string>
|
||||
<string name="markets_selector_interval_6m_title">6m</string>
|
||||
<string name="markets_selector_interval_7d_title">7d</string>
|
||||
<string name="markets_selector_interval_all_title">Todo</string>
|
||||
<string name="markets_sort_by_experienced_buyers_title">Compradores experimentados</string>
|
||||
|
|
@ -413,6 +413,8 @@
|
|||
<string name="markets_token_details_market_rating_description">Posición en la clasificación de criptomonedas entre todas las monedas según la capitalización de mercado</string>
|
||||
<string name="markets_token_details_market_rating_full">Evaluación de mercado</string>
|
||||
<string name="markets_token_details_max_supply">Suministro máximo</string>
|
||||
<string name="markets_token_details_max_supply_description">La cantidad máxima de monedas o tokens que pueden existir para una criptomoneda en particular</string>
|
||||
<string name="markets_token_details_max_supply_full">Suministro máximo</string>
|
||||
<string name="markets_token_details_metrics">Métrica</string>
|
||||
<string name="markets_token_details_official_links">Enlaces oficiales</string>
|
||||
<string name="markets_token_details_price_performance">Rendimiento de precios</string>
|
||||
|
|
|
|||
|
|
@ -413,6 +413,8 @@
|
|||
<string name="markets_token_details_market_rating_description">Position dans le classement des crypto-monnaies entre toutes les pièces en fonction de la capitalisation boursière</string>
|
||||
<string name="markets_token_details_market_rating_full">Évaluation du marché</string>
|
||||
<string name="markets_token_details_max_supply">Approvisionnement maximal</string>
|
||||
<string name="markets_token_details_max_supply_description">Le nombre maximal de pièces ou de jetons pouvant exister pour une crypto-monnaie particulière</string>
|
||||
<string name="markets_token_details_max_supply_full">Approvisionnement maximal</string>
|
||||
<string name="markets_token_details_metrics">Métriques</string>
|
||||
<string name="markets_token_details_official_links">Official links</string>
|
||||
<string name="markets_token_details_price_performance">Performance des prix</string>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
<string name="biometric_lockout_warning_title">試行回数が多すぎます</string>
|
||||
<string name="biometric_unavailable_warning">お使いの携帯電話で生体認証が無効になっているため、アプリにウォレットを保存できません。ウォレットを保存するには、携帯電話の設定で生体認証機能を有効にしてください。</string>
|
||||
<string name="button_start_backup_process">バックアップ処理を開始する</string>
|
||||
<string name="buy_token_description">銀行カードまたは銀行口座から</string>
|
||||
<string name="buy_token_description">銀行カードまたはその他の支払い方法を使用する</string>
|
||||
<plurals name="card_label_card_count">
|
||||
<item quantity="other">%d カード</item>
|
||||
</plurals>
|
||||
|
|
@ -101,7 +101,7 @@
|
|||
<string name="common_enable">有効にする</string>
|
||||
<string name="common_enabled">有効</string>
|
||||
<string name="common_error">エラー</string>
|
||||
<string name="common_exchange">交換</string>
|
||||
<string name="common_exchange">スワップ</string>
|
||||
<string name="common_explore">移動する</string>
|
||||
<string name="common_explore_transaction_history">取引履歴を調べる</string>
|
||||
<string name="common_explorer">エクスプローラー</string>
|
||||
|
|
@ -273,7 +273,7 @@
|
|||
<string name="express_token_list_empty_search">トークンが見つかりません。別のリクエストをお試しください。</string>
|
||||
<string name="express_transaction_id">ID: %s</string>
|
||||
<string name="express_transaction_id_copied">取引IDをコピーしました</string>
|
||||
<string name="exсhange_token_description">ウォレット内の別の通貨から</string>
|
||||
<string name="exсhange_token_description">ポートフォリオ内のアセットをこのトークンと交換する</string>
|
||||
<string name="feedback_data_collection_message">以下の情報はオプションです。共有したくない場合は消去できます。</string>
|
||||
<string name="feedback_preface_rate_negative">どのような機能が不足しているかを教えください。解決できるよう尽力致します。</string>
|
||||
<string name="feedback_preface_scan_failed">お持ちのカードについて教えてください</string>
|
||||
|
|
@ -409,6 +409,8 @@
|
|||
<string name="markets_token_details_market_rating_description">時価総額に基づくすべてのコイン間の暗号資産評価における位置</string>
|
||||
<string name="markets_token_details_market_rating_full">市場格付け</string>
|
||||
<string name="markets_token_details_max_supply">最大供給量</string>
|
||||
<string name="markets_token_details_max_supply_description">特定の暗号資産に存在しうるコインまたはトークンの最大数</string>
|
||||
<string name="markets_token_details_max_supply_full">最大供給量</string>
|
||||
<string name="markets_token_details_metrics">指標</string>
|
||||
<string name="markets_token_details_official_links">公式リンク</string>
|
||||
<string name="markets_token_details_price_performance">値動き</string>
|
||||
|
|
@ -522,7 +524,7 @@
|
|||
<string name="qr_scanner_camera_denied_title">カメラへのアクセスが拒否されました</string>
|
||||
<string name="receive_bottom_sheet_warning_message">%3$sネットワーク上の%1$s ( %2$s )</string>
|
||||
<string name="receive_bottom_sheet_warning_message_full">このアドレスには%sのみを送金してください。他のトークンを送信すると、取り返しのつかない損失が発生します。</string>
|
||||
<string name="receive_token_description">QRコードを表示するか、アドレスを共有してください</string>
|
||||
<string name="receive_token_description">ウォレットや取引所から資金を送金する</string>
|
||||
<string name="referral_button_participate">参加する</string>
|
||||
<string name="referral_error_failed_to_load_info">紹介プログラムに関する情報を読み込めませんでした。しばらくしてからもう一度お試しください。</string>
|
||||
<string name="referral_error_failed_to_load_info_with_reason">紹介プログラムに関する情報を読み込めませんでした。エラー コード: %s 。しばらくしてからもう一度お試しください。</string>
|
||||
|
|
@ -570,7 +572,7 @@
|
|||
<string name="scan_card_settings_message">カードをスキャンして設定を変更します。変更はスキャンしたカードにのみ影響し、ウォレットに関連付けられている他のカードには影響しません。</string>
|
||||
<string name="scan_card_settings_title">カードを準備してください!</string>
|
||||
<string name="send_additional_field_already_included">入力したアドレスにすでに含まれています</string>
|
||||
<string name="send_alert_fee_too_high_text">手数料額が推奨額の%s倍となっています。カスタム設定が正しいことを再度確認してください。</string>
|
||||
<string name="send_alert_fee_too_high_text">手数料額が推奨額の%s倍となっています。設定を再度確認し、調整してください。</string>
|
||||
<string name="send_alert_fee_too_low_text">推奨手数料を下回る手数料が指定されたため、取引に遅れが生じる可能性があります。続行しますか?</string>
|
||||
<string name="send_alert_transaction_failed_text">理由: %1$s \nコード: %2$s</string>
|
||||
<string name="send_alert_transaction_failed_title">取引は完了していません</string>
|
||||
|
|
@ -605,7 +607,7 @@
|
|||
<string name="send_notification_exceed_balance_title">合計が残高を超えています</string>
|
||||
<string name="send_notification_existential_deposit_text">セキュリティリスクを防ぐため、ブロックチェーン上にアカウントを維持するには、少なくとも%s の残高が必要です。この金額は残高に残り、引き出すことはできません。</string>
|
||||
<string name="send_notification_existential_deposit_title">アカウント維持に必要な最低残高</string>
|
||||
<string name="send_notification_fee_too_high_text">手数料額が推奨額の%s倍となっています。カスタム設定が正しいことを再度確認してください。</string>
|
||||
<string name="send_notification_fee_too_high_text">手数料額が推奨額の%s倍となっています。設定を再度確認し、調整してください。</string>
|
||||
<string name="send_notification_fee_too_high_title">カスタム手数料が高くなっています</string>
|
||||
<string name="send_notification_high_fee_text">%1$sネットワークの特殊性により、残高全体を転送する場合の手数料は高くなります。手数料を削減するには、 %2$sを残します。</string>
|
||||
<string name="send_notification_high_fee_title">手数料が高くなっています</string>
|
||||
|
|
@ -690,6 +692,7 @@
|
|||
<string name="staking_notification_earn_rewards_text_period_week">ステーキングにより%1$sを獲得できます。ステーキング報酬は毎週受け取れます。</string>
|
||||
<string name="staking_notification_earn_rewards_text_weekly">安全にステーキングして、報酬を毎週獲得しましょう</string>
|
||||
<string name="staking_notification_earn_rewards_title">ステーキング報酬を獲得</string>
|
||||
<string name="staking_notification_network_error_text">ネットワークの状態により、現在ステーキングはご利用いただけません。しばらくしてからもう一度お試しください。</string>
|
||||
<string name="staking_notification_new_validator_funds_transfer">新しいバリデーターで%1$sネットワークにステーキングすると、以前にステーキングされた資金はすべてこのバリデーターに自動的に転送されます。</string>
|
||||
<string name="staking_notification_restake_rewards_text">獲得した報酬をステーキングに再投資し、潜在的な収益を増やします。</string>
|
||||
<string name="staking_notification_unlock_text">資金をステーキングから引き出すには、ロックを解除してください。ロック解除には%sかかります。</string>
|
||||
|
|
@ -706,14 +709,14 @@
|
|||
<string name="staking_revote">再投票</string>
|
||||
<string name="staking_reward_claiming_auto">自動</string>
|
||||
<string name="staking_reward_claiming_manual">手動</string>
|
||||
<string name="staking_reward_schedule_block">ブロック</string>
|
||||
<string name="staking_reward_schedule_day">日</string>
|
||||
<string name="staking_reward_schedule_block">ブロック毎</string>
|
||||
<string name="staking_reward_schedule_day">毎日</string>
|
||||
<string name="staking_reward_schedule_each_day">毎日</string>
|
||||
<string name="staking_reward_schedule_epoch">エポック</string>
|
||||
<string name="staking_reward_schedule_era">時代</string>
|
||||
<string name="staking_reward_schedule_hour">時</string>
|
||||
<string name="staking_reward_schedule_month">月</string>
|
||||
<string name="staking_reward_schedule_week">週</string>
|
||||
<string name="staking_reward_schedule_epoch">エポック毎</string>
|
||||
<string name="staking_reward_schedule_era">時代毎</string>
|
||||
<string name="staking_reward_schedule_hour">毎時間</string>
|
||||
<string name="staking_reward_schedule_month">毎月</string>
|
||||
<string name="staking_reward_schedule_week">毎週</string>
|
||||
<string name="staking_rewards">報酬</string>
|
||||
<string name="staking_stake_locked">ステーキングはロックされています</string>
|
||||
<string name="staking_stake_more">もっとステーキングする</string>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<string name="alert_manage_tokens_unsupported_message">Токены в сети %1$s не поддерживаются этой картой из-за ограничений прошивки.</string>
|
||||
<string name="alert_troubleshooting_scan_card_title">У вас возникли трудности со сканированием карты?</string>
|
||||
<string name="alert_unsupported_card">Эта карта не предназначена для работы с этим приложением</string>
|
||||
<string name="app_settings_default_fee">Комиссия по-умолчанию</string>
|
||||
<string name="app_settings_default_fee_footer">Подключите функцию комиссии по умолчанию и при формировании транзакции на отправку средств комиссия будет выставлена автоматически, а экран комиссии пропущен. Вы всегда сможете на него вернуться.</string>
|
||||
<string name="app_settings_enable_biometrics_description">Перейдите в настройки, чтобы включить биометрическую аутентификацию в приложении Tangem</string>
|
||||
<string name="app_settings_enable_biometrics_title">Включите биометрическую аутентификацию</string>
|
||||
|
|
@ -178,6 +179,7 @@
|
|||
<string name="custom_token_contract_address_input_title">Адрес контракта</string>
|
||||
<string name="custom_token_creation_error_invalid_contract_address">Адрес контракта некорректен</string>
|
||||
<string name="custom_token_creation_error_network_not_selected">Пожалуйста, выберите сеть</string>
|
||||
<string name="custom_token_creation_error_token_already_exist_message">Этот токен уже добавлен в список</string>
|
||||
<string name="custom_token_creation_error_token_already_exist_title">Токен уже существует</string>
|
||||
<string name="custom_token_creation_error_wrong_decimals">Десятичное число должно быть действительным целым числом, до %d</string>
|
||||
<string name="custom_token_custom_derivation">Своя деривация</string>
|
||||
|
|
@ -358,7 +360,7 @@
|
|||
<string name="markets_loading_error_title">Невозможно загрузить данные</string>
|
||||
<string name="markets_loading_no_data_title">Нет данных</string>
|
||||
<string name="markets_quick_actions">Быстрые действия</string>
|
||||
<string name="markets_search_header_title">Искать на маркете</string>
|
||||
<string name="markets_search_header_title">Поиск на рынке</string>
|
||||
<string name="markets_search_result_title">Результат</string>
|
||||
<string name="markets_search_see_tokens_under_100k">Токены с капитализацией меньше 100к USD</string>
|
||||
<string name="markets_search_show_tokens">Показать токены</string>
|
||||
|
|
@ -416,7 +418,9 @@
|
|||
<string name="markets_token_details_market_rating">Рейтинг</string>
|
||||
<string name="markets_token_details_market_rating_description">Позиция в рейтинге криптовалют среди всех монет на основе рыночной капитализации.</string>
|
||||
<string name="markets_token_details_market_rating_full">Рейтинг</string>
|
||||
<string name="markets_token_details_max_supply">Максимальный объем</string>
|
||||
<string name="markets_token_details_max_supply">Макс. объем</string>
|
||||
<string name="markets_token_details_max_supply_description">Максимальное количество монет или токенов, которое может когда-либо существовать для выбранной криптовалюты</string>
|
||||
<string name="markets_token_details_max_supply_full">Максимальный объем</string>
|
||||
<string name="markets_token_details_metrics">Метрики</string>
|
||||
<string name="markets_token_details_official_links">Официальные ссылки</string>
|
||||
<string name="markets_token_details_price_performance">Динамика цены</string>
|
||||
|
|
@ -424,7 +428,7 @@
|
|||
<string name="markets_token_details_security_score">Оценка безопасности</string>
|
||||
<string name="markets_token_details_social">Социальные</string>
|
||||
<string name="markets_token_details_total_supply">Общ. предл.</string>
|
||||
<string name="markets_token_details_total_supply_description">Максимальное количество монет или токенов, которое может когда-либо существовать для выбранной криптовалюты.</string>
|
||||
<string name="markets_token_details_total_supply_description">Максимальное количество монет или токенов, которое может когда-либо существовать для выбранной криптовалюты</string>
|
||||
<string name="markets_token_details_total_supply_full">Общее предложение</string>
|
||||
<string name="markets_token_details_trading_volume">Объем торгов (24ч)</string>
|
||||
<string name="markets_token_details_trading_volume_24h_description">Общая сумма криптовалюты, которая была продана за последние 24 часа, показывающая уровень активности и ликвидности на рынке.</string>
|
||||
|
|
@ -536,7 +540,7 @@
|
|||
<string name="qr_scanner_camera_denied_title">Доступ к камере запрещен</string>
|
||||
<string name="receive_bottom_sheet_warning_message">%1$s (%2$s) в сети %3$s</string>
|
||||
<string name="receive_bottom_sheet_warning_message_full">Отправляйте только %s на этот адрес. Использование другой сети может привести к утрате средств.</string>
|
||||
<string name="receive_token_description">Переводите средства с другого кошелька или биржи</string>
|
||||
<string name="receive_token_description">Переводите средства с любого кошелька или биржи</string>
|
||||
<string name="referral_button_participate">Участвовать</string>
|
||||
<string name="referral_error_failed_to_load_info">Не удалось загрузить информацию по реферальной программе. Пожалуйста, попробуйте позже.</string>
|
||||
<string name="referral_error_failed_to_load_info_with_reason">Не удалось загрузить информацию по реферальной программе. Код ошибки: %s. Пожалуйста, попробуйте позже.</string>
|
||||
|
|
@ -597,6 +601,7 @@
|
|||
<string name="send_amount_label">Сумма</string>
|
||||
<string name="send_bitcoin_custom_fee_footer">Вы можете установить комиссию за транзакцию, изменив значение в поле Satoshi per vByte.</string>
|
||||
<string name="send_custom_amount_fee_footer">Комиссия, которая будет взята за вашу транзакцию. Вы можете выставить своё собственное значение.</string>
|
||||
<string name="send_custom_evm_max_fee">Максимальная комиссия</string>
|
||||
<string name="send_custom_evm_max_fee_footer">Это стоимость, которую вы готовы заплатить за каждую единицу газа. Чем выше цена газа, тем быстрее ваша транзакция будет обработана. (Приоритетная комиссия включена)</string>
|
||||
<string name="send_custom_evm_priority_fee">Приоритетная комиссия</string>
|
||||
<string name="send_custom_evm_priority_fee_footer">Комиссия, которую пользователь может заплатить майнерам или валидаторам за ускорение включения его транзакции в блок.</string>
|
||||
|
|
@ -685,7 +690,7 @@
|
|||
<string name="staking_details_minimum_requirement">Минимальное количество</string>
|
||||
<string name="staking_details_no_rewards_to_claim">Нет вознаграждений к получению</string>
|
||||
<string name="staking_details_reward_claiming">Способ вознаграждения</string>
|
||||
<string name="staking_details_reward_claiming_info">Способ получения вознаграждений за стейкинг. Он может быть автоматическим, при котором вознаграждение само зачисляется вам на адрес или в ручную, когда вознаграждение нужно вывести, создав транзакцию на её получение.</string>
|
||||
<string name="staking_details_reward_claiming_info">Способ получения вознаграждений за стейкинг. Оно может зачисляться автоматически на ваш адрес или вручную, когда вознаграждение нужно вывести, создав транзакцию на её получение.</string>
|
||||
<string name="staking_details_reward_schedule">Период вознагражения</string>
|
||||
<string name="staking_details_reward_schedule_info">Это период, определяющий, когда участники стейкинга получат свои вознаграждения.</string>
|
||||
<string name="staking_details_rewards_to_claim">Вознаграждение для получения: %s</string>
|
||||
|
|
@ -725,14 +730,14 @@
|
|||
<string name="staking_revote">Переголосовать</string>
|
||||
<string name="staking_reward_claiming_auto">Авто</string>
|
||||
<string name="staking_reward_claiming_manual">Вручную</string>
|
||||
<string name="staking_reward_schedule_block">Блок</string>
|
||||
<string name="staking_reward_schedule_day">День</string>
|
||||
<string name="staking_reward_schedule_block">За блок</string>
|
||||
<string name="staking_reward_schedule_day">Ежедневно</string>
|
||||
<string name="staking_reward_schedule_each_day">Каждый день</string>
|
||||
<string name="staking_reward_schedule_epoch">Эпоха</string>
|
||||
<string name="staking_reward_schedule_era">Эра</string>
|
||||
<string name="staking_reward_schedule_hour">Час</string>
|
||||
<string name="staking_reward_schedule_epoch">За эпоху</string>
|
||||
<string name="staking_reward_schedule_era">За эру</string>
|
||||
<string name="staking_reward_schedule_hour">Ежечасно</string>
|
||||
<string name="staking_reward_schedule_month">Месяц</string>
|
||||
<string name="staking_reward_schedule_week">Неделя</string>
|
||||
<string name="staking_reward_schedule_week">Еженедельно</string>
|
||||
<string name="staking_rewards">Вознаграждения</string>
|
||||
<string name="staking_stake_locked">Стейкинг закрыт</string>
|
||||
<string name="staking_stake_more">Застейкать еще</string>
|
||||
|
|
@ -815,6 +820,7 @@
|
|||
<string name="transaction_history_operation">Операция</string>
|
||||
<string name="transaction_history_transaction_from_address">от: %s</string>
|
||||
<string name="transaction_history_transaction_to_address">на: %s</string>
|
||||
<string name="transaction_history_transaction_validator">валидатор: %s</string>
|
||||
<string name="try_to_load_data_again_button_title">Попробовать снова</string>
|
||||
<string name="twin_error_same_card">Вы отсканировали ту же карту. Для создания twin-кошелька вам необходимо отсканировать карту с номером %d</string>
|
||||
<string name="twin_error_wrong_twin">Вы отсканировали не ту twin-карту. Пожалуйста, попробуйте отсканировать другую</string>
|
||||
|
|
|
|||
|
|
@ -418,7 +418,8 @@
|
|||
<string name="markets_token_details_market_rating">Рейтинг</string>
|
||||
<string name="markets_token_details_market_rating_description">Позиція в крипторейтингу між усіма монетами на основі ринкової капіталізації</string>
|
||||
<string name="markets_token_details_market_rating_full">Рейтинг</string>
|
||||
<string name="markets_token_details_max_supply">Максимальна пропозиція</string>
|
||||
<string name="markets_token_details_max_supply_description">Максимальна кількість монет або токенів, яка може коли-небудь існувати для певної криптовалюти</string>
|
||||
<string name="markets_token_details_max_supply_full">Максимальна пропозиція</string>
|
||||
<string name="markets_token_details_metrics">Метрики</string>
|
||||
<string name="markets_token_details_official_links">Офіційні посилання</string>
|
||||
<string name="markets_token_details_price_performance">Цінова ефективність</string>
|
||||
|
|
|
|||
|
|
@ -413,6 +413,8 @@
|
|||
<string name="markets_token_details_market_rating_description">Position in crypto rating between all coins based on market capitalization</string>
|
||||
<string name="markets_token_details_market_rating_full">Market rating</string>
|
||||
<string name="markets_token_details_max_supply">Max supply</string>
|
||||
<string name="markets_token_details_max_supply_description">The maximum number of coins or tokens that can ever exist for a particular cryptocurrency</string>
|
||||
<string name="markets_token_details_max_supply_full">Max supply</string>
|
||||
<string name="markets_token_details_metrics">Metrics</string>
|
||||
<string name="markets_token_details_official_links">Official links</string>
|
||||
<string name="markets_token_details_price_performance">Price performance</string>
|
||||
|
|
@ -528,7 +530,7 @@
|
|||
<string name="qr_scanner_camera_denied_title">Camera access denied</string>
|
||||
<string name="receive_bottom_sheet_warning_message">%1$s (%2$s) on %3$s network</string>
|
||||
<string name="receive_bottom_sheet_warning_message_full">Send only %s to this address. Sending any other currency will result in its irreversible loss.</string>
|
||||
<string name="receive_token_description">Transfer funds from another wallet or exchange</string>
|
||||
<string name="receive_token_description">Transfer funds from any wallet or exchange</string>
|
||||
<string name="referral_button_participate">Participate</string>
|
||||
<string name="referral_error_failed_to_load_info">Failed to load the information about the referral program. Please try again later.</string>
|
||||
<string name="referral_error_failed_to_load_info_with_reason">Failed to load the information about the referral program. Error code: %s. Please try again later.</string>
|
||||
|
|
@ -715,14 +717,14 @@
|
|||
<string name="staking_revote">Revote</string>
|
||||
<string name="staking_reward_claiming_auto">Auto</string>
|
||||
<string name="staking_reward_claiming_manual">Manual</string>
|
||||
<string name="staking_reward_schedule_block">Block</string>
|
||||
<string name="staking_reward_schedule_day">Day</string>
|
||||
<string name="staking_reward_schedule_block">Per Block</string>
|
||||
<string name="staking_reward_schedule_day">Daily</string>
|
||||
<string name="staking_reward_schedule_each_day">Daily</string>
|
||||
<string name="staking_reward_schedule_epoch">Epoch</string>
|
||||
<string name="staking_reward_schedule_era">Era</string>
|
||||
<string name="staking_reward_schedule_hour">Hour</string>
|
||||
<string name="staking_reward_schedule_month">Month</string>
|
||||
<string name="staking_reward_schedule_week">Week</string>
|
||||
<string name="staking_reward_schedule_epoch">Per Epoch</string>
|
||||
<string name="staking_reward_schedule_era">Per Era</string>
|
||||
<string name="staking_reward_schedule_hour">Hourly</string>
|
||||
<string name="staking_reward_schedule_month">Monthly</string>
|
||||
<string name="staking_reward_schedule_week">Weekly</string>
|
||||
<string name="staking_rewards">Rewards</string>
|
||||
<string name="staking_stake_locked">Stake locked</string>
|
||||
<string name="staking_stake_more">Stake more</string>
|
||||
|
|
@ -805,6 +807,7 @@
|
|||
<string name="transaction_history_operation">Operation</string>
|
||||
<string name="transaction_history_transaction_from_address">from: %s</string>
|
||||
<string name="transaction_history_transaction_to_address">to: %s</string>
|
||||
<string name="transaction_history_transaction_validator">validator: %s</string>
|
||||
<string name="try_to_load_data_again_button_title">Try again</string>
|
||||
<string name="twin_error_same_card">You\'ve scanned the same card. To create a twin wallet you need to scan the card with number %d</string>
|
||||
<string name="twin_error_wrong_twin">You\'ve scanned wrong twin card. Please try another one</string>
|
||||
|
|
|
|||
|
|
@ -207,8 +207,8 @@ class TangemSheetState(
|
|||
absVelocityThreshold = 0.5f,
|
||||
),
|
||||
confirmValueChange = confirmValueChange,
|
||||
positionalThreshold = { with(density) { 56.dp.toPx() } },
|
||||
velocityThreshold = { with(density) { 125.dp.toPx() } },
|
||||
positionalThreshold = { with(density) { 156.dp.toPx() } },
|
||||
velocityThreshold = { with(density) { 225.dp.toPx() } },
|
||||
)
|
||||
|
||||
internal val offset: Float
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ fun TangemTheme(
|
|||
dimens: TangemDimens = TangemTheme.dimens,
|
||||
vibratorHapticManager: VibratorHapticManager? = null,
|
||||
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
|
||||
overrideSystemBarColors: Boolean = true,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
val themeColors = if (isDark) darkThemeColors() else lightThemeColors()
|
||||
|
|
@ -32,14 +33,18 @@ fun TangemTheme(
|
|||
.also { it.update(themeColors) }
|
||||
|
||||
val shapes = remember { TangemShapes(dimens) }
|
||||
val systemUiController = rememberSystemUiController()
|
||||
|
||||
SideEffect {
|
||||
systemUiController.setSystemBarsColor(
|
||||
color = Color.Transparent,
|
||||
darkIcons = !isDark,
|
||||
isNavigationBarContrastEnforced = false,
|
||||
)
|
||||
// we don't want to override system bar colors in case of fragment bottom sheets for example
|
||||
if (overrideSystemBarColors) {
|
||||
val systemUiController = rememberSystemUiController()
|
||||
|
||||
SideEffect {
|
||||
systemUiController.setSystemBarsColor(
|
||||
color = Color.Transparent,
|
||||
darkIcons = !isDark,
|
||||
isNavigationBarContrastEnforced = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val view = LocalView.current
|
||||
|
|
|
|||
|
|
@ -52,7 +52,11 @@ abstract class ComposeBottomSheetFragment : BottomSheetDialogFragment(), Compose
|
|||
override fun getTheme(): Int = R.style.AppTheme_TransparentBottomSheetDialog
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return createComposeView(inflater.context, requireActivity())
|
||||
return createComposeView(
|
||||
context = inflater.context,
|
||||
activity = requireActivity(),
|
||||
overrideSystemBarColors = false,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
|
|
|
|||
|
|
@ -50,9 +50,14 @@ internal interface ComposeScreen {
|
|||
* Creates a [ComposeView] with the defined content for the Compose screen.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param overrideSystemBarColors Whether to override the system bar colors to make them transparent.
|
||||
* @return A [ComposeView] instance with the defined screen content.
|
||||
*/
|
||||
internal fun ComposeScreen.createComposeView(context: Context, activity: Activity): ComposeView {
|
||||
internal fun ComposeScreen.createComposeView(
|
||||
context: Context,
|
||||
activity: Activity,
|
||||
overrideSystemBarColors: Boolean = true,
|
||||
): ComposeView {
|
||||
return ComposeView(context).apply {
|
||||
setContent {
|
||||
val appThemeMode by uiDependencies.appThemeModeHolder.appThemeMode
|
||||
|
|
@ -63,6 +68,7 @@ internal fun ComposeScreen.createComposeView(context: Context, activity: Activit
|
|||
windowSize = windowSize,
|
||||
vibratorHapticManager = uiDependencies.vibratorHapticManager,
|
||||
snackbarHostState = uiDependencies.globalSnackbarHostState,
|
||||
overrideSystemBarColors = overrideSystemBarColors,
|
||||
) {
|
||||
ScreenContent(modifier = screenModifier)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.tangem.domain.tokens.model.CryptoCurrency
|
|||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||
import com.tangem.utils.StringsSigns.LOWER_SIGN
|
||||
import com.tangem.utils.StringsSigns.TILDE_SIGN
|
||||
import com.tangem.utils.extensions.isNotWhitespace
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
|
@ -20,8 +21,6 @@ object BigDecimalFormatter {
|
|||
private const val CAN_BE_LOWER_SIGN = LOWER_SIGN
|
||||
private val FORMAT_THRESHOLD = BigDecimal("0.01")
|
||||
|
||||
private const val TEMP_CURRENCY_CODE = "USD"
|
||||
|
||||
private val FIAT_FORMAT_THRESHOLD = BigDecimal("0.01")
|
||||
private val CRYPTO_FEE_FORMAT_THRESHOLD = BigDecimal("0.000001")
|
||||
|
||||
|
|
@ -29,6 +28,12 @@ object BigDecimalFormatter {
|
|||
private const val FIAT_MARKET_EXTENDED_DIGITS = 6
|
||||
private const val FRACTIONAL_PART_LENGTH_AFTER_LEADING_ZEROES = 4
|
||||
|
||||
private val usdCurrency = Currency.getInstance("USD")
|
||||
|
||||
@Deprecated(
|
||||
"Use formatCryptoAmount2",
|
||||
replaceWith = ReplaceWith("formatCryptoAmount2"),
|
||||
)
|
||||
fun formatCryptoAmount(
|
||||
cryptoAmount: BigDecimal?,
|
||||
cryptoCurrency: String,
|
||||
|
|
@ -53,6 +58,30 @@ object BigDecimalFormatter {
|
|||
}
|
||||
}
|
||||
|
||||
// Migrate to this method from formatCryptoAmount ([REDACTED_TASK_KEY])
|
||||
fun formatCryptoAmount2(
|
||||
cryptoAmount: BigDecimal?,
|
||||
cryptoCurrency: String,
|
||||
decimals: Int,
|
||||
locale: Locale = Locale.getDefault(),
|
||||
): String {
|
||||
if (cryptoAmount == null) return EMPTY_BALANCE_SIGN
|
||||
|
||||
val formatter = NumberFormat.getCurrencyInstance(locale).apply {
|
||||
currency = usdCurrency
|
||||
maximumFractionDigits = decimals.coerceAtMost(maximumValue = 8)
|
||||
minimumFractionDigits = 2
|
||||
isGroupingUsed = true
|
||||
roundingMode = RoundingMode.HALF_UP
|
||||
}
|
||||
|
||||
return formatter.format(cryptoAmount)
|
||||
.replaceFiatSymbolWithCrypto(
|
||||
fiatCurrencySymbol = usdCurrency.symbol,
|
||||
cryptoCurrencySymbol = cryptoCurrency,
|
||||
)
|
||||
}
|
||||
|
||||
fun formatCryptoAmountShorted(
|
||||
cryptoAmount: BigDecimal?,
|
||||
cryptoCurrency: String,
|
||||
|
|
@ -305,7 +334,7 @@ object BigDecimalFormatter {
|
|||
.getOrElse { e ->
|
||||
// Currency code is not valid ISO 4217 code
|
||||
if (e is IllegalArgumentException) {
|
||||
Currency.getInstance(TEMP_CURRENCY_CODE)
|
||||
usdCurrency
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
|
|
@ -316,7 +345,7 @@ object BigDecimalFormatter {
|
|||
* Adds a proper currency sign for the provided formatted [amount]
|
||||
* ex. '10.0k" -> "$10.0k", "string" -> "$string"
|
||||
*/
|
||||
fun addCurrencySymbolToStringAmount(
|
||||
private fun addCurrencySymbolToStringAmount(
|
||||
amount: String,
|
||||
fiatCurrencyCode: String,
|
||||
fiatCurrencySymbol: String,
|
||||
|
|
@ -338,6 +367,32 @@ object BigDecimalFormatter {
|
|||
return formatted
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a proper currency sign for the provided formatted [amount]
|
||||
* ex. '10.0k" -> "ETH 10.0k", "string" -> "ETH string"
|
||||
*/
|
||||
private fun addCryptoCurrencySymbolToStringAmount(
|
||||
amount: String,
|
||||
cryptoCurrencySymbol: String,
|
||||
locale: Locale = Locale.getDefault(),
|
||||
): String {
|
||||
val sampleAmount = BigDecimal.TEN
|
||||
|
||||
val formatter = NumberFormat.getCurrencyInstance(locale).apply {
|
||||
maximumFractionDigits = 0
|
||||
minimumFractionDigits = 0
|
||||
currency = usdCurrency
|
||||
}
|
||||
|
||||
val formatted = formatter.format(sampleAmount)
|
||||
.replace(sampleAmount.toString(), amount)
|
||||
|
||||
return formatted.replaceFiatSymbolWithCrypto(
|
||||
fiatCurrencySymbol = usdCurrency.symbol,
|
||||
cryptoCurrencySymbol = cryptoCurrencySymbol,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* "123456.6" -> "$123.457K"
|
||||
* "12345.6" -> "$123.046K"
|
||||
|
|
@ -380,6 +435,45 @@ object BigDecimalFormatter {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* "123456.6" -> "ETH 123.457K"
|
||||
* "12345.6" -> "123.046K ETH"
|
||||
* Negative amount is not supported
|
||||
* @param threeDigitsMethod if true, will format the amount always with 3 significant digits
|
||||
* @param scale the number of digits to the right of the decimal point
|
||||
*/
|
||||
fun formatCompactCryptoAmount(
|
||||
amount: BigDecimal?,
|
||||
cryptoCurrencySymbol: String,
|
||||
threeDigitsMethod: Boolean = false,
|
||||
decimals: Int = 0,
|
||||
locale: Locale = Locale.getDefault(),
|
||||
): String {
|
||||
if (amount == null) return EMPTY_BALANCE_SIGN
|
||||
|
||||
if (amount < BigDecimal.ONE) {
|
||||
return formatCryptoAmount2(
|
||||
cryptoAmount = amount,
|
||||
cryptoCurrency = cryptoCurrencySymbol,
|
||||
decimals = decimals,
|
||||
locale = locale,
|
||||
)
|
||||
}
|
||||
|
||||
val rawAmount = formatCompactAmount(
|
||||
amount = amount,
|
||||
locale = locale,
|
||||
threeDigitsMethod = threeDigitsMethod,
|
||||
scale = decimals,
|
||||
)
|
||||
|
||||
return addCryptoCurrencySymbolToStringAmount(
|
||||
amount = rawAmount,
|
||||
cryptoCurrencySymbol = cryptoCurrencySymbol,
|
||||
locale = locale,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* "123456.6" -> "123.457K"
|
||||
* "12345.6" -> "123.046K"
|
||||
|
|
@ -413,14 +507,61 @@ object BigDecimalFormatter {
|
|||
|
||||
return formatter.format(amount.setScale(scale, RoundingMode.HALF_UP))
|
||||
} else {
|
||||
val value = amount.setScale(scale, RoundingMode.HALF_UP)
|
||||
val scaledAmount = amount.setScale(scale, RoundingMode.HALF_UP)
|
||||
val digitsCount = scaledAmount.longValueExact().toString().count()
|
||||
val digitsToFormat = 5 - when (digitsCount % 3) {
|
||||
0 -> 0
|
||||
1 -> 2
|
||||
else -> 1
|
||||
}
|
||||
|
||||
val formatter = CompactDecimalFormat.getInstance(
|
||||
locale,
|
||||
CompactDecimalFormat.CompactStyle.SHORT,
|
||||
)
|
||||
).apply {
|
||||
minimumSignificantDigits = 2
|
||||
maximumSignificantDigits = digitsToFormat
|
||||
}
|
||||
|
||||
return formatter.format(value)
|
||||
return formatter.format(amount.setScale(scale, RoundingMode.HALF_UP))
|
||||
}
|
||||
}
|
||||
|
||||
// Replaces fiat currency symbol with crypto currency symbol
|
||||
// with respect to the position of the symbol and whitespace
|
||||
private fun String.replaceFiatSymbolWithCrypto(fiatCurrencySymbol: String, cryptoCurrencySymbol: String): String {
|
||||
val str = this
|
||||
if (str.isEmpty()) return str
|
||||
|
||||
return buildString {
|
||||
when {
|
||||
str.endsWith(fiatCurrencySymbol) -> {
|
||||
val withoutSymbol = str.dropLast(fiatCurrencySymbol.length)
|
||||
val last = withoutSymbol.lastOrNull() ?: return cryptoCurrencySymbol
|
||||
|
||||
append(withoutSymbol)
|
||||
|
||||
if (last.isNotWhitespace()) {
|
||||
append("\u2009")
|
||||
}
|
||||
|
||||
append(cryptoCurrencySymbol)
|
||||
}
|
||||
str.startsWith(fiatCurrencySymbol) -> {
|
||||
append(cryptoCurrencySymbol)
|
||||
|
||||
val withoutSymbol = str.drop(fiatCurrencySymbol.length)
|
||||
val first = withoutSymbol.firstOrNull()
|
||||
?: return cryptoCurrencySymbol
|
||||
|
||||
if (first.isNotWhitespace()) {
|
||||
append("\u2009")
|
||||
}
|
||||
|
||||
append(withoutSymbol)
|
||||
}
|
||||
else -> append(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
package com.tangem.core.ui.utils
|
||||
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
import java.util.Locale
|
||||
|
||||
internal object BigDecimalFormatterCompat {
|
||||
|
||||
/**
|
||||
* Formats value as [BigDecimalFormatter.formatCompactFiatAmount] does using only "T","B","M","K" suffixes
|
||||
* Used for < API24 compatibility
|
||||
*/
|
||||
@Suppress("MagicNumber", "UnnecessaryParentheses")
|
||||
fun formatCompactFiatAmountNoLocaleContext(
|
||||
amount: BigDecimal,
|
||||
fiatCurrencyCode: String,
|
||||
fiatCurrencySymbol: String,
|
||||
locale: Locale = Locale.getDefault(),
|
||||
): String {
|
||||
val formatted = formatCompactAmountNoLocaleContext(amount)
|
||||
|
||||
return BigDecimalFormatter.addCurrencySymbolToStringAmount(
|
||||
amount = formatted,
|
||||
fiatCurrencyCode = fiatCurrencyCode,
|
||||
fiatCurrencySymbol = fiatCurrencySymbol,
|
||||
locale = locale,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats value as [BigDecimalFormatter.formatCompactAmount] does using only "T","B","M","K" suffixes
|
||||
* Used for < API24 compatibility
|
||||
*/
|
||||
@Suppress("MagicNumber", "UnnecessaryParentheses")
|
||||
fun formatCompactAmountNoLocaleContext(amount: BigDecimal): String {
|
||||
val value = amount.setScale(0, RoundingMode.HALF_UP).longValueExact()
|
||||
|
||||
val formatted = when {
|
||||
value > 1_000_000_000_000L -> {
|
||||
val trillion = value / 1_000_000_000_000
|
||||
val billion = (value % 1_000_000_000_000) / 1_000_000_000
|
||||
"$trillion.${billion}T"
|
||||
}
|
||||
value > 1_000_000_000L -> {
|
||||
val billion = value / 1_000_000_000
|
||||
val million = (value % 1_000_000_000) / 1_000_000
|
||||
"$billion.${million}B"
|
||||
}
|
||||
value > 1_000_000L -> {
|
||||
val million = value / 1_000_000
|
||||
val thousand = (value % 1_000_000) / 1_000
|
||||
"$million.${thousand}M"
|
||||
}
|
||||
value > 1_000L -> {
|
||||
val thousand = value / 1_000
|
||||
"${thousand}K"
|
||||
}
|
||||
else -> return value.toString()
|
||||
}
|
||||
|
||||
return formatted
|
||||
}
|
||||
}
|
||||
|
|
@ -8,5 +8,6 @@ object StringsSigns {
|
|||
const val DASH_SIGN = "—"
|
||||
const val LOWER_SIGN = "<"
|
||||
const val TILDE_SIGN = "~"
|
||||
const val INFINITY_SIGN = "∞"
|
||||
const val NON_BREAKING_SPACE = '\u00A0'
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ internal object TokenMarketInfoConverter : Converter<TokenMarketInfoResponse, To
|
|||
circulatingSupply = circulatingSupply,
|
||||
marketCap = marketCap,
|
||||
volume24h = volume24h,
|
||||
totalSupply = totalSupply,
|
||||
maxSupply = maxSupply,
|
||||
fullyDilutedValuation = fullyDilutedValuation,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ data class TokenMarketInfo(
|
|||
val circulatingSupply: BigDecimal?,
|
||||
val marketCap: BigDecimal?,
|
||||
val volume24h: BigDecimal?,
|
||||
val totalSupply: BigDecimal?,
|
||||
val maxSupply: BigDecimal?,
|
||||
val fullyDilutedValuation: BigDecimal?,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,43 @@
|
|||
package com.tangem.domain.staking.model.stakekit.action
|
||||
|
||||
enum class StakingActionType(val type: String) {
|
||||
STAKE("Stake"),
|
||||
UNSTAKE("Unstake"),
|
||||
CLAIM_REWARDS("Claim Rewards"),
|
||||
RESTAKE_REWARDS("Restake Rewards"),
|
||||
WITHDRAW("Withdraw"),
|
||||
RESTAKE("Restake"),
|
||||
CLAIM_UNSTAKED("Claim Unstaked"),
|
||||
UNLOCK_LOCKED("Unlock Locked"),
|
||||
STAKE_LOCKED("Stake Locked"),
|
||||
VOTE("Vote"),
|
||||
REVOKE("Revoke"),
|
||||
VOTE_LOCKED("Vote Locked"),
|
||||
REVOTE("Revote"),
|
||||
REBOND("Rebond"),
|
||||
MIGRATE("Migrate"),
|
||||
UNKNOWN("Unknown"),
|
||||
enum class StakingActionType {
|
||||
STAKE,
|
||||
UNSTAKE,
|
||||
CLAIM_REWARDS,
|
||||
RESTAKE_REWARDS,
|
||||
WITHDRAW,
|
||||
RESTAKE,
|
||||
CLAIM_UNSTAKED,
|
||||
UNLOCK_LOCKED,
|
||||
STAKE_LOCKED,
|
||||
VOTE,
|
||||
REVOKE,
|
||||
VOTE_LOCKED,
|
||||
REVOTE,
|
||||
REBOND,
|
||||
MIGRATE,
|
||||
UNKNOWN,
|
||||
;
|
||||
|
||||
companion object {
|
||||
val StakingActionType.asAnalyticName
|
||||
get() = when (this) {
|
||||
STAKE -> "Stake"
|
||||
UNSTAKE -> "Unstake"
|
||||
CLAIM_REWARDS -> "Claim Rewards"
|
||||
RESTAKE_REWARDS -> "Restake Rewards"
|
||||
WITHDRAW -> "Withdraw"
|
||||
RESTAKE -> "Restake"
|
||||
CLAIM_UNSTAKED -> "Claim Unstaked"
|
||||
UNLOCK_LOCKED -> "Unlock Locked"
|
||||
STAKE_LOCKED -> "Stake Locked"
|
||||
VOTE -> "Vote"
|
||||
REVOKE -> "Revoke"
|
||||
VOTE_LOCKED -> "Vote Locked"
|
||||
REVOTE -> "Revote"
|
||||
REBOND -> "Rebond"
|
||||
MIGRATE -> "Migrate"
|
||||
UNKNOWN -> "Unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ import java.math.BigDecimal
|
|||
@Stable
|
||||
internal class MetricsConverter(
|
||||
private val appCurrency: Provider<AppCurrency>,
|
||||
private val tokenSymbol: String,
|
||||
private val onInfoClick: (InfoBottomSheetContent) -> Unit,
|
||||
) : Converter<TokenMarketInfo.Metrics, MetricsUM> {
|
||||
|
||||
|
|
@ -99,12 +100,12 @@ internal class MetricsConverter(
|
|||
},
|
||||
),
|
||||
InfoPointUM(
|
||||
title = resourceReference(R.string.markets_token_details_total_supply),
|
||||
value = totalSupply.formatAmount(crypto = true),
|
||||
title = resourceReference(R.string.markets_token_details_max_supply),
|
||||
value = maxSupply.formatMaxSupply(),
|
||||
onInfoClick = {
|
||||
onInfoClick(
|
||||
InfoBottomSheetContent(
|
||||
title = resourceReference(R.string.markets_token_details_total_supply_full),
|
||||
title = resourceReference(R.string.markets_token_details_max_supply_full),
|
||||
body = resourceReference(R.string.markets_token_details_total_supply_description),
|
||||
),
|
||||
)
|
||||
|
|
@ -115,13 +116,26 @@ internal class MetricsConverter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun BigDecimal?.formatMaxSupply(): String {
|
||||
when (this) {
|
||||
null -> return StringsSigns.DASH_SIGN
|
||||
BigDecimal.ZERO -> return StringsSigns.INFINITY_SIGN
|
||||
}
|
||||
|
||||
return this.formatAmount(crypto = true)
|
||||
}
|
||||
|
||||
private fun BigDecimal?.formatAmount(crypto: Boolean = false): String {
|
||||
if (this == null) return StringsSigns.DASH_SIGN
|
||||
|
||||
return if (crypto) {
|
||||
BigDecimalFormatter.formatCompactAmount(amount = this)
|
||||
BigDecimalFormatter.formatCompactCryptoAmount(
|
||||
amount = this,
|
||||
cryptoCurrencySymbol = tokenSymbol,
|
||||
)
|
||||
} else {
|
||||
val currency = appCurrency()
|
||||
|
||||
BigDecimalFormatter.formatCompactFiatAmount(
|
||||
amount = this,
|
||||
fiatCurrencyCode = currency.code,
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import com.tangem.utils.converter.Converter
|
|||
|
||||
@Stable
|
||||
internal class TokenMarketInfoConverter(
|
||||
appCurrency: Provider<AppCurrency>,
|
||||
onInfoClick: (InfoBottomSheetContent) -> Unit,
|
||||
private val appCurrency: Provider<AppCurrency>,
|
||||
private val onInfoClick: (InfoBottomSheetContent) -> Unit,
|
||||
onLinkClick: (LinksUM.Link) -> Unit,
|
||||
onPricePerformanceIntervalChanged: (PriceChangeInterval) -> Unit,
|
||||
onInsightsIntervalChanged: (PriceChangeInterval) -> Unit,
|
||||
|
|
@ -28,7 +28,6 @@ internal class TokenMarketInfoConverter(
|
|||
@Suppress("UnusedPrivateMember")
|
||||
// TODO second markets iteration
|
||||
private val securityScoreConverter = SecurityScoreConverter(onInfoClick = onInfoClick)
|
||||
private val metricsConverter = MetricsConverter(appCurrency = appCurrency, onInfoClick = onInfoClick)
|
||||
private val pricePerformanceConverter = PricePerformanceConverter(
|
||||
appCurrency = appCurrency,
|
||||
onIntervalChanged = onPricePerformanceIntervalChanged,
|
||||
|
|
@ -36,6 +35,12 @@ internal class TokenMarketInfoConverter(
|
|||
private val linksConverter = LinksConverter(onLinkClick = onLinkClick)
|
||||
|
||||
override fun convert(value: TokenMarketInfo): MarketsTokenDetailsUM.InformationBlocks {
|
||||
val metricsConverter = MetricsConverter(
|
||||
tokenSymbol = value.symbol,
|
||||
appCurrency = appCurrency,
|
||||
onInfoClick = onInfoClick,
|
||||
)
|
||||
|
||||
return MarketsTokenDetailsUM.InformationBlocks(
|
||||
insights = value.insights?.let { insightsConverter.convert(it) },
|
||||
securityScore = null,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
internal fun LinksBlock(state: LinksUM, modifier: Modifier = Modifier) {
|
||||
InformationBlock(
|
||||
modifier = modifier,
|
||||
contentHorizontalPadding = 0.dp,
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.markets_token_details_links),
|
||||
|
|
@ -81,7 +82,7 @@ private fun SubBlock(
|
|||
showDivider = !lastBlock,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing12),
|
||||
modifier = Modifier.padding(TangemTheme.dimens.spacing12),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
Text(
|
||||
|
|
@ -111,6 +112,7 @@ private fun SubBlock(
|
|||
fun LinksBlockPlaceholder(modifier: Modifier = Modifier) {
|
||||
InformationBlock(
|
||||
modifier = modifier,
|
||||
contentHorizontalPadding = 0.dp,
|
||||
title = {
|
||||
TextShimmer(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
|
@ -134,7 +136,7 @@ private fun SubBlockPlaceholder(modifier: Modifier = Modifier, lastBlock: Boolea
|
|||
showDivider = !lastBlock,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing12),
|
||||
modifier = Modifier.padding(TangemTheme.dimens.spacing12),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
TextShimmer(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.markets.portfolio.impl.model
|
|||
import com.tangem.common.ui.userwallet.converter.UserWalletItemUMConverter
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.components.rows.model.BlockchainRowUM
|
||||
import com.tangem.domain.markets.TokenMarketInfo
|
||||
import com.tangem.domain.markets.TokenMarketParams
|
||||
|
|
@ -45,47 +46,51 @@ internal class AddToPortfolioBSContentUMFactory(
|
|||
fun create(
|
||||
portfolioData: PortfolioData,
|
||||
portfolioUIData: PortfolioUIData,
|
||||
selectedWallet: UserWallet,
|
||||
alreadyAddedNetworks: Set<String>,
|
||||
selectedWallet: UserWallet?,
|
||||
alreadyAddedNetworks: Set<String>?,
|
||||
): TangemBottomSheetConfig {
|
||||
return TangemBottomSheetConfig(
|
||||
isShow = portfolioUIData.portfolioBSVisibilityModel.addToPortfolioBSVisibility,
|
||||
onDismissRequest = { onAddToPortfolioVisibilityChange(false) },
|
||||
content = AddToPortfolioBSContentUM(
|
||||
selectedWallet = selectedWallet.toSelectedUserWalletItemUM(),
|
||||
selectNetworkUM = SelectNetworkUMConverter(
|
||||
networksWithToggle = portfolioUIData.addToPortfolioData.associateWithToggle(
|
||||
userWalletId = selectedWallet.walletId,
|
||||
alreadyAddedNetworkIds = alreadyAddedNetworks,
|
||||
),
|
||||
alreadyAddedNetworks = alreadyAddedNetworks,
|
||||
onNetworkSwitchClick = onNetworkSwitchClick,
|
||||
).convert(value = token),
|
||||
isScanCardNotificationVisible = portfolioUIData.hasMissedDerivations,
|
||||
continueButtonEnabled = portfolioUIData.addToPortfolioData.isUserAddedNetworks(
|
||||
userWalletId = selectedWallet.walletId,
|
||||
),
|
||||
onContinueButtonClick = {
|
||||
val alreadyAddedNetworkIds = portfolioData.walletsWithCurrencies[selectedWallet].orEmpty()
|
||||
.map { it.status.currency.network.backendId }
|
||||
.toSet()
|
||||
|
||||
onContinueClick(
|
||||
selectedWallet.walletId,
|
||||
portfolioUIData.addToPortfolioData.getAddedNetworks(
|
||||
content = if (selectedWallet != null && alreadyAddedNetworks != null) {
|
||||
AddToPortfolioBSContentUM(
|
||||
selectedWallet = selectedWallet.toSelectedUserWalletItemUM(),
|
||||
selectNetworkUM = SelectNetworkUMConverter(
|
||||
networksWithToggle = portfolioUIData.addToPortfolioData.associateWithToggle(
|
||||
userWalletId = selectedWallet.walletId,
|
||||
alreadyAddedNetworkIds = alreadyAddedNetworkIds,
|
||||
alreadyAddedNetworkIds = alreadyAddedNetworks,
|
||||
),
|
||||
)
|
||||
},
|
||||
walletSelectorConfig = crateWalletSelectorBSConfig(
|
||||
isShow = portfolioUIData.portfolioBSVisibilityModel.walletSelectorBSVisibility,
|
||||
portfolioData = portfolioData,
|
||||
selectedWalletId = selectedWallet.walletId,
|
||||
),
|
||||
isWalletBlockVisible = portfolioData.walletsWithCurrencies
|
||||
.filterKeys(UserWallet::isMultiCurrency).size > 1,
|
||||
),
|
||||
alreadyAddedNetworks = alreadyAddedNetworks,
|
||||
onNetworkSwitchClick = onNetworkSwitchClick,
|
||||
).convert(value = token),
|
||||
isScanCardNotificationVisible = portfolioUIData.hasMissedDerivations,
|
||||
continueButtonEnabled = portfolioUIData.addToPortfolioData.isUserAddedNetworks(
|
||||
userWalletId = selectedWallet.walletId,
|
||||
),
|
||||
onContinueButtonClick = {
|
||||
val alreadyAddedNetworkIds = portfolioData.walletsWithCurrencies[selectedWallet].orEmpty()
|
||||
.map { it.status.currency.network.backendId }
|
||||
.toSet()
|
||||
|
||||
onContinueClick(
|
||||
selectedWallet.walletId,
|
||||
portfolioUIData.addToPortfolioData.getAddedNetworks(
|
||||
userWalletId = selectedWallet.walletId,
|
||||
alreadyAddedNetworkIds = alreadyAddedNetworkIds,
|
||||
),
|
||||
)
|
||||
},
|
||||
walletSelectorConfig = crateWalletSelectorBSConfig(
|
||||
isShow = portfolioUIData.portfolioBSVisibilityModel.walletSelectorBSVisibility,
|
||||
portfolioData = portfolioData,
|
||||
selectedWalletId = selectedWallet.walletId,
|
||||
),
|
||||
isWalletBlockVisible = portfolioData.walletsWithCurrencies
|
||||
.filterKeys(UserWallet::isMultiCurrency).size > 1,
|
||||
)
|
||||
} else {
|
||||
TangemBottomSheetConfigContent.Empty
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,8 @@ internal class MyPortfolioUMFactory(
|
|||
fun create(portfolioData: PortfolioData, portfolioUIData: PortfolioUIData): MyPortfolioUM {
|
||||
val addToPortfolioData = portfolioUIData.addToPortfolioData
|
||||
|
||||
val hasAvailableNetworks = addToPortfolioData.availableNetworks?.isEmpty() == true
|
||||
val isOnlySingleWalletsAdded = portfolioData.walletsWithCurrencies.keys.all { !it.isMultiCurrency }
|
||||
if (hasAvailableNetworks || isOnlySingleWalletsAdded) return MyPortfolioUM.Unavailable
|
||||
val isOnlyUnavailableNetworks = addToPortfolioData.availableNetworks?.isEmpty() == true
|
||||
if (isOnlyUnavailableNetworks) return MyPortfolioUM.Unavailable
|
||||
|
||||
val walletsWithCurrencies = if (addToPortfolioData.availableNetworks == null) {
|
||||
portfolioData.walletsWithCurrencies
|
||||
|
|
@ -79,16 +78,13 @@ internal class MyPortfolioUMFactory(
|
|||
val selectedWallet = portfolioData.walletsWithCurrencies.keys
|
||||
.firstOrNull { it.walletId == portfolioUIData.selectedWalletId }
|
||||
?: portfolioData.walletsWithCurrencies.keys.firstOrNull { it.isMultiCurrency }
|
||||
?: error("walletsWithCurrencies don't contain selected wallet or any multi-currency wallet")
|
||||
|
||||
val availableNetworks = portfolioUIData.addToPortfolioData.availableNetworks.orEmpty()
|
||||
|
||||
val alreadyAddedNetworks = requireNotNull(
|
||||
value = portfolioData.walletsWithCurrencies.filterAvailableNetworks(availableNetworks)[selectedWallet],
|
||||
lazyMessage = { "walletsWithCurrencies don't contain ${selectedWallet.walletId}" },
|
||||
)
|
||||
.map { it.status.currency.network.backendId }
|
||||
.toSet()
|
||||
val alreadyAddedNetworks = portfolioData.walletsWithCurrencies
|
||||
.filterAvailableNetworks(availableNetworks)[selectedWallet]
|
||||
?.map { it.status.currency.network.backendId }
|
||||
?.toSet()
|
||||
|
||||
return addToPortfolioBSContentUMFactory.create(
|
||||
portfolioData = portfolioData,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.staking.impl.analytics
|
|||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.domain.staking.model.stakekit.action.StakingActionType
|
||||
import com.tangem.domain.staking.model.stakekit.action.StakingActionType.Companion.asAnalyticName
|
||||
|
||||
internal sealed class StakingAnalyticsEvents(
|
||||
event: String,
|
||||
|
|
@ -47,7 +48,7 @@ internal sealed class StakingAnalyticsEvents(
|
|||
params = mapOf(
|
||||
AnalyticsParam.TOKEN_PARAM to token,
|
||||
"Validator" to validator,
|
||||
"Action" to action.type,
|
||||
"Action" to action.asAnalyticName,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -60,7 +61,7 @@ internal sealed class StakingAnalyticsEvents(
|
|||
params = mapOf(
|
||||
AnalyticsParam.TOKEN_PARAM to token,
|
||||
"Validator" to validator,
|
||||
"Action" to action.type,
|
||||
"Action" to action.asAnalyticName,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -143,7 +144,7 @@ internal sealed class StakingAnalyticsEvents(
|
|||
event = "Errors",
|
||||
params = mapOf(
|
||||
AnalyticsParam.TOKEN_PARAM to token,
|
||||
"ErrorType" to errorType,
|
||||
AnalyticsParam.ERROR_DESCRIPTION to errorType,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import androidx.compose.animation.fadeIn
|
|||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideIn
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
|
|
@ -19,7 +18,6 @@ import androidx.compose.material.ExperimentalMaterialApi
|
|||
import androidx.compose.material.pullrefresh.pullRefresh
|
||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.BottomSheetDefaults
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -46,7 +44,8 @@ import androidx.compose.ui.unit.IntOffset
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.components.BottomFade
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.atoms.Hand
|
||||
import com.tangem.core.ui.components.atoms.handComposableComponentHeight
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
|
|
@ -54,6 +53,7 @@ import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBot
|
|||
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.core.ui.components.rememberIsKeyboardVisible
|
||||
import com.tangem.core.ui.components.sheetscaffold.*
|
||||
import com.tangem.core.ui.components.snackbar.CopiedTextSnackbar
|
||||
import com.tangem.core.ui.components.snackbar.TangemSnackbar
|
||||
|
|
@ -468,7 +468,11 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
}
|
||||
|
||||
BottomSheetScrim(
|
||||
color = BottomSheetDefaults.ScrimColor,
|
||||
color = if (state.showMarketsOnboarding) {
|
||||
Color.Black.copy(alpha = .65f)
|
||||
} else {
|
||||
BottomSheetDefaults.ScrimColor
|
||||
},
|
||||
visible = bottomSheetState.targetValue == TangemSheetValue.Expanded ||
|
||||
state.showMarketsOnboarding,
|
||||
onDismissRequest = {
|
||||
|
|
@ -575,7 +579,7 @@ internal fun MarketsHint(isVisible: Boolean, modifier: Modifier = Modifier) {
|
|||
|
||||
@Composable
|
||||
private fun MarketsTooltipContent(modifier: Modifier = Modifier) {
|
||||
val backgroundColor = TangemTheme.colors.background.primary
|
||||
val backgroundColor = TangemTheme.colors.background.action
|
||||
val cornerRadius = CornerRadius(x = 14.dp.toPx())
|
||||
val tipDpSize = DpSize(width = 20.dp, height = 8.dp)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue