diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 345f06a0f6..6045fd4bd4 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -438,6 +438,7 @@
Amount
Subtract from send amount
The recipient will receive %s
+ Confirm
%1$s at %2$s
Address
Destination Tag
@@ -488,6 +489,7 @@
Please align your QR code with the square to scan it. Ensure you scan %s network address.
Recent
Recipient
+ Send to
Not a valid address
Ensure that you are sending funds to an %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
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/domain/SendRecipientListContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/domain/SendRecipientListContent.kt
index 7f7216e6e3..47761c5956 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/domain/SendRecipientListContent.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/domain/SendRecipientListContent.kt
@@ -11,7 +11,8 @@ internal sealed class SendRecipientListContent {
val id: String,
val title: TextReference,
val subtitle: TextReference,
- val info: TextReference? = null,
+ val timestamp: TextReference? = null,
+ val subtitleEndOffset: Int = 0,
@DrawableRes val subtitleIconRes: Int? = null,
) : SendRecipientListContent()
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt
index e92791bba9..97ad5f2dfc 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt
@@ -8,7 +8,7 @@ import java.lang.ref.WeakReference
internal class StateRouter(
private val fragmentManager: WeakReference,
) {
- var currentState: MutableStateFlow = MutableStateFlow(SendUiStateType.Amount)
+ var currentState: MutableStateFlow = MutableStateFlow(SendUiStateType.Recipient)
private set
private var isFromSend: Boolean = false
@@ -22,9 +22,9 @@ internal class StateRouter(
showSend()
} else {
when (currentState.value) {
- SendUiStateType.Amount -> popBackStack()
- SendUiStateType.Recipient -> showAmount()
- SendUiStateType.Fee -> showRecipient()
+ SendUiStateType.Recipient -> popBackStack()
+ SendUiStateType.Amount -> showRecipient()
+ SendUiStateType.Fee -> showAmount()
SendUiStateType.Send -> showFee()
}
}
@@ -32,8 +32,8 @@ internal class StateRouter(
fun onNextClick() {
when (currentState.value) {
- SendUiStateType.Amount -> showRecipient()
- SendUiStateType.Recipient -> showFee()
+ SendUiStateType.Recipient -> showAmount()
+ SendUiStateType.Amount -> showFee()
SendUiStateType.Fee -> showSend()
SendUiStateType.Send -> onBackClick()
}
@@ -41,9 +41,9 @@ internal class StateRouter(
fun onPrevClick() {
when (currentState.value) {
- SendUiStateType.Amount -> popBackStack()
- SendUiStateType.Recipient -> showAmount()
- SendUiStateType.Fee -> showRecipient()
+ SendUiStateType.Recipient -> popBackStack()
+ SendUiStateType.Amount -> showRecipient()
+ SendUiStateType.Fee -> showAmount()
SendUiStateType.Send -> popBackStack()
}
}
@@ -63,7 +63,7 @@ internal class StateRouter(
currentState.update { SendUiStateType.Fee }
}
- fun showSend() {
+ private fun showSend() {
currentState.update { SendUiStateType.Send }
}
}
\ No newline at end of file
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientListConverter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientListConverter.kt
index 8fd734e781..da2ee1a963 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientListConverter.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/recipient/SendRecipientListConverter.kt
@@ -3,10 +3,12 @@ package com.tangem.features.send.impl.presentation.state.recipient
import androidx.paging.*
import com.tangem.common.Provider
import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.core.ui.utils.toDateFormat
import com.tangem.core.ui.utils.toTimeFormat
+import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.features.send.impl.R
@@ -34,6 +36,7 @@ internal class SendRecipientListConverter(
val walletsItem = getWalletItems(filteredWallets, txHistoryCount)
+ val cryptoCurrency = cryptoCurrencyStatusProvider().currency
currentStateProvider().recipientList.update {
if (txHistoryCount == 0) {
PagingData.from(listOf(walletsItem))
@@ -51,8 +54,9 @@ internal class SendRecipientListConverter(
SendRecipientListContent.Item(
id = tx.txHash,
title = tx.extractAddress(),
- subtitle = TextReference.Str(tx.getAmount()),
- info = tx.extractTimestamp(),
+ subtitle = stringReference(tx.getAmount(cryptoCurrency).trim()),
+ timestamp = tx.extractTimestamp(),
+ subtitleEndOffset = cryptoCurrency.symbol.length,
subtitleIconRes = tx.extractIconRes(),
)
}.insertWallets(walletsItem)
@@ -104,8 +108,7 @@ internal class SendRecipientListConverter(
R.drawable.ic_arrow_down_24
}
- private fun TxHistoryItem.getAmount(): String {
- val cryptoCurrency = cryptoCurrencyStatusProvider().currency
+ private fun TxHistoryItem.getAmount(cryptoCurrency: CryptoCurrency): String {
return amount.toFormattedCurrencyString(
currency = cryptoCurrency.symbol,
decimals = cryptoCurrency.decimals,
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt
index e7c0df4249..e8118443a5 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendNavigationButtons.kt
@@ -50,7 +50,7 @@ internal fun SendNavigationButtons(uiState: SendUiState) {
private fun SendSecondaryNavigationButton(uiState: SendUiState) {
val currentState = uiState.currentState.collectAsState()
AnimatedVisibility(
- visible = currentState.value == SendUiStateType.Recipient ||
+ visible = currentState.value == SendUiStateType.Amount ||
currentState.value == SendUiStateType.Fee,
) {
Icon(
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt
index 1c73c25a04..e20a0b7779 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/SendScreen.kt
@@ -38,16 +38,15 @@ internal fun SendScreen(uiState: SendUiState) {
horizontalAlignment = Alignment.CenterHorizontally,
) {
val titleRes = when (currentState.value) {
- SendUiStateType.Amount -> R.string.common_send
- SendUiStateType.Recipient -> R.string.send_recipient
+ SendUiStateType.Amount -> R.string.send_amount_label
+ SendUiStateType.Recipient -> R.string.send_recipient_label
SendUiStateType.Fee -> R.string.common_fee_selector_title
- SendUiStateType.Send -> if (isSuccess?.value == false) R.string.common_send else null
+ SendUiStateType.Send -> if (isSuccess?.value == false) R.string.send_confirm_label else null
}
- val iconRes = when (currentState.value) {
- SendUiStateType.Amount,
- SendUiStateType.Recipient,
- -> R.drawable.ic_qrcode_scan_24
- else -> null
+ val iconRes = if (currentState.value == SendUiStateType.Recipient) {
+ R.drawable.ic_qrcode_scan_24
+ } else {
+ null
}
AppBarWithBackButtonAndIcon(
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
index f7c2cd613f..e83ba769bd 100644
--- 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
@@ -3,24 +3,26 @@ 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.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
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.runtime.remember
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.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.Dimension
import androidx.constraintlayout.compose.Visibility
-import com.tangem.core.ui.components.MiddleEllipsisText
+import com.tangem.core.ui.components.atoms.text.EllipsisText
+import com.tangem.core.ui.components.atoms.text.TextEllipsis
import com.tangem.core.ui.components.icons.identicon.IdentIcon
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.impl.R
@@ -33,6 +35,7 @@ import com.tangem.features.send.impl.R
* @param onClick click listener
* @param modifier modifier
* @param info info
+ * @param subtitleEndOffset offset for subtitle ellipsis
* @param subtitleIconRes icon
*/
@Suppress("DestructuringDeclarationWithTooManyEntries", "LongMethod")
@@ -43,6 +46,7 @@ fun ListItemWithIcon(
onClick: () -> Unit,
modifier: Modifier = Modifier,
info: String? = null,
+ subtitleEndOffset: Int = 0,
@DrawableRes subtitleIconRes: Int? = null,
) {
ConstraintLayout(
@@ -51,7 +55,7 @@ fun ListItemWithIcon(
.clickable { onClick() }
.padding(horizontal = TangemTheme.dimens.spacing12),
) {
- val (iconRef, titleRef, subtitleRef, subtitleIconRef, infoRef) = createRefs()
+ val (iconRef, titleRef, subtitleRef, subtitleIconRef) = createRefs()
val spacing2 = TangemTheme.dimens.spacing2
val spacing8 = TangemTheme.dimens.spacing8
@@ -68,11 +72,12 @@ fun ListItemWithIcon(
bottom.linkTo(parent.bottom, margin = spacing8)
},
)
- MiddleEllipsisText(
+ EllipsisText(
text = title,
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Justify,
+ ellipsis = TextEllipsis.Middle,
modifier = Modifier
.constrainAs(titleRef) {
start.linkTo(iconRef.end, margin = spacing12)
@@ -87,7 +92,7 @@ fun ListItemWithIcon(
tint = TangemTheme.colors.icon.informative,
modifier = Modifier
.size(TangemTheme.dimens.size16)
- .background(TangemTheme.colors.background.tertiary, CircleShape)
+ .background(TangemTheme.colors.icon.informative.copy(alpha = 0.1f), CircleShape)
.constrainAs(subtitleIconRef) {
start.linkTo(iconRef.end, margin = spacing12)
top.linkTo(titleRef.bottom)
@@ -95,36 +100,29 @@ fun ListItemWithIcon(
visibility = if (subtitleIconRes == null) Visibility.Gone else Visibility.Visible
},
)
- Text(
- text = subtitle,
+
+ val (text, offset) = remember(subtitle, info) {
+ if (info != null) {
+ val suffix = ", $info"
+ subtitle + suffix to suffix.length + subtitleEndOffset
+ } else {
+ subtitle to 0
+ }
+ }
+ EllipsisText(
+ text = text,
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
+ ellipsis = TextEllipsis.OffsetEnd(offsetEnd = offset),
modifier = Modifier
.constrainAs(subtitleRef) {
start.linkTo(subtitleIconRef.end, margin = spacing2, goneMargin = spacing12)
- end.linkTo(infoRef.start)
+ end.linkTo(parent.end)
top.linkTo(titleRef.bottom)
bottom.linkTo(parent.bottom, margin = spacing10)
width = Dimension.fillToConstraints
},
)
- info?.let {
- Text(
- text = it,
- style = TangemTheme.typography.caption2,
- color = TangemTheme.colors.text.tertiary,
- maxLines = 1,
- modifier = Modifier
- .constrainAs(infoRef) {
- start.linkTo(subtitleRef.end, goneMargin = spacing12)
- end.linkTo(parent.end)
- top.linkTo(titleRef.bottom)
- bottom.linkTo(parent.bottom, margin = spacing10)
- },
- )
- }
}
}
@@ -138,7 +136,7 @@ private fun ListItemWithIconPreview_Light(
ListItemWithIcon(
title = config.title,
subtitle = config.subtitle,
- info = config.info,
+ subtitleEndOffset = config.subtitleEndOffset,
subtitleIconRes = config.iconRes,
onClick = {},
)
@@ -154,7 +152,7 @@ private fun ListItemWithIconPreview_Dark(
ListItemWithIcon(
title = config.title,
subtitle = config.subtitle,
- info = config.info,
+ subtitleEndOffset = config.subtitleEndOffset,
subtitleIconRes = config.iconRes,
onClick = {},
)
@@ -165,6 +163,7 @@ private data class ListItemWithIconPreviewConfig(
val title: String,
val subtitle: String,
val info: String? = null,
+ val subtitleEndOffset: Int = 0,
val iconRes: Int? = null,
)
@@ -174,12 +173,14 @@ private class ListItemWithIconPreviewProvider : CollectionPreviewParameterProvid
title = "0x34B4492A412D84A6E606288f3Bd714b89135D4dE",
subtitle = "0.000000000000000000000000000000 BTC",
info = "0.0.0000 at 00:00",
+ subtitleEndOffset = "BTC".length,
iconRes = R.drawable.ic_arrow_down_24,
),
ListItemWithIconPreviewConfig(
title = "0x34B4492A412D84A6E606288f3Bd714b89135D4dE",
subtitle = "1 BTC",
info = "0.0.0000 at 00:00",
+ subtitleEndOffset = "BTC".length,
iconRes = R.drawable.ic_arrow_down_24,
),
ListItemWithIconPreviewConfig(
diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt
index 24319091e1..5e4316a1e4 100644
--- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt
+++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt
@@ -141,7 +141,8 @@ private fun LazyListScope.recipientListItem(
ListItemWithIcon(
title = item.title.resolveReference(),
subtitle = item.subtitle.resolveReference(),
- info = item.info?.let { ", ${it.resolveReference()}" },
+ info = item.timestamp?.resolveReference(),
+ subtitleEndOffset = item.subtitleEndOffset,
subtitleIconRes = item.subtitleIconRes,
modifier = Modifier
.then(