feat: Send transaction componets -- Asset selector

Selects an asset to be used in the send transaction dialog.
This commit is contained in:
emizzle 2020-08-03 15:36:54 +10:00
parent 3cb88d0cfa
commit 82022f655c
No known key found for this signature in database
GPG Key ID: 1FD4BAB3C37EE9BA
6 changed files with 237 additions and 117 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

157
ui/shared/AssetSelector.qml Normal file
View File

@ -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}
}
##^##*/

View File

@ -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)
} }
} }
} }