status-desktop/ui/imports/shared/views/SendModalHeader.qml

220 lines
8.4 KiB
QML

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import StatusQ.Controls.Validators 0.1
import utils 1.0
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import "../controls"
import "../views"
Rectangle {
id: header
property alias accountSelector: accountSelector
property alias recipientSelector: recipientSelector
property alias amountToSendInput: amountToSendInput
property alias assetSelector: assetSelector
property var store
property var contactsStore
property var estimateGas: function() {}
property bool isReady: amountToSendInput.valid && !amountToSendInput.pending && recipientSelector.isValid && !recipientSelector.isPending
QtObject {
id: _internal
property string maxFiatBalance: Utils.stripTrailingZeros(parseFloat(assetSelector.selectedAsset.balance).toFixed(4))
//% "Please enter a valid amount"
property string sendAmountInputErrorMessage: qsTr("Please enter a valid amount")
//% "Max:"
property string maxString: qsTr("Max: ")
}
radius: 8
color: Theme.palette.statusModal.backgroundColor
width: parent.width
height: headerLayout.height + Style.current.xlPadding + (!!recipientSelector.input.text && recipientSelector.input.hasValidSearchResult ? 70 : 0)
Rectangle {
id: border
anchors.bottom: parent.bottom
width: parent.width
height: parent.radius
color: parent.color
StatusModalDivider {
anchors.bottom: parent.bottom
width: parent.width
}
}
ColumnLayout {
id: headerLayout
spacing: 8
width: parent.width
anchors.top: parent.top
anchors.leftMargin: Style.current.xlPadding
anchors.rightMargin: Style.current.xlPadding
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.right: parent.right
StatusAccountSelector {
id: accountSelector
accounts: header.store.accounts
selectedAccount: {
const currAcc = header.store.currentAccount
if (currAcc.walletType !== Constants.watchWalletType) {
return currAcc
}
return null
}
currency: header.store.currentCurrency
width: parent.width
label: ""
onSelectedAccountChanged: {
assetSelector.assets = Qt.binding(function() {
if (selectedAccount) {
return selectedAccount.assets
}
})
if (isValid) { estimateGas() }
}
showAccountDetails: false
selectField.select.height: 32
}
ColumnLayout {
id: assetAndAmmountSelector
RowLayout {
spacing: 16
StatusBaseText {
//% "Send"
text: qsTrId("command-button-send")
font.pixelSize: 15
color: Theme.palette.directColor1
Layout.alignment: Qt.AlignVCenter
}
StatusListItemTag {
//% "No balances active"
title: assetSelector.selectedAsset.balance > 0 ? _internal.maxString + (assetSelector.selectedAsset ? _internal.maxFiatBalance : "0.00") : qsTr("No balances active")
closeButtonVisible: false
titleText.font.pixelSize: 12
height: 22
}
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
AmountInputWithCursor {
id: amountToSendInput
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
width: parent.width - assetSelector.width
input.placeholderText: "0.00" + " " + assetSelector.selectedAsset.symbol
errorMessageCmp.anchors.rightMargin: -100
validators: [
StatusFloatValidator{
id: floatValidator
bottom: 0
top: _internal.maxFiatBalance
errorMessage: _internal.sendAmountInputErrorMessage
}
]
Keys.onReleased: {
let amount = amountToSendInput.text.trim()
if (isNaN(amount)) {
return
}
if (amount === "") {
txtFiatBalance.text = "0.00"
} else {
txtFiatBalance.text = header.store.getFiatValue(amount, assetSelector.selectedAsset.symbol, header.store.currentCurrency)
}
estimateGas()
}
}
StatusAssetSelector {
id: assetSelector
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
defaultToken: Style.png("tokens/DEFAULT-TOKEN@3x")
getCurrencyBalanceString: function (currencyBalance) {
return Utils.toLocaleString(currencyBalance.toFixed(2), header.store.locale, {"currency": true}) + " " + header.store.currentCurrency.toUpperCase()
}
tokenAssetSourceFn: function (symbol) {
return symbol ? Style.png("tokens/" + symbol) : defaultToken
}
onSelectedAssetChanged: {
if (!assetSelector.selectedAsset) {
return
}
if (amountToSendInput.text === "" || isNaN(amountToSendInput.text)) {
return
}
txtFiatBalance.text = header.store.getFiatValue(amountToSendInput.text, assetSelector.selectedAsset.symbol, header.store.currentCurrency)
estimateGas()
}
}
}
RowLayout {
StyledTextField {
id: txtFiatBalance
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
}
// To-Do Not refactored yet
// amountToSendInput.text = root.getCryptoValue(balance, header.store.currentCurrency, assetSelector.selectedAsset.symbol)
}
}
StatusBaseText {
id: currencyText
text: header.store.currentCurrency.toUpperCase()
font.pixelSize: 13
color: Theme.palette.directColor5
}
}
}
// To-do use standard StatusInput component once the flow for ens name resolution is clear
RecipientSelector {
id: recipientSelector
accounts: header.store.accounts
contactsStore: header.contactsStore
//% To
label: qsTr("To")
Layout.fillWidth: true
//% "Enter an ENS name or address"
input.placeholderText: qsTr("Enter an ENS name or address")
input.anchors.leftMargin: 0
input.anchors.rightMargin: 0
labelFont.pixelSize: 15
labelFont.weight: Font.Normal
input.height: 56
isSelectorVisible: false
addContactEnabled: false
onSelectedRecipientChanged: estimateGas()
}
}
}