feat(@desktop/wallet): Handle multitransactions (#11124)

closes #11071
This commit is contained in:
Cuteivist 2023-06-30 17:07:53 +02:00 committed by GitHub
parent bade10c5e0
commit 7a7394628e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 198 additions and 233 deletions

View File

@ -21,7 +21,6 @@ import app_service/service/currency/service as currency_service
import app_service/service/transaction/service as transaction_service import app_service/service/transaction/service as transaction_service
import app_service/service/token/service as token_service import app_service/service/token/service as token_service
proc toRef*[T](obj: T): ref T = proc toRef*[T](obj: T): ref T =
new(result) new(result)
result[] = obj result[] = obj

View File

@ -93,38 +93,27 @@ QtObject:
return self.transaction return self.transaction
proc getSender*(self: ActivityEntry): string {.slot.} = proc getSender*(self: ActivityEntry): string {.slot.} =
# TODO: lookup sender's name
if self.isMultiTransaction(): if self.isMultiTransaction():
return self.multi_transaction.fromAddress return self.multi_transaction.fromAddress
if self.transaction == nil:
error "getSender: ActivityEntry is not an transaction.Item"
return ""
return self.transaction[].getfrom() return self.transaction[].getfrom()
QtProperty[string] sender: QtProperty[string] sender:
read = getSender read = getSender
proc getRecipient*(self: ActivityEntry): string {.slot.} = proc getRecipient*(self: ActivityEntry): string {.slot.} =
# TODO: lookup recipient name
if self.isMultiTransaction(): if self.isMultiTransaction():
return self.multi_transaction.toAddress return self.multi_transaction.toAddress
if self.transaction == nil:
error "getRecipient: ActivityEntry is not an transaction.Item"
return ""
return self.transaction[].getTo() return self.transaction[].getTo()
QtProperty[string] recipient: QtProperty[string] recipient:
read = getRecipient read = getRecipient
proc getInAmount*(self: ActivityEntry): float {.slot.} =
return float(self.extradata.inAmount)
QtProperty[float] inAmount:
read = getInAmount
proc getOutAmount*(self: ActivityEntry): float {.slot.} =
return float(self.extradata.outAmount)
QtProperty[float] outAmount:
read = getOutAmount
proc getInSymbol*(self: ActivityEntry): string {.slot.} = proc getInSymbol*(self: ActivityEntry): string {.slot.} =
return self.extradata.inSymbol return self.extradata.inSymbol
@ -137,9 +126,20 @@ QtObject:
QtProperty[string] outSymbol: QtProperty[string] outSymbol:
read = getOutSymbol read = getOutSymbol
proc getSymbol*(self: ActivityEntry): string {.slot.} =
if self.metadata.activityType == backend.ActivityType.Receive:
return self.getInSymbol()
return self.getOutSymbol()
QtProperty[string] symbol:
read = getSymbol
proc getTimestamp*(self: ActivityEntry): int {.slot.} = proc getTimestamp*(self: ActivityEntry): int {.slot.} =
if self.isMultiTransaction(): if self.isMultiTransaction():
return self.multi_transaction.timestamp return self.multi_transaction.timestamp
if self.transaction == nil:
error "getTimestamp: ActivityEntry is not an transaction.Item"
return 0
# TODO: should we account for self.transaction[].isTimeStamp? # TODO: should we account for self.transaction[].isTimeStamp?
return self.transaction[].getTimestamp() return self.transaction[].getTimestamp()
@ -191,7 +191,7 @@ QtObject:
proc getTotalFees*(self: ActivityEntry): QVariant {.slot.} = proc getTotalFees*(self: ActivityEntry): QVariant {.slot.} =
if self.transaction == nil: if self.transaction == nil:
error "getTotalFees: ActivityEntry is not an transaction.Item" error "getTotalFees: ActivityEntry is not an transaction.Item"
return newQVariant(0) return newQVariant(newCurrencyAmount())
return newQVariant(self.transaction[].getTotalFees()) return newQVariant(self.transaction[].getTotalFees())
QtProperty[QVariant] totalFees: QtProperty[QVariant] totalFees:
@ -257,47 +257,31 @@ QtObject:
QtProperty[string] nonce: QtProperty[string] nonce:
read = getNonce read = getNonce
# TODO: Replaced usage of these for in/out versions in the QML modules proc getBlockNumber*(self: ActivityEntry): string {.slot.} =
proc getSymbol*(self: ActivityEntry): string {.slot.} =
if self.transaction == nil: if self.transaction == nil:
error "getSymbol: ActivityEntry is not an transaction.Item" error "getBlockNumber: ActivityEntry is not an transaction.Item"
return "" return ""
return $self.transaction[].getBlockNumber()
if self.metadata.activityType == backend.ActivityType.Receive: QtProperty[string] blockNumber:
return self.getInSymbol() read = getBlockNumber
return self.getOutSymbol() proc getOutAmount*(self: ActivityEntry): float {.slot.} =
return float(self.extradata.outAmount)
QtProperty[string] symbol: QtProperty[float] outAmount:
read = getSymbol read = getOutAmount
proc getFromAmount*(self: ActivityEntry): float {.slot.} = proc getInAmount*(self: ActivityEntry): float {.slot.} =
if self.isMultiTransaction(): return float(self.extradata.inAmount)
return self.getOutAmount()
error "getFromAmount: ActivityEntry is not a MultiTransaction"
return 0.0
QtProperty[float] fromAmount: QtProperty[float] inAmount:
read = getFromAmount read = getInAmount
proc getToAmount*(self: ActivityEntry): float {.slot.} =
if self.isMultiTransaction():
return self.getInAmount()
error "getToAmount: ActivityEntry is not a MultiTransaction"
return 0.0
QtProperty[float] toAmount:
read = getToAmount
proc getValue*(self: ActivityEntry): float {.slot.} =
if self.isMultiTransaction():
error "getToAmount: ActivityEntry is a MultiTransaction"
return 0.0
proc getAmount*(self: ActivityEntry): float {.slot.} =
if self.metadata.activityType == backend.ActivityType.Receive: if self.metadata.activityType == backend.ActivityType.Receive:
return self.getInAmount() return self.getInAmount()
return self.getOutAmount() return self.getOutAmount()
QtProperty[float] value: QtProperty[float] amount:
read = getValue read = getAmount

View File

@ -39,33 +39,25 @@ Item {
QtObject { QtObject {
id: d id: d
readonly property bool isIncoming: root.isTransactionValid ? root.transaction.recipient.toLowerCase() === root.overview.mixedcaseAddress.toLowerCase() : false readonly property bool isIncoming: transactionType === Constants.TransactionType.Received
readonly property bool isNFT: root.isTransactionValid ? root.transaction.isNFT : false
readonly property string savedAddressNameTo: root.isTransactionValid ? d.getNameForSavedWalletAddress(transaction.recipient) : ""
readonly property string savedAddressNameFrom: root.isTransactionValid ? d.getNameForSavedWalletAddress(transaction.sender): ""
readonly property string from: root.isTransactionValid ? !!savedAddressNameFrom ? savedAddressNameFrom : Utils.compactAddress(transaction.sender, 4): ""
readonly property string to: root.isTransactionValid ? !!savedAddressNameTo ? savedAddressNameTo : Utils.compactAddress(transaction.recipient, 4): ""
readonly property string savedAddressEns: root.isTransactionValid ? RootStore.getEnsForSavedWalletAddress(isIncoming ? transaction.sender : transaction.recipient) : ""
readonly property string savedAddressChains: root.isTransactionValid ? RootStore.getChainShortNamesForSavedWalletAddress(isIncoming ? transaction.sender : transaction.recipient) : ""
readonly property string networkShortName: root.isTransactionValid ? RootStore.getNetworkShortName(transaction.chainId) : "" readonly property string networkShortName: root.isTransactionValid ? RootStore.getNetworkShortName(transaction.chainId) : ""
readonly property string networkFullName: root.isTransactionValid ? RootStore.getNetworkFullName(transaction.chainId): "" readonly property string networkIcon: isTransactionValid ? RootStore.getNetworkIcon(transaction.chainId) : ""
readonly property string networkIcon: root.isTransactionValid ? RootStore.getNetworkIcon(transaction.chainId): ""
readonly property int blockNumber: root.isTransactionValid ? RootStore.hex2Dec(root.transaction.blockNumber) : 0 readonly property int blockNumber: root.isTransactionValid ? RootStore.hex2Dec(root.transaction.blockNumber) : 0
readonly property string bridgeNetworkIcon: "" // TODO fill when bridge data is implemented readonly property int toBlockNumber: 0 // TODO fill when bridge data is implemented
readonly property string bridgeNetworkFullname: "" // TODO fill when bridge data is implemented readonly property string toNetworkIcon: "" // TODO fill when bridge data is implemented
readonly property string bridgeNetworkShortName: "" // TODO fill when bridge data is implemented readonly property string toNetworkShortName: "" // TODO fill when bridge data is implemented
readonly property int bridgeBlockNumber: 0 // TODO fill when bridge data is implemented readonly property string symbol: isTransactionValid ? transaction.symbol : ""
readonly property double swapCryptoValue: 0 // TODO fill when swap data is implemented readonly property string inSymbol: isTransactionValid ? transaction.inSymbol : ""
readonly property string swapSymbol: "" // TODO fill when swap data is implemented readonly property string outSymbol: isTransactionValid ? transaction.outSymbol : ""
readonly property string symbol: root.isTransactionValid ? transaction.symbol : ""
readonly property var multichainNetworks: [] // TODO fill icon for networks for multichain readonly property var multichainNetworks: [] // TODO fill icon for networks for multichain
readonly property double cryptoValue: root.isTransactionValid ? transaction.value : 0.0 readonly property string fiatValueFormatted: root.isTransactionValid && !transactionHeader.isMultiTransaction ? RootStore.formatCurrencyAmount(transactionHeader.fiatValue, RootStore.currentCurrency) : ""
readonly property double fiatValue: root.isTransactionValid ? RootStore.getFiatValue(cryptoValue, symbol, RootStore.currentCurrency): 0.0 readonly property string cryptoValueFormatted: root.isTransactionValid && !transactionHeader.isMultiTransaction ? RootStore.formatCurrencyAmount(transaction.amount, transaction.symbol) : ""
readonly property string fiatValueFormatted: root.isTransactionValid ? RootStore.formatCurrencyAmount(d.fiatValue, RootStore.currentCurrency) : "" readonly property string outFiatValueFormatted: root.isTransactionValid && transactionHeader.isMultiTransaction ? RootStore.formatCurrencyAmount(transactionHeader.outFiatValue, RootStore.currentCurrency) : ""
readonly property string cryptoValueFormatted: root.isTransactionValid ? RootStore.formatCurrencyAmount(d.cryptoValue, symbol) : "" readonly property string outCryptoValueFormatted: root.isTransactionValid && transactionHeader.isMultiTransaction ? RootStore.formatCurrencyAmount(transaction.outAmount, transaction.outSymbol) : ""
readonly property real feeEthValue: root.isTransactionValid && transaction.totalFees ? RootStore.getGasEthValue(transaction.totalFees.amount, 1) : 0 readonly property real feeEthValue: root.isTransactionValid ? RootStore.getGasEthValue(transaction.totalFees.amount, 1) : 0 // TODO use directly?
readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, "ETH", RootStore.currentCurrency) : 0 readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, "ETH", RootStore.currentCurrency) : 0 // TODO use directly?
readonly property int transactionType: root.isTransactionValid ? transaction.txType : Constants.TransactionType.Send readonly property int transactionType: root.isTransactionValid ? transaction.txType : Constants.TransactionType.Send
readonly property string toNetworkName: "" // TODO fill network name for bridge
property string decodedInputData: "" property string decodedInputData: ""
@ -116,26 +108,15 @@ Item {
objectName: "transactionDetailHeader" objectName: "transactionDetailHeader"
width: parent.width width: parent.width
leftPadding: 0 leftPadding: 0
modelData: transaction
currentCurrency: RootStore.currentCurrency
cryptoValue: d.cryptoValue
fiatValue: d.fiatValue
networkIcon: d.networkIcon
networkColor: root.isTransactionValid ? RootStore.getNetworkColor(transaction.chainId): ""
networkName: d.networkFullName
swapSymbol: d.swapSymbol
bridgeNetworkName: d.bridgeNetworkFullname
symbol: d.symbol
transactionStatus: root.isTransactionValid ? transaction.status : Constants.TransactionStatus.Pending
timeStampText: root.isTransactionValid ? qsTr("Signed at %1").arg(LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat)): ""
addressNameTo: root.isTransactionValid ? WalletStores.RootStore.getNameForAddress(transaction.recipient): ""
addressNameFrom: root.isTransactionValid ? WalletStores.RootStore.getNameForAddress(transaction.sender): ""
sensor.enabled: false sensor.enabled: false
rootStore: RootStore
walletRootStore: WalletStores.RootStore
color: Theme.palette.transparent color: Theme.palette.transparent
state: "header" state: "header"
modelData: transaction
timeStampText: root.isTransactionValid ? qsTr("Signed at %1").arg(LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat)): ""
rootStore: RootStore
walletRootStore: WalletStores.RootStore
onRetryClicked: d.retryTransaction() onRetryClicked: d.retryTransaction()
} }
@ -148,7 +129,7 @@ Item {
error: transactionHeader.transactionStatus === Constants.TransactionStatus.Failed error: transactionHeader.transactionStatus === Constants.TransactionStatus.Failed
isLayer1: root.isTransactionValid && RootStore.getNetworkLayer(root.transaction.chainId) == 1 isLayer1: root.isTransactionValid && RootStore.getNetworkLayer(root.transaction.chainId) == 1
confirmations: root.isTransactionValid ? Math.abs(WalletStores.RootStore.getLatestBlockNumber(root.transaction.chainId) - d.blockNumber): 0 confirmations: root.isTransactionValid ? Math.abs(WalletStores.RootStore.getLatestBlockNumber(root.transaction.chainId) - d.blockNumber): 0
chainName: d.networkFullName chainName: transactionHeader.networkName
timeStamp: root.isTransactionValid ? transaction.timestamp: "" timeStamp: root.isTransactionValid ? transaction.timestamp: ""
} }
@ -157,7 +138,7 @@ Item {
} }
WalletNftPreview { WalletNftPreview {
visible: root.isTransactionValid && d.isNFT && !!transaction.nftImageUrl visible: root.isTransactionValid && transactionHeader.isNFT && !!transaction.nftImageUrl
width: Math.min(304, progressBlock.width) width: Math.min(304, progressBlock.width)
nftName: root.isTransactionValid ? transaction.nftName : "" nftName: root.isTransactionValid ? transaction.nftName : ""
nftUrl: root.isTransactionValid && !!transaction.nftImageUrl ? transaction.nftImageUrl : "" nftUrl: root.isTransactionValid && !!transaction.nftImageUrl ? transaction.nftImageUrl : ""
@ -187,8 +168,7 @@ Item {
RowLayout { RowLayout {
spacing: 0 spacing: 0
width: parent.width width: parent.width
height: opacity > 0 ? Math.max(implicitHeight, 85) : 0 height: fromNetworkTile.visible || toNetworkTile.visible ? 85 : 0
opacity: fromNetworkTile.visible || toNetworkTile.visible ? 1 : 0
TransactionDataTile { TransactionDataTile {
id: fromNetworkTile id: fromNetworkTile
Layout.fillWidth: true Layout.fillWidth: true
@ -197,9 +177,9 @@ Item {
subTitle: { subTitle: {
switch(d.transactionType) { switch(d.transactionType) {
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
return d.symbol return d.outSymbol
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
return d.networkFullName return transactionHeader.networkName
default: default:
return "" return ""
} }
@ -207,7 +187,7 @@ Item {
asset.name: { asset.name: {
switch(d.transactionType) { switch(d.transactionType) {
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
return !!d.symbol ? Constants.tokenIcon(d.symbol) : "" return !!d.outSymbol ? Constants.tokenIcon(d.outSymbol) : ""
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
return !!d.networkIcon ? Style.svg(d.networkIcon) : "" return !!d.networkIcon ? Style.svg(d.networkIcon) : ""
default: default:
@ -224,9 +204,9 @@ Item {
subTitle: { subTitle: {
switch(d.transactionType) { switch(d.transactionType) {
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
return d.swapSymbol return d.inSymbol
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
return d.bridgeNetworkFullname return d.toNetworkName
default: default:
return "" return ""
} }
@ -234,9 +214,9 @@ Item {
asset.name: { asset.name: {
switch(d.transactionType) { switch(d.transactionType) {
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
return !!d.swapSymbol ? Constants.tokenIcon(d.swapSymbol) : "" return !!d.inSymbol ? Constants.tokenIcon(d.inSymbol) : ""
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
return !!d.bridgeNetworkIcon ? Style.svg(d.bridgeNetworkIcon) : "" return !!d.toNetworkIcon ? Style.svg(d.toNetworkIcon) : ""
default: default:
return "" return ""
} }
@ -262,7 +242,7 @@ Item {
TransactionAddressTile { TransactionAddressTile {
width: parent.width width: parent.width
title: qsTr("To") title: qsTr("To")
addresses: root.isTransactionValid ? [root.transaction.recipient] : [] addresses: root.isTransactionValid && visible ? [root.transaction.recipient] : []
contactsStore: root.contactsStore contactsStore: root.contactsStore
rootStore: WalletStores.RootStore rootStore: WalletStores.RootStore
onButtonClicked: addressMenu.openReceiverMenu(this, addresses[0], d.networkShortName) onButtonClicked: addressMenu.openReceiverMenu(this, addresses[0], d.networkShortName)
@ -281,7 +261,7 @@ Item {
} }
TransactionDataTile { TransactionDataTile {
width: parent.width width: parent.width
title: qsTr("%1 Tx hash").arg(d.networkFullName) title: qsTr("%1 Tx hash").arg(transactionHeader.networkName)
subTitle: root.isTransactionValid ? root.transaction.txHash : "" subTitle: root.isTransactionValid ? root.transaction.txHash : ""
visible: !!subTitle visible: !!subTitle
buttonIconName: "more" buttonIconName: "more"
@ -289,17 +269,17 @@ Item {
} }
TransactionDataTile { TransactionDataTile {
width: parent.width width: parent.width
title: qsTr("%1 Tx hash").arg(d.bridgeNetworkFullname) title: qsTr("%1 Tx hash").arg(d.toNetworkName)
subTitle: "" // TODO fill tx hash for Bridge subTitle: "" // TODO fill tx hash for Bridge
visible: !!subTitle visible: !!subTitle
buttonIconName: "more" buttonIconName: "more"
onButtonClicked: addressMenu.openTxMenu(this, subTitle, d.bridgeNetworkShortName) onButtonClicked: addressMenu.openTxMenu(this, subTitle, d.toNetworkShortName)
} }
TransactionContractTile { TransactionContractTile {
// Used for Bridge and Swap to display 'From' network Protocol contract address // Used for Bridge and Swap to display 'From' network Protocol contract address
address: "" // TODO fill protocol contract address for 'from' network for Bridge and Swap address: "" // TODO fill protocol contract address for 'from' network for Bridge and Swap
symbol: "" // TODO fill protocol name for Bridge and Swap symbol: "" // TODO fill protocol name for Bridge and Swap
networkName: d.networkFullName networkName: transactionHeader.networkName
shortNetworkName: d.networkShortName shortNetworkName: d.networkShortName
visible: !!subTitle && (d.transactionType === Constants.TransactionType.Bridge || d.transactionType === Constants.TransactionType.Swap) visible: !!subTitle && (d.transactionType === Constants.TransactionType.Bridge || d.transactionType === Constants.TransactionType.Swap)
} }
@ -307,15 +287,15 @@ Item {
// Used to display contract address for any network // Used to display contract address for any network
address: root.isTransactionValid ? transaction.contract : "" address: root.isTransactionValid ? transaction.contract : ""
symbol: root.isTransactionValid ? d.symbol : "" symbol: root.isTransactionValid ? d.symbol : ""
networkName: d.networkFullName networkName: transactionHeader.networkName
shortNetworkName: d.networkShortName shortNetworkName: d.networkShortName
} }
TransactionContractTile { TransactionContractTile {
// Used for Bridge to display 'To' network Protocol contract address // Used for Bridge to display 'To' network Protocol contract address
address: "" // TODO fill protocol contract address for 'to' network for Bridge address: "" // TODO fill protocol contract address for 'to' network for Bridge
symbol: "" // TODO fill protocol name for Bridge symbol: "" // TODO fill protocol name for Bridge
networkName: d.bridgeNetworkFullname networkName: d.toNetworkName
shortNetworkName: d.bridgeNetworkShortName shortNetworkName: d.toNetworkShortName
visible: !!subTitle && d.transactionType === Constants.TransactionType.Bridge visible: !!subTitle && d.transactionType === Constants.TransactionType.Bridge
} }
TransactionContractTile { TransactionContractTile {
@ -337,15 +317,15 @@ Item {
return "" return ""
switch(d.transactionType) { switch(d.transactionType) {
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
return d.swapSymbol return d.inSymbol
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
return d.symbol return d.outSymbol
default: default:
return "" return ""
} }
} }
networkName: d.bridgeNetworkFullname networkName: d.toNetworkName
shortNetworkName: d.bridgeNetworkShortName shortNetworkName: d.toNetworkShortName
visible: root.isTransactionValid && !!subTitle visible: root.isTransactionValid && !!subTitle
} }
} }
@ -393,7 +373,7 @@ Item {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("Network") title: qsTr("Network")
subTitle: d.networkFullName subTitle: transactionHeader.networkName
asset.name: !!d.networkIcon ? Style.svg("%1".arg(d.networkIcon)) : "" asset.name: !!d.networkIcon ? Style.svg("%1".arg(d.networkIcon)) : ""
smallIcon: true smallIcon: true
visible: d.transactionType !== Constants.TransactionType.Bridge visible: d.transactionType !== Constants.TransactionType.Bridge
@ -446,17 +426,17 @@ Item {
} }
TransactionDataTile { TransactionDataTile {
width: parent.width width: parent.width
title: !!d.networkFullName ? qsTr("Included in Block on %1").arg(d.networkFullName) : qsTr("Included on Block") title: !!transactionHeader.networkName ? qsTr("Included in Block on %1").arg(transactionHeader.networkName) : qsTr("Included on Block")
subTitle: d.blockNumber subTitle: d.blockNumber
tertiaryTitle: root.isTransactionValid ? LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat) : "" tertiaryTitle: root.isTransactionValid ? LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat) : ""
visible: d.blockNumber > 0 visible: d.blockNumber > 0
} }
TransactionDataTile { TransactionDataTile {
width: parent.width width: parent.width
title: !!d.bridgeNetworkFullname ? qsTr("Included in Block on %1").arg(d.bridgeNetworkFullname) : qsTr("Included on Block") title: !!d.toNetworkName ? qsTr("Included in Block on %1").arg(d.toNetworkName) : qsTr("Included on Block")
subTitle: d.bridgeBlockNumber subTitle: d.toBlockNumber
tertiaryTitle: root.isTransactionValid ? LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat) : "" tertiaryTitle: root.isTransactionValid ? LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat) : ""
visible: d.bridgeBlockNumber > 0 visible: d.toBlockNumber > 0
} }
} }
} }
@ -464,7 +444,7 @@ Item {
Column { Column {
width: progressBlock.width width: progressBlock.width
spacing: Style.current.smallPadding spacing: Style.current.smallPadding
visible: !(d.isNFT && d.isIncoming) visible: !(transactionHeader.isNFT && d.isIncoming)
RowLayout { RowLayout {
width: parent.width width: parent.width
@ -489,10 +469,10 @@ Item {
TransactionDataTile { TransactionDataTile {
width: parent.width width: parent.width
title: qsTr("Amount sent") title: qsTr("Amount sent")
subTitle: d.cryptoValueFormatted subTitle: transactionHeader.isMultiTransaction ? d.outCryptoValueFormatted : d.cryptoValueFormatted
tertiaryTitle: d.fiatValueFormatted tertiaryTitle: transactionHeader.isMultiTransaction ? d.outFiatValueFormatted : d.fiatValueFormatted
visible: { visible: {
if (d.isNFT) if (transactionHeader.isNFT)
return false return false
switch(d.transactionType) { switch(d.transactionType) {
case Constants.TransactionType.Send: case Constants.TransactionType.Send:
@ -508,24 +488,24 @@ Item {
width: parent.width width: parent.width
title: transactionHeader.transactionStatus === Constants.TransactionType.Pending ? qsTr("Amount to receive") : qsTr("Amount received") title: transactionHeader.transactionStatus === Constants.TransactionType.Pending ? qsTr("Amount to receive") : qsTr("Amount received")
subTitle: { subTitle: {
if (d.isNFT) if (!root.isTransactionValid || transactionHeader.isNFT)
return "" return ""
const type = d.transactionType const type = d.transactionType
if (type === Constants.TransactionType.Swap) { if (type === Constants.TransactionType.Swap) {
return RootStore.formatCurrencyAmount(d.swapCryptoValue, d.swapSymbol) return RootStore.formatCurrencyAmount(transactionHeader.inCryptoValue, d.inSymbol)
} else if (type === Constants.TransactionType.Bridge) { } else if (type === Constants.TransactionType.Bridge) {
// Reduce crypto value by fee value // Reduce crypto value by fee value
const valueInCrypto = RootStore.getCryptoValue(d.fiatValue - d.feeFiatValue, d.symbol, RootStore.currentCurrency) const valueInCrypto = RootStore.getCryptoValue(transactionHeader.fiatValue - d.feeFiatValue, d.inSymbol, RootStore.currentCurrency)
return RootStore.formatCurrencyAmount(valueInCrypto, d.symbol) return RootStore.formatCurrencyAmount(valueInCrypto, d.inSymbol)
} }
return "" return ""
} }
tertiaryTitle: { tertiaryTitle: {
const type = d.transactionType const type = d.transactionType
if (type === Constants.TransactionType.Swap) { if (type === Constants.TransactionType.Swap) {
return RootStore.formatCurrencyAmount(d.swapCryptoValue, d.swapSymbol) return RootStore.formatCurrencyAmount(transactionHeader.inFiatValue, RootStore.currentCurrency)
} else if (type === Constants.TransactionType.Bridge) { } else if (type === Constants.TransactionType.Bridge) {
return RootStore.formatCurrencyAmount(d.fiatValue - d.feeFiatValue, RootStore.currentCurrency) return RootStore.formatCurrencyAmount(transactionHeader.fiatValue - d.feeFiatValue, RootStore.currentCurrency)
} }
return "" return ""
} }
@ -535,7 +515,7 @@ Item {
width: parent.width width: parent.width
title: qsTr("Fees") title: qsTr("Fees")
subTitle: { subTitle: {
if (!root.isTransactionValid || d.isNFT) if (!root.isTransactionValid || transactionHeader.isNFT)
return "" return ""
switch(d.transactionType) { switch(d.transactionType) {
case Constants.TransactionType.Send: case Constants.TransactionType.Send:
@ -552,28 +532,30 @@ Item {
TransactionDataTile { TransactionDataTile {
width: parent.width width: parent.width
// Using fees in this tile because of same higlight and color settings as Total // Using fees in this tile because of same higlight and color settings as Total
title: d.transactionType === Constants.TransactionType.Destroy || d.isNFT ? qsTr("Fees") : qsTr("Total") title: d.transactionType === Constants.TransactionType.Destroy || transactionHeader.isNFT ? qsTr("Fees") : qsTr("Total")
subTitle: { subTitle: {
if (d.isNFT && d.isIncoming) if (transactionHeader.isNFT && d.isIncoming)
return "" return ""
const type = d.transactionType const type = d.transactionType
if (type === Constants.TransactionType.Destroy || d.isNFT) { if (type === Constants.TransactionType.Destroy || transactionHeader.isNFT) {
return RootStore.formatCurrencyAmount(d.feeEthValue, "ETH") return RootStore.formatCurrencyAmount(d.feeEthValue, "ETH")
} else if (type === Constants.TransactionType.Receive || (type === Constants.TransactionType.Buy && progressBlock.isLayer1)) { } else if (type === Constants.TransactionType.Receive || (type === Constants.TransactionType.Buy && progressBlock.isLayer1)) {
return d.cryptoValueFormatted return d.cryptoValueFormatted
} }
return "%1 + %2".arg(d.cryptoValueFormatted).arg(RootStore.formatCurrencyAmount(d.feeEthValue, "ETH")) const cryptoValue = transactionHeader.isMultiTransaction ? d.outCryptoValueFormatted : d.cryptoValueFormatted
return "%1 + %2".arg(cryptoValue).arg(RootStore.formatCurrencyAmount(d.feeEthValue, "ETH"))
} }
tertiaryTitle: { tertiaryTitle: {
if (d.isNFT && d.isIncoming) if (transactionHeader.isNFT && d.isIncoming)
return "" return ""
const type = d.transactionType const type = d.transactionType
if (type === Constants.TransactionType.Destroy || d.isNFT) { if (type === Constants.TransactionType.Destroy || transactionHeader.isNFT) {
return RootStore.formatCurrencyAmount(d.feeFiatValue, RootStore.currentCurrency) return RootStore.formatCurrencyAmount(d.feeFiatValue, RootStore.currentCurrency)
} else if (type === Constants.TransactionType.Receive || (type === Constants.TransactionType.Buy && progressBlock.isLayer1)) { } else if (type === Constants.TransactionType.Receive || (type === Constants.TransactionType.Buy && progressBlock.isLayer1)) {
return d.fiatValueFormatted return d.fiatValueFormatted
} }
return RootStore.formatCurrencyAmount(d.fiatValue + d.feeFiatValue, RootStore.currentCurrency) const fiatValue = transactionHeader.isMultiTransaction ? transactionHeader.outFiatValue : transactionHeader.fiatValue
return RootStore.formatCurrencyAmount(fiatValue + d.feeFiatValue, RootStore.currentCurrency)
} }
visible: !!subTitle visible: !!subTitle
highlighted: true highlighted: true
@ -624,7 +606,22 @@ Item {
component DetailsPanel: Item { component DetailsPanel: Item {
width: parent.width width: parent.width
height: detailsColumn.childrenRect.height height: {
// Using childrenRect and transactionvalid properties to refresh this binding
if (!isTransactionValid || detailsColumn.childrenRect.height === 0)
return 0
// Height is calculated from visible children because Column doesn't handle
// visibility change properly and childrenRect.height gives different values
// comparing to manual check
var visibleHeight = 0
for (var i = 0 ; i < detailsColumn.children.length ; i++) {
if (detailsColumn.children[i].visible)
visibleHeight += detailsColumn.children[i].height
}
return visibleHeight
}
default property alias content: detailsColumn.children default property alias content: detailsColumn.children
Rectangle { Rectangle {
@ -659,7 +656,7 @@ Item {
property string address: "" property string address: ""
property string shortNetworkName: "" property string shortNetworkName: ""
width: parent.width width: parent.width
title: qsTr("%1 %2 contract address").arg(networkName).arg(symbol) title: visible ? qsTr("%1 %2 contract address").arg(networkName).arg(symbol) : ""
subTitle: !!address && !/0x0+$/.test(address) ? address : "" subTitle: !!address && !/0x0+$/.test(address) ? address : ""
buttonIconName: "more" buttonIconName: "more"
visible: !!subTitle visible: !!subTitle

View File

@ -64,7 +64,7 @@ Item {
charactersLen: 2 charactersLen: 2
} }
implicitHeight: Math.max(identicon.height, contentColumn.height) + 12 implicitHeight: Math.max(44, contentColumn.height) + 12
QtObject { QtObject {
id: d id: d

View File

@ -62,7 +62,7 @@ StatusListItem {
height: visible ? implicitHeight + bottomPadding : 0 height: visible ? implicitHeight + bottomPadding : 0
radius: 0 radius: 0
sensor.cursorShape: Qt.ArrowCursor sensor.cursorShape: Qt.ArrowCursor
color: sensor.containsMouse ? Theme.palette.baseColor5 : Style.current.transparent color: sensor.containsMouse || highlighted ? Theme.palette.baseColor5 : Style.current.transparent
// Title // Title
statusListItemTitle.customColor: Theme.palette.directColor5 statusListItemTitle.customColor: Theme.palette.directColor5

View File

@ -23,23 +23,10 @@ import shared 1.0
TransactionDelegate { TransactionDelegate {
id: delegate id: delegate
width: ListView.view.width width: ListView.view.width
modelData: model modelData: model.activityEntry
swapCryptoValue: 0.18
swapFiatValue: 340
swapSymbol: "SNT"
timeStampText: LocaleUtils.formatRelativeTimestamp(modelData.timestamp * 1000)
cryptoValue: 0.1234
fiatValue: 123123
currentCurrency: "USD"
networkName: "Optimism"
symbol: "ETH"
bridgeNetworkName: "Mainnet"
feeFiatValue: 10.34
feeCryptoValue: 0.013
transactionStatus: TransactionDelegate.Pending
transactionType: TransactionDelegate.Send
rootStore: RootStore rootStore: RootStore
loading: isModelDataValid && modelData.loadingTransaction walletRootStore: WalletStore.RootStore
loading: isModelDataValid
} }
\endqml \endqml
@ -52,59 +39,53 @@ StatusListItem {
signal retryClicked() signal retryClicked()
property var modelData property var modelData
property string symbol property string timeStampText: isModelDataValid ? LocaleUtils.formatRelativeTimestamp(modelData.timestamp * 1000) : ""
property string swapSymbol // TODO fill when swap data is implemented
property int transactionStatus required property var rootStore
property string currentCurrency required property var walletRootStore
property double cryptoValue
property double swapCryptoValue // TODO fill when swap data is implemented
property double fiatValue
property double swapFiatValue // TODO fill when swap data is implemented
property double feeCryptoValue // TODO fill when bridge data is implemented
property double feeFiatValue // TODO fill when bridge data is implemented
property string networkIcon
property string networkColor
property string networkName
property string bridgeNetworkName // TODO fill when bridge data is implemented
property string timeStampText
property string addressNameTo
property string addressNameFrom
property var rootStore
property var walletRootStore
readonly property bool isModelDataValid: modelData !== undefined && !!modelData readonly property bool isModelDataValid: modelData !== undefined && !!modelData
readonly property int transactionStatus: isModelDataValid ? modelData.status : Constants.TransactionStatus.Pending
readonly property bool isMultiTransaction: isModelDataValid && modelData.isMultiTransaction
readonly property string currentCurrency: rootStore.currentCurrency
readonly property double cryptoValue: isModelDataValid && !isMultiTransaction ? modelData.amount : 0.0
readonly property double fiatValue: isModelDataValid && !isMultiTransaction ? rootStore.getFiatValue(cryptoValue, modelData.symbol, currentCurrency) : 0.0
readonly property double inCryptoValue: isModelDataValid ? modelData.inAmount : 0.0
readonly property double inFiatValue: isModelDataValid && isMultiTransaction ? rootStore.getFiatValue(inCryptoValue, modelData.inSymbol, currentCurrency): 0.0
readonly property double outCryptoValue: isModelDataValid ? modelData.outAmount : 0.0
readonly property double outFiatValue: isModelDataValid && isMultiTransaction ? rootStore.getFiatValue(outCryptoValue, modelData.outSymbol, currentCurrency): 0.0
readonly property double feeCryptoValue: 0.0 // TODO fill when bridge data is implemented
readonly property double feeFiatValue: 0.0 // TODO fill when bridge data is implemented
readonly property string networkColor: isModelDataValid ? rootStore.getNetworkColor(modelData.chainId) : ""
readonly property string networkName: isModelDataValid ? rootStore.getNetworkFullName(modelData.chainId) : ""
readonly property string addressNameTo: isModelDataValid ? walletRootStore.getNameForAddress(modelData.recipient) : ""
readonly property string addressNameFrom: isModelDataValid ? walletRootStore.getNameForAddress(modelData.sender) : ""
readonly property bool isNFT: isModelDataValid && modelData.isNFT readonly property bool isNFT: isModelDataValid && modelData.isNFT
readonly property string transactionValue: { readonly property string transactionValue: {
if (!isModelDataValid)
return qsTr("N/A")
if (root.isNFT) {
return modelData.nftName ? modelData.nftName : "#" + modelData.tokenID
} else {
return root.rootStore.formatCurrencyAmount(cryptoValue, symbol)
}
}
readonly property string swapTransactionValue: {
if (!isModelDataValid) { if (!isModelDataValid) {
return qsTr("N/A") return qsTr("N/A")
} else if (root.isNFT) {
return modelData.nftName ? modelData.nftName : "#" + modelData.tokenID
} }
return root.rootStore.formatCurrencyAmount(swapCryptoValue, swapSymbol) return root.rootStore.formatCurrencyAmount(cryptoValue, modelData.symbol)
} }
readonly property string inTransactionValue: isModelDataValid && isMultiTransaction ? rootStore.formatCurrencyAmount(inCryptoValue, modelData.inSymbol) : qsTr("N/A")
readonly property string outTransactionValue: isModelDataValid && isMultiTransaction ? rootStore.formatCurrencyAmount(outCryptoValue, modelData.outSymbol) : qsTr("N/A")
readonly property string tokenImage: { readonly property string tokenImage: {
if (!isModelDataValid) if (!isModelDataValid)
return "" return ""
if (root.isNFT) { if (root.isNFT) {
return modelData.nftImageUrl ? modelData.nftImageUrl : "" return modelData.nftImageUrl ? modelData.nftImageUrl : ""
} else { } else {
return Constants.tokenIcon(root.symbol) return Constants.tokenIcon(isMultiTransaction ? modelData.outSymbol : modelData.symbol)
} }
} }
readonly property string swapTokenImage: { readonly property string inTokenImage: isModelDataValid ? Constants.tokenIcon(modelData.inSymbol) : ""
if (!isModelDataValid)
return ""
return Constants.tokenIcon(root.swapSymbol)
}
readonly property string toAddress: !!addressNameTo ? readonly property string toAddress: !!addressNameTo ?
addressNameTo : addressNameTo :
@ -168,7 +149,7 @@ StatusListItem {
const endl = "\n" const endl = "\n"
const endl2 = endl + endl const endl2 = endl + endl
const type = modelData.txType const type = modelData.txType
const feeEthValue = modelData.totalFees ? rootStore.getGasEthValue(modelData.totalFees.amount, 1) : 0 const feeEthValue = rootStore.getGasEthValue(modelData.totalFees.amount, 1)
// TITLE // TITLE
switch (type) { switch (type) {
@ -258,20 +239,21 @@ StatusListItem {
} }
// SUMMARY ADRESSES // SUMMARY ADRESSES
const toNetworkName = "" // TODO fill when bridge data is implemented
switch (type) { switch (type) {
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
details += qsTr("From") + endl + root.symbol + endl2 details += qsTr("From") + endl + modelData.outSymbol + endl2
details += qsTr("To") + endl + root.swapSymbol + endl2 details += qsTr("To") + endl + modelData.inSymbol + endl2
details += qsTr("In") + endl + root.fromAddress + endl2 details += qsTr("In") + endl + root.fromAddress + endl2
break break
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
details += qsTr("From") + endl + root.networkName + endl2 details += qsTr("From") + endl + root.networkName + endl2
details += qsTr("To") + endl + root.bridgeNetworkName + endl2 details += qsTr("To") + endl + toNetworkName + endl2
details += qsTr("In") + endl + modelData.from + endl2 details += qsTr("In") + endl + modelData.from + endl2
break break
default: default:
details += qsTr("From") + endl + modelData.from + endl2 details += qsTr("From") + endl + modelData.sender + endl2
details += qsTr("To") + endl + modelData.to + endl2 details += qsTr("To") + endl + modelData.recipient + endl2
break break
} }
const protocolName = "" // TODO fill protocol name for Bridge and Swap const protocolName = "" // TODO fill protocol name for Bridge and Swap
@ -283,7 +265,7 @@ StatusListItem {
} }
const bridgeTxHash = "" // TODO fill tx hash for Bridge const bridgeTxHash = "" // TODO fill tx hash for Bridge
if (!!bridgeTxHash) { if (!!bridgeTxHash) {
details += qsTr("%1 Tx hash").arg(root.bridgeNetworkName) + endl + bridgeTxHash + endl2 details += qsTr("%1 Tx hash").arg(toNetworkName) + endl + bridgeTxHash + endl2
} }
const protocolFromContractAddress = "" // TODO fill protocol contract address for 'from' network for Bridge and Swap const protocolFromContractAddress = "" // TODO fill protocol contract address for 'from' network for Bridge and Swap
if (!!protocolName && !!protocolFromContractAddress) { if (!!protocolName && !!protocolFromContractAddress) {
@ -291,12 +273,12 @@ StatusListItem {
details += protocolFromContractAddress + endl2 details += protocolFromContractAddress + endl2
} }
if (!!modelData.contract) { if (!!modelData.contract) {
details += qsTr("%1 %2 contract address").arg(root.networkName).arg(root.symbol) + endl details += qsTr("%1 %2 contract address").arg(root.networkName).arg(modelData.symbol) + endl
details += modelData.contract + endl2 details += modelData.contract + endl2
} }
const protocolToContractAddress = "" // TODO fill protocol contract address for 'to' network for Bridge const protocolToContractAddress = "" // TODO fill protocol contract address for 'to' network for Bridge
if (!!protocolToContractAddress && !!protocolName) { if (!!protocolToContractAddress && !!protocolName) {
details += qsTr("%1 %2 contract address").arg(root.bridgeNetworkName).arg(protocolName) + endl details += qsTr("%1 %2 contract address").arg(toNetworkName).arg(protocolName) + endl
details += protocolToContractAddress + endl2 details += protocolToContractAddress + endl2
} }
const swapContractAddress = "" // TODO fill swap contract address for Swap const swapContractAddress = "" // TODO fill swap contract address for Swap
@ -304,13 +286,13 @@ StatusListItem {
switch (type) { switch (type) {
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
if (!!swapContractAddress) { if (!!swapContractAddress) {
details += qsTr("%1 %2 contract address").arg(root.networkName).arg(root.swapSymbol) + endl details += qsTr("%1 %2 contract address").arg(root.networkName).arg(modelData.toSymbol) + endl
details += swapContractAddress + endl2 details += swapContractAddress + endl2
} }
break break
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
if (!!bridgeContractAddress) { if (!!bridgeContractAddress) {
details += qsTr("%1 %2 contract address").arg(root.bridgeNetworkName).arg(root.symbol) + endl details += qsTr("%1 %2 contract address").arg(toNetworkName).arg(modelData.symbol) + endl
details += bridgeContractAddress + endl2 details += bridgeContractAddress + endl2
} }
break break
@ -327,7 +309,7 @@ StatusListItem {
if (type === Constants.TransactionType.Bridge) { if (type === Constants.TransactionType.Bridge) {
details += qsTr("Included in Block on %1").arg(networkName) + endl details += qsTr("Included in Block on %1").arg(networkName) + endl
details += rootStore.hex2Dec(modelData.blockNumber) + endl2 details += rootStore.hex2Dec(modelData.blockNumber) + endl2
details += qsTr("Included in Block on %1").arg(bridgeNetworkName) + endl details += qsTr("Included in Block on %1").arg(toNetworkName) + endl
const bridgeBlockNumber = 0 // TODO fill when bridge data is implemented const bridgeBlockNumber = 0 // TODO fill when bridge data is implemented
details += rootStore.hex2Dec(bridgeBlockNumber) + endl2 details += rootStore.hex2Dec(bridgeBlockNumber) + endl2
} else { } else {
@ -335,27 +317,29 @@ StatusListItem {
} }
// VALUES // VALUES
const fiatTransactionValue = rootStore.formatCurrencyAmount(root.fiatValue, root.currentCurrency) const fiatTransactionValue = rootStore.formatCurrencyAmount(isMultiTransaction ? root.outFiatValue : root.fiatValue, root.currentCurrency)
const feeFiatValue = rootStore.getFiatValue(feeEthValue, "ETH", root.currentCurrency) const feeFiatValue = rootStore.getFiatValue(feeEthValue, "ETH", root.currentCurrency)
let valuesString = "" let valuesString = ""
if (!root.isNFT) { if (!root.isNFT) {
switch(type) { switch(type) {
case Constants.TransactionType.Send: case Constants.TransactionType.Send:
valuesString += qsTr("Amount sent %1 (%2)").arg(root.transactionValue).arg(fiatTransactionValue) + endl2
break
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
valuesString += qsTr("Amount sent %1 (%2)").arg(root.transactionValue).arg(fiatTransactionValue) + endl2 valuesString += qsTr("Amount sent %1 (%2)").arg(root.outTransactionValue).arg(fiatTransactionValue) + endl2
break break
default: default:
break break
} }
if (type === Constants.TransactionType.Swap) { if (type === Constants.TransactionType.Swap) {
const crypto = rootStore.formatCurrencyAmount(root.swapCryptoValue, root.swapSymbol) const crypto = rootStore.formatCurrencyAmount(root.inCryptoValue, modelData.inSymbol)
const fiat = rootStore.formatCurrencyAmount(root.swapCryptoValue, root.swapSymbol) const fiat = rootStore.formatCurrencyAmount(root.inCryptoValue, modelData.inSymbol)
valuesString += qsTr("Amount received %1 (%2)").arg(crypto).arg(fiat) + endl2 valuesString += qsTr("Amount received %1 (%2)").arg(crypto).arg(fiat) + endl2
} else if (type === Constants.TransactionType.Bridge) { } else if (type === Constants.TransactionType.Bridge) {
// Reduce crypto value by fee value // Reduce crypto value by fee value
const valueInCrypto = rootStore.getCryptoValue(root.fiatValue - feeFiatValue, root.symbol, root.currentCurrency) const valueInCrypto = rootStore.getCryptoValue(root.fiatValue - feeFiatValue, modelData.inSymbol, root.currentCurrency)
const crypto = rootStore.formatCurrencyAmount(valueInCrypto, root.symbol) const crypto = rootStore.formatCurrencyAmount(valueInCrypto, modelData.inSymbol)
const fiat = rootStore.formatCurrencyAmount(root.fiatValue - feeFiatValue, root.currentCurrency) const fiat = rootStore.formatCurrencyAmount(root.fiatValue - feeFiatValue, root.currentCurrency)
valuesString += qsTr("Amount received %1 (%2)").arg(crypto).arg(fiat) + endl2 valuesString += qsTr("Amount received %1 (%2)").arg(crypto).arg(fiat) + endl2
} }
@ -381,7 +365,8 @@ StatusListItem {
valuesString += qsTr("Total %1 (%2)").arg(root.transactionValue).arg(fiatTransactionValue) + endl2 valuesString += qsTr("Total %1 (%2)").arg(root.transactionValue).arg(fiatTransactionValue) + endl2
} else { } else {
const feeEth = rootStore.formatCurrencyAmount(feeEthValue, "ETH") const feeEth = rootStore.formatCurrencyAmount(feeEthValue, "ETH")
valuesString += qsTr("Total %1 + %2 (%3)").arg(root.transactionValue).arg(feeEth).arg(fiatTransactionValue) + endl2 const txValue = isMultiTransaction ? root.inTransactionValue : root.transactionValue
valuesString += qsTr("Total %1 + %2 (%3)").arg(txValue).arg(feeEth).arg(fiatTransactionValue) + endl2
} }
} }
@ -399,6 +384,7 @@ StatusListItem {
rightPadding: 16 rightPadding: 16
enabled: !loading enabled: !loading
loading: !isModelDataValid
color: sensor.containsMouse ? Theme.palette.baseColor5 : Style.current.transparent color: sensor.containsMouse ? Theme.palette.baseColor5 : Style.current.transparent
statusListItemIcon.active: (loading || root.asset.name) statusListItemIcon.active: (loading || root.asset.name)
@ -486,15 +472,15 @@ StatusListItem {
spacing: 8 spacing: 8
Row { Row {
visible: !root.loading visible: !root.loading
spacing: swapTokenImage.visible ? -tokenImage.width * 0.2 : 0 spacing: secondTokenImage.visible ? -tokenImage.width * 0.2 : 0
StatusRoundIcon { StatusRoundIcon {
id: tokenImage id: tokenImage
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
asset: root.tokenIconAsset asset: root.tokenIconAsset
} }
StatusRoundIcon { StatusRoundIcon {
id: swapTokenImage id: secondTokenImage
visible: root.isModelDataValid && !root.isNFT && !!root.swapTokenImage &&modelData.txType === Constants.TransactionType.Swap visible: root.isModelDataValid && !root.isNFT && !!root.inTokenImage &&modelData.txType === Constants.TransactionType.Swap
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
asset: StatusAssetSettings { asset: StatusAssetSettings {
width: root.tokenIconAsset.width width: root.tokenIconAsset.width
@ -505,7 +491,7 @@ StatusListItem {
bgColor: root.color bgColor: root.color
isImage:root.tokenIconAsset.isImage isImage:root.tokenIconAsset.isImage
color: root.tokenIconAsset.color color: root.tokenIconAsset.color
name: root.swapTokenImage name: root.inTokenImage
isLetterIdenticon: root.tokenIconAsset.isLetterIdenticon isLetterIdenticon: root.tokenIconAsset.isLetterIdenticon
} }
} }
@ -537,11 +523,12 @@ StatusListItem {
case Constants.TransactionType.Sell: case Constants.TransactionType.Sell:
return qsTr("%1 on %2 via %3").arg(transactionValue).arg(toAddress).arg(networkName) return qsTr("%1 on %2 via %3").arg(transactionValue).arg(toAddress).arg(networkName)
case Constants.TransactionType.Destroy: case Constants.TransactionType.Destroy:
return qsTr("%1 at %2 via %3").arg(transactionValue).arg(toAddress).arg(networkName) return qsTr("%1 at %2 via %3").arg(inTransactionValue).arg(toAddress).arg(networkName)
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
return qsTr("%1 to %2 via %3").arg(transactionValue).arg(swapTransactionValue).arg(networkName) return qsTr("%1 to %2 via %3").arg(outTransactionValue).arg(inTransactionValue).arg(networkName)
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
return qsTr("%1 from %2 to %3").arg(transactionValue).arg(bridgeNetworkName).arg(networkName) let toNetworkName = "" // TODO fill when Bridge data is implemented
return qsTr("%1 from %2 to %3").arg(inTransactionValue).arg(networkName).arg(toNetworkName)
default: default:
return qsTr("%1 to %2 via %3").arg(transactionValue).arg(toAddress).arg(networkName) return qsTr("%1 to %2 via %3").arg(transactionValue).arg(toAddress).arg(networkName)
} }
@ -574,14 +561,18 @@ StatusListItem {
case Constants.TransactionType.Receive: case Constants.TransactionType.Receive:
return "+" + root.transactionValue return "+" + root.transactionValue
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
let outValue = root.outTransactionValue
outValue = outValue.replace('<', '&lt;')
let inValue = root.inTransactionValue
inValue = inValue.replace('<', '&lt;')
return "<font color=\"%1\">-%2</font> <font color=\"%3\">/</font> <font color=\"%4\">+%5</font>" return "<font color=\"%1\">-%2</font> <font color=\"%3\">/</font> <font color=\"%4\">+%5</font>"
.arg(Theme.palette.directColor1) .arg(Theme.palette.directColor1)
.arg(root.transactionValue) .arg(outValue)
.arg(Theme.palette.baseColor1) .arg(Theme.palette.baseColor1)
.arg(Theme.palette.successColor1) .arg(Theme.palette.successColor1)
.arg(root.swapTransactionValue) .arg(inValue)
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
return "" + root.rootStore.formatCurrencyAmount(feeCryptoValue, root.symbol) return "" + root.rootStore.formatCurrencyAmount(feeCryptoValue, modelData.symbol)
default: default:
return "" return ""
} }
@ -623,8 +614,8 @@ StatusListItem {
case Constants.TransactionType.Receive: case Constants.TransactionType.Receive:
return "+" + root.rootStore.formatCurrencyAmount(root.fiatValue, root.currentCurrency) return "+" + root.rootStore.formatCurrencyAmount(root.fiatValue, root.currentCurrency)
case Constants.TransactionType.Swap: case Constants.TransactionType.Swap:
return "-%1 / +%2".arg(root.rootStore.formatCurrencyAmount(root.fiatValue, root.currentCurrency)) return "-%1 / +%2".arg(root.rootStore.formatCurrencyAmount(root.outFiatValue, root.currentCurrency))
.arg(root.rootStore.formatCurrencyAmount(root.swapFiatValue, root.currentCurrency)) .arg(root.rootStore.formatCurrencyAmount(root.inFiatValue, root.currentCurrency))
case Constants.TransactionType.Bridge: case Constants.TransactionType.Bridge:
return "" + root.rootStore.formatCurrencyAmount(root.feeFiatValue, root.currentCurrency) return "" + root.rootStore.formatCurrencyAmount(root.feeFiatValue, root.currentCurrency)
default: default:

View File

@ -256,19 +256,11 @@ ColumnLayout {
Component { Component {
id: transactionDelegate id: transactionDelegate
TransactionDelegate { TransactionDelegate {
required property var model
required property int index
width: ListView.view.width width: ListView.view.width
modelData: model.activityEntry modelData: model.activityEntry
currentCurrency: RootStore.currentCurrency
cryptoValue: isModelDataValid ? modelData.value : 0.0
fiatValue: isModelDataValid ? RootStore.getFiatValue(cryptoValue, symbol, currentCurrency): 0.0
networkIcon: isModelDataValid ? RootStore.getNetworkIcon(modelData.chainId) : ""
networkColor: isModelDataValid ? RootStore.getNetworkColor(modelData.chainId) : ""
networkName: isModelDataValid ? RootStore.getNetworkFullName(modelData.chainId) : ""
symbol: isModelDataValid && !!modelData.symbol ? modelData.symbol : ""
transactionStatus: isModelDataValid ? modelData.status : 0
timeStampText: isModelDataValid ? LocaleUtils.formatRelativeTimestamp(modelData.timestamp * 1000, true) : "" timeStampText: isModelDataValid ? LocaleUtils.formatRelativeTimestamp(modelData.timestamp * 1000, true) : ""
addressNameTo: isModelDataValid ? WalletStores.RootStore.getNameForAddress(modelData.recipient) : ""
addressNameFrom: isModelDataValid ? WalletStores.RootStore.getNameForAddress(modelData.sender) : ""
rootStore: RootStore rootStore: RootStore
walletRootStore: WalletStores.RootStore walletRootStore: WalletStores.RootStore
onClicked: { onClicked: {
@ -309,6 +301,8 @@ ColumnLayout {
model: RootStore.historyTransactions.hasMore || d.isInitialLoading ? 10 : 0 model: RootStore.historyTransactions.hasMore || d.isInitialLoading ? 10 : 0
TransactionDelegate { TransactionDelegate {
Layout.fillWidth: true Layout.fillWidth: true
rootStore: RootStore
walletRootStore: WalletStores.RootStore
loading: true loading: true
} }
} }