fix: from/to account not showing correctly
Fixes #1202 I had to revert the loader changes that switched from/to as it was causes quite a lot of logistical complexity. Instead of using Loaders, we are setting the type of account (account or contact), and it is being displayed appropriately. There is a very slight deviation from the design, however it is consistent with the design for other transaction previews. feat: add BalanceValidator Shows an exclamation icon next to the "from" account when the balance for the requested asset is too low. This is useful when the user starts the transaction wizard on the TransactionPreview step.
This commit is contained in:
parent
32a4afe037
commit
0a9852758d
|
@ -64,7 +64,9 @@ ModalPopup {
|
|||
id: selectRecipient
|
||||
accounts: walletModel.accounts
|
||||
contacts: profileModel.addedContacts
|
||||
label: qsTr("From")
|
||||
label: root.isRequested ?
|
||||
qsTr("From") :
|
||||
qsTr("To")
|
||||
readOnly: true
|
||||
anchors.top: separator.bottom
|
||||
anchors.topMargin: 10
|
||||
|
@ -95,21 +97,31 @@ ModalPopup {
|
|||
}
|
||||
TransactionFormGroup {
|
||||
id: group3
|
||||
headerText: root.isRequested ?
|
||||
qsTr("Preview") :
|
||||
//% "Transaction preview"
|
||||
headerText: qsTrId("transaction-preview")
|
||||
qsTrId("transaction-preview")
|
||||
footerText: root.finalButtonLabel
|
||||
|
||||
TransactionPreview {
|
||||
id: pvwTransaction
|
||||
width: stack.width
|
||||
fromAccount: selectFromAccount.selectedAccount
|
||||
toAccount: selectRecipient.selectedRecipient
|
||||
fromAccount: root.isRequested ? selectRecipient.selectedRecipient : selectFromAccount.selectedAccount
|
||||
toAccount: root.isRequested ? selectFromAccount.selectedAccount : selectRecipient.selectedRecipient
|
||||
asset: txtAmount.selectedAsset
|
||||
amount: { "value": txtAmount.selectedAmount, "fiatValue": txtAmount.selectedFiatAmount }
|
||||
currency: walletModel.defaultCurrency
|
||||
reset: function() {
|
||||
fromAccount = Qt.binding(function() { return selectFromAccount.selectedAccount })
|
||||
toAccount = Qt.binding(function() { return selectRecipient.selectedRecipient })
|
||||
fromAccount = Qt.binding(function() {
|
||||
return root.isRequested ?
|
||||
selectRecipient.selectedRecipient :
|
||||
selectFromAccount.selectedAccount
|
||||
})
|
||||
toAccount = Qt.binding(function() {
|
||||
return root.isRequested ?
|
||||
selectFromAccount.selectedAccount :
|
||||
selectRecipient.selectedRecipient
|
||||
})
|
||||
asset = Qt.binding(function() { return txtAmount.selectedAsset })
|
||||
amount = Qt.binding(function() { return { "value": txtAmount.selectedAmount, "fiatValue": txtAmount.selectedFiatAmount } })
|
||||
}
|
||||
|
|
|
@ -96,7 +96,6 @@ ModalPopup {
|
|||
AccountSelector {
|
||||
id: selectFromAccount
|
||||
accounts: walletModel.accounts
|
||||
selectedAccount: root.selectedAccount
|
||||
currency: walletModel.defaultCurrency
|
||||
width: stack.width
|
||||
//% "Choose account"
|
||||
|
@ -105,7 +104,6 @@ ModalPopup {
|
|||
minRequiredAssetBalance: parseFloat(root.selectedAmount)
|
||||
reset: function() {
|
||||
accounts = Qt.binding(function() { return walletModel.accounts })
|
||||
selectedAccount = Qt.binding(function() { return root.selectedAccount })
|
||||
showBalanceForAssetSymbol = Qt.binding(function() { return root.selectedAsset.symbol })
|
||||
minRequiredAssetBalance = Qt.binding(function() { return parseFloat(root.selectedAmount) })
|
||||
}
|
||||
|
@ -176,12 +174,12 @@ ModalPopup {
|
|||
id: gasValidator
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
selectedAccount: root.selectedAccount
|
||||
selectedAccount: selectFromAccount.selectedAccount
|
||||
selectedAmount: parseFloat(root.selectedAmount)
|
||||
selectedAsset: root.selectedAsset
|
||||
selectedGasEthValue: gasSelector.selectedGasEthValue
|
||||
reset: function() {
|
||||
selectedAccount = Qt.binding(function() { return root.selectedAccount })
|
||||
selectedAccount = Qt.binding(function() { return selectFromAccount.selectedAccount })
|
||||
selectedAmount = Qt.binding(function() { return parseFloat(root.selectedAmount) })
|
||||
selectedAsset = Qt.binding(function() { return root.selectedAsset })
|
||||
selectedGasEthValue = Qt.binding(function() { return gasSelector.selectedGasEthValue })
|
||||
|
@ -199,24 +197,23 @@ ModalPopup {
|
|||
onNextClicked: function() {
|
||||
stack.push(groupSignTx, StackView.Immediate)
|
||||
}
|
||||
isValid: groupSelectAcct.isValid && groupSelectGas.isValid && gasValidator.isValid && pvwTransaction.isValid
|
||||
isValid: groupSelectAcct.isValid && groupSelectGas.isValid && pvwTransaction.isValid
|
||||
|
||||
TransactionPreview {
|
||||
id: pvwTransaction
|
||||
width: stack.width
|
||||
fromAccount: root.selectedAccount
|
||||
fromAccount: selectFromAccount.selectedAccount
|
||||
gas: {
|
||||
"value": gasSelector.selectedGasEthValue,
|
||||
"symbol": "ETH",
|
||||
"fiatValue": gasSelector.selectedGasFiatValue
|
||||
}
|
||||
toAccount: root.selectedRecipient
|
||||
toAccount: selectRecipient.selectedRecipient
|
||||
asset: root.selectedAsset
|
||||
amount: { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount }
|
||||
currency: walletModel.defaultCurrency
|
||||
outgoing: root.outgoing
|
||||
reset: function() {
|
||||
fromAccount = Qt.binding(function() { return root.selectedAccount })
|
||||
fromAccount = Qt.binding(function() { return selectFromAccount.selectedAccount })
|
||||
gas = Qt.binding(function() {
|
||||
return {
|
||||
"value": gasSelector.selectedGasEthValue,
|
||||
|
@ -224,7 +221,7 @@ ModalPopup {
|
|||
"fiatValue": gasSelector.selectedGasFiatValue
|
||||
}
|
||||
})
|
||||
toAccount = Qt.binding(function() { return root.selectedRecipient })
|
||||
toAccount = Qt.binding(function() { return selectRecipient.selectedRecipient })
|
||||
asset = Qt.binding(function() { return root.selectedAsset })
|
||||
amount = Qt.binding(function() { return { "value": root.selectedAmount, "fiatValue": root.selectedFiatAmount } })
|
||||
}
|
||||
|
@ -237,12 +234,12 @@ ModalPopup {
|
|||
id: gasValidator2
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 8
|
||||
selectedAccount: root.selectedAccount
|
||||
selectedAccount: selectFromAccount.selectedAccount
|
||||
selectedAmount: parseFloat(root.selectedAmount)
|
||||
selectedAsset: root.selectedAsset
|
||||
selectedGasEthValue: gasSelector.selectedGasEthValue
|
||||
reset: function() {
|
||||
selectedAccount = Qt.binding(function() { return root.selectedAccount })
|
||||
selectedAccount = Qt.binding(function() { return selectFromAccount.selectedAccount })
|
||||
selectedAmount = Qt.binding(function() { return parseFloat(root.selectedAmount) })
|
||||
selectedAsset = Qt.binding(function() { return root.selectedAsset })
|
||||
selectedGasEthValue = Qt.binding(function() { return gasSelector.selectedGasEthValue })
|
||||
|
|
|
@ -39,8 +39,8 @@ Item {
|
|||
switch (root.state) {
|
||||
case Constants.pending:
|
||||
case Constants.confirmed:
|
||||
case Constants.addressRequested: return isCurrentUser
|
||||
case Constants.transactionRequested:
|
||||
case Constants.addressRequested: return isCurrentUser
|
||||
case Constants.declined:
|
||||
case Constants.transactionDeclined:
|
||||
case Constants.addressReceived: return !isCurrentUser
|
||||
|
@ -82,7 +82,7 @@ Item {
|
|||
color: Style.current.secondaryText
|
||||
text: {
|
||||
if (root.state === Constants.transactionRequested) {
|
||||
let prefix = root.outgoing ? "↑ " : "↓ "
|
||||
let prefix = root.outgoing ? "↓ ": "↑ "
|
||||
return prefix + qsTr("Transaction request")
|
||||
}
|
||||
return root.outgoing ?
|
||||
|
@ -176,7 +176,7 @@ Item {
|
|||
active: !root.isError && (
|
||||
(root.state === Constants.addressRequested && !root.outgoing) ||
|
||||
(root.state === Constants.addressReceived && root.outgoing) ||
|
||||
(root.state === Constants.transactionRequested && root.outgoing)
|
||||
(root.state === Constants.transactionRequested && !root.outgoing)
|
||||
)
|
||||
sourceComponent: root.outgoing ? signAndSendComponent : acceptTransactionComponent
|
||||
anchors.top: bubbleLoader.active ? bubbleLoader.bottom : valueContainer.bottom
|
||||
|
|
|
@ -7,7 +7,6 @@ Item {
|
|||
id: root
|
||||
width: parent.width
|
||||
height: childrenRect.height + Style.current.halfPadding
|
||||
// property bool outgoing: true
|
||||
|
||||
Separator {
|
||||
id: separator
|
||||
|
@ -48,7 +47,6 @@ Item {
|
|||
onOpened: {
|
||||
walletModel.getGasPricePredictions()
|
||||
}
|
||||
selectedAccount: {}
|
||||
selectedRecipient: {
|
||||
return {
|
||||
address: commandParametersObject.address,
|
||||
|
@ -60,7 +58,6 @@ Item {
|
|||
selectedAsset: token
|
||||
selectedAmount: tokenAmount
|
||||
selectedFiatAmount: fiatValue
|
||||
outgoing: root.outgoing
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ Item {
|
|||
console.warn(qsTrId("cannot-find-asset---1---ensure-this-asset-has-been-added-to-the-token-list-").arg(showBalanceForAssetSymbol))
|
||||
}
|
||||
}
|
||||
if (!selectedAccount.type) {
|
||||
selectedAccount.type = RecipientSelector.Type.Account
|
||||
}
|
||||
validate()
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
import "../imports"
|
||||
import "./status"
|
||||
|
||||
IconButton {
|
||||
id: root
|
||||
property var account
|
||||
property double amount
|
||||
property var asset
|
||||
property bool isValid: true
|
||||
property var reset: function() {}
|
||||
clickable: false
|
||||
width: 13.33
|
||||
height: 13.33
|
||||
iconWidth: width
|
||||
iconHeight: height
|
||||
iconName: "exclamation_outline"
|
||||
color: Style.current.transparent
|
||||
visible: !isValid
|
||||
|
||||
onAccountChanged: validate()
|
||||
onAmountChanged: validate()
|
||||
onAssetChanged: validate()
|
||||
|
||||
function resetInternal() {
|
||||
account = undefined
|
||||
amount = 0
|
||||
asset = undefined
|
||||
isValid = true
|
||||
}
|
||||
|
||||
function validate() {
|
||||
let isValid = true
|
||||
if (!(account && account.assets && asset && amount > 0)) {
|
||||
return root.isValid
|
||||
}
|
||||
const currAcctAsset = Utils.findAssetBySymbol(account.assets, asset.symbol)
|
||||
|
||||
if (currAcctAsset && currAcctAsset.value < amount) {
|
||||
isValid = false
|
||||
}
|
||||
root.isValid = isValid
|
||||
return isValid
|
||||
}
|
||||
|
||||
StatusToolTip {
|
||||
id: tooltip
|
||||
visible: parent.hovered
|
||||
width: 100
|
||||
text: qsTr("Insufficient balance")
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ RoundButton {
|
|||
icon.width: iconWidth
|
||||
icon.height: iconHeight
|
||||
|
||||
id: btnAddContainer
|
||||
id: root
|
||||
width: 36
|
||||
height: 36
|
||||
radius: width / 2
|
||||
|
@ -29,8 +29,10 @@ RoundButton {
|
|||
id: imgIcon
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "../app/img/" + parent.iconName + ".svg"
|
||||
width: btnAddContainer.iconWidth
|
||||
height: btnAddContainer.iconHeight
|
||||
width: root.iconWidth
|
||||
height: root.iconHeight
|
||||
sourceSize.height: height * 2
|
||||
sourceSize.width: width * 2
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
|
@ -76,14 +78,14 @@ RoundButton {
|
|||
}
|
||||
|
||||
onClicked: {
|
||||
if (btnAddContainer.clickable) {
|
||||
if (root.clickable) {
|
||||
imgIcon.state = "rotated"
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
visible: btnAddContainer.clickable
|
||||
visible: root.clickable
|
||||
anchors.fill: parent
|
||||
onPressed: mouse.accepted = false
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
|
|
@ -23,8 +23,7 @@ Item {
|
|||
// Creates a mouse area around the "network fee". When clicked, triggers
|
||||
// the "gasClicked" signal
|
||||
property bool isGasEditable: false
|
||||
property bool isValid: true
|
||||
property bool outgoing: true
|
||||
property alias isValid: balanceValidator.isValid
|
||||
|
||||
function resetInternal() {
|
||||
fromAccount = undefined
|
||||
|
@ -32,38 +31,14 @@ Item {
|
|||
asset = undefined
|
||||
amount = undefined
|
||||
gas = undefined
|
||||
isValid = true
|
||||
balanceValidator.resetInternal()
|
||||
balanceValidator.reset()
|
||||
}
|
||||
|
||||
function validate() {
|
||||
let isValid = true
|
||||
imgInsufficientBalance.visible = false
|
||||
console.log(">>> [TransactionPreview.validate] outgoing:", outgoing)
|
||||
if (outgoing && hasInsufficientBalance()) {
|
||||
isValid = false
|
||||
imgInsufficientBalance.visible = true
|
||||
}
|
||||
root.isValid = isValid
|
||||
return isValid
|
||||
}
|
||||
|
||||
function hasInsufficientBalance() {
|
||||
if (!root.asset || !root.fromAccount || !root.fromAccount.assets || !root.amount) {
|
||||
return true
|
||||
}
|
||||
const currAcctAsset = Utils.findAssetBySymbol(root.fromAccount.assets, root.asset.symbol)
|
||||
if (!currAcctAsset) return true
|
||||
return currAcctAsset.value < root.amount.value
|
||||
}
|
||||
|
||||
onAssetChanged: validate()
|
||||
onFromAccountChanged: validate()
|
||||
|
||||
Column {
|
||||
id: content
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
LabelValueRow {
|
||||
id: itmFrom
|
||||
//% "From"
|
||||
|
@ -71,9 +46,8 @@ Item {
|
|||
value: Item {
|
||||
id: itmFromValue
|
||||
anchors.fill: parent
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
function needsRightPadding() {
|
||||
return imgInsufficientBalance.visible || fromArrow.visible
|
||||
return !balanceValidator.isValid || fromArrow.visible
|
||||
}
|
||||
Row {
|
||||
spacing: Style.current.halfPadding
|
||||
|
@ -94,24 +68,30 @@ Item {
|
|||
id: imgFromWallet
|
||||
sourceSize.height: 18
|
||||
sourceSize.width: 18
|
||||
visible: !!root.fromAccount ? root.fromAccount.type === RecipientSelector.Type.Account : true
|
||||
horizontalAlignment: Image.AlignLeft
|
||||
width: itmFromValue.needsRightPadding() ? (Style.current.halfPadding + sourceSize.width) : undefined // adding width to add addl spacing to image
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "../app/img/walletIcon.svg"
|
||||
ColorOverlay {
|
||||
visible: parent.visible
|
||||
anchors.fill: parent
|
||||
source: parent
|
||||
color: root.fromAccount ? root.fromAccount.iconColor : Style.current.blue
|
||||
color: root.fromAccount && root.fromAccount.iconColor ? root.fromAccount.iconColor : Style.current.blue
|
||||
}
|
||||
}
|
||||
SVGImage {
|
||||
id: imgInsufficientBalance
|
||||
width: 13
|
||||
visible: false
|
||||
BalanceValidator {
|
||||
id: balanceValidator
|
||||
account: root.fromAccount
|
||||
amount: !!(root.amount && root.amount.value) ? parseFloat(root.amount.value) : 0.0
|
||||
asset: root.asset
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "../app/img/exclamation_outline.svg"
|
||||
reset: function() {
|
||||
account = Qt.binding(function() { return root.fromAccount })
|
||||
amount = Qt.binding(function() { return !!(root.amount && root.amount.value) ? parseFloat(root.amount.value) : 0.0 })
|
||||
asset = Qt.binding(function() { return root.asset })
|
||||
}
|
||||
}
|
||||
SVGImage {
|
||||
id: fromArrow
|
||||
|
@ -210,10 +190,6 @@ Item {
|
|||
}
|
||||
}
|
||||
]
|
||||
value: Item {
|
||||
id: recipientRoot
|
||||
anchors.fill: parent
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
StyledText {
|
||||
id: txtToPrimary
|
||||
|
@ -279,7 +255,6 @@ Item {
|
|||
height: 32
|
||||
}
|
||||
}
|
||||
}
|
||||
LabelValueRow {
|
||||
id: itmAsset
|
||||
//% "Asset"
|
||||
|
|
Loading…
Reference in New Issue