feat: Send transaction componets -- Asset selector
Selects an asset to be used in the send transaction dialog.
This commit is contained in:
parent
3cb88d0cfa
commit
82022f655c
|
@ -34,12 +34,24 @@ Item {
|
||||||
}
|
}
|
||||||
Select {
|
Select {
|
||||||
id: select
|
id: select
|
||||||
selectedText: languageSetting.currentLocale
|
|
||||||
anchors.right: undefined
|
anchors.right: undefined
|
||||||
anchors.left: undefined
|
anchors.left: undefined
|
||||||
width: 100
|
width: 100
|
||||||
Layout.leftMargin: Style.current.padding
|
Layout.leftMargin: Style.current.padding
|
||||||
model: Locales_JSON.locales
|
model: Locales_JSON.locales
|
||||||
|
selectedItemView: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
StyledText {
|
||||||
|
id: selectedTextField
|
||||||
|
text: languageSetting.currentLocale
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: 15
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
height: 22
|
||||||
|
}
|
||||||
|
}
|
||||||
menu.delegate: Component {
|
menu.delegate: Component {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
id: menuItem
|
id: menuItem
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.13
|
||||||
//import QtQuick.Layouts 1.13
|
|
||||||
//import Qt.labs.platform 1.1
|
|
||||||
import "../../../imports"
|
import "../../../imports"
|
||||||
import "../../../shared"
|
import "../../../shared"
|
||||||
import "./components"
|
import "./components"
|
||||||
|
@ -17,19 +15,6 @@ ModalPopup {
|
||||||
sendModalContent.amountInput.text = ""
|
sendModalContent.amountInput.text = ""
|
||||||
sendModalContent.passwordInput.text = ""
|
sendModalContent.passwordInput.text = ""
|
||||||
sendModalContent.amountInput.forceActiveFocus(Qt.MouseFocusReason)
|
sendModalContent.amountInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||||
|
|
||||||
const assets = walletModel.assets
|
|
||||||
const numAssets = assets.rowCount()
|
|
||||||
const assetsData = []
|
|
||||||
for (let f = 0; f < numAssets; f++) {
|
|
||||||
assetsData.push({
|
|
||||||
name: assets.rowData(f, 'name'),
|
|
||||||
symbol: assets.rowData(f, 'symbol'),
|
|
||||||
value: assets.rowData(f, 'value'),
|
|
||||||
address: assets.rowData(f, 'address')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
sendModalContent.assets = assetsData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SendModalContent {
|
SendModalContent {
|
||||||
|
|
|
@ -9,13 +9,6 @@ Item {
|
||||||
property var closePopup: function(){}
|
property var closePopup: function(){}
|
||||||
property alias amountInput: txtAmount
|
property alias amountInput: txtAmount
|
||||||
property alias passwordInput: txtPassword
|
property alias passwordInput: txtPassword
|
||||||
property var assets: []
|
|
||||||
|
|
||||||
property int selectedAssetIndex: 0
|
|
||||||
property string selectedAssetName: assets && assets.length ? assets[selectedAssetIndex].name : ""
|
|
||||||
property string selectedAssetAddress: assets && assets.length ? assets[selectedAssetIndex].address : ""
|
|
||||||
property string selectedAssetSymbol: assets && assets.length ? assets[selectedAssetIndex].symbol : ""
|
|
||||||
property string selectedAccountValue: assets && assets.length ? assets[selectedAssetIndex].value : ""
|
|
||||||
|
|
||||||
property string passwordValidationError: ""
|
property string passwordValidationError: ""
|
||||||
property string toValidationError: ""
|
property string toValidationError: ""
|
||||||
|
@ -27,7 +20,7 @@ Item {
|
||||||
}
|
}
|
||||||
let result = walletModel.onSendTransaction(selectFromAccount.selectedAccount.address,
|
let result = walletModel.onSendTransaction(selectFromAccount.selectedAccount.address,
|
||||||
txtTo.text,
|
txtTo.text,
|
||||||
selectedAssetAddress,
|
selectAsset.selectedAsset.address,
|
||||||
txtAmount.text,
|
txtAmount.text,
|
||||||
txtPassword.text)
|
txtPassword.text)
|
||||||
|
|
||||||
|
@ -68,7 +61,7 @@ Item {
|
||||||
} else if (isNaN(txtAmount.text)) {
|
} else if (isNaN(txtAmount.text)) {
|
||||||
//% "This needs to be a number"
|
//% "This needs to be a number"
|
||||||
amountValidationError = qsTrId("this-needs-to-be-a-number")
|
amountValidationError = qsTrId("this-needs-to-be-a-number")
|
||||||
} else if (parseFloat(txtAmount.text) > parseFloat(selectedAccountValue)) {
|
} else if (parseFloat(txtAmount.text) > parseFloat(selectAsset.selectedAsset.Value)) {
|
||||||
//% "Amount needs to be lower than your balance (%1)"
|
//% "Amount needs to be lower than your balance (%1)"
|
||||||
amountValidationError = qsTrId("amount-needs-to-be-lower-than-your-balance-(%1)").arg(selectedAccountValue)
|
amountValidationError = qsTrId("amount-needs-to-be-lower-than-your-balance-(%1)").arg(selectedAccountValue)
|
||||||
} else {
|
} else {
|
||||||
|
@ -108,57 +101,20 @@ Item {
|
||||||
validationError: amountValidationError
|
validationError: amountValidationError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssetSelector {
|
||||||
Select {
|
id: selectAsset
|
||||||
id: assetTypeSelect
|
assets: walletModel.assets
|
||||||
iconHeight: 24
|
|
||||||
iconWidth: 24
|
|
||||||
icon: selectedAssetSymbol ? "../../../img/tokens/" + selectedAssetSymbol.toUpperCase() + ".png" : ""
|
|
||||||
//% "Select the asset"
|
|
||||||
label: qsTrId("select-the-asset")
|
|
||||||
anchors.top: txtAmount.bottom
|
anchors.top: txtAmount.bottom
|
||||||
anchors.topMargin: Style.current.padding
|
anchors.topMargin: Style.current.padding
|
||||||
selectedText: selectedAssetName
|
anchors.right: parent.right
|
||||||
model: sendModalContent.assets
|
width: 86
|
||||||
menu.delegate: Component {
|
height: 28
|
||||||
MenuItem {
|
|
||||||
|
|
||||||
height: itemText.height + 4
|
|
||||||
width: parent ? parent.width : selectMenu.width
|
|
||||||
padding: 10
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: itemText
|
|
||||||
text: sendModalContent.assets[index].name
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 5
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
onTriggered: function () {
|
|
||||||
selectedAssetIndex = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: currentBalanceText
|
|
||||||
//% "Balance: %1"
|
|
||||||
text: qsTrId("balance:-%1").arg(selectedAccountValue)
|
|
||||||
font.pixelSize: 13
|
|
||||||
color: Style.current.darkGrey
|
|
||||||
anchors.top: assetTypeSelect.top
|
|
||||||
anchors.topMargin: 0
|
|
||||||
anchors.right: assetTypeSelect.right
|
|
||||||
anchors.rightMargin: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AccountSelector {
|
AccountSelector {
|
||||||
id: selectFromAccount
|
id: selectFromAccount
|
||||||
accounts: walletModel.accounts
|
accounts: walletModel.accounts
|
||||||
anchors.top: assetTypeSelect.bottom
|
anchors.top: selectAsset.bottom
|
||||||
anchors.topMargin: Style.current.padding
|
anchors.topMargin: Style.current.padding
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
|
@ -33,10 +33,7 @@ Item {
|
||||||
}
|
}
|
||||||
Select {
|
Select {
|
||||||
id: select
|
id: select
|
||||||
icon: "../app/img/walletIcon.svg"
|
|
||||||
iconColor: selectedAccount.iconColor || Style.current.blue
|
|
||||||
label: root.label
|
label: root.label
|
||||||
selectedText: selectedAccount.name
|
|
||||||
model: root.accounts
|
model: root.accounts
|
||||||
|
|
||||||
menu.delegate: menuItem
|
menu.delegate: menuItem
|
||||||
|
@ -46,6 +43,36 @@ Item {
|
||||||
menu.onClosed: {
|
menu.onClosed: {
|
||||||
selectedAccountDetails.visible = true
|
selectedAccountDetails.visible = true
|
||||||
}
|
}
|
||||||
|
selectedItemView: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
SVGImage {
|
||||||
|
id: selectedIconImg
|
||||||
|
sourceSize.height: 12
|
||||||
|
sourceSize.width: 12
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: "../app/img/walletIcon.svg"
|
||||||
|
}
|
||||||
|
ColorOverlay {
|
||||||
|
anchors.fill: selectedIconImg
|
||||||
|
source: selectedIconImg
|
||||||
|
color: selectedAccount.iconColor
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: selectedTextField
|
||||||
|
text: selectedAccount.name
|
||||||
|
anchors.left: selectedIconImg.right
|
||||||
|
anchors.leftMargin: 8
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: 15
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
height: 22
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
@ -98,12 +125,12 @@ Item {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: Style.current.padding
|
anchors.leftMargin: Style.current.padding
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: select.iconWidth
|
width: 12
|
||||||
height: select.iconHeight
|
height: 12
|
||||||
sourceSize.height: select.iconHeight
|
sourceSize.height: height
|
||||||
sourceSize.width: select.iconWidth
|
sourceSize.width: width
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: select.icon
|
source: "../app/img/walletIcon.svg"
|
||||||
}
|
}
|
||||||
ColorOverlay {
|
ColorOverlay {
|
||||||
anchors.fill: iconImg
|
anchors.fill: iconImg
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
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 assets
|
||||||
|
property var selectedAsset: {
|
||||||
|
"symbol": "snt", "name": "", "value": "", "fiatValue": "", "address": ""
|
||||||
|
}
|
||||||
|
width: 86
|
||||||
|
height: 24
|
||||||
|
|
||||||
|
Select {
|
||||||
|
id: select
|
||||||
|
model: root.assets
|
||||||
|
width: parent.width
|
||||||
|
bgColor: Style.current.transparent
|
||||||
|
bgColorHover: Style.current.secondaryHover
|
||||||
|
|
||||||
|
caretRightMargin: 7
|
||||||
|
select.radius: 6
|
||||||
|
select.height: root.height
|
||||||
|
menu.width: 343
|
||||||
|
selectedItemView: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
SVGImage {
|
||||||
|
id: iconImg
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 4
|
||||||
|
sourceSize.height: 24
|
||||||
|
sourceSize.width: 24
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: "../app/img/tokens/" + selectedAsset.symbol.toUpperCase() + ".png"
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: selectedTextField
|
||||||
|
text: selectedAsset.symbol.toUpperCase()
|
||||||
|
anchors.left: iconImg.right
|
||||||
|
anchors.leftMargin: 4
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.pixelSize: 15
|
||||||
|
height: 22
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.delegate: menuItem
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: menuItem
|
||||||
|
MenuItem {
|
||||||
|
id: itemContainer
|
||||||
|
property bool isFirstItem: index === 0
|
||||||
|
property bool isLastItem: index === assets.rowCount() - 1
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (root.selectedAsset.name === "") {
|
||||||
|
root.selectedAsset = { address, name, value, symbol, fiatValue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
height: 72
|
||||||
|
SVGImage {
|
||||||
|
id: iconImg
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
sourceSize.height: height
|
||||||
|
sourceSize.width: width
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: "../app/img/tokens/" + symbol.toUpperCase() + ".png"
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
anchors.left: iconImg.right
|
||||||
|
anchors.leftMargin: 12
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: symbol.toUpperCase()
|
||||||
|
font.pixelSize: 15
|
||||||
|
height: 22
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: name
|
||||||
|
color: Style.current.secondaryText
|
||||||
|
font.pixelSize: 15
|
||||||
|
height: 22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
StyledText {
|
||||||
|
font.pixelSize: 15
|
||||||
|
height: 22
|
||||||
|
text: parseFloat(value).toFixed(4) + " " + symbol
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
font.pixelSize: 15
|
||||||
|
anchors.right: parent.right
|
||||||
|
height: 22
|
||||||
|
text: fiatValue.toUpperCase()
|
||||||
|
color: Style.current.secondaryText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
background: Rectangle {
|
||||||
|
color: itemContainer.highlighted ? Style.current.backgroundHover : Style.current.background
|
||||||
|
radius: Style.current.radius
|
||||||
|
|
||||||
|
// cover bottom left/right corners with square corners
|
||||||
|
Rectangle {
|
||||||
|
visible: !isLastItem
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: parent.radius
|
||||||
|
color: parent.color
|
||||||
|
}
|
||||||
|
|
||||||
|
// cover top left/right corners with square corners
|
||||||
|
Rectangle {
|
||||||
|
visible: !isFirstItem
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
height: parent.radius
|
||||||
|
color: parent.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: itemContainer
|
||||||
|
onClicked: {
|
||||||
|
root.selectedAsset = { address, name, value, symbol, fiatValue }
|
||||||
|
select.menu.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*##^##
|
||||||
|
Designer {
|
||||||
|
D{i:0;autoSize:true;height:480;width:640}
|
||||||
|
}
|
||||||
|
##^##*/
|
|
@ -10,23 +10,20 @@ Item {
|
||||||
property color bgColor: Style.current.inputBackground
|
property color bgColor: Style.current.inputBackground
|
||||||
readonly property int labelMargin: 7
|
readonly property int labelMargin: 7
|
||||||
property var model
|
property var model
|
||||||
property int customHeight: 56
|
|
||||||
property string selectedText: ""
|
|
||||||
property url icon: ""
|
|
||||||
property int iconHeight: 12
|
|
||||||
property int iconWidth: 12
|
|
||||||
property color iconColor: Style.current.transparent
|
|
||||||
property alias menu: selectMenu
|
property alias menu: selectMenu
|
||||||
|
property color bgColorHover: bgColor
|
||||||
readonly property bool hasIcon: icon.toString() !== ""
|
property alias selectedItemView: selectedItemContainer.children
|
||||||
|
property int caretRightMargin: Style.current.padding
|
||||||
|
property alias select: inputRectangle
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
id: root
|
id: root
|
||||||
height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0)
|
height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0)
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.left: parent.left
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: inputLabel
|
id: inputLabel
|
||||||
|
visible: hasLabel
|
||||||
text: root.label
|
text: root.label
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
@ -38,41 +35,19 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
property bool hovered: false
|
||||||
id: inputRectangle
|
id: inputRectangle
|
||||||
height: customHeight
|
height: 56
|
||||||
color: bgColor
|
color: hovered ? bgColorHover : bgColor
|
||||||
radius: Style.current.radius
|
radius: Style.current.radius
|
||||||
anchors.top: root.hasLabel ? inputLabel.bottom : parent.top
|
anchors.top: root.hasLabel ? inputLabel.bottom : parent.top
|
||||||
anchors.topMargin: root.hasLabel ? root.labelMargin : 0
|
anchors.topMargin: root.hasLabel ? root.labelMargin : 0
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
||||||
SVGImage {
|
Item {
|
||||||
id: iconImg
|
id: selectedItemContainer
|
||||||
visible: root.hasIcon
|
anchors.fill: parent
|
||||||
sourceSize.height: iconHeight
|
|
||||||
sourceSize.width: iconWidth
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Style.current.padding
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
source: root.icon
|
|
||||||
}
|
|
||||||
ColorOverlay {
|
|
||||||
anchors.fill: iconImg
|
|
||||||
source: iconImg
|
|
||||||
color: iconColor
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: selectedTextField
|
|
||||||
visible: root.selectedText !== ""
|
|
||||||
text: root.selectedText
|
|
||||||
anchors.left: iconImg.right
|
|
||||||
anchors.leftMargin: hasIcon ? 8 : 0
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
font.pixelSize: 15
|
|
||||||
height: 22
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SVGImage {
|
SVGImage {
|
||||||
|
@ -80,7 +55,7 @@ Item {
|
||||||
width: 11
|
width: 11
|
||||||
height: 6
|
height: 6
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: Style.current.padding
|
anchors.rightMargin: caretRightMargin
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: "../app/img/caret.svg"
|
source: "../app/img/caret.svg"
|
||||||
|
@ -137,11 +112,19 @@ Item {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: inputRectangle
|
anchors.fill: inputRectangle
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
inputRectangle.hovered = true
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
inputRectangle.hovered = false
|
||||||
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (selectMenu.opened) {
|
if (selectMenu.opened) {
|
||||||
selectMenu.close()
|
selectMenu.close()
|
||||||
} else {
|
} else {
|
||||||
selectMenu.popup(inputRectangle.x, inputRectangle.y + inputRectangle.height + 8)
|
const offset = inputRectangle.width - selectMenu.width
|
||||||
|
selectMenu.popup(inputRectangle.x + offset, inputRectangle.y + inputRectangle.height + 8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue