From b5fafb55c9ba3e3e1c8122b066202784f1339691 Mon Sep 17 00:00:00 2001 From: xiphon Date: Wed, 22 Jan 2020 16:32:19 +0000 Subject: [PATCH] Transfer: display estimated transaction fee, requires #6302 --- js/Utils.js | 4 +++ pages/Transfer.qml | 59 ++++++++++++++++++++++++++++++++++---- src/libwalletqt/Wallet.cpp | 13 +++++++++ src/libwalletqt/Wallet.h | 5 ++++ 4 files changed, 75 insertions(+), 6 deletions(-) diff --git a/js/Utils.js b/js/Utils.js index f32f80a9..51395dce 100644 --- a/js/Utils.js +++ b/js/Utils.js @@ -133,3 +133,7 @@ function capitalize(s){ if (typeof s !== 'string') return '' return s.charAt(0).toUpperCase() + s.slice(1) } + +function removeTrailingZeros(value) { + return (value + '').replace(/(\.\d*[1-9])0+$/, '$1'); +} diff --git a/pages/Transfer.qml b/pages/Transfer.qml index 21d44ed9..bdda4019 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -27,6 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.9 +import QtQuick.Controls 1.4 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.2 import moneroComponents.Clipboard 1.0 @@ -38,6 +39,7 @@ import "../components" import "../components" as MoneroComponents import "." 1.0 import "../js/TxUtils.js" as TxUtils +import "../js/Utils.js" as Utils Rectangle { @@ -155,7 +157,7 @@ Rectangle { Amount ( Change account )") + translationManager.emptyString copyButton: !isNaN(amountLine.text) && persistentSettings.fiatPriceEnabled - copyButtonText: fiatApiCurrencySymbol() + " ~" + fiatApiConvertToFiat(amountLine.text) + copyButtonText: "~%1 %2".arg(fiatApiConvertToFiat(amountLine.text)).arg(fiatApiCurrencySymbol()) copyButtonEnabled: false onLabelLinkActivated: { @@ -186,14 +188,61 @@ Rectangle { regExp: /^(\d{1,8})?([\.]\d{1,12})?$/ } } + + MoneroComponents.TextPlain { + id: feeLabel + Layout.alignment: Qt.AlignRight + Layout.topMargin: 12 + font.family: MoneroComponents.Style.fontRegular.name + font.pixelSize: 14 + color: MoneroComponents.Style.defaultFontColor + property bool estimating: false + property var estimatedFee: null + property string estimatedFeeFiat: { + if (!persistentSettings.fiatPriceEnabled || estimatedFee == null) { + return ""; + } + const fiatFee = fiatApiConvertToFiat(estimatedFee); + return " (%1 %3)".arg(fiatFee < 0.01 ? "<0.01" : "~" + fiatFee).arg(fiatApiCurrencySymbol()); + } + property var fee: { + estimatedFee = null; + estimating = sendButton.enabled; + if (!sendButton.enabled) { + return; + } + currentWallet.estimateTransactionFeeAsync( + addressLine.text, + walletManager.amountFromString(amountLine.text), + priorityModelV5.get(priorityDropdown.currentIndex).priority, + function (amount) { + estimatedFee = Utils.removeTrailingZeros(amount); + estimating = false; + }); + } + text: { + if (!sendButton.enabled || estimatedFee == null) { + return "" + } + return "%1: ~%2 XMR".arg(qsTr("Fee")).arg(estimatedFee) + + estimatedFeeFiat + + translationManager.emptyString; + } + + BusyIndicator { + anchors.right: parent.right + running: feeLabel.estimating + height: parent.height + } + } } ColumnLayout { visible: appWindow.walletMode >= 2 - Layout.fillWidth: true + Layout.alignment: Qt.AlignTop Label { id: transactionPriority - Layout.topMargin: 12 + Layout.topMargin: 0 text: qsTr("Transaction priority") + translationManager.emptyString fontBold: false fontSize: 16 @@ -217,14 +266,12 @@ Rectangle { } StandardDropdown { - Layout.fillWidth: true + Layout.preferredWidth: 200 id: priorityDropdown Layout.topMargin: 5 currentIndex: 0 } } - // Make sure dropdown is on top - z: parent.z + 1 } // recipient address input diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index c32026f8..5f632725 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -575,6 +575,19 @@ void Wallet::disposeTransaction(UnsignedTransaction *t) delete t; } +void Wallet::estimateTransactionFeeAsync(const QString &destination, + quint64 amount, + PendingTransaction::Priority priority, + const QJSValue &callback) +{ + m_scheduler.run([this, destination, amount, priority] { + const uint64_t fee = m_walletImpl->estimateTransactionFee( + {std::make_pair(destination.toStdString(), amount)}, + static_cast(priority)); + return QJSValueList({QString::fromStdString(Monero::Wallet::displayAmount(fee))}); + }, callback); +} + TransactionHistory *Wallet::history() const { return m_history; diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index a6add1da..e43bd59d 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -248,6 +248,11 @@ public: //! deletes unsigned transaction and frees memory Q_INVOKABLE void disposeTransaction(UnsignedTransaction * t); + Q_INVOKABLE void estimateTransactionFeeAsync(const QString &destination, + quint64 amount, + PendingTransaction::Priority priority, + const QJSValue &callback); + //! returns transaction history TransactionHistory * history() const;