feat/tx-comps: Add TransactionPreview component

Adds a TransactionPreview component as per the spec https://www.notion.so/emizzle/Wallet-transaction-components-2003b78a8d0d41c4ab3d21eb2496fb20

- update ReceiveModal dropdown to match design
- long alias and account name support
- long name support in account selector
- strip all trailing zeros from displayed balances
This commit is contained in:
emizzle 2020-08-13 18:24:51 +10:00 committed by Iuri Matias
parent 832518a0e1
commit 3dac87df3d
13 changed files with 543 additions and 39 deletions

View File

@ -46,6 +46,8 @@ ModalPopup {
anchors.topMargin: Style.current.padding
anchors.horizontalCenter: parent.horizontalCenter
width: 240
dropdownWidth: parent.width - (Style.current.padding * 2)
dropdownAlignment: Select.MenuAlignment.Center
}
Input {

View File

@ -1,5 +1,6 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../imports"
import "../../../shared"
import "./components"
@ -9,10 +10,10 @@ ModalPopup {
//% "Send"
title: qsTrId("command-button-send")
height: 600
height: 700
onOpened: {
sendModalContent.amountInput.text = ""
sendModalContent.amountInput.selectedAmount = ""
sendModalContent.passwordInput.text = ""
sendModalContent.amountInput.forceActiveFocus(Qt.MouseFocusReason)
}
@ -24,15 +25,41 @@ ModalPopup {
}
}
footer: StyledButton {
footer: Item {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
//% "Send"
label: qsTrId("command-button-send")
onClicked: {
sendModalContent.send()
StyledButton {
id: btnBack
anchors.left: parent.left
label: qsTr("Back")
visible: !btnPreview.visible
onClicked: {
btnPreview.visible = true
sendModalContent.showInputs()
}
}
StyledButton {
id: btnPreview
anchors.right: parent.right
label: qsTr("Preview")
onClicked: {
if (!sendModalContent.validate()) {
return
}
visible = false
sendModalContent.showPreview()
}
}
StyledButton {
id: btnSend
anchors.right: parent.right
visible: !btnPreview.visible
//% "Send"
label: qsTrId("command-button-send")
onClicked: {
sendModalContent.send()
}
}
}
}

View File

@ -11,8 +11,6 @@ Item {
property alias passwordInput: txtPassword
property string passwordValidationError: ""
property string toValidationError: ""
property string amountValidationError: ""
function send() {
if (!validate()) {
@ -20,7 +18,7 @@ Item {
}
let result = walletModel.onSendTransaction(selectFromAccount.selectedAccount.address,
selectRecipient.selectedRecipient,
selectAsset.selectedAsset.address,
txtAmount.selectedAsset.address,
txtAmount.text,
txtPassword.text)
@ -47,7 +45,17 @@ Item {
passwordValidationError = ""
}
return passwordValidationError === "" && toValidationError === "" && amountValidationError === "" && isRecipientValid && isAssetAndAmountValid
return passwordValidationError === "" && isRecipientValid && isAssetAndAmountValid
}
function showPreview() {
pvwTransaction.visible = true
txtAmount.visible = selectFromAccount.visible = selectRecipient.visible = txtPassword.visible = gasSelector.visible = false
}
function showInputs() {
pvwTransaction.visible = false
txtAmount.visible = selectFromAccount.visible = selectRecipient.visible = txtPassword.visible = gasSelector.visible = true
}
anchors.left: parent.left
@ -58,6 +66,9 @@ Item {
title: "Error sending the transaction"
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
onAccepted: {
sendModalContent.showInputs()
}
}
MessageDialog {
id: sendingSuccess
@ -67,6 +78,7 @@ Item {
standardButtons: StandardButton.Ok
onAccepted: {
closePopup()
sendModalContent.showInputs()
}
}
@ -87,20 +99,21 @@ Item {
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.right: parent.right
label: qsTr("From account")
onSelectedAccountChanged: {
txtAmount.selectedAccount = selectFromAccount.selectedAccount
}
}
GasSelector {
id: gasSelector
anchors.top: selectFromAccount.bottom
anchors.topMargin: Style.current.bigPadding
slowestGasPrice: parseFloat(walletModel.safeLowGasPrice)
fastestGasPrice: parseFloat(walletModel.fastestGasPrice)
getGasEthValue: walletModel.getGasEthValue
getFiatValue: walletModel.getFiatValue
defaultCurrency: walletModel.defaultCurrency
id: gasSelector
anchors.top: selectFromAccount.bottom
anchors.topMargin: Style.current.bigPadding
slowestGasPrice: parseFloat(walletModel.safeLowGasPrice)
fastestGasPrice: parseFloat(walletModel.fastestGasPrice)
getGasEthValue: walletModel.getGasEthValue
getFiatValue: walletModel.getFiatValue
defaultCurrency: walletModel.defaultCurrency
}
RecipientSelector {
@ -114,6 +127,23 @@ Item {
anchors.right: parent.right
}
TransactionPreview {
id: pvwTransaction
visible: false
anchors.left: parent.left
anchors.right: parent.right
fromAccount: selectFromAccount.selectedAccount
gas: {
const value = walletModel.getGasEthValue(gasSelector.selectedGasPrice, gasSelector.selectedGasLimit)
const fiatValue = walletModel.getFiatValue(value, "ETH", walletModel.defaultCurrency)
return { value, "symbol": "ETH", fiatValue }
}
toAccount: selectRecipient.selectedRecipient
asset: txtAmount.selectedAsset
amount: { "value": txtAmount.selectedAmount, "fiatValue": txtAmount.selectedFiatAmount }
currency: walletModel.defaultCurrency
}
Input {
id: txtPassword
//% "Password"
@ -125,6 +155,7 @@ Item {
textField.echoMode: TextInput.Password
validationError: passwordValidationError
}
}
/*##^##

View File

@ -69,4 +69,15 @@ QtObject {
function isValidAddress(inputValue) {
return /0x[a-fA-F0-9]{40}/.test(inputValue)
}
/**
* Removes trailing zeros from a string-representation of a number. Throws
* if parameter is not a string
*/
function stripTrailingZeros(strNumber) {
if (!(typeof strNumber === "string")) {
throw "must be a string"
}
return strNumber.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1')
}
}

View File

@ -313,6 +313,7 @@ DISTFILES += \
shared/AddButton.qml \
shared/IconButton.qml \
shared/Input.qml \
shared/LabelValueRow.qml \
shared/ModalPopup.qml \
shared/NotificationWindow.qml \
shared/PopupMenu.qml \
@ -332,6 +333,7 @@ DISTFILES += \
shared/StyledTextField.qml \
shared/SVGImage.qml \
shared/TextWithLabel.qml \
shared/TransactionPreview.qml \
shared/img/check.svg \
shared/img/close.svg \
shared/img/loading.png \

View File

@ -20,6 +20,7 @@ Item {
// nothing will be displayed
property string showAssetBalance: ""
property int dropdownWidth: width
property alias dropdownAlignment: select.menuAlignment
Repeater {
visible: showAssetBalance !== ""
@ -71,11 +72,10 @@ Item {
id: selectedTextField
text: selectedAccount.name
elide: Text.ElideRight
anchors.right: parent.right
anchors.rightMargin: Style.current.bigPadding
anchors.left: selectedIconImg.right
anchors.leftMargin: 8
anchors.verticalCenter: parent.verticalCenter
width: select.contentWidth - (Style.current.padding + selectedIconImg.width + anchors.leftMargin)
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
height: 22
@ -143,15 +143,17 @@ Item {
id: column
anchors.left: iconImg.right
anchors.leftMargin: 14
anchors.right: txtFiatBalance.left
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
StyledText {
id: accountName
text: name
elide: Text.ElideRight
anchors.right: parent.right
anchors.left: parent.left
font.pixelSize: 15
anchors.left: parent.left
anchors.right: parent.right
height: 22
}
@ -166,6 +168,7 @@ Item {
}
}
StyledText {
id: txtFiatBalance
anchors.right: fiatCurrencySymbol.left
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter

View File

@ -9,11 +9,10 @@ Item {
property string greaterThan0ErrorMessage: qsTr("Must be greater than 0")
//% "This needs to be a number"
property string invalidInputErrorMessage: qsTrId("this-needs-to-be-a-number")
//% "You need to enter an amount"
property string noInputErrorMessage: qsTrId("you-need-to-enter-an-amount")
property string noInputErrorMessage: qsTr("Please enter an amount")
property string defaultCurrency: "USD"
property string fiatBalance: "0.00"
property alias text: inputAmount.text
property alias selectedFiatAmount: txtFiatBalance.text
property alias selectedAmount: inputAmount.text
property var selectedAccount
property alias selectedAsset: selectAsset.selectedAsset
property var getFiatValue: function () {}
@ -62,7 +61,7 @@ Item {
if (!selectAsset.selectedAsset) {
return
}
txtBalance.text = selectAsset.selectedAsset.value
txtBalance.text = Utils.stripTrailingZeros(selectAsset.selectedAsset.value)
}
Item {
@ -83,7 +82,7 @@ Item {
StyledText {
id: txtBalance
property bool hovered: false
text: selectAsset.selectedAsset ? selectAsset.selectedAsset.value : "0.00"
text: selectAsset.selectedAsset ? Utils.stripTrailingZeros(selectAsset.selectedAsset.value) : "0.00"
anchors.right: parent.right
font.weight: Font.Medium
font.pixelSize: 13
@ -146,7 +145,7 @@ Item {
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
onSelectedAssetChanged: {
txtBalance.text = selectAsset.selectedAsset.value
txtBalance.text = Utils.stripTrailingZeros(selectAsset.selectedAsset.value)
if (inputAmount.text === "" || isNan(inputAmount.text)) {
return
}
@ -168,7 +167,7 @@ Item {
font.weight: Font.Medium
font.pixelSize: 12
inputMethodHints: Qt.ImhFormattedNumbersOnly
text: root.fiatBalance
text: "0.00"
selectByMouse: true
background: Rectangle {
color: Style.current.transparent

View File

@ -28,6 +28,7 @@ Item {
select.select.border.width = 0
validationErrorText.visible = false
}
return isValid
}
Select {

View File

@ -23,9 +23,13 @@ Item {
}
function updateGasEthValue() {
// causes error on application load without this null check
if (!inputGasPrice || !inputGasLimit) {
return
}
let ethValue = root.getGasEthValue(inputGasPrice.text, inputGasLimit.text)
let fiatValue = root.getFiatValue(ethValue, "ETH", root.defaultCurrency)
let summary = ethValue + " ETH ~" + fiatValue + " " + root.defaultCurrency.toUpperCase()
let summary = Utils.stripTrailingZeros(ethValue) + " ETH ~" + fiatValue + " " + root.defaultCurrency.toUpperCase()
labelGasPriceSummary.text = summary
labelGasPriceSummaryAdvanced.text = summary
}

View File

@ -0,0 +1,32 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../imports"
Item {
id: itmFrom
property alias label: txtLabel.text
property alias value: itmValue.children
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Layout.preferredWidth: parent.width
width: parent.width
height: 52
StyledText {
id: txtLabel
font.pixelSize: 15
height: parent.height
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
verticalAlignment: Text.AlignVCenter
width: 105
}
Item {
id: itmValue
anchors.left: txtLabel.right
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
height: parent.height
}
}

View File

@ -18,6 +18,12 @@ Item {
height: (readOnly ? inpReadOnly.height : inpAddress.height) + txtLabel.height
readonly property string addressValidationError: qsTr("Invalid ethereum address")
enum Type {
Address,
Contact,
Account
}
function validate() {
let isValid = true
if (readOnly) {
@ -97,7 +103,7 @@ Item {
if (root.readOnly) {
return
}
root.selectedRecipient = { address: selectedAddress }
root.selectedRecipient = { address: selectedAddress, type: RecipientSelector.Type.Address }
}
}
@ -115,7 +121,8 @@ Item {
return
}
if(selectedContact && selectedContact.address) {
root.selectedRecipient = { name: selectedContact.name, address: selectedContact.address }
const { address, name, alias, isContact, identicon, ensVerified } = selectedContact
root.selectedRecipient = { address, name, alias, isContact, identicon, ensVerified, type: RecipientSelector.Type.Contact }
}
}
}
@ -134,7 +141,8 @@ Item {
if (root.readOnly) {
return
}
root.selectedRecipient = { address: selectedAccount.address }
const { address, name, iconColor, assets, fiatBalance } = selectedAccount
root.selectedRecipient = { address, name, iconColor, assets, fiatBalance, type: RecipientSelector.Type.Account }
}
}
AddressSourceSelector {
@ -149,21 +157,31 @@ Item {
if (root.readOnly) {
return
}
let address, name
switch (selectedSource) {
case "Address":
inpAddress.visible = true
selContact.visible = selAccount.visible = false
root.height = Qt.binding(function() { return inpAddress.height + txtLabel.height })
root.selectedRecipient = { address: inpAddress.selectedAddress, type: RecipientSelector.Type.Address }
break;
case "Contact":
selContact.visible = true
inpAddress.visible = selAccount.visible = false
root.height = Qt.binding(function() { return selContact.height + txtLabel.height })
let { alias, isContact, identicon, ensVerified } = selContact.selectedContact
address = selContact.selectedContact.address
name = selContact.selectedContact.name
root.selectedRecipient = { address, name, alias, isContact, identicon, ensVerified, type: RecipientSelector.Type.Contact }
break;
case "My account":
selAccount.visible = true
inpAddress.visible = selContact.visible = false
root.height = Qt.binding(function() { return selAccount.height + txtLabel.height })
const { iconColor, assets, fiatBalance } = selAccount.selectedAccount
address = selAccount.selectedAccount.address
name = selAccount.selectedAccount.name
root.selectedRecipient = { address, name, iconColor, assets, fiatBalance, type: RecipientSelector.Type.Account }
break;
}
}

View File

@ -7,7 +7,8 @@ import "../imports"
Item {
enum MenuAlignment {
Left,
Right
Right,
Center
}
property string label: ""
readonly property bool hasLabel: label !== ""
@ -18,9 +19,11 @@ Item {
property color bgColorHover: bgColor
property alias selectedItemView: selectedItemContainer.children
property int caretRightMargin: Style.current.padding
property int caretLeftMargin: 8
property alias select: inputRectangle
property int menuAlignment: Select.MenuAlignment.Right
property Item zeroItemsView: Item {}
property int contentWidth: inputRectangle.width - (caret.width + caretRightMargin + caretLeftMargin)
anchors.left: parent.left
anchors.right: parent.right
@ -147,7 +150,17 @@ Item {
selectMenu.close()
} else {
const rightOffset = inputRectangle.width - selectMenu.width
const offset = root.menuAlignment === Select.MenuAlignment.Left ? 0 : rightOffset
let offset = rightOffset
switch (root.menuAlignment) {
case Select.MenuAlignment.Left:
offset = 0
break
case Select.MenuAlignment.Right:
offset = rightOffset
break
case Select.MenuAlignment.Center:
offset = rightOffset / 2
}
selectMenu.popup(inputRectangle.x + offset, inputRectangle.y + inputRectangle.height + 8)
}
}

View File

@ -0,0 +1,361 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import "../imports"
Item {
id: root
property var fromAccount: ({})
property var toAccount: ({ type: "" })
property var asset: ({ name: "", symbol: "" })
property var amount: ({ value: "", fiatValue: "", currency: "" })
property string currency: "USD"
property var gas: ({ value: "", symbol: "", fiatValue: "" })
height: itmFrom.height
Column {
anchors.left: parent.left
anchors.right: parent.right
LabelValueRow {
id: itmFrom
label: qsTr("From")
value: Item {
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
StyledText {
font.pixelSize: 15
height: 22
text: root.fromAccount.name
elide: Text.ElideRight
anchors.left: parent.left
anchors.right: imgFromWallet.left
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
SVGImage {
id: imgFromWallet
sourceSize.height: 18
sourceSize.width: 18
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
source: "../app/img/walletIcon.svg"
}
ColorOverlay {
anchors.fill: imgFromWallet
source: imgFromWallet
color: fromAccount.iconColor
}
}
}
LabelValueRow {
id: itmTo
property var props: { "primaryText": "replace1", "secondaryText": "me1" }
label: qsTr("Recipient")
states: [
State {
name: "Address"
when: root.toAccount.type === RecipientSelector.Type.Address
PropertyChanges {
target: txtToPrimary
text: root.toAccount.address
elide: Text.ElideMiddle
anchors.leftMargin: 190
}
PropertyChanges {
target: txtToSecondary
width: 0
}
},
State {
name: "Contact"
when: root.toAccount.type === RecipientSelector.Type.Contact && !!root.toAccount.address
PropertyChanges {
target: metSecondary
text: root.toAccount.ensVerified ? root.toAccount.alias : root.toAccount.address
}
PropertyChanges {
target: txtToSecondary
anchors.rightMargin: Style.current.padding + idtToContact.width + 8
width: metSecondary.elidedWidth
text: metSecondary.elidedText
}
PropertyChanges {
target: idtToContact
source: root.toAccount.identicon
visible: true
}
PropertyChanges {
target: txtToPrimary
text: Utils.removeStatusEns(root.toAccount.name)
}
},
State {
name: "Account"
when: root.toAccount.type === RecipientSelector.Type.Account && !!root.toAccount.address
PropertyChanges {
target: metSecondary
text: root.toAccount.address
}
PropertyChanges {
target: txtToSecondary
anchors.rightMargin: Style.current.padding + imgToWallet.width + 8
text: metSecondary.elidedText
width: metSecondary.elidedWidth
}
PropertyChanges {
target: imgToWallet
visible: true
}
PropertyChanges {
target: ovlToWallet
visible: true
color: root.toAccount.iconColor
}
PropertyChanges {
target: txtToPrimary
text: root.toAccount.name
}
}
]
value: Item {
id: recipientRoot
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
StyledText {
id: txtToPrimary
font.pixelSize: 15
height: 22
anchors.left: parent.left
anchors.right: txtToSeparator.left
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
StyledText {
id: txtToSeparator
font.pixelSize: 15
height: 22
text: " • "
visible: txtToSecondary.visible && txtToSecondary.width > 0
color: Style.current.secondaryText
anchors.right: txtToSecondary.left
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
StyledText {
id: txtToSecondary
visible: true
font.pixelSize: 15
height: 22
color: Style.current.secondaryText
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
TextMetrics {
id: metSecondary
elideWidth: 102
elide: Text.ElideMiddle
}
SVGImage {
id: imgToWallet
visible: false
sourceSize.height: 18
sourceSize.width: 18
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
source: "../app/img/walletIcon.svg"
}
ColorOverlay {
id: ovlToWallet
anchors.fill: imgToWallet
visible: false
source: imgToWallet
}
Identicon {
id: idtToContact
visible: false
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
width: 32
height: 32
}
}
}
LabelValueRow {
id: itmAsset
label: qsTr("Asset")
value: Item {
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
StyledText {
font.pixelSize: 15
height: 22
text: (root.asset && root.asset.name) ? root.asset.name : ""
anchors.left: parent.left
anchors.right: txtAssetSymbol.left
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
StyledText {
id: txtAssetSymbol
font.pixelSize: 15
height: 22
text: (root.asset && root.asset.symbol) ? root.asset.symbol : ""
color: Style.current.secondaryText
anchors.right: imgAsset.left
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
Image {
id: imgAsset
sourceSize.height: 32
sourceSize.width: 32
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
source: "../app/img/tokens/" + ((root.asset && root.asset.symbol) ? root.asset.symbol : "ETH") + ".png"
onStatusChanged: {
if (status == Image.Error) {
source = "../app/img/tokens/0-native.png"
}
}
}
}
}
LabelValueRow {
id: itmAmount
label: qsTr("Amount")
value: Item {
id: amountRoot
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
StyledText {
font.pixelSize: 15
height: 22
text: root.amount.value ? Utils.stripTrailingZeros(root.amount.value) : ""
anchors.left: parent.left
anchors.right: txtAmountSymbol.left
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
StyledText {
id: txtAmountSymbol
font.pixelSize: 15
height: 22
text: ((root.asset && root.asset.symbol) ? root.asset.symbol : "") + " •"
color: Style.current.secondaryText
anchors.right: txtAmountFiat.left
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
StyledText {
id: txtAmountFiat
font.pixelSize: 15
height: 22
text: "~" + (root.amount.fiatValue ? root.amount.fiatValue : "0.00")
anchors.right: txtAmountCurrency.left
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
StyledText {
id: txtAmountCurrency
font.pixelSize: 15
height: 22
text: root.currency.toUpperCase()
color: Style.current.secondaryText
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
}
}
LabelValueRow {
id: itmNetworkFee
label: qsTr("Network fee")
value: Item {
id: networkFeeRoot
anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
StyledText {
font.pixelSize: 15
height: 22
text: (root.gas && root.gas.value) ? Utils.stripTrailingZeros(root.gas.value) : ""
anchors.left: parent.left
anchors.right: txtFeeSymbol.left
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
StyledText {
id: txtFeeSymbol
font.pixelSize: 15
height: 22
text: ((root.gas && root.gas.symbol) ? root.gas.symbol : "") + " •"
color: Style.current.secondaryText
anchors.right: txtFeeFiat.left
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
StyledText {
id: txtFeeFiat
font.pixelSize: 15
height: 22
text: "~" + ((root.gas && root.gas.fiatValue) ? root.gas.fiatValue : "0.00")
anchors.right: txtFeeCurrency.left
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
StyledText {
id: txtFeeCurrency
font.pixelSize: 15
height: 22
text: root.currency.toUpperCase()
color: Style.current.secondaryText
anchors.right: parent.right
anchors.rightMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
}
}
}
}