Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-16 17:48:58 +03:00
parent f2bdbb33a1
commit 2059c817fa
8 changed files with 146 additions and 73 deletions

View file

@ -36,9 +36,9 @@ sealed interface TransactionState {
) : TransactionState {
sealed class Status {
object Failed : Status()
object Confirmed : Status()
object Unconfirmed : Status()
data object Failed : Status()
data object Confirmed : Status()
data object Unconfirmed : Status()
}
enum class Direction {

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M10,15.45L16.142,10.667L17.5,11.725L10,17.558L2.5,11.725L3.85,10.675L10,15.45ZM10,13.333L2.5,7.5L10,1.667L17.5,7.5L10,13.333ZM10,3.775L5.217,7.5L10,11.225L14.783,7.5L10,3.775Z"
android:fillColor="#000000"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M17.012,4.167L18.923,2.256L17.744,1.077L15.833,2.988L15.34,2.495C15.077,2.231 14.764,2.021 14.42,1.878C14.075,1.735 13.706,1.662 13.333,1.662C12.96,1.662 12.591,1.735 12.247,1.878C11.903,2.021 11.59,2.231 11.326,2.495L9.411,4.411C9.254,4.567 9.167,4.779 9.167,5C9.167,5.221 9.254,5.433 9.411,5.589L14.411,10.589C14.567,10.745 14.779,10.833 15,10.833C15.221,10.833 15.433,10.745 15.589,10.589L17.506,8.673C17.769,8.41 17.979,8.097 18.122,7.753C18.265,7.409 18.338,7.04 18.338,6.667C18.338,6.294 18.265,5.924 18.122,5.58C17.979,5.236 17.769,4.923 17.505,4.66L17.012,4.167ZM2.256,18.923L4.167,17.012L4.66,17.506C4.923,17.769 5.236,17.979 5.58,18.122C5.925,18.265 6.294,18.338 6.667,18.338C7.04,18.338 7.409,18.265 7.753,18.122C8.097,17.979 8.411,17.769 8.674,17.505L10.589,15.589C10.745,15.433 10.833,15.221 10.833,15C10.833,14.779 10.745,14.567 10.589,14.411L9.79,13.611L11.7,11.7L10.522,10.522L8.611,12.433L7.567,11.389L9.478,9.478L8.3,8.3L6.389,10.21L5.589,9.411C5.433,9.254 5.221,9.167 5,9.167C4.779,9.167 4.567,9.254 4.411,9.411L2.495,11.327C2.231,11.59 2.021,11.903 1.878,12.247C1.735,12.591 1.662,12.96 1.662,13.333C1.662,13.706 1.735,14.075 1.878,14.42C2.021,14.764 2.231,15.077 2.495,15.34L2.988,15.833L1.077,17.744L2.256,18.923ZM5,11.179L3.672,12.507C3.563,12.615 3.477,12.744 3.418,12.886C3.359,13.028 3.328,13.18 3.328,13.333C3.328,13.487 3.359,13.639 3.418,13.781C3.477,13.922 3.563,14.051 3.672,14.16L3.673,14.161L5.84,16.328C5.949,16.437 6.077,16.524 6.219,16.582C6.361,16.641 6.513,16.672 6.667,16.672C6.82,16.672 6.972,16.641 7.114,16.582C7.256,16.524 7.385,16.437 7.493,16.328L7.494,16.327L8.821,15L5,11.179ZM12.886,3.418C13.028,3.359 13.18,3.328 13.333,3.328C13.487,3.328 13.639,3.359 13.781,3.418C13.922,3.476 14.051,3.563 14.16,3.672L16.328,5.84C16.437,5.949 16.524,6.077 16.582,6.219C16.641,6.361 16.672,6.513 16.672,6.667C16.672,6.82 16.641,6.972 16.582,7.114C16.524,7.256 16.437,7.385 16.328,7.493L16.327,7.494L15,8.821L11.179,5L12.507,3.672C12.615,3.563 12.744,3.476 12.886,3.418Z"
android:fillColor="#000000"
android:fillType="evenOdd"/>
</vector>

View file

@ -54,17 +54,13 @@ internal class SdkTransactionHistoryItemConverter(
} else {
mapToInteractionAddressType(sourceType = sourceType)
}
is SdkTransactionHistoryItem.TransactionType.TronStakingTransactionType -> {
TxHistoryItem.InteractionAddressType.Staking
}
is SdkTransactionHistoryItem.TransactionType.ContractMethod,
is SdkTransactionHistoryItem.TransactionType.ContractMethodName,
-> mapToInteractionAddressType(destinationType)
TransactionHistoryItem.TransactionType.TronStakingTransactionType.FreezeBalanceV2Contract ->
mapToInteractionAddressType(destinationType) // todo map correct [REDACTED_JIRA]
TransactionHistoryItem.TransactionType.TronStakingTransactionType.UnfreezeBalanceV2Contract ->
mapToInteractionAddressType(destinationType) // todo map correct [REDACTED_JIRA]
TransactionHistoryItem.TransactionType.TronStakingTransactionType.VoteWitnessContract ->
mapToInteractionAddressType(destinationType) // todo map correct [REDACTED_JIRA]
TransactionHistoryItem.TransactionType.TronStakingTransactionType.WithdrawBalanceContract ->
mapToInteractionAddressType(destinationType) // todo map correct [REDACTED_JIRA]
}
}

View file

@ -1,29 +1,37 @@
package com.tangem.domain.walletmanager.utils
import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem
import com.tangem.blockchain.transactionhistory.models.TransactionHistoryItem.TransactionType
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.walletmanager.model.SmartContractMethod
import com.tangem.utils.converter.Converter
internal class SdkTransactionTypeConverter(
private val smartContractMethods: Map<String, SmartContractMethod>,
) : Converter<TransactionHistoryItem.TransactionType, TxHistoryItem.TransactionType> {
) : Converter<TransactionType, TxHistoryItem.TransactionType> {
override fun convert(value: TransactionHistoryItem.TransactionType): TxHistoryItem.TransactionType {
override fun convert(value: TransactionType): TxHistoryItem.TransactionType {
return when (value) {
is TransactionHistoryItem.TransactionType.ContractMethod ->
is TransactionType.ContractMethod -> {
getTransactionType(methodName = smartContractMethods[value.id]?.name)
is TransactionHistoryItem.TransactionType.ContractMethodName -> getTransactionType(methodName = value.name)
is TransactionHistoryItem.TransactionType.Transfer -> TxHistoryItem.TransactionType.Transfer
TransactionHistoryItem.TransactionType.TronStakingTransactionType.FreezeBalanceV2Contract ->
TxHistoryItem.TransactionType.Transfer // TODO map correct [REDACTED_JIRA]
TransactionHistoryItem.TransactionType.TronStakingTransactionType.UnfreezeBalanceV2Contract ->
TxHistoryItem.TransactionType.Transfer // TODO map correct [REDACTED_JIRA]
TransactionHistoryItem.TransactionType.TronStakingTransactionType.VoteWitnessContract ->
TxHistoryItem
.TransactionType.Transfer // TODO map correct [REDACTED_JIRA]
TransactionHistoryItem.TransactionType.TronStakingTransactionType.WithdrawBalanceContract ->
TxHistoryItem.TransactionType.Transfer // TODO map correct [REDACTED_JIRA]
}
is TransactionType.ContractMethodName -> {
getTransactionType(methodName = value.name)
}
is TransactionType.Transfer -> {
TxHistoryItem.TransactionType.Transfer
}
is TransactionType.TronStakingTransactionType.FreezeBalanceV2Contract -> {
TxHistoryItem.TransactionType.TronStakingTransactionType.Stake
}
is TransactionType.TronStakingTransactionType.UnfreezeBalanceV2Contract -> {
TxHistoryItem.TransactionType.TronStakingTransactionType.Unstake
}
is TransactionType.TronStakingTransactionType.VoteWitnessContract -> {
TxHistoryItem.TransactionType.TronStakingTransactionType.Vote
}
is TransactionType.TronStakingTransactionType.WithdrawBalanceContract -> {
TxHistoryItem.TransactionType.TronStakingTransactionType.Withdraw
}
}
}

View file

@ -33,20 +33,28 @@ data class TxHistoryItem(
}
sealed interface TransactionType {
object Transfer : TransactionType
object Approve : TransactionType
object Swap : TransactionType
object UnknownOperation : TransactionType
data object Transfer : TransactionType
data object Approve : TransactionType
data object Swap : TransactionType
data object UnknownOperation : TransactionType
data class Operation(val name: String) : TransactionType
sealed interface TronStakingTransactionType : TransactionType {
data object Vote : TronStakingTransactionType
data object Withdraw : TronStakingTransactionType
data object Stake : TronStakingTransactionType
data object Unstake : TronStakingTransactionType
}
}
sealed class TransactionStatus {
object Failed : TransactionStatus()
object Unconfirmed : TransactionStatus()
object Confirmed : TransactionStatus()
data object Failed : TransactionStatus()
data object Unconfirmed : TransactionStatus()
data object Confirmed : TransactionStatus()
}
sealed class InteractionAddressType {
data object Staking : InteractionAddressType()
data class User(val address: String) : InteractionAddressType()
data class Contract(val address: String) : InteractionAddressType()
data class Multiple(val addresses: List<String>) : InteractionAddressType()

View file

@ -1,5 +1,6 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory
import com.tangem.common.extensions.isZero
import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.components.transactions.state.TransactionState.Content.Direction
import com.tangem.core.ui.extensions.TextReference
@ -8,6 +9,7 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.utils.toTimeFormat
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryItem.*
import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents
import com.tangem.features.tokendetails.impl.R
import com.tangem.utils.StringsSigns.MINUS
@ -42,34 +44,44 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
)
}
private fun TxHistoryItem.extractIcon(): Int = if (status == TxHistoryItem.TransactionStatus.Failed) {
private fun TxHistoryItem.extractIcon(): Int = if (status == TransactionStatus.Failed) {
R.drawable.ic_close_24
} else {
when (type) {
is TxHistoryItem.TransactionType.Approve -> R.drawable.ic_doc_24
is TxHistoryItem.TransactionType.Operation,
is TxHistoryItem.TransactionType.Swap,
is TxHistoryItem.TransactionType.Transfer,
is TxHistoryItem.TransactionType.UnknownOperation,
is TransactionType.Approve -> R.drawable.ic_doc_24
is TransactionType.TronStakingTransactionType.Stake,
is TransactionType.TronStakingTransactionType.Vote,
-> R.drawable.ic_transaction_history_staking
is TransactionType.TronStakingTransactionType.Withdraw,
is TransactionType.TronStakingTransactionType.Unstake,
-> R.drawable.ic_transaction_history_unstaking
is TransactionType.Operation,
is TransactionType.Swap,
is TransactionType.Transfer,
is TransactionType.UnknownOperation,
-> if (isOutgoing) R.drawable.ic_arrow_up_24 else R.drawable.ic_arrow_down_24
}
}
private fun TxHistoryItem.extractTitle(): TextReference = when (val type = type) {
is TxHistoryItem.TransactionType.Approve -> resourceReference(R.string.common_approval)
is TxHistoryItem.TransactionType.Operation -> stringReference(type.name)
is TxHistoryItem.TransactionType.Swap -> resourceReference(R.string.common_swap)
is TxHistoryItem.TransactionType.Transfer -> resourceReference(R.string.common_transfer)
is TxHistoryItem.TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
is TransactionType.Approve -> resourceReference(R.string.common_approval)
is TransactionType.Operation -> stringReference(type.name)
is TransactionType.Swap -> resourceReference(R.string.common_swap)
is TransactionType.Transfer -> resourceReference(R.string.common_transfer)
is TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
is TransactionType.TronStakingTransactionType.Stake -> resourceReference(R.string.common_stake)
is TransactionType.TronStakingTransactionType.Unstake -> resourceReference(R.string.common_unstake)
is TransactionType.TronStakingTransactionType.Vote -> resourceReference(R.string.staking_vote)
is TransactionType.TronStakingTransactionType.Withdraw -> resourceReference(R.string.staking_withdraw)
}
private fun TxHistoryItem.extractSubtitle(): TextReference =
when (val interactionAddress = interactionAddressType) {
is TxHistoryItem.InteractionAddressType.Contract -> resourceReference(
is InteractionAddressType.Contract -> resourceReference(
id = R.string.transaction_history_contract_address,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is TxHistoryItem.InteractionAddressType.Multiple -> resourceReference(
is InteractionAddressType.Multiple -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
@ -77,7 +89,7 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
},
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
)
is TxHistoryItem.InteractionAddressType.User -> resourceReference(
is InteractionAddressType.User -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
@ -85,19 +97,28 @@ internal class TokenDetailsTxHistoryTransactionStateConverter(
},
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Staking -> resourceReference(
id = R.string.common_staking,
)
}
private fun TxHistoryItem.extractDirection() = if (isOutgoing) Direction.OUTGOING else Direction.INCOMING
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
TxHistoryItem.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
TxHistoryItem.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
private fun TransactionStatus.tiUiStatus() = when (this) {
TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
TransactionStatus.Failed -> TransactionState.Content.Status.Failed
TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
}
private fun TxHistoryItem.getAmount(): String {
val prefix = when (status) {
TxHistoryItem.TransactionStatus.Failed -> ""
if (type == TransactionType.TronStakingTransactionType.Vote ||
type == TransactionType.TronStakingTransactionType.Withdraw
) {
return ""
}
val prefix = when {
status == TransactionStatus.Failed -> ""
this.amount.isZero() -> ""
else -> if (isOutgoing) MINUS else PLUS
}
return prefix + amount.toFormattedCurrencyString(currency = symbol, decimals = decimals)

View file

@ -1,5 +1,6 @@
package com.tangem.feature.wallet.presentation.wallet.state.transformers.converter
import com.tangem.common.extensions.isZero
import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
@ -7,6 +8,7 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.utils.toTimeFormat
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryItem.*
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
import com.tangem.utils.StringsSigns.MINUS
@ -41,34 +43,44 @@ internal class TxHistoryItemStateConverter(
)
}
private fun TxHistoryItem.extractIcon(): Int = if (status == TxHistoryItem.TransactionStatus.Failed) {
private fun TxHistoryItem.extractIcon(): Int = if (status == TransactionStatus.Failed) {
R.drawable.ic_close_24
} else {
when (type) {
is TxHistoryItem.TransactionType.Approve -> R.drawable.ic_doc_24
is TxHistoryItem.TransactionType.Operation,
is TxHistoryItem.TransactionType.Swap,
is TxHistoryItem.TransactionType.Transfer,
is TxHistoryItem.TransactionType.UnknownOperation,
is TransactionType.Approve -> R.drawable.ic_doc_24
is TransactionType.TronStakingTransactionType.Stake,
is TransactionType.TronStakingTransactionType.Vote,
-> R.drawable.ic_transaction_history_staking
is TransactionType.TronStakingTransactionType.Withdraw,
is TransactionType.TronStakingTransactionType.Unstake,
-> R.drawable.ic_transaction_history_unstaking
is TransactionType.Operation,
is TransactionType.Swap,
is TransactionType.Transfer,
is TransactionType.UnknownOperation,
-> if (isOutgoing) R.drawable.ic_arrow_up_24 else R.drawable.ic_arrow_down_24
}
}
private fun TxHistoryItem.extractTitle(): TextReference = when (val type = type) {
is TxHistoryItem.TransactionType.Approve -> resourceReference(R.string.common_approval)
is TxHistoryItem.TransactionType.Operation -> stringReference(type.name)
is TxHistoryItem.TransactionType.Swap -> resourceReference(R.string.common_swap)
is TxHistoryItem.TransactionType.Transfer -> resourceReference(R.string.common_transfer)
is TxHistoryItem.TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
is TransactionType.Approve -> resourceReference(R.string.common_approval)
is TransactionType.Operation -> stringReference(type.name)
is TransactionType.Swap -> resourceReference(R.string.common_swap)
is TransactionType.Transfer -> resourceReference(R.string.common_transfer)
is TransactionType.TronStakingTransactionType.Stake -> resourceReference(R.string.common_stake)
is TransactionType.TronStakingTransactionType.Unstake -> resourceReference(R.string.common_unstake)
is TransactionType.TronStakingTransactionType.Vote -> resourceReference(R.string.staking_vote)
is TransactionType.TronStakingTransactionType.Withdraw -> resourceReference(R.string.staking_withdraw)
is TransactionType.UnknownOperation -> resourceReference(R.string.transaction_history_operation)
}
private fun TxHistoryItem.extractSubtitle(): TextReference =
when (val interactionAddress = interactionAddressType) {
is TxHistoryItem.InteractionAddressType.Contract -> resourceReference(
is InteractionAddressType.Contract -> resourceReference(
id = R.string.transaction_history_contract_address,
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is TxHistoryItem.InteractionAddressType.Multiple -> resourceReference(
is InteractionAddressType.Multiple -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
@ -76,7 +88,7 @@ internal class TxHistoryItemStateConverter(
},
formatArgs = wrappedList(resourceReference(R.string.transaction_history_multiple_addresses)),
)
is TxHistoryItem.InteractionAddressType.User -> resourceReference(
is InteractionAddressType.User -> resourceReference(
id = if (isOutgoing) {
R.string.transaction_history_transaction_to_address
} else {
@ -84,20 +96,29 @@ internal class TxHistoryItemStateConverter(
},
formatArgs = wrappedList(interactionAddress.address.toBriefAddressFormat()),
)
is InteractionAddressType.Staking -> resourceReference(
id = R.string.common_staking,
)
}
private fun TxHistoryItem.extractDirection() =
if (isOutgoing) TransactionState.Content.Direction.OUTGOING else TransactionState.Content.Direction.INCOMING
private fun TxHistoryItem.TransactionStatus.tiUiStatus() = when (this) {
TxHistoryItem.TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
TxHistoryItem.TransactionStatus.Failed -> TransactionState.Content.Status.Failed
TxHistoryItem.TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
private fun TransactionStatus.tiUiStatus() = when (this) {
TransactionStatus.Confirmed -> TransactionState.Content.Status.Confirmed
TransactionStatus.Failed -> TransactionState.Content.Status.Failed
TransactionStatus.Unconfirmed -> TransactionState.Content.Status.Unconfirmed
}
private fun TxHistoryItem.getAmount(): String {
val prefix = when (status) {
TxHistoryItem.TransactionStatus.Failed -> ""
if (type == TransactionType.TronStakingTransactionType.Vote ||
type == TransactionType.TronStakingTransactionType.Withdraw
) {
return ""
}
val prefix = when {
status == TransactionStatus.Failed -> ""
this.amount.isZero() -> ""
else -> if (isOutgoing) MINUS else PLUS
}
return prefix + amount.toFormattedCurrencyString(currency = symbol, decimals = decimals)