feat: move validators outside of TransactionPreview

BalanceValidator and GasValidator have been moved outside of the TransactionPreview component, because there are some transaction modals that may not need them to be baked in to TransactionPreview. It is useful to have these components on the tx preview step only when we start the process on the preview step.
This commit is contained in:
emizzle 2020-10-22 23:06:35 +11:00 committed by Pascal Precht
parent c6d3d47982
commit bc0855bcdc
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
4 changed files with 155 additions and 128 deletions

View File

@ -212,6 +212,10 @@ ModalPopup {
asset: root.selectedAsset asset: root.selectedAsset
amount: { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount } amount: { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount }
currency: walletModel.defaultCurrency currency: walletModel.defaultCurrency
isFromEditable: true
isGasEditable: true
fromValid: balanceValidator.isValid
gasValid: gasValidator.isValid
reset: function() { reset: function() {
fromAccount = Qt.binding(function() { return selectFromAccount.selectedAccount }) fromAccount = Qt.binding(function() { return selectFromAccount.selectedAccount })
gas = Qt.binding(function() { gas = Qt.binding(function() {
@ -224,16 +228,30 @@ ModalPopup {
toAccount = Qt.binding(function() { return selectRecipient.selectedRecipient }) toAccount = Qt.binding(function() { return selectRecipient.selectedRecipient })
asset = Qt.binding(function() { return root.selectedAsset }) asset = Qt.binding(function() { return root.selectedAsset })
amount = Qt.binding(function() { return { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount } }) amount = Qt.binding(function() { return { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount } })
fromValid = Qt.binding(function() { return balanceValidator.isValid })
gasValid = Qt.binding(function() { return gasValidator.isValid })
} }
isFromEditable: true
isGasEditable: true
onFromClicked: { stack.push(groupSelectAcct, StackView.Immediate) } onFromClicked: { stack.push(groupSelectAcct, StackView.Immediate) }
onGasClicked: { stack.push(groupSelectGas, StackView.Immediate) } onGasClicked: { stack.push(groupSelectGas, StackView.Immediate) }
} }
BalanceValidator {
id: balanceValidator
anchors.top: pvwTransaction.bottom
anchors.horizontalCenter: parent.horizontalCenter
account: selectFromAccount.selectedAccount
amount: !!root.selectedAmount ? parseFloat(root.selectedAmount) : 0.0
asset: root.selectedAsset
reset: function() {
account = Qt.binding(function() { return selectFromAccount.selectedAccount })
amount = Qt.binding(function() { return !!root.selectedAmount ? parseFloat(root.selectedAmount) : 0.0 })
asset = Qt.binding(function() { return root.selectedAsset })
}
}
GasValidator { GasValidator {
id: gasValidator2 id: gasValidator2
anchors.bottom: parent.bottom anchors.top: balanceValidator.visible ? balanceValidator.bottom : pvwTransaction.bottom
anchors.bottomMargin: 8 anchors.topMargin: balanceValidator.visible ? 5 : 0
anchors.horizontalCenter: parent.horizontalCenter
selectedAccount: selectFromAccount.selectedAccount selectedAccount: selectFromAccount.selectedAccount
selectedAmount: parseFloat(root.selectedAmount) selectedAmount: parseFloat(root.selectedAmount)
selectedAsset: root.selectedAsset selectedAsset: root.selectedAsset

View File

@ -4,21 +4,18 @@ import QtQuick.Layouts 1.13
import "../imports" import "../imports"
import "./status" import "./status"
IconButton { Column {
id: root id: root
anchors.horizontalCenter: parent.horizontalCenter
visible: !isValid
spacing: 5
property var account property var account
property double amount property double amount
property var asset property var asset
property bool isValid: true property bool isValid: false
property var reset: function() {} property var reset: function() {}
clickable: false property alias errorMessage: txtValidationError.text
width: 13.33
height: 13.33
iconWidth: width
iconHeight: height
iconName: "exclamation_outline"
color: Style.current.transparent
visible: !isValid
onAccountChanged: validate() onAccountChanged: validate()
onAmountChanged: validate() onAmountChanged: validate()
@ -28,7 +25,7 @@ IconButton {
account = undefined account = undefined
amount = 0 amount = 0
asset = undefined asset = undefined
isValid = true isValid = false
} }
function validate() { function validate() {
@ -44,11 +41,23 @@ IconButton {
root.isValid = isValid root.isValid = isValid
return isValid return isValid
} }
SVGImage {
StatusToolTip { id: imgExclamation
id: tooltip width: 13.33
visible: parent.hovered height: 13.33
width: 100 sourceSize.height: height * 2
sourceSize.width: width * 2
anchors.horizontalCenter: parent.horizontalCenter
fillMode: Image.PreserveAspectFit
source: "../app/img/exclamation_outline.svg"
}
StyledText {
id: txtValidationError
text: qsTr("Insufficient balance") text: qsTr("Insufficient balance")
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 13
height: 18
color: Style.current.danger
} }
} }

View File

@ -2,15 +2,15 @@ import QtQuick 2.13
import QtQuick.Controls 2.13 import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import "../imports" import "../imports"
import "./" import "./status"
Item { Column {
id: root id: root
anchors.left: parent.left anchors.horizontalCenter: parent.horizontalCenter
anchors.right: parent.right visible: !isValid
height: colValidation.height spacing: 5
//% "Not enough ETH for gas"
property string notEnoughEthForGasMessage: qsTrId("wallet-insufficient-gas") property alias errorMessage: txtValidationError.text
property var selectedAccount property var selectedAccount
property double selectedAmount property double selectedAmount
property var selectedAsset property var selectedAsset
@ -28,7 +28,7 @@ Item {
selectedAmount = 0 selectedAmount = 0
selectedAsset = undefined selectedAsset = undefined
selectedGasEthValue = 0 selectedGasEthValue = 0
isValid = true isValid = false
} }
function validate() { function validate() {
@ -36,7 +36,7 @@ Item {
if (!(selectedAccount && selectedAccount.assets && selectedAsset && selectedGasEthValue > 0)) { if (!(selectedAccount && selectedAccount.assets && selectedAsset && selectedGasEthValue > 0)) {
return root.isValid return root.isValid
} }
txtValidationError.text = "" isValid = true
let gasTotal = selectedGasEthValue let gasTotal = selectedGasEthValue
if (selectedAsset && selectedAsset.symbol && selectedAsset.symbol.toUpperCase() === "ETH") { if (selectedAsset && selectedAsset.symbol && selectedAsset.symbol.toUpperCase() === "ETH") {
gasTotal += selectedAmount gasTotal += selectedAmount
@ -44,36 +44,28 @@ Item {
const currAcctGasAsset = Utils.findAssetBySymbol(selectedAccount.assets, "ETH") const currAcctGasAsset = Utils.findAssetBySymbol(selectedAccount.assets, "ETH")
if (currAcctGasAsset && currAcctGasAsset.value < gasTotal) { if (currAcctGasAsset && currAcctGasAsset.value < gasTotal) {
isValid = false isValid = false
txtValidationError.text = notEnoughEthForGasMessage
} }
root.isValid = isValid root.isValid = isValid
return isValid return isValid
} }
SVGImage {
Column { id: imgExclamation
id: colValidation width: 13.33
height: 13.33
sourceSize.height: height * 2
sourceSize.width: width * 2
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: txtValidationError.text !== "" fillMode: Image.PreserveAspectFit
spacing: 5 source: "../app/img/exclamation_outline.svg"
}
SVGImage { StyledText {
id: imgExclamation id: txtValidationError
width: 13.33 //% "Not enough ETH for gas"
height: 13.33 text: qsTrId("wallet-insufficient-gas")
sourceSize.height: height * 2 verticalAlignment: Text.AlignVCenter
sourceSize.width: width * 2 horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter font.pixelSize: 13
fillMode: Image.PreserveAspectFit height: 18
source: "../app/img/exclamation_outline.svg" color: Style.current.danger
}
StyledText {
id: txtValidationError
text: ""
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 13
height: 18
color: Style.current.danger
}
} }
} }

View File

@ -23,7 +23,9 @@ Item {
// Creates a mouse area around the "network fee". When clicked, triggers // Creates a mouse area around the "network fee". When clicked, triggers
// the "gasClicked" signal // the "gasClicked" signal
property bool isGasEditable: false property bool isGasEditable: false
property alias isValid: balanceValidator.isValid property bool isValid: fromValid && gasValid
property bool fromValid: true
property bool gasValid: true
function resetInternal() { function resetInternal() {
fromAccount = undefined fromAccount = undefined
@ -31,8 +33,6 @@ Item {
asset = undefined asset = undefined
amount = undefined amount = undefined
gas = undefined gas = undefined
balanceValidator.resetInternal()
balanceValidator.reset()
} }
Column { Column {
@ -46,8 +46,9 @@ Item {
value: Item { value: Item {
id: itmFromValue id: itmFromValue
anchors.fill: parent anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter
function needsRightPadding() { function needsRightPadding() {
return !balanceValidator.isValid || fromArrow.visible return !root.fromValid || root.isFromEditable
} }
Row { Row {
spacing: Style.current.halfPadding spacing: Style.current.halfPadding
@ -81,17 +82,16 @@ Item {
color: root.fromAccount && root.fromAccount.iconColor ? root.fromAccount.iconColor : Style.current.blue color: root.fromAccount && root.fromAccount.iconColor ? root.fromAccount.iconColor : Style.current.blue
} }
} }
BalanceValidator { SVGImage {
id: balanceValidator id: fromInvalid
account: root.fromAccount
amount: !!(root.amount && root.amount.value) ? parseFloat(root.amount.value) : 0.0
asset: root.asset
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
reset: function() { width: 13.33
account = Qt.binding(function() { return root.fromAccount }) height: 13.33
amount = Qt.binding(function() { return !!(root.amount && root.amount.value) ? parseFloat(root.amount.value) : 0.0 }) sourceSize.height: height * 2
asset = Qt.binding(function() { return root.asset }) sourceSize.width: width * 2
} fillMode: Image.PreserveAspectFit
source: "../app/img/exclamation_outline.svg"
visible: !root.fromValid
} }
SVGImage { SVGImage {
id: fromArrow id: fromArrow
@ -370,69 +370,77 @@ Item {
id: networkFeeRoot id: networkFeeRoot
anchors.fill: parent anchors.fill: parent
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
function needsRightPadding() {
StyledText { return !root.gasValid || root.isGasEditable
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 { Row {
id: txtFeeSymbol spacing: Style.current.halfPadding
font.pixelSize: 15 rightPadding: networkFeeRoot.needsRightPadding() ? Style.current.halfPadding : 0
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: gasArrow.visible ? gasArrow.left : parent.right
anchors.rightMargin: gasArrow.visible ? Style.current.padding : 0
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
SVGImage {
id: gasArrow
width: 13
visible: root.isGasEditable
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 7
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit StyledText {
source: "../app/img/caret.svg" font.pixelSize: 15
rotation: 270 height: 22
ColorOverlay { text: (root.gas && root.gas.value) ? Utils.stripTrailingZeros(root.gas.value) : ""
anchors.fill: parent anchors.verticalCenter: parent.verticalCenter
visible: parent.visible horizontalAlignment: Text.AlignRight
source: parent 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 color: Style.current.secondaryText
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.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.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
SVGImage {
id: gasInvalid
anchors.verticalCenter: parent.verticalCenter
width: 13.33
height: 13.33
sourceSize.height: height * 2
sourceSize.width: width * 2
fillMode: Image.PreserveAspectFit
source: "../app/img/exclamation_outline.svg"
visible: !root.gasValid
}
SVGImage {
id: gasArrow
width: 13
visible: root.isGasEditable
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
source: "../app/img/caret.svg"
rotation: 270
ColorOverlay {
anchors.fill: parent
visible: parent.visible
source: parent
color: Style.current.secondaryText
}
} }
} }
MouseArea { MouseArea {