feat(@desktop/wallet): Transactions values (#10832)

This commit is contained in:
Cuteivist 2023-06-05 08:22:30 +02:00 committed by GitHub
parent 4e54ee57a6
commit dc9193424f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 171 additions and 52 deletions

View File

@ -20,8 +20,10 @@ SplitView {
property bool mainModuleReady: false
property bool rootStoreReady: false
property bool isIncoming: false
Component.onCompleted: {
RootStore.getFiatValue = (cryptoValue, symbol, currentCurrency) => { return 123 }
RootStore.getFiatValue = (cryptoValue, symbol, currentCurrency) => { return (cryptoValue * 1800).toPrecision(2) }
RootStore.getNetworkIcon = (chainId) => { return "tiny/network/Network=Ethereum" }
RootStore.getLatestBlockNumber = () => { return 4 }
RootStore.hex2Dec = (number) => { return 10 }
@ -33,6 +35,8 @@ SplitView {
RootStore.getNameForAddress = (address) => { return "Address Name" }
RootStore.getEnsForSavedWalletAddress = (address) => { return "123" }
RootStore.getChainShortNamesForSavedWalletAddress = (address) => { return "" }
RootStore.getGasEthValue = (gasAmount, gasPrice) => { return (gasAmount * Math.pow(10, -9)).toPrecision(5) }
RootStore.getNetworkLayer = (chainId) => { return 1 }
RootStore.currentCurrency = "USD"
root.rootStoreReady = true
@ -120,8 +124,28 @@ SplitView {
readonly property var value: QtObject {
property real amount: amountSpinbox.realValue
property string symbol: "eth"
property string symbol: "ETH"
property int displayDecimals: 5
property bool stripTrailingZeroes: true
}
readonly property var totalFees: QtObject {
property real amount: (transactionData.value.amount / 15) * Math.pow(10, 9)
property string symbol: "Gwei"
property int displayDecimals: 8
property bool stripTrailingZeroes: true
}
readonly property var gasPrice: QtObject {
property real amount: 0.0000005
property string symbol: "ETH"
}
}
QtObject {
id: overviewMockup
property var mixedcaseAddress: root.isIncoming ? transactionData.to : transactionData.from
}
SplitView {
@ -149,6 +173,7 @@ SplitView {
sourceComponent: TransactionDetailView {
contactsStore: contactsStoreMockup
transaction: transactionData
overview: overviewMockup
}
}
}
@ -189,6 +214,11 @@ SplitView {
checked: transactionData.isNFT
onCheckedChanged: transactionData.isNFT = checked
}
CheckBox {
text: "is incoming"
checked: root.isIncoming
onCheckedChanged: root.isIncoming = checked
}
}
}
}

View File

@ -25,4 +25,6 @@ QtObject {
property var getNameForAddress
property var getEnsForSavedWalletAddress
property var getChainShortNamesForSavedWalletAddress
property var getGasEthValue
property var getNetworkLayer
}

View File

@ -214,21 +214,30 @@ StatusMenu {
enabled: false
text: d.getViewText(qsTr("Etherscan"))
assetSettings.name: "link"
onTriggered: Global.openLink("https://etherscan.io/address/%1".arg(d.selectedAddress))
onTriggered: {
const type = d.addressType === TransactionAddressMenu.Tx ? "tx" : "address"
Global.openLink("https://etherscan.io/%1/%2".arg(type).arg(d.selectedAddress))
}
}
StatusAction {
id: showOnArbiscanAction
enabled: false
text: d.getViewText(qsTr("Arbiscan"))
assetSettings.name: "link"
onTriggered: Global.openLink("https://arbiscan.io/address/%1".arg(d.selectedAddress))
onTriggered: {
const type = d.addressType === TransactionAddressMenu.Tx ? "tx" : "address"
Global.openLink("https://arbiscan.io/%1/%2".arg(type).arg(d.selectedAddress))
}
}
StatusAction {
id: showOnOptimismAction
enabled: false
text: d.getViewText(qsTr("Optimism Explorer"))
assetSettings.name: "link"
onTriggered: Global.openLink("https://optimistic.etherscan.io/address/%1".arg(d.selectedAddress))
onTriggered: {
const type = d.addressType === TransactionAddressMenu.Tx ? "tx" : "address"
Global.openLink("https://optimistic.etherscan.io/%1/%2".arg(type).arg(d.selectedAddress))
}
}
StatusCopyAction {
id: copyAddressAction

View File

@ -48,9 +48,16 @@ Item {
readonly property string bridgeNetworkFullname: "" // TODO fill when bridge data is implemented
readonly property string bridgeNetworkShortName: "" // TODO fill when bridge data is implemented
readonly property int bridgeBlockNumber: 0 // TODO fill when bridge data is implemented
readonly property double swapCryptoValue: 0 // TODO fill when swap data is implemented
readonly property string swapSymbol: "" // TODO fill when swap data is implemented
readonly property string symbol: root.isTransactionValid ? transaction.symbol : ""
readonly property var multichainNetworks: [] // TODO fill icon for networks for multichain
readonly property double cryptoValue: root.isTransactionValid ? transaction.value.amount: 0.0
readonly property double fiatValue: root.isTransactionValid ? RootStore.getFiatValue(cryptoValue, symbol, RootStore.currentCurrency): 0.0
readonly property string fiatValueFormatted: root.isTransactionValid ? RootStore.formatCurrencyAmount(d.fiatValue, RootStore.currentCurrency) : ""
readonly property string cryptoValueFormatted: root.isTransactionValid ? LocaleUtils.currencyAmountToLocaleString(transaction.value) : ""
readonly property real feeEthValue: root.isTransactionValid ? RootStore.getGasEthValue(transaction.totalFees.amount, 1) : 0
readonly property real feeFiatValue: root.isTransactionValid ? RootStore.getFiatValue(d.feeEthValue, "ETH", RootStore.currentCurrency) : 0
function getNameForSavedWalletAddress(address) {
return RootStore.getNameForSavedWalletAddress(address)
@ -84,8 +91,8 @@ Item {
modelData: transaction
transactionType: d.isIncoming ? TransactionDelegate.Receive : TransactionDelegate.Send
currentCurrency: RootStore.currentCurrency
cryptoValue: root.isTransactionValid ? transaction.value.amount: 0.0
fiatValue: root.isTransactionValid ? RootStore.getFiatValue(cryptoValue, symbol, currentCurrency): 0.0
cryptoValue: d.cryptoValue
fiatValue: d.fiatValue
networkIcon: d.networkIcon
networkColor: root.isTransactionValid ? RootStore.getNetworkColor(transaction.chainId): ""
networkName: d.networkFullName
@ -401,55 +408,126 @@ Item {
}
}
StatusExpandableItem {
width: parent.width
anchors.horizontalCenter: parent.horizontalCenter
Column {
width: progressBlock.width
spacing: Style.current.smallPadding
visible: !(d.isNFT && d.isIncoming)
type: StatusExpandableItem.Type.Tertiary
expandable: true
primaryText: qsTr("Fees")
expandableComponent: fees
expanded: true
}
}
}
RowLayout {
width: parent.width
StatusBaseText {
Layout.alignment: Qt.AlignLeft
font.pixelSize: 15
color: Theme.palette.directColor5
text: qsTr("Values")
elide: Text.ElideRight
}
Component {
id: fees
Column {
width: parent.width
spacing: 8
Row {
spacing: 8
InformationTile {
id: baseFee
maxWidth: parent.width
primaryText: qsTr("Base fee")
secondaryText: root.isTransactionValid ? qsTr("%1").arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.baseGasFees)) : ""
StatusBaseText {
Layout.alignment: Qt.AlignRight
font.pixelSize: 15
color: Theme.palette.directColor5
text: root.isTransactionValid ? qsTr("as of %1").arg(LocaleUtils.formatDateTime(transaction.timestamp * 1000, Locale.LongFormat)) : ""
elide: Text.ElideRight
}
}
InformationTile {
maxWidth: parent.width
primaryText: qsTr("Tip")
secondaryText: root.isTransactionValid ? "%1 <font color=\"%2\">&#8226; ".
arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.maxPriorityFeePerGas)).
arg(Theme.palette.baseColor1) +
qsTr("Max: %1").
arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.maxFeePerGas)) +
"</font>" : ""
secondaryLabel.textFormat: Text.RichText
DetailsPanel {
TransactionDataTile {
width: parent.width
title: qsTr("Amount sent")
subTitle: d.cryptoValueFormatted
tertiaryTitle: d.fiatValueFormatted
visible: {
if (d.isNFT)
return false
switch(transactionHeader.transactionType) {
case TransactionDelegate.Send:
case TransactionDelegate.Swap:
case TransactionDelegate.Bridge:
return true
default:
return false
}
}
}
TransactionDataTile {
width: parent.width
title: transactionHeader.transactionStatus === TransactionDelegate.Pending ? qsTr("Amount to receive") : qsTr("Amount received")
subTitle: {
if (d.isNFT)
return ""
const type = transactionHeader.transactionType
if (type === TransactionDelegate.Swap) {
return RootStore.formatCurrencyAmount(d.swapCryptoValue, d.swapSymbol)
} else if (type === TransactionDelegate.Bridge) {
// Reduce crypto value by fee value
const valueInCrypto = RootStore.getCryptoValue(d.fiatValue - d.feeFiatValue, d.symbol, RootStore.currentCurrency)
return RootStore.formatCurrencyAmount(valueInCrypto, d.symbol)
}
return ""
}
tertiaryTitle: {
const type = transactionHeader.transactionType
if (type === TransactionDelegate.Swap) {
return RootStore.formatCurrencyAmount(d.swapCryptoValue, d.swapSymbol)
} else if (type === TransactionDelegate.Bridge) {
return RootStore.formatCurrencyAmount(d.fiatValue - d.feeFiatValue, RootStore.currentCurrency)
}
return ""
}
visible: !!subTitle
}
TransactionDataTile {
width: parent.width
title: qsTr("Fees")
subTitle: {
if (!root.isTransactionValid || d.isNFT)
return ""
switch(transactionHeader.transactionType) {
case TransactionDelegate.Send:
case TransactionDelegate.Swap:
case TransactionDelegate.Bridge:
return LocaleUtils.currencyAmountToLocaleString(root.transaction.totalFees)
default:
return ""
}
}
tertiaryTitle: !!subTitle ? RootStore.formatCurrencyAmount(d.feeFiatValue, RootStore.currentCurrency) : ""
visible: !!subTitle
}
TransactionDataTile {
width: parent.width
// Using fees in this tile because of same higlight and color settings as Total
title: transactionHeader.transactionType === TransactionDelegate.Destroy || d.isNFT ? qsTr("Fees") : qsTr("Total")
subTitle: {
if (d.isNFT && d.isIncoming)
return ""
const type = transactionHeader.transactionType
if (type === TransactionDelegate.Destroy || d.isNFT) {
return RootStore.formatCurrencyAmount(d.feeEthValue, "ETH")
} else if (type === TransactionDelegate.Receive || (type === TransactionDelegate.Buy && progressBlock.isLayer1)) {
return d.cryptoValueFormatted
}
return "%1 + %2".arg(d.cryptoValueFormatted).arg(RootStore.formatCurrencyAmount(d.feeEthValue, "ETH"))
}
tertiaryTitle: {
if (d.isNFT && d.isIncoming)
return ""
const type = transactionHeader.transactionType
if (type === TransactionDelegate.Destroy || d.isNFT) {
return RootStore.formatCurrencyAmount(d.feeFiatValue, RootStore.currentCurrency)
} else if (type === TransactionDelegate.Receive || (type === TransactionDelegate.Buy && progressBlock.isLayer1)) {
return d.fiatValueFormatted
}
return RootStore.formatCurrencyAmount(d.fiatValue + d.feeFiatValue, RootStore.currentCurrency)
}
visible: !!subTitle
highlighted: true
statusListItemTertiaryTitle.customColor: Theme.palette.directColor1
}
}
}
InformationTile {
maxWidth: parent.width
primaryText: qsTr("Total fee")
secondaryText: root.isTransactionValid ? "%1 <font color=\"%2\">&#8226; ".
arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.totalFees)).
arg(Theme.palette.baseColor1) +
qsTr("Max: %1").
arg(LocaleUtils.currencyAmountToLocaleString(root.transaction.maxTotalFees)) +
"</font>" : ""
secondaryLabel.textFormat: Text.RichText
}
}
}

View File

@ -58,7 +58,7 @@ StatusListItem {
leftPadding: 12
rightPadding: 12
height: implicitHeight + bottomPadding
height: visible ? implicitHeight + bottomPadding : 0
radius: 0
sensor.cursorShape: Qt.ArrowCursor