diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 8532b9050c..2af2ae2c68 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -89,6 +89,12 @@ Обменять Посмотреть историю транзакций Обозреватель + Скорость и комиссия + Сетевые комиссии за транзакции используются для поддержки безопасности сети, поощрения валидаторов, выделения ресурсов и определения приоритета транзакции. + Медленно + По рынку + Быстро + Свое Сгенерировать адреса Импортировать Нравится @@ -100,6 +106,7 @@ Нет данных OK Основная карта + Вставить Получить Отклонить Перезагрузить @@ -384,19 +391,52 @@ Отсканируйте карту, чтобы изменить ее настройки. Изменения затронут только ту карту, которую вы отсканировали, и не повлияют на другие карты, привязанные к вашему кошельку. Приготовьте свою карту Сумма + Вычесть из суммы отправки + Сумма к получению %1$s Адрес + Код назначения + %1$s в %2$s + Введите адрес Адрес совпадает с адресом кошелька Недопустимый Tag. Он не будет добавлен в транзакцию. Недопустимый Memo. Он не будет добавлен в транзакцию. Tag Memo + Последние + Убедитесь, что вы отправляете средства на адрес кошелька %1$s. Ошибки могут привести к потере ваших токенов. + Мемо/Код назначения - это код, разделяющий транзакции к общему получателю в сети криптовалют. Внимание: отсутствие мемо может привести к потере средств. Включая комиссию Комиссия Низкая Нормальная Приоритетная + Цена газа + Цена газа влияет на скорость транзакции. При сильно низкой, транзакция может быть не обработана. + Лимит газа Максимальная сумма + Всё + Максимальная cумма комиссии + Комиссия не превысит Сетевая комиссия + Покрытие сетевой комиссии + Сумма отправки будет уменьшена для покрытия выбранного уровня комиссии + Обратите внимание, что при определенных параметрах комиссии возможны задержки по вашей транзакции + Недостаточно средств + Недостаточно средств для перевода, так как сумма комиссии и сумма перевода в совокупности больше имеющегося баланса. + Недопустимая сумма + Включенная комиссия превышает сумму перевода, что приводит к отрицательному значению. + Минимальная сумма отправки - %1$s. Пожалуйста, убедитесь, что остаток после отправки также не будет меньше %1$s. + Сумма резерва не может быть менее %1$s. + Пожалуйста, пополните свой баланс, чтобы продолжить. + Увеличение комиссии + Комиссия при переводе всего баланса выше. Для того, чтобы снизить комиссию Вы можете оставить 0.01. + Комиссия превышает баланс + Размер комиссии превышает баланс сети. Для продолжения необходимо пополнить баланс сети. + Возможны задержки по транзакции + Необязательное + QR код содержит информацию о сумме отправки равной %s + Получатель + Мои кошельки Отправка %s Всего %1$s и %2$s будет отправлено diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index ab48be1b10..0559b57bcc 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -87,6 +87,12 @@ Exchange Explore transaction history Explorer + Speed and fee + Network transaction fees are used to support network security, incentivize validators, allocate resources, and determine transaction priority + Slow + Market + Fast + Custom Generate addresses Import Learn & Earn @@ -99,6 +105,7 @@ No data OK Primary Card + Paste Receive Reject Reload @@ -383,20 +390,64 @@ Scan the card to change its settings. The changes will impact only the card you\'ve scanned and will not affect other cards tied to your wallet. Get your card ready! Amount + Subtract from send amount + The recipient will receive %1$s Address + Destination Tag + %1$s at %2$s + Enter address Address is the same as wallet address Invalid Tag. It won\'t be added to the transaction. Invalid Memo. It won\'t be added to the transaction. Tag Memo + Insufficient funds for transfer Include fee Fee Low Normal Priority + Network fee info unreachable + Check your network connection + Gas limit + Gas Limit is auto-calculated; raise it during network congestion + Gas price + Gas Price affects transaction speed. If it\'s too low, the transaction might not be processed. Maximum amount Max + Maximum fee amount + Max fee + Numbers only for Destination Tag Network fee + Network fee coverage + Sending amount will be reduced to cover the selected fee level + Kindly be aware that your transaction may experience delays under specific fee settings + Total exceeds balance + Insufficient funds for the transfer, as the total of the fee and transfer amount exceeds the existing balance. + Invalid amount + The included commission exceeds the transfer amount, leading to a negative value. + The minimum sending amount is %1$s. Please ensure that the remaining balance after sending will not be less than %1$s. + The balance amount must be at least %1$s. + Please top up your balance to continue. + Fee is increased + The fee for transferring the entire balance is higher. To reduce the commission, you can leave 0.01. + Fee exceeds balance + The commission fee exceeds the network balance. To continue, it is necessary to replenish the network balance. + Transaction delays are possible + Optional + Please align your QR code with the square to scan it. Ensure you scan %s network address. + Recipient’s address scanned + Sending amount was changed + QR code contains information about the sending amount equal to %s + Change the entered amount? + Change + Decline + Recent + Recipient + Not a valid address + My wallets + Ensure that you are sending funds to an %1$s wallet address. Errors may result in the loss of your tokens. + A Memo/Destination Tag is a unique ID for differentiating transactions sent to the same recipient on the same network. Caution: Omitting a memo may lead to misplaced funds. Sending %s Total %1$s and %2$s will be sent @@ -404,7 +455,6 @@ %s will be sent Transaction has been successfully signed and sent to the blockchain node. Wallet balance will be updated in a while Invalid address - Insufficient funds for transfer Buy now I have a promo code… Tangem Wallet diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/icons/identicon/Blockies.kt b/core/ui/src/main/java/com/tangem/core/ui/components/icons/identicon/Blockies.kt new file mode 100644 index 0000000000..f1ba4a748e --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/icons/identicon/Blockies.kt @@ -0,0 +1,115 @@ +package com.tangem.core.ui.components.icons.identicon + +import kotlin.math.abs +import kotlin.math.floor + +/** + * Ident icon. Blockies algorithm. + * @see [Blockies](https://github.com/ethereum/blockies) + * + * @param address Address to generate the ident icon + */ +@Suppress("MagicNumber") +internal data class Blockies( + val address: String, +) { + + val primaryColor: Int + val backgroundColor: Int + val spotColor: Int + val data: MutableList + + init { + val seed = seedFromAddress(address) + // IMPORTANT! Color generation is based on the seed, thus ORDER is important. + primaryColor = colorFromSeed(seed) + backgroundColor = colorFromSeed(seed) + spotColor = colorFromSeed(seed) + data = dataFromSeed(seed) + } + + private fun seedFromAddress(address: String): MutableList { + val seed = MutableList(SIZE) { DEFAULT_VALUE_L } + address.indices.forEach { index -> + seed[index % HALF_SIZE] = + (seed[index % HALF_SIZE] shl 5) - seed[index % HALF_SIZE] + Character.codePointAt(address, index) + } + + // Important cast to preserve JavaScript type behavior + seed.indices.map { seed[it] = seed[it].toInt().toLong() } + return seed + } + + private fun colorFromSeed(seed: MutableList): Int { + val h = floor(nextSeed(seed) * DEGREE_CIRCLE_F) + val s = nextSeed(seed) * SATURATION_MAX + SATURATION_MIN + val l = (nextSeed(seed) + nextSeed(seed) + nextSeed(seed) + nextSeed(seed)) * PROBABILITY_LIGHTNESS + return toRgb(h, s, l) + } + + private fun nextSeed(seed: MutableList): Float { + val t = (seed[0] xor (seed[0] shl 11)).toInt() + seed[0] = seed[1] + seed[1] = seed[2] + seed[2] = seed[3] + seed[3] = seed[3] xor (seed[3] shr 19) xor t.toLong() xor (t shr 8).toLong() + + return abs(seed[3]).toFloat() / Integer.MAX_VALUE + } + + private fun dataFromSeed(seed: MutableList) = MutableList(SIZE * SIZE) { DEFAULT_VALUE_F }.apply { + (0 until SIZE).forEach { row -> + (0 until HALF_SIZE).forEach { column -> + val value = floor(nextSeed(seed) * PROBABILITY_COLOR) + this[row * SIZE + column] = value + this[(row + 1) * SIZE - column - 1] = value + } + } + } + + private fun toRgb(paramH: Float, paramS: Float, paramL: Float): Int { + val h = paramH % DEGREE_CIRCLE_F / DEGREE_CIRCLE_F + val s = paramS / PERCENT_MAX + val l = paramL / PERCENT_MAX + + val q = if (l < 0.5) l * (1 + s) else l + s - s * l + val p = 2 * l - q + + val r = hueToRGB(p, q, h + 1f / 3f).coerceIn(0f, 1f) + val g = hueToRGB(p, q, h).coerceIn(0f, 1f) + val b = hueToRGB(p, q, h - 1f / 3f).coerceIn(0f, 1f) + + val red = (r * HEX_COLOR_MAX).toInt() + val green = (g * HEX_COLOR_MAX).toInt() + val blue = (b * HEX_COLOR_MAX).toInt() + return RGB_ALPHA_PART shl RGB_R_PART or (red shl RGB_G_PART) or (green shl RGB_B_PART) or blue + } + + private fun hueToRGB(p: Float, q: Float, h: Float): Float { + var hue = h + if (hue < 0) hue += 1f + if (hue > 1) hue -= 1f + if (6 * hue < 1) return p + (q - p) * 6f * hue + if (2 * hue < 1) return q + + return if (3 * hue < 2) p + (q - p) * 6f * (2f / 3f - hue) else p + } + + companion object { + internal const val SIZE = 8 + private const val HALF_SIZE = SIZE / 2 + private const val DEFAULT_VALUE_L = 0L + private const val DEFAULT_VALUE_F = 0f + private const val DEGREE_CIRCLE_F = 360.0f + private const val HEX_COLOR_MAX = 255 + private const val PERCENT_MAX = 100f + private const val SATURATION_MIN = 40f + private const val SATURATION_MAX = 60f + private const val PROBABILITY_LIGHTNESS = 25f + private const val PROBABILITY_COLOR = 2.3f + private const val RGB_ALPHA_PART = 0xFF + private const val RGB_R_PART = 24 + private const val RGB_G_PART = 16 + private const val RGB_B_PART = 8 + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/icons/identicon/IdentIcon.kt b/core/ui/src/main/java/com/tangem/core/ui/components/icons/identicon/IdentIcon.kt new file mode 100644 index 0000000000..23f26292ee --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/icons/identicon/IdentIcon.kt @@ -0,0 +1,88 @@ +package com.tangem.core.ui.components.icons.identicon + +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.intl.Locale +import androidx.compose.ui.text.toLowerCase +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.res.LocalIsInDarkTheme +import com.tangem.core.ui.res.TangemTheme + +private const val GAP_WIDTH = 1f +private const val ALPHA = 0.9f + +/** + * Ident icon + * + * @param address to generate ident icon from + * @param modifier to apply to ident icon + */ +@Suppress("MagicNumber") +@Composable +fun IdentIcon(address: String, modifier: Modifier = Modifier) { + if (address.isBlank()) { + Box(modifier = modifier) + } else { + val blockies = Blockies(address.toLowerCase(Locale.current)) + Canvas( + modifier = modifier + .then( + if (LocalIsInDarkTheme.current) { + Modifier.alpha(ALPHA) + } else { + Modifier + }, + ), + ) { + val cellWidth = size.width / Blockies.SIZE + blockies.data.forEachIndexed { index, item -> + val y = index / Blockies.SIZE + val x = index % Blockies.SIZE + val colorInt = when (item) { + 1f -> blockies.primaryColor + 2f -> blockies.spotColor + else -> blockies.backgroundColor + } + drawRect( + color = Color(colorInt), + topLeft = Offset(x * cellWidth, y * cellWidth), + size = Size(cellWidth + GAP_WIDTH, cellWidth + GAP_WIDTH), + ) + } + } + } +} + +//region preview +@Preview +@Composable +private fun IdentIconPreview_Light() { + TangemTheme { + IdentIcon( + address = "0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", + modifier = Modifier + .size(TangemTheme.dimens.size40), + ) + } +} + +@Preview +@Composable +private fun IdentIconPreview_Dark() { + TangemTheme(isDark = true) { + IdentIcon( + address = "0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", + modifier = Modifier + .size(TangemTheme.dimens.size40), + ) + } +} + +//endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt index b3820d111f..cb2f374b0c 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt @@ -31,6 +31,7 @@ data class TangemDimens internal constructor( val radius14: Dp = 14.dp, val radius16: Dp = 16.dp, val radius18: Dp = 18.dp, + val radius20: Dp = 20.dp, val radius24: Dp = 24.dp, val radius26: Dp = 26.dp, val radius28: Dp = 28.dp, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/SendFragment.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/SendFragment.kt index d33b82b860..61136054f5 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/SendFragment.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/SendFragment.kt @@ -9,9 +9,9 @@ import androidx.hilt.navigation.compose.hiltViewModel import com.tangem.core.ui.components.SystemBarsEffect import com.tangem.core.ui.screen.ComposeBottomSheetFragment import com.tangem.core.ui.theme.AppThemeModeHolder -import com.tangem.features.send.impl.presentation.send.state.SendUiState -import com.tangem.features.send.impl.presentation.send.ui.SendScreen -import com.tangem.features.send.impl.presentation.send.viewmodel.SendViewModel +import com.tangem.features.send.impl.presentation.state.SendUiState +import com.tangem.features.send.impl.presentation.ui.SendScreen +import com.tangem.features.send.impl.presentation.viewmodel.SendViewModel import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendStateFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt similarity index 84% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendStateFactory.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt index bfca56ad1d..d60ad8e28b 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendStateFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendStateFactory.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.state +package com.tangem.features.send.impl.presentation.state import arrow.core.Either import com.tangem.common.Provider @@ -7,9 +7,10 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.error.CurrencyStatusError import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.wallets.models.UserWallet -import com.tangem.features.send.impl.presentation.send.state.fields.SendAmountFieldChangeConverter -import com.tangem.features.send.impl.presentation.send.state.fields.SendAmountFieldConverter -import com.tangem.features.send.impl.presentation.send.viewmodel.SendClickIntents +import com.tangem.features.send.impl.presentation.state.amount.SendAmountStateConverter +import com.tangem.features.send.impl.presentation.state.fields.SendAmountFieldChangeConverter +import com.tangem.features.send.impl.presentation.state.fields.SendAmountFieldConverter +import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents internal class SendStateFactory( private val clickIntents: SendClickIntents, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendUiState.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt similarity index 87% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendUiState.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt index 0c48ca14b0..f4c9014b85 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendUiState.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendUiState.kt @@ -1,11 +1,12 @@ -package com.tangem.features.send.impl.presentation.send.state +package com.tangem.features.send.impl.presentation.state import androidx.compose.runtime.Immutable import com.tangem.core.ui.components.currency.tokenicon.TokenIconState import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus -import com.tangem.features.send.impl.presentation.send.state.fields.SendTextField -import com.tangem.features.send.impl.presentation.send.viewmodel.SendClickIntents +import com.tangem.features.send.impl.presentation.state.amount.SendAmountSegmentedButtonsConfig +import com.tangem.features.send.impl.presentation.state.fields.SendTextField +import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents import kotlinx.collections.immutable.PersistentList /** diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendAmountSegmentedButtonsConfig.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountSegmentedButtonsConfig.kt similarity index 89% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendAmountSegmentedButtonsConfig.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountSegmentedButtonsConfig.kt index ea3220b6e6..eca219a09d 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendAmountSegmentedButtonsConfig.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountSegmentedButtonsConfig.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.state +package com.tangem.features.send.impl.presentation.state.amount import androidx.compose.runtime.Immutable import com.tangem.core.ui.components.currency.tokenicon.TokenIconState diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendAmountStateConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountStateConverter.kt similarity index 90% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendAmountStateConverter.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountStateConverter.kt index c1a17d6011..3545aeccc6 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/SendAmountStateConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/amount/SendAmountStateConverter.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.state +package com.tangem.features.send.impl.presentation.state.amount import arrow.core.Either import com.tangem.common.Provider @@ -10,8 +10,9 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.error.CurrencyStatusError import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.wallets.models.UserWallet -import com.tangem.features.send.impl.presentation.send.state.fields.SendAmountFieldConverter -import com.tangem.features.send.impl.presentation.send.viewmodel.SendClickIntents +import com.tangem.features.send.impl.presentation.state.SendUiState +import com.tangem.features.send.impl.presentation.state.fields.SendAmountFieldConverter +import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents import com.tangem.utils.converter.Converter import kotlinx.collections.immutable.persistentListOf diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendAmountFieldChangeConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt similarity index 95% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendAmountFieldChangeConverter.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt index 0775989341..5c91a7489e 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendAmountFieldChangeConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldChangeConverter.kt @@ -1,7 +1,7 @@ -package com.tangem.features.send.impl.presentation.send.state.fields +package com.tangem.features.send.impl.presentation.state.fields import com.tangem.common.Provider -import com.tangem.features.send.impl.presentation.send.state.SendUiState +import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.utils.converter.Converter import java.text.DecimalFormatSymbols import java.text.NumberFormat diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendAmountFieldConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldConverter.kt similarity index 88% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendAmountFieldConverter.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldConverter.kt index 8f09a10a04..d6577f14c2 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendAmountFieldConverter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendAmountFieldConverter.kt @@ -1,11 +1,11 @@ -package com.tangem.features.send.impl.presentation.send.state.fields +package com.tangem.features.send.impl.presentation.state.fields import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import com.tangem.core.ui.extensions.TextReference import com.tangem.features.send.impl.R -import com.tangem.features.send.impl.presentation.send.viewmodel.SendClickIntents +import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents import com.tangem.utils.converter.Converter import java.text.NumberFormat diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendTextField.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendTextField.kt similarity index 93% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendTextField.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendTextField.kt index e7677e747d..f62f981b67 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/state/fields/SendTextField.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fields/SendTextField.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.state.fields +package com.tangem.features.send.impl.presentation.state.fields import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Immutable diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendAmountContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendAmountContent.kt similarity index 92% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendAmountContent.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendAmountContent.kt index 8f6dbcabc9..0cc832db0c 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendAmountContent.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendAmountContent.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.ui +package com.tangem.features.send.impl.presentation.ui import androidx.compose.foundation.background import androidx.compose.foundation.layout.* @@ -18,9 +18,9 @@ import com.tangem.core.ui.components.currency.tokenicon.TokenIcon import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.res.TangemTheme import com.tangem.features.send.impl.R -import com.tangem.features.send.impl.presentation.send.state.SendAmountSegmentedButtonsConfig -import com.tangem.features.send.impl.presentation.send.state.SendUiState -import com.tangem.features.send.impl.presentation.send.ui.amount.AmountFieldContainer +import com.tangem.features.send.impl.presentation.state.amount.SendAmountSegmentedButtonsConfig +import com.tangem.features.send.impl.presentation.state.SendUiState +import com.tangem.features.send.impl.presentation.ui.amount.AmountFieldContainer @Composable internal fun SendAmountContent(amountState: SendUiState.Content.AmountState) { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendNavigationButtons.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt similarity index 96% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendNavigationButtons.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt index cf453d487a..599b46babc 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendNavigationButtons.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.ui +package com.tangem.features.send.impl.presentation.ui import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedVisibility @@ -18,7 +18,7 @@ import com.tangem.core.ui.R import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.components.PrimaryButtonIconEnd import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.impl.presentation.send.state.SendUiState +import com.tangem.features.send.impl.presentation.state.SendUiState @Composable internal fun SendNavigationButtons(uiState: SendUiState.Content) { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendScreen.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt similarity index 93% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendScreen.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt index 1e52cf291a..34df63ae5a 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/SendScreen.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.ui +package com.tangem.features.send.impl.presentation.ui import androidx.compose.foundation.background import androidx.compose.foundation.gestures.Orientation @@ -13,7 +13,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetDraggableHeader import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.impl.presentation.send.state.SendUiState +import com.tangem.features.send.impl.presentation.state.SendUiState @Composable internal fun SendScreen(uiState: SendUiState.Content) { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/amount/AmountField.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountField.kt similarity index 97% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/amount/AmountField.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountField.kt index 4eda379a95..5cd1c54f34 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/amount/AmountField.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountField.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.ui.amount +package com.tangem.features.send.impl.presentation.ui.amount import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn @@ -27,7 +27,7 @@ import androidx.compose.ui.text.style.TextAlign import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.impl.presentation.send.state.fields.SendTextField +import com.tangem.features.send.impl.presentation.state.fields.SendTextField @Composable internal fun ColumnScope.AmountField( diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/amount/AmountFieldContainer.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountFieldContainer.kt similarity index 94% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/amount/AmountFieldContainer.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountFieldContainer.kt index b7810d5acb..0bb6d13de0 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/ui/amount/AmountFieldContainer.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/amount/AmountFieldContainer.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.ui.amount +package com.tangem.features.send.impl.presentation.ui.amount import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column @@ -13,7 +13,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.text.style.TextAlign import com.tangem.core.ui.components.currency.tokenicon.TokenIcon import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.send.impl.presentation.send.state.SendUiState +import com.tangem.features.send.impl.presentation.state.SendUiState @Composable internal fun AmountFieldContainer(amountState: SendUiState.Content.AmountState, modifier: Modifier = Modifier) { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/ListItemWithIcon.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/ListItemWithIcon.kt new file mode 100644 index 0000000000..2c3bfff4b4 --- /dev/null +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/ListItemWithIcon.kt @@ -0,0 +1,154 @@ +package com.tangem.features.send.impl.presentation.ui.recipient + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +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.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import com.tangem.core.ui.components.MiddleEllipsisText +import com.tangem.core.ui.components.icons.identicon.IdentIcon +import com.tangem.core.ui.res.TangemTheme +import com.tangem.features.send.impl.R + +/** + * Row item with title and subtitle + * + * @param title title + * @param subtitle subtitle + * @param onClick click listener + * @param modifier modifier + * @param subtitleIconRes icon + */ +@Composable +fun ListItemWithIcon( + title: String, + subtitle: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + @DrawableRes subtitleIconRes: Int? = null, +) { + Row( + modifier = modifier + .fillMaxWidth() + .background(TangemTheme.colors.background.action) + .clickable { onClick() } + .padding( + vertical = TangemTheme.dimens.spacing8, + horizontal = TangemTheme.dimens.spacing12, + ), + ) { + IdentIcon( + address = title, + modifier = Modifier + .size(TangemTheme.dimens.size40) + .clip(RoundedCornerShape(TangemTheme.dimens.radius20)), + ) + Column( + modifier = Modifier + .fillMaxWidth() + .padding( + start = TangemTheme.dimens.spacing12, + top = TangemTheme.dimens.spacing2, + bottom = TangemTheme.dimens.spacing2, + ), + ) { + MiddleEllipsisText( + text = title, + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.primary1, + textAlign = TextAlign.Justify, + modifier = Modifier.fillMaxSize(), + ) + Row { + subtitleIconRes?.let { iconRes -> + Icon( + painter = painterResource(id = iconRes), + contentDescription = null, + tint = TangemTheme.colors.icon.informative, + modifier = Modifier + .size(TangemTheme.dimens.size16) + .background(TangemTheme.colors.background.tertiary, CircleShape) + .padding(TangemTheme.dimens.spacing3), + ) + } + Text( + text = subtitle, + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.tertiary, + maxLines = 1, + modifier = Modifier + .then( + if (subtitleIconRes != null) { + Modifier.padding(start = TangemTheme.dimens.spacing4) + } else { + Modifier + }, + ), + ) + } + } + } +} + +// region preview +@Preview +@Composable +private fun ListItemWithIconPreview_Light( + @PreviewParameter(ListItemWithIconPreviewProvider::class) config: ListItemWithIconPreviewConfig, +) { + TangemTheme { + ListItemWithIcon( + title = config.title, + subtitle = config.subtitle, + subtitleIconRes = config.iconRes, + onClick = {}, + ) + } +} + +@Preview +@Composable +private fun ListItemWithIconPreview_Dark( + @PreviewParameter(ListItemWithIconPreviewProvider::class) config: ListItemWithIconPreviewConfig, +) { + TangemTheme(isDark = true) { + ListItemWithIcon( + title = config.title, + subtitle = config.subtitle, + subtitleIconRes = config.iconRes, + onClick = {}, + ) + } +} + +private data class ListItemWithIconPreviewConfig( + val title: String, + val subtitle: String, + val iconRes: Int? = null, +) + +private class ListItemWithIconPreviewProvider : CollectionPreviewParameterProvider( + collection = listOf( + ListItemWithIconPreviewConfig( + title = "0x34B4492A412D84A6E606288f3Bd714b89135D4dE", + subtitle = "Wallet", + iconRes = R.drawable.ic_arrow_down_24, + ), + ListItemWithIconPreviewConfig( + title = "0x34B4492A412D84A6E606288f3Bd714b89135D4dE", + subtitle = "Wallet", + ), + ), +) +//endregion \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/TextFields.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/TextFields.kt new file mode 100644 index 0000000000..1b9118851a --- /dev/null +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/TextFields.kt @@ -0,0 +1,380 @@ +package com.tangem.features.send.impl.presentation.ui.recipient + +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.BasicTextField +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Alignment.Companion.CenterVertically +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalHapticFeedback +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import com.tangem.core.ui.components.SpacerH8 +import com.tangem.core.ui.components.icons.identicon.IdentIcon +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.features.send.impl.R + +@Composable +internal fun TextFieldWithPasteAndIcon( + value: String, + placeholder: TextReference, + label: TextReference, + onValueChange: (String) -> Unit, + onPasteClick: (String) -> Unit, + modifier: Modifier = Modifier, + footer: String? = null, + singleLine: Boolean = false, +) { + FooterContainer(modifier, footer) { + Column( + modifier = Modifier + .fillMaxWidth() + .background( + color = TangemTheme.colors.background.action, + shape = TangemTheme.shapes.roundedCornersXMedium, + ), + ) { + Text( + text = label.resolveReference(), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.secondary, + modifier = Modifier + .padding( + start = TangemTheme.dimens.spacing12, + end = TangemTheme.dimens.spacing12, + top = TangemTheme.dimens.spacing12, + ), + ) + Row { + IdentIcon( + address = value, + modifier = Modifier + .padding( + start = TangemTheme.dimens.spacing16, + top = TangemTheme.dimens.spacing8, + bottom = TangemTheme.dimens.spacing10, + ) + .clip(RoundedCornerShape(TangemTheme.dimens.radius20)) + .size(TangemTheme.dimens.size40) + .background(TangemTheme.colors.background.tertiary), + ) + SimpleTextField( + value = value, + placeholder = placeholder, + onValueChange = onValueChange, + singleLine = singleLine, + modifier = Modifier + .padding( + start = TangemTheme.dimens.spacing12, + top = TangemTheme.dimens.spacing8, + bottom = TangemTheme.dimens.spacing10, + ) + .weight(1f) + .align(CenterVertically), + ) + PasteButton( + isPasteButtonVisible = value.isBlank(), + onClick = onPasteClick, + modifier = Modifier + .align(CenterVertically) + .padding( + start = TangemTheme.dimens.spacing4, + end = TangemTheme.dimens.spacing16, + ), + ) + } + } + } +} + +@Composable +internal fun TextFieldWithPaste( + value: String, + placeholder: TextReference, + label: TextReference, + onValueChange: (String) -> Unit, + onPasteClick: (String) -> Unit, + modifier: Modifier = Modifier, + footer: String? = null, +) { + FooterContainer(modifier, footer) { + Row( + modifier = Modifier + .background( + color = TangemTheme.colors.background.action, + shape = TangemTheme.shapes.roundedCornersXMedium, + ), + ) { + Column( + modifier = Modifier + .weight(1f) + .padding(TangemTheme.dimens.spacing12), + ) { + Text( + text = label.resolveReference(), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.secondary, + ) + SimpleTextField( + value = value, + placeholder = placeholder, + onValueChange = onValueChange, + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing6), + ) + } + PasteButton( + isPasteButtonVisible = value.isBlank(), + onClick = onPasteClick, + modifier = Modifier + .align(CenterVertically) + .padding(end = TangemTheme.dimens.spacing16), + ) + } + } +} + +@Composable +internal fun TextFieldWithInfo( + value: String, + label: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + info: TextReference? = null, + footer: String? = null, +) { + FooterContainer( + footer = footer, + footerTopPadding = TangemTheme.dimens.spacing6, + modifier = modifier, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .background( + color = TangemTheme.colors.background.action, + shape = TangemTheme.shapes.roundedCornersXMedium, + ) + .padding( + start = TangemTheme.dimens.spacing16, + end = TangemTheme.dimens.spacing16, + top = TangemTheme.dimens.spacing12, + bottom = TangemTheme.dimens.spacing14, + ), + ) { + Text( + text = label, + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.secondary, + ) + Row { + SimpleTextField( + value = value, + onValueChange = onValueChange, + modifier = Modifier + .padding(top = TangemTheme.dimens.spacing6) + .weight(1f), + ) + info?.let { + Text( + text = it.resolveReference(), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.tertiary, + modifier = Modifier + .padding(start = TangemTheme.dimens.spacing8) + .align(Alignment.Bottom), + ) + } + } + } + } +} + +@Composable +private fun FooterContainer( + modifier: Modifier = Modifier, + footer: String? = null, + footerTopPadding: Dp = TangemTheme.dimens.spacing8, + content: @Composable () -> Unit, +) { + Column(modifier = modifier) { + content() + footer?.let { + Text( + text = it, + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.tertiary, + modifier = Modifier + .padding(top = footerTopPadding), + ) + } + } +} + +@Composable +private fun PasteButton(isPasteButtonVisible: Boolean, onClick: (String) -> Unit, modifier: Modifier = Modifier) { + val clipboardManager = LocalClipboardManager.current + val hapticFeedback = LocalHapticFeedback.current + + if (isPasteButtonVisible) { + Box(modifier = modifier) { + Text( + text = "Paste", + style = TangemTheme.typography.button, + color = TangemTheme.colors.text.primary2, + modifier = Modifier + .background( + color = TangemTheme.colors.button.primary, + shape = TangemTheme.shapes.roundedCornersXMedium, + ) + .padding( + horizontal = TangemTheme.dimens.spacing10, + vertical = TangemTheme.dimens.spacing2, + ) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(radius = TangemTheme.dimens.radius8), + onClick = { + hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) + onClick( + clipboardManager + .getText() + ?.toString() + .orEmpty(), + ) + }, + ), + ) + } + } else { + Icon( + painter = painterResource(id = R.drawable.ic_close_24), + tint = TangemTheme.colors.icon.informative, + contentDescription = stringResource(R.string.common_close), + modifier = modifier + .size(TangemTheme.dimens.size20) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(radius = TangemTheme.dimens.radius10), + onClick = { onClick("") }, + ), + ) + } +} + +@Composable +private fun SimpleTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + placeholder: TextReference? = null, + singleLine: Boolean = false, +) { + val focusRequester = remember { FocusRequester() } + BasicTextField( + value = value, + onValueChange = onValueChange, + textStyle = TangemTheme.typography.body2, + cursorBrush = SolidColor(TangemTheme.colors.text.primary1), + singleLine = singleLine, + decorationBox = { textValue -> + Box { + if (value.isBlank() && placeholder != null) { + Text( + text = placeholder.resolveReference(), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.disabled, + modifier = Modifier, + ) + } + textValue() + } + }, + modifier = modifier + .focusRequester(focusRequester), + ) +} + +//region preview +@Preview +@Composable +private fun TextFieldPreview_Light() { + TangemTheme { + Column { + TextFieldWithPaste( + value = "", + label = TextReference.Res(R.string.send_recipient), + placeholder = TextReference.Res(R.string.send_enter_address_field), + onValueChange = {}, + onPasteClick = {}, + ) + SpacerH8() + TextFieldWithPasteAndIcon( + value = "", + label = TextReference.Res(R.string.send_extras_hint_memo), + placeholder = TextReference.Res(R.string.send_optional_field), + onValueChange = {}, + onPasteClick = {}, + ) + SpacerH8() + TextFieldWithInfo( + value = "Text", + label = stringResource(R.string.send_extras_hint_memo), + info = TextReference.Res(R.string.send_optional_field), + footer = stringResource(R.string.send_max_fee), + onValueChange = {}, + ) + } + } +} + +@Preview +@Composable +private fun TextFieldPreview_Dark() { + TangemTheme(isDark = true) { + Column { + TextFieldWithPaste( + value = "", + label = TextReference.Res(R.string.send_recipient), + placeholder = TextReference.Res(R.string.send_enter_address_field), + onValueChange = {}, + onPasteClick = {}, + ) + SpacerH8() + TextFieldWithPasteAndIcon( + value = "", + label = TextReference.Res(R.string.send_extras_hint_memo), + placeholder = TextReference.Res(R.string.send_optional_field), + onValueChange = {}, + onPasteClick = {}, + ) + SpacerH8() + TextFieldWithInfo( + value = "Text", + label = stringResource(R.string.send_extras_hint_memo), + info = TextReference.Res(R.string.send_optional_field), + footer = stringResource(R.string.send_max_fee), + onValueChange = {}, + ) + } + } +} +//endregion \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/viewmodel/SendClickIntents.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt similarity index 74% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/viewmodel/SendClickIntents.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt index 3e6885543a..118d166c69 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/viewmodel/SendClickIntents.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.viewmodel +package com.tangem.features.send.impl.presentation.viewmodel interface SendClickIntents { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt similarity index 96% rename from features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/viewmodel/SendViewModel.kt rename to features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index eac86c94a9..274feef98e 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/send/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.impl.presentation.send.viewmodel +package com.tangem.features.send.impl.presentation.viewmodel import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -14,8 +14,8 @@ import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.features.send.api.navigation.SendRouter -import com.tangem.features.send.impl.presentation.send.state.SendStateFactory -import com.tangem.features.send.impl.presentation.send.state.SendUiState +import com.tangem.features.send.impl.presentation.state.SendStateFactory +import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.saveIn