chore(AmountToSend): AmountToSendNew is dead, long live AmountToSend
This commit is contained in:
parent
114abc7015
commit
7c10b16b67
|
@ -1,159 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
|
|
||||||
import Qt.labs.settings 1.0
|
|
||||||
|
|
||||||
import shared.popups.send.views 1.0
|
|
||||||
|
|
||||||
SplitView {
|
|
||||||
orientation: Qt.Vertical
|
|
||||||
SplitView.fillWidth: true
|
|
||||||
|
|
||||||
Item {
|
|
||||||
SplitView.fillWidth: true
|
|
||||||
SplitView.fillHeight: true
|
|
||||||
|
|
||||||
AmountToSendNew {
|
|
||||||
id: amountToSend
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
interactive: interactiveCheckBox.checked
|
|
||||||
fiatInputInteractive: fiatInteractiveCheckBox.checked
|
|
||||||
markAsInvalid: markAsInvalidCheckBox.checked
|
|
||||||
|
|
||||||
mainInputLoading: ctrlMainInputLoading.checked
|
|
||||||
bottomTextLoading: ctrlBottomTextLoading.checked
|
|
||||||
|
|
||||||
caption: "Amount to send"
|
|
||||||
|
|
||||||
decimalPoint: decimalPointRadioButton.checked ? "." : ","
|
|
||||||
price: parseFloat(priceTextField.text)
|
|
||||||
|
|
||||||
multiplierIndex: multiplierIndexSpinBox.value
|
|
||||||
|
|
||||||
formatFiat: balance => `${balance.toLocaleString(Qt.locale())} USD`
|
|
||||||
formatBalance: balance => `${balance.toLocaleString(Qt.locale())} ETH`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pane {
|
|
||||||
id: logsAndControlsPanel
|
|
||||||
|
|
||||||
SplitView.minimumHeight: 350
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: 15
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Label {
|
|
||||||
text: "Price"
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: priceTextField
|
|
||||||
|
|
||||||
text: "812.323"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Label {
|
|
||||||
text: "Decimal point"
|
|
||||||
}
|
|
||||||
|
|
||||||
RadioButton {
|
|
||||||
id: decimalPointRadioButton
|
|
||||||
|
|
||||||
text: "."
|
|
||||||
}
|
|
||||||
|
|
||||||
RadioButton {
|
|
||||||
text: ","
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Label {
|
|
||||||
text: "Multiplier index"
|
|
||||||
}
|
|
||||||
|
|
||||||
SpinBox {
|
|
||||||
id: multiplierIndexSpinBox
|
|
||||||
|
|
||||||
editable: true
|
|
||||||
value: 18
|
|
||||||
to: 30
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
CheckBox {
|
|
||||||
id: interactiveCheckBox
|
|
||||||
|
|
||||||
text: "Interactive"
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: fiatInteractiveCheckBox
|
|
||||||
|
|
||||||
text: "Fiat mode interactive"
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: markAsInvalidCheckBox
|
|
||||||
|
|
||||||
text: "Mark as invalid"
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: ctrlMainInputLoading
|
|
||||||
text: "Input loading"
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: ctrlBottomTextLoading
|
|
||||||
text: "Bottom text loading"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
font.bold: true
|
|
||||||
text: `fiat mode: ${amountToSend.fiatMode}, ` +
|
|
||||||
`valid: ${amountToSend.valid}, ` +
|
|
||||||
`empty: ${amountToSend.empty}, ` +
|
|
||||||
`amount: ${amountToSend.amount}`
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Label {
|
|
||||||
text: `Set value`
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: amountTextField
|
|
||||||
|
|
||||||
text: "0.0012"
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
text: "SET"
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
amountToSend.setValue(amountTextField.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings {
|
|
||||||
property alias multiplier: multiplierIndexSpinBox.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// category: Components
|
|
|
@ -2,100 +2,158 @@ import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import Qt.labs.settings 1.1
|
||||||
|
|
||||||
import shared.popups.send.views 1.0
|
import shared.popups.send.views 1.0
|
||||||
|
|
||||||
import Storybook 1.0
|
|
||||||
import Models 1.0
|
|
||||||
|
|
||||||
SplitView {
|
SplitView {
|
||||||
id: root
|
orientation: Qt.Vertical
|
||||||
|
SplitView.fillWidth: true
|
||||||
|
|
||||||
readonly property var tokensBySymbolModel: TokensBySymbolModel {}
|
Item {
|
||||||
|
|
||||||
readonly property double maxCryptoBalance: parseFloat(maxCryptoBalanceText.text)
|
|
||||||
readonly property int decimals: parseInt(decimalsText.text)
|
|
||||||
|
|
||||||
Logs { id: logs }
|
|
||||||
|
|
||||||
Component.onCompleted: amountToSendInput.input.forceActiveFocus()
|
|
||||||
|
|
||||||
SplitView {
|
|
||||||
orientation: Qt.Vertical
|
|
||||||
SplitView.fillWidth: true
|
SplitView.fillWidth: true
|
||||||
|
SplitView.fillHeight: true
|
||||||
|
|
||||||
Item {
|
AmountToSend {
|
||||||
SplitView.fillWidth: true
|
id: amountToSend
|
||||||
SplitView.fillHeight: true
|
|
||||||
|
|
||||||
AmountToSend {
|
anchors.centerIn: parent
|
||||||
id: amountToSendInput
|
|
||||||
isBridgeTx: false
|
|
||||||
interactive: true
|
|
||||||
selectedHolding: tokensBySymbolModel.data[0]
|
|
||||||
|
|
||||||
inputIsFiat: fiatInput.checked
|
interactive: interactiveCheckBox.checked
|
||||||
|
fiatInputInteractive: fiatInteractiveCheckBox.checked
|
||||||
|
markAsInvalid: markAsInvalidCheckBox.checked
|
||||||
|
|
||||||
maxInputBalance: inputIsFiat ? root.maxCryptoBalance*amountToSendInput.selectedHolding.marketDetails.currencyPrice.amount
|
mainInputLoading: ctrlMainInputLoading.checked
|
||||||
: root.maxCryptoBalance
|
bottomTextLoading: ctrlBottomTextLoading.checked
|
||||||
currentCurrency: "USD"
|
|
||||||
formatCurrencyAmount: function(amount, symbol, options, locale) {
|
caption: "Amount to send"
|
||||||
const currencyAmount = {
|
|
||||||
amount: amount,
|
decimalPoint: decimalPointRadioButton.checked ? "." : ","
|
||||||
symbol: symbol,
|
price: parseFloat(priceTextField.text)
|
||||||
displayDecimals: root.decimals,
|
|
||||||
stripTrailingZeroes: true
|
multiplierIndex: multiplierIndexSpinBox.value
|
||||||
}
|
|
||||||
return LocaleUtils.currencyAmountToLocaleString(currencyAmount, options, locale)
|
formatFiat: balance => `${balance.toLocaleString(Qt.locale())} USD`
|
||||||
|
formatBalance: balance => `${balance.toLocaleString(Qt.locale())} ETH`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
id: logsAndControlsPanel
|
||||||
|
|
||||||
|
SplitView.minimumHeight: 350
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 15
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
text: "Price"
|
||||||
}
|
}
|
||||||
onReCalculateSuggestedRoute: function() {
|
|
||||||
logs.logEvent("onReCalculateSuggestedRoute")
|
TextField {
|
||||||
|
id: priceTextField
|
||||||
|
|
||||||
|
text: "812.323"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LogsAndControlsPanel {
|
RowLayout {
|
||||||
id: logsAndControlsPanel
|
|
||||||
|
|
||||||
SplitView.minimumHeight: 250
|
|
||||||
|
|
||||||
logsView.logText: logs.logText
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Label {
|
Label {
|
||||||
Layout.topMargin: 10
|
text: "Decimal point"
|
||||||
Layout.fillWidth: true
|
|
||||||
text: "Max Crypto Balance"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextField {
|
RadioButton {
|
||||||
id: maxCryptoBalanceText
|
id: decimalPointRadioButton
|
||||||
background: Rectangle { border.color: 'lightgrey' }
|
|
||||||
Layout.preferredWidth: 200
|
text: "."
|
||||||
text: "1000000"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RadioButton {
|
||||||
|
text: ","
|
||||||
|
checked: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
Label {
|
Label {
|
||||||
Layout.topMargin: 10
|
text: "Multiplier index"
|
||||||
Layout.fillWidth: true
|
|
||||||
text: "Decimals"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextField {
|
SpinBox {
|
||||||
id: decimalsText
|
id: multiplierIndexSpinBox
|
||||||
background: Rectangle { border.color: 'lightgrey' }
|
|
||||||
Layout.preferredWidth: 200
|
editable: true
|
||||||
text: "6"
|
value: 18
|
||||||
|
to: 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
CheckBox {
|
||||||
|
id: interactiveCheckBox
|
||||||
|
|
||||||
|
text: "Interactive"
|
||||||
|
checked: true
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: fiatInput
|
id: fiatInteractiveCheckBox
|
||||||
|
|
||||||
text: "Fiat input value"
|
text: "Fiat mode interactive"
|
||||||
|
checked: true
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
id: markAsInvalidCheckBox
|
||||||
|
|
||||||
|
text: "Mark as invalid"
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
id: ctrlMainInputLoading
|
||||||
|
text: "Input loading"
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
id: ctrlBottomTextLoading
|
||||||
|
text: "Bottom text loading"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
font.bold: true
|
||||||
|
text: `fiat mode: ${amountToSend.fiatMode}, ` +
|
||||||
|
`valid: ${amountToSend.valid}, ` +
|
||||||
|
`empty: ${amountToSend.empty}, ` +
|
||||||
|
`amount: ${amountToSend.amount}`
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
text: `Set value`
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: amountTextField
|
||||||
|
|
||||||
|
text: "0.0012"
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "SET"
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
amountToSend.setValue(amountTextField.text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Settings {
|
||||||
|
property alias multiplier: multiplierIndexSpinBox.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// category: Components
|
// category: Components
|
||||||
|
|
|
@ -13,10 +13,10 @@ Item {
|
||||||
Component {
|
Component {
|
||||||
id: componentUnderTest
|
id: componentUnderTest
|
||||||
|
|
||||||
AmountToSendNew {}
|
AmountToSend {}
|
||||||
}
|
}
|
||||||
|
|
||||||
property AmountToSendNew amountToSend
|
property AmountToSend amountToSend
|
||||||
|
|
||||||
SignalSpy {
|
SignalSpy {
|
||||||
id: amountChangedSpy
|
id: amountChangedSpy
|
||||||
|
@ -25,7 +25,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCase {
|
TestCase {
|
||||||
name: "AmountToSendNew"
|
name: "AmountToSend"
|
||||||
when: windowShown
|
when: windowShown
|
||||||
|
|
||||||
function type(key, times = 1) {
|
function type(key, times = 1) {
|
|
@ -213,7 +213,7 @@ Control {
|
||||||
Layout.preferredWidth: parent.width*.66
|
Layout.preferredWidth: parent.width*.66
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
AmountToSendNew {
|
AmountToSend {
|
||||||
readonly property bool balanceExceeded:
|
readonly property bool balanceExceeded:
|
||||||
SQUtils.AmountsArithmetic.fromNumber(maxSendButton.maxSafeCryptoValue, multiplierIndex).cmp(amount) === -1
|
SQUtils.AmountsArithmetic.fromNumber(maxSendButton.maxSafeCryptoValue, multiplierIndex).cmp(amount) === -1
|
||||||
|
|
||||||
|
|
|
@ -480,7 +480,7 @@ StatusDialog {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
visible: d.isSelectedHoldingValidAsset && !d.isCollectiblesTransfer
|
visible: d.isSelectedHoldingValidAsset && !d.isCollectiblesTransfer
|
||||||
|
|
||||||
AmountToSendNew {
|
AmountToSend {
|
||||||
id: amountToSend
|
id: amountToSend
|
||||||
|
|
||||||
caption: d.isBridgeTx ? qsTr("Amount to bridge")
|
caption: d.isBridgeTx ? qsTr("Amount to bridge")
|
||||||
|
|
|
@ -1,232 +1,284 @@
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Controls 0.1
|
|
||||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||||
import StatusQ.Components 0.1
|
import StatusQ.Components 0.1
|
||||||
import StatusQ.Controls.Validators 0.1
|
import StatusQ.Validators 0.1
|
||||||
|
|
||||||
import "../controls"
|
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
import shared.controls 1.0
|
||||||
|
|
||||||
ColumnLayout {
|
Control {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property alias input: topAmountToSendInput
|
/* Crypto value in a base unit as a string integer, e.g. 1000000000000000000
|
||||||
readonly property bool inputNumberValid: !!input.text && !isNaN(d.parsedInput) && input.valid
|
* for 1 ETH */
|
||||||
|
readonly property alias amount: d.amountBaseUnit
|
||||||
|
|
||||||
readonly property int minSendCryptoDecimals:
|
/* In fiat mode the input value is meant to be a fiat value, conversely,
|
||||||
!inputIsFiat ? LocaleUtils.fractionalPartLength(d.inputNumber) : 0
|
* crypto value otherwise. */
|
||||||
readonly property int minReceiveCryptoDecimals:
|
readonly property alias fiatMode: d.fiatMode
|
||||||
!inputIsFiat ? minSendCryptoDecimals + 1 : 0
|
|
||||||
readonly property int minSendFiatDecimals:
|
|
||||||
inputIsFiat ? LocaleUtils.fractionalPartLength(d.inputNumber) : 0
|
|
||||||
readonly property int minReceiveFiatDecimals:
|
|
||||||
inputIsFiat ? minSendFiatDecimals + 1 : 0
|
|
||||||
|
|
||||||
property var selectedHolding // Crypto asset symbol like ETH
|
/* Indicates whether toggling the fiatMode is enabled for the user */
|
||||||
property string currentCurrency // Fiat currency symbol like USD
|
property bool fiatInputInteractive: interactive
|
||||||
|
|
||||||
property int multiplierIndex // How divisible the token is, 18 for ETH
|
/* Indicates if input represent valid number. E.g. empty input or containing
|
||||||
|
* only decimal point is not valid. */
|
||||||
|
readonly property alias valid: textField.acceptableInput
|
||||||
|
readonly property bool empty: textField.length === 0
|
||||||
|
|
||||||
property double maxInputBalance
|
// TODO: remove, temporarily for backward compatibility. External components
|
||||||
|
// should not rely on formatted amount because formatting rules are internal
|
||||||
|
// detail of that component.
|
||||||
|
readonly property alias text: textField.text
|
||||||
|
|
||||||
property bool isBridgeTx: false
|
/* Decimal point character to be displayed. Both "." and "," will be
|
||||||
property bool interactive: false
|
* replaced by the provided decimal point on the fly */
|
||||||
property bool inputIsFiat: false
|
property alias decimalPoint: validator.decimalPoint
|
||||||
|
|
||||||
property string caption: isBridgeTx ? qsTr("Amount to bridge") : qsTr("Amount to send")
|
/* Number of fiat decimal places used to limit allowed decimal places in
|
||||||
|
* fiatMode */
|
||||||
|
property int fiatDecimalPlaces: 2
|
||||||
|
|
||||||
property bool fiatInputInteractive: true
|
/* Specifies how divisible given cryptocurrency is, e.g. 18 for ETH. Used
|
||||||
|
* for limiting allowed decimal places and computing final amount as an
|
||||||
|
* integer value */
|
||||||
|
property int multiplierIndex: 18
|
||||||
|
|
||||||
// Crypto value to send expressed in base units (like wei for ETH),
|
/* Price of one unit of given cryptocurrency (e.g. price for 1 ETH) */
|
||||||
// as a string representing integer decimal
|
property real price: 1.0
|
||||||
readonly property alias cryptoValueToSend: d.cryptoValueRawToSend
|
|
||||||
|
|
||||||
readonly property alias cryptoValueToSendFloat: d.cryptoValueToSend
|
property alias caption: captionText.text
|
||||||
|
property bool interactive: true
|
||||||
|
|
||||||
property var formatCurrencyAmount:
|
readonly property bool cursorVisible: textField.cursorVisible
|
||||||
(amount, symbol, options = null, locale = null) => {}
|
readonly property alias placeholderText: textField.placeholderText
|
||||||
|
|
||||||
|
/* Loading states for the input and text below */
|
||||||
property bool mainInputLoading
|
property bool mainInputLoading
|
||||||
property bool bottomTextLoading
|
property bool bottomTextLoading
|
||||||
|
|
||||||
signal reCalculateSuggestedRoute()
|
/* Allows mark input as invalid when it's valid number but doesn't satisfy
|
||||||
|
* arbitrary external criteria, e.g. is higher than maximum expected value. */
|
||||||
|
property bool markAsInvalid: false
|
||||||
|
|
||||||
|
/* Methods for formatting crypto and fiat value expecting double values,
|
||||||
|
e.g. 1.0 for 1 ETH or 1.0 for 1 USD. */
|
||||||
|
property var formatFiat: balance =>
|
||||||
|
`${balance.toLocaleString(Qt.locale())} FIAT`
|
||||||
|
property var formatBalance: balance =>
|
||||||
|
`${balance.toLocaleString(Qt.locale())} CRYPTO`
|
||||||
|
|
||||||
|
/* Allows to set value to be displayed. The value is expected to be a not
|
||||||
|
localized string like "1", "1.1" or "0.000000023400234222". Provided
|
||||||
|
value will be formatted and displayed. Depending on the fiatMode flag
|
||||||
|
it will affect output amount appropriately. */
|
||||||
|
function setValue(valueString) {
|
||||||
|
if (!valueString)
|
||||||
|
valueString = "0"
|
||||||
|
|
||||||
|
const decimalPlaces = d.fiatMode ? root.fiatDecimalPlaces
|
||||||
|
: root.multiplierIndex
|
||||||
|
|
||||||
|
const stringNumber = SQUtils.AmountsArithmetic.fromString(
|
||||||
|
valueString).toFixed(decimalPlaces)
|
||||||
|
|
||||||
|
const trimmed = d.fiatMode
|
||||||
|
? stringNumber
|
||||||
|
: d.removeDecimalTrailingZeros(stringNumber)
|
||||||
|
|
||||||
|
textField.text = d.localize(trimmed)
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
textField.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceActiveFocus() {
|
||||||
|
textField.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
property double cryptoValueToSend
|
property bool fiatMode: false
|
||||||
property double fiatValueToSend
|
|
||||||
|
|
||||||
Binding on cryptoValueToSend {
|
readonly property string inputDelocalized:
|
||||||
value: {
|
root.valid && textField.length !== 0
|
||||||
root.selectedHolding
|
? textField.text.replace(root.decimalPoint, ".") : "0"
|
||||||
if(!root.selectedHolding || !root.selectedHolding.marketDetails || !root.selectedHolding.marketDetails.currencyPrice) {
|
|
||||||
return 0
|
function removeDecimalTrailingZeros(num) {
|
||||||
}
|
if (!num.includes("."))
|
||||||
return root.inputIsFiat ? d.fiatValueToSend/root.selectedHolding.marketDetails.currencyPrice.amount
|
return num
|
||||||
: d.inputNumber
|
|
||||||
}
|
return num.replace(/\.?0*$/g, "")
|
||||||
delayed: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding on fiatValueToSend {
|
function localize(num) {
|
||||||
value: {
|
return num.replace(".", root.decimalPoint)
|
||||||
root.selectedHolding
|
|
||||||
if(!root.selectedHolding || !root.selectedHolding.marketDetails || !root.selectedHolding.marketDetails.currencyPrice) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return root.inputIsFiat ? d.inputNumber
|
|
||||||
: d.cryptoValueToSend * root.selectedHolding.marketDetails.currencyPrice.amount
|
|
||||||
}
|
|
||||||
delayed: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property string selectedSymbol: !!root.selectedHolding && !!root.selectedHolding.symbol ? root.selectedHolding.symbol: ""
|
readonly property string amountBaseUnit: {
|
||||||
|
if (d.fiatMode)
|
||||||
|
return secondaryValue
|
||||||
|
|
||||||
readonly property string cryptoValueRawToSend: {
|
const multiplier = SQUtils.AmountsArithmetic.fromExponent(
|
||||||
return SQUtils.AmountsArithmetic.fromNumber(
|
root.multiplierIndex)
|
||||||
d.cryptoValueToSend, root.multiplierIndex).toString()
|
|
||||||
|
return SQUtils.AmountsArithmetic.times(
|
||||||
|
SQUtils.AmountsArithmetic.fromString(inputDelocalized),
|
||||||
|
multiplier).toFixed()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crypto value should be represented by 0 and fiat with 0.00
|
readonly property string secondaryValue: {
|
||||||
readonly property string zeroString: {
|
const price = isNaN(root.price) ? 0 : root.price
|
||||||
let decimals = root.inputIsFiat ? 2 : 0
|
|
||||||
LocaleUtils.numberToLocaleString(0, decimals, topAmountToSendInput.locale)
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property double parsedInput:
|
if (!d.fiatMode)
|
||||||
LocaleUtils.numberFromLocaleString(topAmountToSendInput.text,
|
return SQUtils.AmountsArithmetic.times(
|
||||||
topAmountToSendInput.locale)
|
SQUtils.AmountsArithmetic.fromString(inputDelocalized),
|
||||||
|
SQUtils.AmountsArithmetic.fromNumber(
|
||||||
|
price * (10 ** root.fiatDecimalPlaces))).toFixed()
|
||||||
|
|
||||||
readonly property double inputNumber:
|
if (!price) // prevent div by zero below
|
||||||
// we should still calculate if value entered is greater than max safe value
|
return 0
|
||||||
!!input.text && !isNaN(d.parsedInput) && d.parsedInput >= 0 ? d.parsedInput : 0
|
|
||||||
|
|
||||||
readonly property Timer waitTimer: Timer {
|
const multiplier = SQUtils.AmountsArithmetic.fromExponent(
|
||||||
interval: 1000
|
root.multiplierIndex)
|
||||||
onTriggered: reCalculateSuggestedRoute()
|
|
||||||
|
return SQUtils.AmountsArithmetic.div(
|
||||||
|
SQUtils.AmountsArithmetic.times(
|
||||||
|
SQUtils.AmountsArithmetic.fromString(inputDelocalized),
|
||||||
|
multiplier),
|
||||||
|
SQUtils.AmountsArithmetic.fromNumber(price)).toFixed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMaxInputBalanceChanged: {
|
contentItem: ColumnLayout {
|
||||||
input.validate()
|
StatusBaseText {
|
||||||
}
|
id: captionText
|
||||||
|
|
||||||
onSelectedHoldingChanged: {
|
|
||||||
input.validate()
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusBaseText {
|
|
||||||
text: root.caption
|
|
||||||
font.pixelSize: 13
|
|
||||||
lineHeight: 18
|
|
||||||
lineHeightMode: Text.FixedHeight
|
|
||||||
color: Theme.palette.directColor1
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
id: topItem
|
|
||||||
|
|
||||||
AmountInputWithCursor {
|
|
||||||
id: topAmountToSendInput
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.maximumWidth: 250
|
|
||||||
Layout.preferredWidth: !!text ? input.edit.paintedWidth + 2
|
|
||||||
: textMetrics.advanceWidth
|
|
||||||
placeholderText: d.zeroString
|
|
||||||
input.edit.color: input.valid ? Theme.palette.directColor1
|
|
||||||
: Theme.palette.dangerColor1
|
|
||||||
input.edit.readOnly: !root.interactive
|
|
||||||
validationMode: StatusInput.ValidationMode.Always
|
|
||||||
validators: [
|
|
||||||
StatusValidator {
|
|
||||||
errorMessage: ""
|
|
||||||
|
|
||||||
validate: (text) => {
|
visible: text.length > 0
|
||||||
const num = LocaleUtils.numberFromLocaleString(topAmountToSendInput.text,
|
|
||||||
topAmountToSendInput.locale)
|
|
||||||
if (isNaN(num) || num <= 0 || num > root.maxInputBalance) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if(!root.selectedHolding || !root.selectedHolding.marketDetails || !root.selectedHolding.marketDetails.currencyPrice) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
const cryptoValueToSend = root.inputIsFiat ? num / root.selectedHolding.marketDetails.currencyPrice.amount : num
|
|
||||||
const cryptoValueToSendRaw = SQUtils.AmountsArithmetic.fromNumber(cryptoValueToSend, root.multiplierIndex).toString()
|
|
||||||
return cryptoValueToSendRaw >= 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
TextMetrics {
|
font.pixelSize: 13
|
||||||
id: textMetrics
|
lineHeight: 18
|
||||||
text: topAmountToSendInput.placeholderText
|
lineHeightMode: Text.FixedHeight
|
||||||
font: topAmountToSendInput.placeholderFont
|
color: Theme.palette.directColor1
|
||||||
}
|
elide: Text.ElideRight
|
||||||
|
|
||||||
Keys.onReleased: {
|
|
||||||
const amount = LocaleUtils.numberFromLocaleString(
|
|
||||||
topAmountToSendInput.text,
|
|
||||||
locale)
|
|
||||||
if (!isNaN(amount))
|
|
||||||
d.waitTimer.restart()
|
|
||||||
}
|
|
||||||
|
|
||||||
visible: !root.mainInputLoading
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
StyledTextField {
|
||||||
|
id: textField
|
||||||
|
|
||||||
|
objectName: "amountToSend_textField"
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
implicitHeight: 44
|
||||||
|
padding: 0
|
||||||
|
background: null
|
||||||
|
|
||||||
|
readOnly: !root.interactive
|
||||||
|
|
||||||
|
color: text.length === 0 || (root.valid && !root.markAsInvalid)
|
||||||
|
? Theme.palette.directColor1
|
||||||
|
: Theme.palette.dangerColor1
|
||||||
|
|
||||||
|
placeholderText: {
|
||||||
|
if (!d.fiatMode || root.fiatDecimalPlaces === 0)
|
||||||
|
return "0"
|
||||||
|
|
||||||
|
return "0" + root.decimalPoint
|
||||||
|
+ "0".repeat(root.fiatDecimalPlaces)
|
||||||
|
}
|
||||||
|
|
||||||
|
font.pixelSize: Utils.getFontSizeBasedOnLetterCount(text)
|
||||||
|
|
||||||
|
validator: AmountValidator {
|
||||||
|
id: validator
|
||||||
|
|
||||||
|
maxDecimalDigits: d.fiatMode ? root.fiatDecimalPlaces
|
||||||
|
: root.multiplierIndex
|
||||||
|
locale: root.locale.name
|
||||||
|
}
|
||||||
|
visible: !root.mainInputLoading
|
||||||
|
}
|
||||||
|
LoadingComponent {
|
||||||
|
objectName: "topAmountToSendInputLoadingComponent"
|
||||||
|
Layout.preferredWidth: textField.width
|
||||||
|
Layout.preferredHeight: textField.height
|
||||||
|
visible: root.mainInputLoading
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBaseText {
|
||||||
|
id: bottomItem
|
||||||
|
|
||||||
|
objectName: "bottomItemText"
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: {
|
||||||
|
const divisor = SQUtils.AmountsArithmetic.fromExponent(
|
||||||
|
d.fiatMode ? root.multiplierIndex
|
||||||
|
: root.fiatDecimalPlaces)
|
||||||
|
const divided = SQUtils.AmountsArithmetic.div(
|
||||||
|
SQUtils.AmountsArithmetic.fromString(
|
||||||
|
d.secondaryValue), divisor)
|
||||||
|
const asNumber = SQUtils.AmountsArithmetic.toNumber(divided)
|
||||||
|
|
||||||
|
return d.fiatMode ? root.formatBalance(asNumber)
|
||||||
|
: root.formatFiat(asNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
font.pixelSize: 13
|
||||||
|
color: Theme.palette.directColor5
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
objectName: "amountToSend_mouseArea"
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: enabled ? Qt.PointingHandCursor : undefined
|
||||||
|
enabled: root.fiatInputInteractive
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
const secondaryValue = d.secondaryValue
|
||||||
|
|
||||||
|
d.fiatMode = !d.fiatMode
|
||||||
|
|
||||||
|
if (textField.length === 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
const decimalPlaces = d.fiatMode ? root.fiatDecimalPlaces
|
||||||
|
: root.multiplierIndex
|
||||||
|
const divisor = SQUtils.AmountsArithmetic.fromExponent(
|
||||||
|
decimalPlaces)
|
||||||
|
|
||||||
|
const stringNumber = SQUtils.AmountsArithmetic.div(
|
||||||
|
SQUtils.AmountsArithmetic.fromString(secondaryValue),
|
||||||
|
divisor).toFixed(decimalPlaces)
|
||||||
|
|
||||||
|
const trimmed = d.fiatMode
|
||||||
|
? stringNumber
|
||||||
|
: d.removeDecimalTrailingZeros(stringNumber)
|
||||||
|
|
||||||
|
textField.text = d.localize(trimmed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visible: !root.bottomTextLoading
|
||||||
|
}
|
||||||
|
|
||||||
LoadingComponent {
|
LoadingComponent {
|
||||||
objectName: "topAmountToSendInputLoadingComponent"
|
objectName: "bottomItemTextLoadingComponent"
|
||||||
Layout.preferredWidth: topAmountToSendInput.width
|
Layout.preferredWidth: bottomItem.width
|
||||||
Layout.preferredHeight: topAmountToSendInput.height
|
Layout.preferredHeight: bottomItem.height
|
||||||
visible: root.mainInputLoading
|
visible: root.bottomTextLoading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusBaseText {
|
|
||||||
Layout.maximumWidth: parent.width
|
|
||||||
id: bottomItem
|
|
||||||
objectName: "bottomItemText"
|
|
||||||
|
|
||||||
readonly property double bottomAmountToSend: inputIsFiat ? d.cryptoValueToSend
|
|
||||||
: d.fiatValueToSend
|
|
||||||
readonly property string bottomAmountSymbol: inputIsFiat ? d.selectedSymbol
|
|
||||||
: root.currentCurrency
|
|
||||||
elide: Text.ElideMiddle
|
|
||||||
text: root.formatCurrencyAmount(bottomAmountToSend, bottomAmountSymbol)
|
|
||||||
font.pixelSize: 13
|
|
||||||
color: Theme.palette.directColor5
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: enabled ? Qt.PointingHandCursor : undefined
|
|
||||||
enabled: root.fiatInputInteractive && !!root.selectedHolding
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
topAmountToSendInput.validate()
|
|
||||||
if(!!topAmountToSendInput.text) {
|
|
||||||
topAmountToSendInput.text = root.formatCurrencyAmount(
|
|
||||||
bottomItem.bottomAmountToSend,
|
|
||||||
bottomItem.bottomAmountSymbol,
|
|
||||||
{ noSymbol: true, rawAmount: true },
|
|
||||||
topAmountToSendInput.locale)
|
|
||||||
}
|
|
||||||
root.inputIsFiat = !root.inputIsFiat
|
|
||||||
d.waitTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
visible: !root.bottomTextLoading
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadingComponent {
|
|
||||||
objectName: "bottomItemTextLoadingComponent"
|
|
||||||
Layout.preferredWidth: bottomItem.width
|
|
||||||
Layout.preferredHeight: bottomItem.height
|
|
||||||
visible: root.bottomTextLoading
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,284 +0,0 @@
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.15
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Core.Theme 0.1
|
|
||||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Validators 0.1
|
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
import shared.controls 1.0
|
|
||||||
|
|
||||||
Control {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
/* Crypto value in a base unit as a string integer, e.g. 1000000000000000000
|
|
||||||
* for 1 ETH */
|
|
||||||
readonly property alias amount: d.amountBaseUnit
|
|
||||||
|
|
||||||
/* In fiat mode the input value is meant to be a fiat value, conversely,
|
|
||||||
* crypto value otherwise. */
|
|
||||||
readonly property alias fiatMode: d.fiatMode
|
|
||||||
|
|
||||||
/* Indicates whether toggling the fiatMode is enabled for the user */
|
|
||||||
property bool fiatInputInteractive: interactive
|
|
||||||
|
|
||||||
/* Indicates if input represent valid number. E.g. empty input or containing
|
|
||||||
* only decimal point is not valid. */
|
|
||||||
readonly property alias valid: textField.acceptableInput
|
|
||||||
readonly property bool empty: textField.length === 0
|
|
||||||
|
|
||||||
// TODO: remove, temporarily for backward compatibility. External components
|
|
||||||
// should not rely on formatted amount because formatting rules are internal
|
|
||||||
// detail of that component.
|
|
||||||
readonly property alias text: textField.text
|
|
||||||
|
|
||||||
/* Decimal point character to be displayed. Both "." and "," will be
|
|
||||||
* replaced by the provided decimal point on the fly */
|
|
||||||
property alias decimalPoint: validator.decimalPoint
|
|
||||||
|
|
||||||
/* Number of fiat decimal places used to limit allowed decimal places in
|
|
||||||
* fiatMode */
|
|
||||||
property int fiatDecimalPlaces: 2
|
|
||||||
|
|
||||||
/* Specifies how divisible given cryptocurrency is, e.g. 18 for ETH. Used
|
|
||||||
* for limiting allowed decimal places and computing final amount as an
|
|
||||||
* integer value */
|
|
||||||
property int multiplierIndex: 18
|
|
||||||
|
|
||||||
/* Price of one unit of given cryptocurrency (e.g. price for 1 ETH) */
|
|
||||||
property real price: 1.0
|
|
||||||
|
|
||||||
property alias caption: captionText.text
|
|
||||||
property bool interactive: true
|
|
||||||
|
|
||||||
readonly property bool cursorVisible: textField.cursorVisible
|
|
||||||
readonly property alias placeholderText: textField.placeholderText
|
|
||||||
|
|
||||||
/* Loading states for the input and text below */
|
|
||||||
property bool mainInputLoading
|
|
||||||
property bool bottomTextLoading
|
|
||||||
|
|
||||||
/* Allows mark input as invalid when it's valid number but doesn't satisfy
|
|
||||||
* arbitrary external criteria, e.g. is higher than maximum expected value. */
|
|
||||||
property bool markAsInvalid: false
|
|
||||||
|
|
||||||
/* Methods for formatting crypto and fiat value expecting double values,
|
|
||||||
e.g. 1.0 for 1 ETH or 1.0 for 1 USD. */
|
|
||||||
property var formatFiat: balance =>
|
|
||||||
`${balance.toLocaleString(Qt.locale())} FIAT`
|
|
||||||
property var formatBalance: balance =>
|
|
||||||
`${balance.toLocaleString(Qt.locale())} CRYPTO`
|
|
||||||
|
|
||||||
/* Allows to set value to be displayed. The value is expected to be a not
|
|
||||||
localized string like "1", "1.1" or "0.000000023400234222". Provided
|
|
||||||
value will be formatted and displayed. Depending on the fiatMode flag
|
|
||||||
it will affect output amount appropriately. */
|
|
||||||
function setValue(valueString) {
|
|
||||||
if (!valueString)
|
|
||||||
valueString = "0"
|
|
||||||
|
|
||||||
const decimalPlaces = d.fiatMode ? root.fiatDecimalPlaces
|
|
||||||
: root.multiplierIndex
|
|
||||||
|
|
||||||
const stringNumber = SQUtils.AmountsArithmetic.fromString(
|
|
||||||
valueString).toFixed(decimalPlaces)
|
|
||||||
|
|
||||||
const trimmed = d.fiatMode
|
|
||||||
? stringNumber
|
|
||||||
: d.removeDecimalTrailingZeros(stringNumber)
|
|
||||||
|
|
||||||
textField.text = d.localize(trimmed)
|
|
||||||
}
|
|
||||||
|
|
||||||
function clear() {
|
|
||||||
textField.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
function forceActiveFocus() {
|
|
||||||
textField.forceActiveFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: d
|
|
||||||
|
|
||||||
property bool fiatMode: false
|
|
||||||
|
|
||||||
readonly property string inputDelocalized:
|
|
||||||
root.valid && textField.length !== 0
|
|
||||||
? textField.text.replace(root.decimalPoint, ".") : "0"
|
|
||||||
|
|
||||||
function removeDecimalTrailingZeros(num) {
|
|
||||||
if (!num.includes("."))
|
|
||||||
return num
|
|
||||||
|
|
||||||
return num.replace(/\.?0*$/g, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
function localize(num) {
|
|
||||||
return num.replace(".", root.decimalPoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property string amountBaseUnit: {
|
|
||||||
if (d.fiatMode)
|
|
||||||
return secondaryValue
|
|
||||||
|
|
||||||
const multiplier = SQUtils.AmountsArithmetic.fromExponent(
|
|
||||||
root.multiplierIndex)
|
|
||||||
|
|
||||||
return SQUtils.AmountsArithmetic.times(
|
|
||||||
SQUtils.AmountsArithmetic.fromString(inputDelocalized),
|
|
||||||
multiplier).toFixed()
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property string secondaryValue: {
|
|
||||||
const price = isNaN(root.price) ? 0 : root.price
|
|
||||||
|
|
||||||
if (!d.fiatMode)
|
|
||||||
return SQUtils.AmountsArithmetic.times(
|
|
||||||
SQUtils.AmountsArithmetic.fromString(inputDelocalized),
|
|
||||||
SQUtils.AmountsArithmetic.fromNumber(
|
|
||||||
price * (10 ** root.fiatDecimalPlaces))).toFixed()
|
|
||||||
|
|
||||||
if (!price) // prevent div by zero below
|
|
||||||
return 0
|
|
||||||
|
|
||||||
const multiplier = SQUtils.AmountsArithmetic.fromExponent(
|
|
||||||
root.multiplierIndex)
|
|
||||||
|
|
||||||
return SQUtils.AmountsArithmetic.div(
|
|
||||||
SQUtils.AmountsArithmetic.times(
|
|
||||||
SQUtils.AmountsArithmetic.fromString(inputDelocalized),
|
|
||||||
multiplier),
|
|
||||||
SQUtils.AmountsArithmetic.fromNumber(price)).toFixed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
StatusBaseText {
|
|
||||||
id: captionText
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
visible: text.length > 0
|
|
||||||
|
|
||||||
font.pixelSize: 13
|
|
||||||
lineHeight: 18
|
|
||||||
lineHeightMode: Text.FixedHeight
|
|
||||||
color: Theme.palette.directColor1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
StyledTextField {
|
|
||||||
id: textField
|
|
||||||
|
|
||||||
objectName: "amountToSend_textField"
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
implicitHeight: 44
|
|
||||||
padding: 0
|
|
||||||
background: null
|
|
||||||
|
|
||||||
readOnly: !root.interactive
|
|
||||||
|
|
||||||
color: text.length === 0 || (root.valid && !root.markAsInvalid)
|
|
||||||
? Theme.palette.directColor1
|
|
||||||
: Theme.palette.dangerColor1
|
|
||||||
|
|
||||||
placeholderText: {
|
|
||||||
if (!d.fiatMode || root.fiatDecimalPlaces === 0)
|
|
||||||
return "0"
|
|
||||||
|
|
||||||
return "0" + root.decimalPoint
|
|
||||||
+ "0".repeat(root.fiatDecimalPlaces)
|
|
||||||
}
|
|
||||||
|
|
||||||
font.pixelSize: Utils.getFontSizeBasedOnLetterCount(text)
|
|
||||||
|
|
||||||
validator: AmountValidator {
|
|
||||||
id: validator
|
|
||||||
|
|
||||||
maxDecimalDigits: d.fiatMode ? root.fiatDecimalPlaces
|
|
||||||
: root.multiplierIndex
|
|
||||||
locale: root.locale.name
|
|
||||||
}
|
|
||||||
visible: !root.mainInputLoading
|
|
||||||
}
|
|
||||||
LoadingComponent {
|
|
||||||
objectName: "topAmountToSendInputLoadingComponent"
|
|
||||||
Layout.preferredWidth: textField.width
|
|
||||||
Layout.preferredHeight: textField.height
|
|
||||||
visible: root.mainInputLoading
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusBaseText {
|
|
||||||
id: bottomItem
|
|
||||||
|
|
||||||
objectName: "bottomItemText"
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
text: {
|
|
||||||
const divisor = SQUtils.AmountsArithmetic.fromExponent(
|
|
||||||
d.fiatMode ? root.multiplierIndex
|
|
||||||
: root.fiatDecimalPlaces)
|
|
||||||
const divided = SQUtils.AmountsArithmetic.div(
|
|
||||||
SQUtils.AmountsArithmetic.fromString(
|
|
||||||
d.secondaryValue), divisor)
|
|
||||||
const asNumber = SQUtils.AmountsArithmetic.toNumber(divided)
|
|
||||||
|
|
||||||
return d.fiatMode ? root.formatBalance(asNumber)
|
|
||||||
: root.formatFiat(asNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
elide: Text.ElideMiddle
|
|
||||||
font.pixelSize: 13
|
|
||||||
color: Theme.palette.directColor5
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
objectName: "amountToSend_mouseArea"
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: enabled ? Qt.PointingHandCursor : undefined
|
|
||||||
enabled: root.fiatInputInteractive
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
const secondaryValue = d.secondaryValue
|
|
||||||
|
|
||||||
d.fiatMode = !d.fiatMode
|
|
||||||
|
|
||||||
if (textField.length === 0)
|
|
||||||
return
|
|
||||||
|
|
||||||
const decimalPlaces = d.fiatMode ? root.fiatDecimalPlaces
|
|
||||||
: root.multiplierIndex
|
|
||||||
const divisor = SQUtils.AmountsArithmetic.fromExponent(
|
|
||||||
decimalPlaces)
|
|
||||||
|
|
||||||
const stringNumber = SQUtils.AmountsArithmetic.div(
|
|
||||||
SQUtils.AmountsArithmetic.fromString(secondaryValue),
|
|
||||||
divisor).toFixed(decimalPlaces)
|
|
||||||
|
|
||||||
const trimmed = d.fiatMode
|
|
||||||
? stringNumber
|
|
||||||
: d.removeDecimalTrailingZeros(stringNumber)
|
|
||||||
|
|
||||||
textField.text = d.localize(trimmed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
visible: !root.bottomTextLoading
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadingComponent {
|
|
||||||
objectName: "bottomItemTextLoadingComponent"
|
|
||||||
Layout.preferredWidth: bottomItem.width
|
|
||||||
Layout.preferredHeight: bottomItem.height
|
|
||||||
visible: root.bottomTextLoading
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
AmountToReceive 1.0 AmountToReceive.qml
|
AmountToReceive 1.0 AmountToReceive.qml
|
||||||
AmountToSend 1.0 AmountToSend.qml
|
AmountToSend 1.0 AmountToSend.qml
|
||||||
AmountToSendNew 1.0 AmountToSendNew.qml
|
|
||||||
FeesView 1.0 FeesView.qml
|
FeesView 1.0 FeesView.qml
|
||||||
NetworkCardsComponent 1.0 NetworkCardsComponent.qml
|
NetworkCardsComponent 1.0 NetworkCardsComponent.qml
|
||||||
NetworkSelector 1.0 NetworkSelector.qml
|
NetworkSelector 1.0 NetworkSelector.qml
|
||||||
|
|
Loading…
Reference in New Issue