status-desktop/ui/shared/AssetAndAmountInput.qml
Alexandra Betouni 4ee21ada05 feat(desktop) Added image function in Style
Introduced Style.svg() Style.png() Style.emoji() and
Style.icon() in Style.qml. Those should be used to
set the source in Images instead of using relative
paths. Usage:
Image {
   source: Style.svg("check)
   ....

Also moved all Singletons inside a new "utils"
folder and made it a QML module, to use
import utils 1.0 instead of relative paths

Closes #3678
2021-09-28 15:28:00 -04:00

225 lines
7.9 KiB
QML

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import utils 1.0
Item {
//% "Insufficient balance"
property string balanceErrorMessage: qsTrId("insufficient-balance")
//% "Must be greater than or equal to 0"
property string greaterThanOrEqualTo0ErrorMessage: qsTrId("must-be-greater-than-or-equal-to-0")
//% "This needs to be a number"
property string invalidInputErrorMessage: qsTrId("this-needs-to-be-a-number")
//% "Please enter an amount"
property string noInputErrorMessage: qsTrId("please-enter-an-amount")
property string defaultCurrency: "USD"
property alias selectedFiatAmount: txtFiatBalance.text
property alias selectedAmount: inputAmount.text
property var selectedAccount
property alias selectedAsset: selectAsset.selectedAsset
property var getFiatValue: function () {}
property var getCryptoValue: function () {}
property bool isDirty: false
property bool validateBalance: true
property bool isValid: false
property string validationError
property var formattedInputValue
id: root
height: inputAmount.height + (inputAmount.validationError ? -16 - inputAmount.validationErrorTopMargin : 0) + txtFiatBalance.height + txtFiatBalance.anchors.topMargin
anchors.right: parent.right
anchors.left: parent.left
function validate(checkDirty) {
let isValid = true
let error = ""
const hasTyped = checkDirty ? isDirty : true
const balance = parseFloat(txtBalance.text || "0.00")
formattedInputValue = parseFloat(inputAmount.text || "0.00")
const noInput = inputAmount.text === ""
if (noInput && hasTyped) {
error = noInputErrorMessage
isValid = false
} else if (isNaN(inputAmount.text)) {
error = invalidInputErrorMessage
isValid = false
} else if (formattedInputValue < 0.00 && hasTyped) {
error = greaterThanOrEqualTo0ErrorMessage
isValid = false
} else if (validateBalance && formattedInputValue > balance && !noInput) {
error = balanceErrorMessage
isValid = false
}
if (!isValid) {
root.validationError = error
txtBalanceDesc.color = Style.current.danger
txtBalance.color = Style.current.danger
} else {
root.validationError = ""
txtBalanceDesc.color = Style.current.secondaryText
txtBalance.color = Qt.binding(function() { return txtBalance.hovered ? Style.current.textColor : Style.current.secondaryText })
}
root.isValid = isValid
return isValid
}
onSelectedAccountChanged: {
selectAsset.assets = Qt.binding(function() {
if (selectedAccount) {
return selectedAccount.assets
}
})
txtBalance.text = Qt.binding(function() {
return selectAsset.selectedAsset ? Utils.stripTrailingZeros(selectAsset.selectedAsset.value) : ""
})
}
Item {
visible: root.validateBalance
anchors.right: parent.right
anchors.left: parent.left
anchors.top: parent.top
height: txtBalanceDesc.height
StyledText {
id: txtBalanceDesc
//% "Balance: "
text: qsTrId("balance--")
anchors.right: txtBalance.left
font.weight: Font.Medium
font.pixelSize: 13
color: Style.current.secondaryText
}
StyledText {
id: txtBalance
property bool hovered: false
text: selectAsset.selectedAsset ? Utils.stripTrailingZeros(selectAsset.selectedAsset.value) : "0.00"
anchors.right: parent.right
font.weight: Font.Medium
font.pixelSize: 13
color: hovered ? Style.current.textColor : Style.current.secondaryText
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onExited: {
txtBalance.hovered = false
}
onEntered: {
txtBalance.hovered = true
}
onClicked: {
inputAmount.text = Utils.stripTrailingZeros(selectAsset.selectedAsset.value)
txtFiatBalance.text = root.getFiatValue(inputAmount.text, selectAsset.selectedAsset.symbol, root.defaultCurrency)
}
}
}
}
Input {
id: inputAmount
//% "Asset & Amount"
label: qsTrId("asset---amount")
placeholderText: "0.00"
anchors.top: parent.top
customHeight: 56
validationErrorAlignment: TextEdit.AlignRight
validationErrorTopMargin: 8
validationErrorColor: formattedInputValue === 0 ? Style.current.warning : Style.current.danger
validationError: {
if (root.validationError) {
return root.validationError
}
if (formattedInputValue === 0) {
//% "The amount is 0. Proceed only if this is desired."
return qsTrId("the-amount-is-0--proceed-only-if-this-is-desired-")
}
return ""
}
Keys.onReleased: {
let amount = inputAmount.text.trim()
if (isNaN(amount)) {
return
}
if (amount === "") {
txtFiatBalance.text = "0.00"
} else {
txtFiatBalance.text = root.getFiatValue(amount, selectAsset.selectedAsset.symbol, root.defaultCurrency)
}
}
onTextChanged: {
root.isDirty = true
root.validate(true)
}
}
AssetSelector {
id: selectAsset
width: 86
height: 28
anchors.top: inputAmount.top
anchors.topMargin: Style.current.bigPadding + 14
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
onSelectedAssetChanged: {
if (!selectAsset.selectedAsset) {
return
}
txtBalance.text = Utils.stripTrailingZeros(selectAsset.selectedAsset.value)
if (inputAmount.text === "" || isNaN(inputAmount.text)) {
return
}
txtFiatBalance.text = root.getFiatValue(inputAmount.text, selectAsset.selectedAsset.symbol, root.defaultCurrency)
root.validate(true)
}
}
Item {
height: txtFiatBalance.height
anchors.left: parent.left
anchors.top: inputAmount.bottom
anchors.topMargin: inputAmount.validationError ? -16 : inputAmount.validationErrorTopMargin
StyledTextField {
id: txtFiatBalance
anchors.left: parent.left
anchors.top: parent.top
color: txtFiatBalance.activeFocus ? Style.current.textColor : Style.current.secondaryText
font.weight: Font.Medium
font.pixelSize: 12
inputMethodHints: Qt.ImhFormattedNumbersOnly
text: "0.00"
selectByMouse: true
background: Rectangle {
color: Style.current.transparent
}
padding: 0
Keys.onReleased: {
let balance = txtFiatBalance.text.trim()
if (balance === "" || isNaN(balance)) {
return
}
inputAmount.text = root.getCryptoValue(balance, root.defaultCurrency, selectAsset.selectedAsset.symbol)
}
}
StyledText {
id: txtFiatSymbol
text: root.defaultCurrency.toUpperCase()
font.weight: Font.Medium
font.pixelSize: 12
color: Style.current.secondaryText
anchors.top: parent.top
anchors.left: txtFiatBalance.right
anchors.leftMargin: 2
}
}
}