Updated on 2026-08-14
This commit is contained in:
commit
d05b884698
13 changed files with 114 additions and 32 deletions
|
|
@ -368,6 +368,7 @@
|
|||
<string name="organize_tokens_sort_by_balance">По балансу</string>
|
||||
<string name="organize_tokens_title">Сортировка токенов</string>
|
||||
<string name="organize_tokens_ungroup">Список</string>
|
||||
<string name="qr_scanner_camera_denied_gallery_button">Выбрать из галереи</string>
|
||||
<string name="rate_app_sheet_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>
|
||||
|
|
@ -444,17 +445,23 @@
|
|||
<string name="send_fee_picker_low">Низкая</string>
|
||||
<string name="send_fee_picker_normal">Нормальная</string>
|
||||
<string name="send_fee_picker_priority">Приоритетная</string>
|
||||
<string name="send_fee_unreachable_error_text">Проверьте своё интернет соединение</string>
|
||||
<string name="send_fee_unreachable_error_title">Информация о комиссии сети недоступна</string>
|
||||
<string name="send_from_wallet_android">Из</string>
|
||||
<string name="send_gas_limit">Лимит газа</string>
|
||||
<string name="send_gas_limit_footer">Это максимальное количество газа, которое будет потрачено на выполнение транзакции или контракта. Лимит газа предотвращает неожиданные или неограниченные расходы при выполнении транзакции.</string>
|
||||
<string name="send_gas_price">Цена газа</string>
|
||||
<string name="send_gas_price_footer">Цена газа влияет на скорость транзакции. При сильно низкой, транзакция может быть не обработана.</string>
|
||||
<string name="send_gas_price_footer">Это стоимость, которую вы готовы заплатить за каждую единицу газа. Чем выше цена газа, тем быстрее ваша транзакция будет обработана.</string>
|
||||
<string name="send_max_amount">Всё</string>
|
||||
<string name="send_max_amount_label">Максимальная сумма</string>
|
||||
<string name="send_max_fee">Комиссия не превысит </string>
|
||||
<string name="send_max_fee_footer">Максимальная cумма комиссии</string>
|
||||
<string name="send_max_fee_footer">Комиссия, которая будет взята за вашу транзакцию. Вы можете выставить своё собственное значение.</string>
|
||||
<string name="send_network_fee_warning_content">Сумма отправки будет уменьшена на %1$s для покрытия выбранного уровня комиссии. Получателю будет отправлено %2$s.</string>
|
||||
<string name="send_network_fee_warning_title">Покрытие сетевой комиссии</string>
|
||||
<string name="send_notification_exceed_balance_text">Недостаточно средств для перевода, так как сумма комиссии и сумма перевода в совокупности больше имеющегося баланса</string>
|
||||
<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_title">Установлена высокая комиссия</string>
|
||||
<string name="send_notification_high_fee_text">Комиссия при переводе всего баланса выше. Для того, чтобы снизить комиссию Вы можете оставить %s.</string>
|
||||
|
|
@ -471,12 +478,18 @@
|
|||
<string name="send_notification_transaction_limit_text">Из-за ограничений %1$s в одну транзакцию может поместиться только %2$s UTXO. Это означает, что вы можете отправить только %3$s или меньше. Вам нужно уменьшить сумму.</string>
|
||||
<string name="send_notification_transaction_limit_title">Лимит транзакции</string>
|
||||
<string name="send_optional_field">Необязательное</string>
|
||||
<string name="send_qrcode_scan_info">Пожалуйста, совместите свой QR-код с квадратом, чтобы отсканировать его. Убедитесь, что вы сканируете адрес в сети %s.</string>
|
||||
<string name="send_recent_transactions">Последние</string>
|
||||
<string name="send_recipient">Получатель</string>
|
||||
<string name="send_recipient_address_error">Неверный адрес</string>
|
||||
<string name="send_recipient_address_footer">Убедитесь, что вы отправляете средства на адрес кошелька %s. Ошибки могут привести к потере ваших токенов</string>
|
||||
<string name="send_recipient_label">Отправить</string>
|
||||
<string name="send_recipient_memo_footer">Мемо/ Код назначения - это код, разделяющий транзакции к общему получателю в сети криптовалют. Внимание: отсутствие мемо может привести к потере средств.</string>
|
||||
<string name="send_recipient_wallets_title">Мои кошельки</string>
|
||||
<string name="send_sending">Отправка</string>
|
||||
<string name="send_summary_tap_hint">Нажмите на любое поле, чтобы изменить его</string>
|
||||
<string name="send_summary_title">Отправка %s</string>
|
||||
<string name="send_summary_transaction_description">Вы отправляете %1$s, включая комиссию сети %2$s</string>
|
||||
<string name="send_title_currency_format">Отправка %s</string>
|
||||
<string name="send_total_label">Всего</string>
|
||||
<string name="send_total_subtitle_asset_format">%1$s и %2$s будет отправлено</string>
|
||||
|
|
@ -484,6 +497,7 @@
|
|||
<string name="send_total_subtitle_format">%s будет отправлено</string>
|
||||
<string name="send_transaction_success">Транзакция успешно подписана и отправлена в блокчейн. Баланс будет обновлен через некоторое время</string>
|
||||
<string name="send_validation_invalid_address">Неверный адрес</string>
|
||||
<string name="sent_transaction_sent_title">Транзакция отправлена</string>
|
||||
<string name="story_awe_description">Держите свои криптосбережения в безопасности. Приватные ключи надежно хранятся на карте.</string>
|
||||
<string name="story_awe_title">Революционный аппаратный кошелек</string>
|
||||
<string name="story_backup_description">До трех карт с одним кошельком</string>
|
||||
|
|
@ -521,6 +535,11 @@
|
|||
<string name="toast_balances_hidden">Балансы скрыты</string>
|
||||
<string name="toast_balances_shown">Балансы показаны</string>
|
||||
<string name="toast_undo">Отменить</string>
|
||||
<string name="token_button_unavailability_reason_buy_unavailable">В данный момент покупка монеты %s недоступна. Но мы работаем над её добавлением.”</string>
|
||||
<string name="token_button_unavailability_reason_empty_balance">У вас нет средств для отправки. Пополните счет, чтобы иметь возможность отправить с него средства.</string>
|
||||
<string name="token_button_unavailability_reason_no_quotes">Выбранная операция в данный момент недоступна. Попробуйте позже.</string>
|
||||
<string name="token_button_unavailability_reason_not_exchangeable">Обмен %s не доступен. Но мы работаем над его добавлением.</string>
|
||||
<string name="token_button_unavailability_reason_sell_unavailable">В данный момент продажа монеты %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>
|
||||
|
|
|
|||
|
|
@ -444,13 +444,13 @@
|
|||
<string name="send_fee_unreachable_error_title">Network fee info unreachable</string>
|
||||
<string name="send_from_wallet_android">From</string>
|
||||
<string name="send_gas_limit">Gas limit</string>
|
||||
<string name="send_gas_limit_footer">Gas Limit is auto-calculated; raise it during network congestion</string>
|
||||
<string name="send_gas_limit_footer">This is the maximum amount of gas that will be spent to complete a transaction or contract. A gas limit prevents unexpected or unlimited charges when executing a transaction.</string>
|
||||
<string name="send_gas_price">Gas price</string>
|
||||
<string name="send_gas_price_footer">Gas Price affects transaction speed. If it\'s too low, the transaction might not be processed</string>
|
||||
<string name="send_gas_price_footer">This is the cost you are willing to pay for each unit of gas. The higher the gas price, the faster your transaction will be processed.</string>
|
||||
<string name="send_max_amount">Max</string>
|
||||
<string name="send_max_amount_label">Maximum amount</string>
|
||||
<string name="send_max_fee">Max fee</string>
|
||||
<string name="send_max_fee_footer">Maximum fee amount</string>
|
||||
<string name="send_max_fee_footer">The fee that will be charged for your transaction. You can set your own value.</string>
|
||||
<string name="send_memo_destination_tag_error">Numbers only for Destination Tag</string>
|
||||
<string name="send_network_fee_warning_content">Sending amount will be reduced by %1$s to cover the selected commission level. The recipient will get %2$s.</string>
|
||||
<string name="send_network_fee_warning_title">Network fee coverage</string>
|
||||
|
|
@ -532,6 +532,11 @@
|
|||
<string name="toast_balances_hidden">Balances hidden</string>
|
||||
<string name="toast_balances_shown">Balances shown</string>
|
||||
<string name="toast_undo">Undo</string>
|
||||
<string name="token_button_unavailability_reason_buy_unavailable">The purchase of the %s is currently unavailable. But we are working on adding it.</string>
|
||||
<string name="token_button_unavailability_reason_empty_balance">You do not have funds to send. Top up your account to be able to send funds from it.</string>
|
||||
<string name="token_button_unavailability_reason_no_quotes">This operation is currently unavailable. Please try again later.</string>
|
||||
<string name="token_button_unavailability_reason_not_exchangeable">%s swap is not available. But we are working on adding it.</string>
|
||||
<string name="token_button_unavailability_reason_sell_unavailable">Sell of the %s coin is currently unavailable. But we are working on adding it.</string>
|
||||
<string name="token_details_generate_xpub">Generate XPUB</string>
|
||||
<string name="token_details_hide_alert_hide">Hide</string>
|
||||
<string name="token_details_hide_alert_message">You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page.</string>
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ data class TangemDimens internal constructor(
|
|||
val spacing56: Dp = 56.dp,
|
||||
val spacing60: Dp = 60.dp,
|
||||
val spacing70: Dp = 70.dp,
|
||||
val spacing72: Dp = 72.dp,
|
||||
val spacing76: Dp = 76.dp,
|
||||
val spacing80: Dp = 80.dp,
|
||||
val spacing92: Dp = 92.dp,
|
||||
|
|
|
|||
|
|
@ -31,13 +31,17 @@ import com.tangem.features.send.impl.presentation.state.SendUiState
|
|||
import com.tangem.features.send.impl.presentation.state.SendUiStateType
|
||||
|
||||
@Composable
|
||||
internal fun SendNavigationButtons(uiState: SendUiState, currentState: SendUiCurrentScreen) {
|
||||
internal fun SendNavigationButtons(
|
||||
uiState: SendUiState,
|
||||
currentState: SendUiCurrentScreen,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val sendState = uiState.sendState ?: return
|
||||
val isSuccess = sendState.isSuccess
|
||||
val isSendingState = currentState.type == SendUiStateType.Send && !isSuccess
|
||||
val isSentState = currentState.type == SendUiStateType.Send && isSuccess
|
||||
Column(
|
||||
modifier = Modifier
|
||||
modifier = modifier
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing16,
|
||||
end = TangemTheme.dimens.spacing16,
|
||||
|
|
|
|||
|
|
@ -74,13 +74,17 @@ internal fun SendScreen(uiState: SendUiState, currentStateFlow: StateFlow<SendUi
|
|||
backgroundColor = TangemTheme.colors.background.tertiary,
|
||||
modifier = Modifier.height(TangemTheme.dimens.size56),
|
||||
)
|
||||
SendScreenContent(
|
||||
uiState = uiState,
|
||||
currentState = currentState.value,
|
||||
modifier = Modifier
|
||||
.weight(1f),
|
||||
)
|
||||
SendNavigationButtons(uiState, currentState.value)
|
||||
Box(modifier = Modifier.weight(1f)) {
|
||||
SendScreenContent(
|
||||
uiState = uiState,
|
||||
currentState = currentState.value,
|
||||
)
|
||||
SendNavigationButtons(
|
||||
uiState = uiState,
|
||||
currentState = currentState.value,
|
||||
modifier = Modifier.align(Alignment.BottomCenter),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SendEventEffect(
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ package com.tangem.features.send.impl.presentation.ui.amount
|
|||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment.Companion.BottomCenter
|
||||
|
|
@ -22,15 +21,15 @@ import com.tangem.core.ui.utils.rememberDecimalFormat
|
|||
import com.tangem.features.send.impl.presentation.state.fields.SendTextField
|
||||
|
||||
@Composable
|
||||
internal fun AmountField(sendField: SendTextField.AmountField, isFiat: Boolean, isEnabled: Boolean) {
|
||||
internal fun AmountField(sendField: SendTextField.AmountField, isEnabled: Boolean) {
|
||||
val decimalFormat = rememberDecimalFormat()
|
||||
val (primaryValue, secondaryValue) = if (isFiat) {
|
||||
val (primaryValue, secondaryValue) = if (sendField.isFiatValue) {
|
||||
sendField.fiatValue to sendField.value
|
||||
} else {
|
||||
sendField.value to sendField.fiatValue
|
||||
}
|
||||
|
||||
val (primaryAmount, secondaryAmount) = if (isFiat) {
|
||||
val (primaryAmount, secondaryAmount) = if (sendField.isFiatValue) {
|
||||
sendField.fiatAmount to sendField.cryptoAmount
|
||||
} else {
|
||||
sendField.cryptoAmount to sendField.fiatAmount
|
||||
|
|
@ -48,13 +47,15 @@ internal fun AmountField(sendField: SendTextField.AmountField, isFiat: Boolean,
|
|||
textAlign = TextAlign.Center,
|
||||
),
|
||||
isEnabled = isEnabled,
|
||||
isAutoResize = true,
|
||||
placeholderAlignment = TopCenter,
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
top = TangemTheme.dimens.spacing24,
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
end = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
)
|
||||
.requiredHeightIn(min = TangemTheme.dimens.size32),
|
||||
)
|
||||
|
||||
Box(
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ internal fun LazyListScope.amountField(
|
|||
)
|
||||
AmountField(
|
||||
sendField = amountState.amountTextField,
|
||||
isFiat = amountState.amountTextField.isFiatValue,
|
||||
isEnabled = !amountState.isFeeLoading,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,13 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.send.impl.presentation.state.SendStates
|
||||
import com.tangem.features.send.impl.presentation.state.previewdata.AmountStatePreviewData
|
||||
import com.tangem.features.send.impl.presentation.state.previewdata.SendClickIntentsStub
|
||||
import com.tangem.features.send.impl.presentation.ui.common.notifications
|
||||
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
|
||||
|
||||
|
|
@ -30,4 +35,41 @@ internal fun SendAmountContent(
|
|||
)
|
||||
notifications(amountState.notifications)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Preview
|
||||
@Composable
|
||||
private fun AmountFieldPreview_Light(
|
||||
@PreviewParameter(AmountFieldPreviewProvider::class) amountState: SendStates.AmountState,
|
||||
) {
|
||||
TangemTheme {
|
||||
SendAmountContent(
|
||||
amountState = amountState,
|
||||
isBalanceHiding = false,
|
||||
clickIntents = SendClickIntentsStub,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun AmountFieldPreview_Dark(
|
||||
@PreviewParameter(AmountFieldPreviewProvider::class) amountState: SendStates.AmountState,
|
||||
) {
|
||||
TangemTheme(isDark = true) {
|
||||
SendAmountContent(
|
||||
amountState = amountState,
|
||||
isBalanceHiding = false,
|
||||
clickIntents = SendClickIntentsStub,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class AmountFieldPreviewProvider : PreviewParameterProvider<SendStates.AmountState> {
|
||||
override val values: Sequence<SendStates.AmountState>
|
||||
get() = sequenceOf(
|
||||
AmountStatePreviewData.amountState,
|
||||
)
|
||||
}
|
||||
// endregion
|
||||
|
|
@ -22,7 +22,7 @@ internal fun LazyListScope.notifications(
|
|||
contentType = { _, item -> item::class.java },
|
||||
itemContent = { i, item ->
|
||||
val bottomPadding = if (i == notifications.lastIndex) {
|
||||
TangemTheme.dimens.spacing12
|
||||
TangemTheme.dimens.spacing72
|
||||
} else {
|
||||
TangemTheme.dimens.spacing0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
internal fun SendCustomFeeEthereum(
|
||||
customValues: ImmutableList<SendTextField.CustomFee>,
|
||||
selectedFee: FeeType,
|
||||
hasNotifications: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
|
|
@ -34,8 +35,8 @@ internal fun SendCustomFeeEthereum(
|
|||
) {
|
||||
repeat(customValues.size) { index ->
|
||||
val value = customValues[index]
|
||||
val bottomPadding = if (index == customValues.lastIndex) {
|
||||
TangemTheme.dimens.spacing12
|
||||
val bottomPadding = if (index == customValues.lastIndex && !hasNotifications) {
|
||||
TangemTheme.dimens.spacing72
|
||||
} else {
|
||||
TangemTheme.dimens.spacing0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@ private const val FEE_CUSTOM_KEY = "FEE_CUSTOM_KEY"
|
|||
internal fun SendSpeedAndFeeContent(state: SendStates.FeeState?, clickIntents: SendClickIntents) {
|
||||
if (state == null) return
|
||||
val feeSendState = state.feeSelectorState as? FeeSelectorState.Content
|
||||
val isCustomSelected = feeSendState?.selectedFee == FeeType.Custom
|
||||
val notifications = state.notifications
|
||||
val isCustomSelected = feeSendState?.selectedFee == FeeType.Custom
|
||||
val hasNotifications = notifications.isNotEmpty()
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -35,7 +36,7 @@ internal fun SendSpeedAndFeeContent(state: SendStates.FeeState?, clickIntents: S
|
|||
) {
|
||||
feeSelector(state, clickIntents)
|
||||
if (feeSendState != null) {
|
||||
customFee(feeSendState)
|
||||
customFee(feeSendState = feeSendState, hasNotifications = hasNotifications)
|
||||
}
|
||||
notifications(notifications = notifications, hasPaddingAbove = isCustomSelected)
|
||||
}
|
||||
|
|
@ -55,13 +56,18 @@ private fun LazyListScope.feeSelector(state: SendStates.FeeState, clickIntents:
|
|||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
internal fun LazyListScope.customFee(feeSendState: FeeSelectorState.Content, modifier: Modifier = Modifier) {
|
||||
internal fun LazyListScope.customFee(
|
||||
feeSendState: FeeSelectorState.Content,
|
||||
hasNotifications: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
item(
|
||||
key = FEE_CUSTOM_KEY,
|
||||
) {
|
||||
SendCustomFeeEthereum(
|
||||
customValues = feeSendState.customValues,
|
||||
selectedFee = feeSendState.selectedFee,
|
||||
hasNotifications = hasNotifications,
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.animateItemPlacement()
|
||||
|
|
|
|||
|
|
@ -163,11 +163,11 @@ private fun FeeSelectorState.Content.getAmount(feeType: FeeType): Amount? {
|
|||
private fun FeeSelectorState.Content?.getDividerAndVisibility(feeType: FeeType): Pair<Boolean, Boolean> {
|
||||
val hasCustomValues = !this?.customValues.isNullOrEmpty()
|
||||
val isNotSingle = this?.fees !is TransactionFee.Single
|
||||
val isSingle = this?.fees is TransactionFee.Single
|
||||
val isLoaded = this?.fees != null
|
||||
return when (feeType) {
|
||||
FeeType.Slow -> true to isNotSingle
|
||||
FeeType.Market -> isNotSingle to isSingle
|
||||
FeeType.Market -> isNotSingle to isLoaded
|
||||
FeeType.Fast -> hasCustomValues to isNotSingle
|
||||
FeeType.Custom -> false to isNotSingle
|
||||
FeeType.Custom -> false to hasCustomValues
|
||||
}
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ private fun LazyListScope.listItem(
|
|||
.then(
|
||||
if (isLast && index == list.lastIndex) {
|
||||
Modifier
|
||||
.padding(bottom = TangemTheme.dimens.spacing12)
|
||||
.padding(bottom = TangemTheme.dimens.spacing72)
|
||||
.clip(
|
||||
shape = RoundedCornerShape(
|
||||
bottomStart = TangemTheme.dimens.radius16,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue