Updated on 2026-08-14

This commit is contained in:
Tangem 2024-03-01 18:40:30 +00:00
parent 3f2373bca7
commit 5c37996587
6 changed files with 86 additions and 22 deletions

View file

@ -5,6 +5,7 @@ data class ExchangeStatusModel(
val status: ExchangeStatus? = null,
val txId: String? = null,
val txExternalUrl: String? = null,
val txExternalId: String? = null,
)
enum class ExchangeStatus {

View file

@ -606,7 +606,7 @@ internal class SwapInteractorImpl @Inject constructor(
network = currencyToSend.currency.network,
)
val externalUrl = (exchangeData.transaction as? ExpressTransactionModel.CEX)?.externalTxUrl
val txCexModel = exchangeData.transaction as? ExpressTransactionModel.CEX
val derivationPath = currencyToSend.currency.network.derivationPath.value
return result.fold(
@ -621,6 +621,7 @@ internal class SwapInteractorImpl @Inject constructor(
},
ifRight = {
val timestamp = System.currentTimeMillis()
val txExternalUrl = txCexModel?.externalTxUrl
storeSwapTransaction(
currencyToSend = currencyToSend,
currencyToGet = currencyToGet,
@ -628,7 +629,8 @@ internal class SwapInteractorImpl @Inject constructor(
swapProvider = swapProvider,
swapDataModel = exchangeData,
timestamp = timestamp,
txExternalUrl = externalUrl.orEmpty(),
txExternalUrl = txExternalUrl.orEmpty(),
txExternalId = txCexModel?.externalTxId.orEmpty(),
)
storeLastCryptoCurrencyId(currencyToGet.currency)
TxState.TxSent(
@ -646,7 +648,7 @@ internal class SwapInteractorImpl @Inject constructor(
currencyToSend.currency.network.backendId,
derivationPath,
).orEmpty(),
txExternalUrl = externalUrl,
txExternalUrl = txExternalUrl,
timestamp = timestamp,
)
},
@ -697,6 +699,7 @@ internal class SwapInteractorImpl @Inject constructor(
swapDataModel: SwapDataModel,
timestamp: Long,
txExternalUrl: String,
txExternalId: String,
) {
swapTransactionRepository.storeTransaction(
userWalletId = UserWalletId(userWalletManager.getWalletId()),
@ -713,6 +716,7 @@ internal class SwapInteractorImpl @Inject constructor(
status = ExchangeStatus.New,
txId = swapDataModel.transaction.txId,
txExternalUrl = txExternalUrl,
txExternalId = txExternalId,
),
),
)

View file

@ -13,6 +13,7 @@ internal data class SwapTransactionsState(
val txId: String,
val provider: SwapProvider,
val txUrl: String? = null,
val txExternalId: String? = null,
val timestamp: TextReference,
val fiatSymbol: String,
val activeStatus: ExchangeStatus?,

View file

@ -47,18 +47,18 @@ internal class TokenDetailsSwapTransactionsStateConverter(
val result = mutableListOf<SwapTransactionsState>()
savedTransactions
.forEach { swapCurrency ->
val toCryptoCurrency = swapCurrency.toCryptoCurrency
val fromCryptoCurrency = swapCurrency.fromCryptoCurrency
.forEach { swapTransaction ->
val toCryptoCurrency = swapTransaction.toCryptoCurrency
val fromCryptoCurrency = swapTransaction.fromCryptoCurrency
swapCurrency.transactions.forEach { transaction ->
swapTransaction.transactions.forEach { transaction ->
val toAmount = transaction.toCryptoAmount
val fromAmount = transaction.fromCryptoAmount
val toFiatAmount = quotes.firstOrNull {
it.rawCurrencyId == swapCurrency.toCryptoCurrency.id.rawCurrencyId
it.rawCurrencyId == swapTransaction.toCryptoCurrency.id.rawCurrencyId
}?.fiatRate?.multiply(toAmount)
val fromFiatAmount = quotes.firstOrNull {
it.rawCurrencyId == swapCurrency.fromCryptoCurrency.id.rawCurrencyId
it.rawCurrencyId == swapTransaction.fromCryptoCurrency.id.rawCurrencyId
}?.fiatRate?.multiply(fromAmount)
val timestamp = transaction.timestamp
val notifications =
@ -69,6 +69,7 @@ internal class TokenDetailsSwapTransactionsStateConverter(
txId = transaction.txId,
provider = transaction.provider,
txUrl = transaction.status?.txExternalUrl,
txExternalId = transaction.status?.txExternalId,
timestamp = TextReference.Str(
"${timestamp.toDateFormat()}, ${timestamp.toTimeFormat()}",
),

View file

@ -1,36 +1,79 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.exchange
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.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.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.components.inputrow.InputRowBestRate
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.res.TangemTheme
@Composable
internal fun ExchangeProvider(providerName: TextReference, providerType: TextReference, imageUrl: String) {
internal fun ExchangeProvider(
providerName: TextReference,
providerType: TextReference,
providerTxId: String?,
imageUrl: String,
) {
val clipboardManager = LocalClipboardManager.current
val hapticFeedback = LocalHapticFeedback.current
Column(
modifier = Modifier
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(TangemTheme.colors.background.action),
) {
Text(
text = stringResource(id = R.string.express_provider),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
Box(
modifier = Modifier
.padding(
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing12,
),
)
.padding(top = TangemTheme.dimens.spacing12)
.padding(horizontal = TangemTheme.dimens.spacing12)
.fillMaxWidth(),
) {
Text(
text = stringResource(id = R.string.express_provider),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.align(Alignment.CenterStart),
)
if (!providerTxId.isNullOrEmpty()) {
Row(
modifier = Modifier
.align(Alignment.CenterEnd)
.clickable {
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
clipboardManager.setText(AnnotatedString(providerTxId))
},
) {
Icon(
modifier = Modifier
.size(TangemTheme.dimens.size20)
.padding(end = TangemTheme.dimens.spacing4)
.align(Alignment.CenterVertically),
painter = painterResource(id = R.drawable.ic_copy_24),
contentDescription = null,
tint = TangemTheme.colors.text.tertiary,
)
Text(
modifier = Modifier.align(Alignment.CenterVertically),
text = "ID: $providerTxId",
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
)
}
}
}
InputRowBestRate(
imageUrl = imageUrl,
title = providerName,
@ -38,4 +81,17 @@ internal fun ExchangeProvider(providerName: TextReference, providerType: TextRef
subtitle = TextReference.Res(R.string.express_floating_rate),
)
}
}
@Preview(showBackground = true)
@Composable
private fun ExchangeProvider_Preview() {
TangemTheme(isDark = false) {
ExchangeProvider(
providerName = TextReference.Str("Changelly"),
providerType = TextReference.Str("CEX"),
providerTxId = "hjsbajcqb",
imageUrl = "",
)
}
}

View file

@ -71,6 +71,7 @@ private fun ExchangeStatusBottomSheetContent(content: ExchangeStatusBottomSheetC
ExchangeProvider(
providerName = TextReference.Str(config.provider.name),
providerType = TextReference.Str(config.provider.type.name),
providerTxId = config.txExternalId,
imageUrl = config.provider.imageLarge,
)
SpacerH12()