mirror of
https://github.com/monero-project/monero-gui
synced 2024-11-28 09:31:37 +01:00
Merge pull request #3163
25ca0811
transfer: new TxConfirmationDialog (rating89us)
This commit is contained in:
commit
08635e3030
466
components/TxConfirmationDialog.qml
Normal file
466
components/TxConfirmationDialog.qml
Normal file
@ -0,0 +1,466 @@
|
||||
// Copyright (c) 2014-2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// 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 "../components" as MoneroComponents
|
||||
import FontAwesome 1.0
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
x: parent.width/2 - root.width/2
|
||||
y: parent.height/2 - root.height/2
|
||||
// TODO: implement without hardcoding sizes
|
||||
width: 580
|
||||
height: 400
|
||||
color: MoneroComponents.Style.blackTheme ? "black" : "white"
|
||||
visible: false
|
||||
radius: 10
|
||||
border.color: MoneroComponents.Style.blackTheme ? Qt.rgba(255, 255, 255, 0.25) : Qt.rgba(0, 0, 0, 0.25)
|
||||
border.width: 1
|
||||
focus: true
|
||||
Keys.enabled: true
|
||||
Keys.onEscapePressed: {
|
||||
root.close()
|
||||
root.clearFields()
|
||||
root.rejected()
|
||||
}
|
||||
Keys.onEnterPressed: {
|
||||
if (root.state == "default") {
|
||||
root.close()
|
||||
root.accepted()
|
||||
} else if (root.state == "error") {
|
||||
root.close()
|
||||
root.clearFields()
|
||||
root.rejected()
|
||||
}
|
||||
}
|
||||
Keys.onReturnPressed: {
|
||||
if (root.state == "default") {
|
||||
root.close()
|
||||
root.accepted()
|
||||
} else if (root.state == "error") {
|
||||
root.close()
|
||||
root.clearFields()
|
||||
root.rejected()
|
||||
}
|
||||
}
|
||||
KeyNavigation.tab: confirmButton
|
||||
|
||||
property var transactionAmount: ""
|
||||
property var transactionAddress: ""
|
||||
property var transactionDescription: ""
|
||||
property var transactionFee: ""
|
||||
property var transactionPriority: ""
|
||||
property bool sweepUnmixable: false
|
||||
property alias errorText: errorText
|
||||
property alias confirmButton: confirmButton
|
||||
property alias backButton: backButton
|
||||
property alias bottomText: bottomText
|
||||
property alias bottomTextAnimation: bottomTextAnimation
|
||||
|
||||
state: "default"
|
||||
states: [
|
||||
State {
|
||||
// waiting for user action, show tx details + back and confirm buttons
|
||||
name: "default";
|
||||
when: errorText.text == "" && bottomText.text == ""
|
||||
PropertyChanges { target: errorText; visible: false }
|
||||
PropertyChanges { target: txAmountText; visible: root.transactionAmount !== "(all)" || (root.transactionAmount === "(all)" && currentWallet.isHwBacked() === true) }
|
||||
PropertyChanges { target: txAmountBusyIndicator; visible: !txAmountText.visible }
|
||||
PropertyChanges { target: txFiatAmountText; visible: txAmountText.visible && persistentSettings.fiatPriceEnabled && root.transactionAmount !== "(all)" }
|
||||
PropertyChanges { target: txDetails; visible: true }
|
||||
PropertyChanges { target: bottom; visible: true }
|
||||
PropertyChanges { target: bottomMessage; visible: false }
|
||||
PropertyChanges { target: buttons; visible: true }
|
||||
PropertyChanges { target: backButton; visible: true; primary: false }
|
||||
PropertyChanges { target: confirmButton; visible: true }
|
||||
}, State {
|
||||
// error message being displayed, show only back button
|
||||
name: "error";
|
||||
when: errorText.text !== ""
|
||||
PropertyChanges { target: dialogTitle; text: "Error" }
|
||||
PropertyChanges { target: errorText; visible: true }
|
||||
PropertyChanges { target: txAmountText; visible: false }
|
||||
PropertyChanges { target: txAmountBusyIndicator; visible: false }
|
||||
PropertyChanges { target: txFiatAmountText; visible: false }
|
||||
PropertyChanges { target: txDetails; visible: false }
|
||||
PropertyChanges { target: bottom; visible: true }
|
||||
PropertyChanges { target: bottomMessage; visible: false }
|
||||
PropertyChanges { target: buttons; visible: true }
|
||||
PropertyChanges { target: backButton; visible: true; primary: true }
|
||||
PropertyChanges { target: confirmButton; visible: false }
|
||||
}, State {
|
||||
// creating or sending transaction, show tx details and don't show any button
|
||||
name: "bottomText";
|
||||
when: errorText.text == "" && bottomText.text !== ""
|
||||
PropertyChanges { target: errorText; visible: false }
|
||||
PropertyChanges { target: txAmountText; visible: root.transactionAmount !== "(all)" || (root.transactionAmount === "(all)" && currentWallet.isHwBacked() === true) }
|
||||
PropertyChanges { target: txAmountBusyIndicator; visible: !txAmountText.visible }
|
||||
PropertyChanges { target: txFiatAmountText; visible: txAmountText.visible && persistentSettings.fiatPriceEnabled && root.transactionAmount !== "(all)" }
|
||||
PropertyChanges { target: txDetails; visible: true }
|
||||
PropertyChanges { target: bottom; visible: true }
|
||||
PropertyChanges { target: bottomMessage; visible: true }
|
||||
PropertyChanges { target: buttons; visible: false }
|
||||
}
|
||||
]
|
||||
|
||||
// same signals as Dialog has
|
||||
signal accepted()
|
||||
signal rejected()
|
||||
|
||||
function open() {
|
||||
root.visible = true;
|
||||
|
||||
//clean previous error message
|
||||
errorText.text = "";
|
||||
root.forceActiveFocus()
|
||||
}
|
||||
|
||||
function close() {
|
||||
root.visible = false;
|
||||
}
|
||||
|
||||
function clearFields() {
|
||||
root.transactionAmount = "";
|
||||
root.transactionAddress = "";
|
||||
root.transactionDescription = "";
|
||||
root.transactionFee = "";
|
||||
root.transactionPriority = "";
|
||||
root.sweepUnmixable = false;
|
||||
}
|
||||
|
||||
function showFiatConversion(valueXMR) {
|
||||
const fiatFee = fiatApiConvertToFiat(valueXMR);
|
||||
return "%1 %2".arg(fiatFee < 0.01 ? "<0.01" : "~" + fiatFee).arg(fiatApiCurrencySymbol());
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 10
|
||||
anchors.fill: parent
|
||||
anchors.margins: 25
|
||||
|
||||
RowLayout {
|
||||
Layout.topMargin: 10
|
||||
Layout.fillWidth: true
|
||||
|
||||
MoneroComponents.Label {
|
||||
id: dialogTitle
|
||||
Layout.fillWidth: true
|
||||
fontSize: 18
|
||||
fontFamily: "Arial"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: {
|
||||
if (appWindow.viewOnly) {
|
||||
return qsTr("Create transaction file") + translationManager.emptyString;
|
||||
} else if (root.sweepUnmixable) {
|
||||
return qsTr("Sweep unmixable outputs") + translationManager.emptyString;
|
||||
} else {
|
||||
return qsTr("Confirm send") + translationManager.emptyString;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: errorText
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
wrapMode: Text.Wrap
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 71
|
||||
|
||||
BusyIndicator {
|
||||
id: txAmountBusyIndicator
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||
running: root.transactionAmount == "(all)"
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txAmountText
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: root.transactionAmount == "(all)" && currentWallet.isHwBacked() === true ? 32 : 42
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
text: {
|
||||
if (root.transactionAmount == "(all)" && currentWallet.isHwBacked() === true) {
|
||||
return qsTr("All unlocked balance") + translationManager.emptyString;
|
||||
} else {
|
||||
return root.transactionAmount + " XMR " + translationManager.emptyString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txFiatAmountText
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: 20
|
||||
color: MoneroComponents.Style.buttonSecondaryTextColor
|
||||
text: showFiatConversion(transactionAmount) + translationManager.emptyString
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
id: txDetails
|
||||
Layout.fillWidth: true
|
||||
columnSpacing: 15
|
||||
rowSpacing: 16
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
color: MoneroComponents.Style.dimmedFontColor
|
||||
text: qsTr("From") + ":" + translationManager.emptyString
|
||||
font.pixelSize: 15
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 16
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: 15
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
text: {
|
||||
if (currentWallet) {
|
||||
var walletTitle = function() {
|
||||
if (currentWallet.isLedger()) {
|
||||
return "Ledger";
|
||||
} else if (currentWallet.isTrezor()) {
|
||||
return "Trezor";
|
||||
} else {
|
||||
return qsTr("My wallet");
|
||||
}
|
||||
}
|
||||
var walletName = appWindow.walletName;
|
||||
if (appWindow.currentWallet.numSubaddressAccounts() > 1) {
|
||||
var currentSubaddressAccount = currentWallet.currentSubaddressAccount;
|
||||
var currentAccountLabel = currentWallet.getSubaddressLabel(currentWallet.currentSubaddressAccount, 0);
|
||||
return walletTitle() + " (" + walletName + ")" + "<br>" + qsTr("Account #") + currentSubaddressAccount + (currentAccountLabel !== "" ? " (" + currentAccountLabel + ")" : "") + translationManager.emptyString;
|
||||
} else {
|
||||
return walletTitle() + " (" + walletName + ")" + translationManager.emptyString;
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: 15
|
||||
color: MoneroComponents.Style.dimmedFontColor
|
||||
text: qsTr("To") + ":" + translationManager.emptyString
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 16
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: 15
|
||||
font.family: MoneroComponents.Style.fontRegular.name
|
||||
textFormat: Text.RichText
|
||||
wrapMode: Text.Wrap
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
text: {
|
||||
if (root.transactionAddress) {
|
||||
const addressBookName = currentWallet ? currentWallet.addressBook.getDescription(root.transactionAddress) : null;
|
||||
var fulladdress = root.transactionAddress;
|
||||
var spacedaddress = fulladdress.match(/.{1,4}/g);
|
||||
var spacedaddress = spacedaddress.join(' ');
|
||||
if (!addressBookName) {
|
||||
return qsTr("Monero address") + "<br>" + spacedaddress + translationManager.emptyString;
|
||||
} else {
|
||||
return FontAwesome.addressBook + " " + addressBookName + "<br>" + spacedaddress;
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
color: MoneroComponents.Style.dimmedFontColor
|
||||
text: qsTr("Fee") + ":" + translationManager.emptyString
|
||||
font.pixelSize: 15
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 16
|
||||
|
||||
Text {
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
font.pixelSize: 15
|
||||
text: {
|
||||
if (currentWallet) {
|
||||
if (!root.transactionFee) {
|
||||
if (currentWallet.isHwBacked() === true) {
|
||||
return qsTr("See on device") + translationManager.emptyString;
|
||||
} else {
|
||||
return qsTr("Calculating fee") + "..." + translationManager.emptyString;
|
||||
}
|
||||
} else {
|
||||
return root.transactionFee + " XMR"
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 8
|
||||
color: MoneroComponents.Style.buttonSecondaryTextColor
|
||||
visible: persistentSettings.fiatPriceEnabled && root.transactionFee
|
||||
font.pixelSize: 15
|
||||
text: showFiatConversion(root.transactionFee)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: bottom
|
||||
Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
id: bottomMessage
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 50
|
||||
|
||||
BusyIndicator {
|
||||
visible: !bottomTextAnimation.running
|
||||
running: !bottomTextAnimation.running
|
||||
scale: .5
|
||||
}
|
||||
|
||||
Text {
|
||||
id: bottomText
|
||||
color: MoneroComponents.Style.defaultFontColor
|
||||
text: ""
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.Wrap
|
||||
font.pixelSize: 17
|
||||
opacity: 1
|
||||
|
||||
SequentialAnimation{
|
||||
id:bottomTextAnimation
|
||||
running: false
|
||||
loops: Animation.Infinite
|
||||
alwaysRunToEnd: true
|
||||
NumberAnimation { target: bottomText; property: "opacity"; to: 0; duration: 500}
|
||||
NumberAnimation { target: bottomText; property: "opacity"; to: 1; duration: 500}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: buttons
|
||||
spacing: 70
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 50
|
||||
|
||||
MoneroComponents.StandardButton {
|
||||
id: backButton
|
||||
text: qsTr("Back") + translationManager.emptyString;
|
||||
width: 200
|
||||
focus: false
|
||||
primary: false
|
||||
KeyNavigation.tab: confirmButton
|
||||
Keys.enabled: backButton.visible
|
||||
Keys.onReturnPressed: backButton.onClicked
|
||||
Keys.onEnterPressed: backButton.onClicked
|
||||
Keys.onEscapePressed: {
|
||||
root.close()
|
||||
root.clearFields()
|
||||
root.rejected()
|
||||
}
|
||||
onClicked: {
|
||||
root.close()
|
||||
root.clearFields()
|
||||
root.rejected()
|
||||
}
|
||||
}
|
||||
|
||||
MoneroComponents.StandardButton {
|
||||
id: confirmButton
|
||||
text: qsTr("Confirm") + translationManager.emptyString;
|
||||
rightIcon: "qrc:///images/rightArrow.png"
|
||||
width: 200
|
||||
focus: false
|
||||
KeyNavigation.tab: backButton
|
||||
Keys.enabled: confirmButton.visible
|
||||
Keys.onReturnPressed: confirmButton.onClicked
|
||||
Keys.onEnterPressed: confirmButton.onClicked
|
||||
Keys.onEscapePressed: {
|
||||
root.close()
|
||||
root.clearFields()
|
||||
root.rejected()
|
||||
}
|
||||
onClicked: {
|
||||
root.close()
|
||||
root.accepted()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
155
main.qml
155
main.qml
@ -65,7 +65,6 @@ ApplicationWindow {
|
||||
property var currentWallet;
|
||||
property bool disconnected: currentWallet ? currentWallet.disconnected : false
|
||||
property var transaction;
|
||||
property var transactionDescription;
|
||||
property var walletPassword
|
||||
property int restoreHeight:0
|
||||
property bool daemonSynced: false
|
||||
@ -508,16 +507,30 @@ ApplicationWindow {
|
||||
}
|
||||
|
||||
function onDeviceButtonRequest(code){
|
||||
prevSplashText = splash.messageText;
|
||||
splashDisplayedBeforeButtonRequest = splash.visible;
|
||||
appWindow.showProcessingSplash(qsTr("Please proceed to the device..."));
|
||||
if (txConfirmationPopup.visible) {
|
||||
txConfirmationPopup.bottomTextAnimation.running = true
|
||||
if (!txConfirmationPopup.errorText.visible) {
|
||||
txConfirmationPopup.bottomText.text = qsTr("Please confirm transaction on the device...") + translationManager.emptyString;
|
||||
} else {
|
||||
txConfirmationPopup.bottomText.text = qsTr("Please proceed to the device...") + translationManager.emptyString;
|
||||
}
|
||||
} else {
|
||||
prevSplashText = splash.messageText;
|
||||
splashDisplayedBeforeButtonRequest = splash.visible;
|
||||
appWindow.showProcessingSplash(qsTr("Please proceed to the device..."));
|
||||
}
|
||||
}
|
||||
|
||||
function onDeviceButtonPressed(){
|
||||
if (splashDisplayedBeforeButtonRequest){
|
||||
appWindow.showProcessingSplash(prevSplashText);
|
||||
if (txConfirmationPopup.visible) {
|
||||
txConfirmationPopup.bottomTextAnimation.running = false;
|
||||
txConfirmationPopup.bottomText.text = qsTr("Signing transaction in the device...") + translationManager.emptyString;
|
||||
} else {
|
||||
hideProcessingSplash();
|
||||
if (splashDisplayedBeforeButtonRequest){
|
||||
appWindow.showProcessingSplash(prevSplashText);
|
||||
} else {
|
||||
hideProcessingSplash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -812,51 +825,33 @@ ApplicationWindow {
|
||||
|
||||
function onTransactionCreated(pendingTransaction,address,paymentId,mixinCount){
|
||||
console.log("Transaction created");
|
||||
hideProcessingSplash();
|
||||
txConfirmationPopup.bottomText.text = "";
|
||||
transaction = pendingTransaction;
|
||||
// validate address;
|
||||
if (transaction.status !== PendingTransaction.Status_Ok) {
|
||||
console.error("Can't create transaction: ", transaction.errorString);
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
if (currentWallet.connected() == Wallet.ConnectionStatus_WrongVersion)
|
||||
informationPopup.text = qsTr("Can't create transaction: Wrong daemon version: ") + transaction.errorString
|
||||
else
|
||||
informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString
|
||||
informationPopup.icon = StandardIcon.Critical
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open();
|
||||
if (currentWallet.connected() == Wallet.ConnectionStatus_WrongVersion) {
|
||||
txConfirmationPopup.errorText.text = qsTr("Can't create transaction: Wrong daemon version: ") + transaction.errorString
|
||||
} else {
|
||||
txConfirmationPopup.errorText.text = qsTr("Can't create transaction: ") + transaction.errorString
|
||||
}
|
||||
// deleting transaction object, we don't want memleaks
|
||||
currentWallet.disposeTransaction(transaction);
|
||||
|
||||
} else if (transaction.txCount == 0) {
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString
|
||||
informationPopup.text = qsTr("No unmixable outputs to sweep") + translationManager.emptyString
|
||||
informationPopup.icon = StandardIcon.Information
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open()
|
||||
console.error("Can't create transaction: ", transaction.errorString);
|
||||
txConfirmationPopup.errorText.text = qsTr("No unmixable outputs to sweep") + translationManager.emptyString
|
||||
// deleting transaction object, we don't want memleaks
|
||||
currentWallet.disposeTransaction(transaction);
|
||||
} else {
|
||||
console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount)
|
||||
+ ", fee: " + walletManager.displayAmount(transaction.fee));
|
||||
|
||||
// here we show confirmation popup;
|
||||
transactionConfirmationPopup.title = qsTr("Please confirm transaction:\n") + translationManager.emptyString;
|
||||
transactionConfirmationPopup.text = "";
|
||||
transactionConfirmationPopup.text += (address === "" ? "" : (qsTr("Address: ") + address));
|
||||
transactionConfirmationPopup.text += (paymentId === "" ? "" : (qsTr("\nPayment ID: ") + paymentId));
|
||||
transactionConfirmationPopup.text += qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount);
|
||||
transactionConfirmationPopup.text += qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee);
|
||||
transactionConfirmationPopup.text += qsTr("\nRingsize: ") + (mixinCount + 1);
|
||||
transactionConfirmationPopup.text += qsTr("\n\nNumber of transactions: ") + transaction.txCount
|
||||
transactionConfirmationPopup.text += (transactionDescription === "" ? "" : (qsTr("\nDescription: ") + transactionDescription))
|
||||
for (var i = 0; i < transaction.subaddrIndices.length; ++i){
|
||||
transactionConfirmationPopup.text += qsTr("\nSpending address index: ") + transaction.subaddrIndices[i];
|
||||
}
|
||||
|
||||
transactionConfirmationPopup.text += translationManager.emptyString;
|
||||
transactionConfirmationPopup.icon = StandardIcon.Question
|
||||
transactionConfirmationPopup.open()
|
||||
// here we update txConfirmationPopup
|
||||
txConfirmationPopup.transactionAmount = Utils.removeTrailingZeros(walletManager.displayAmount(transaction.amount));
|
||||
txConfirmationPopup.transactionFee = Utils.removeTrailingZeros(walletManager.displayAmount(transaction.fee));
|
||||
txConfirmationPopup.confirmButton.text = viewOnly ? qsTr("Save as file") : qsTr("Confirm") + translationManager.emptyString;
|
||||
txConfirmationPopup.confirmButton.rightIcon = viewOnly ? "" : "qrc:///images/rightArrow.png"
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,12 +865,12 @@ ApplicationWindow {
|
||||
", mixins: ", mixinCount,
|
||||
", priority: ", priority,
|
||||
", description: ", description);
|
||||
|
||||
var splashMsg = qsTr("Creating transaction...");
|
||||
splashMsg += appWindow.currentWallet.isLedger() ? qsTr("\n\nPlease check your hardware wallet –\nyour input may be required.") : "";
|
||||
showProcessingSplash(splashMsg);
|
||||
|
||||
transactionDescription = description;
|
||||
txConfirmationPopup.bottomTextAnimation.running = false
|
||||
txConfirmationPopup.bottomText.text = qsTr("Creating transaction...") + translationManager.emptyString;
|
||||
txConfirmationPopup.transactionAddress = address;
|
||||
txConfirmationPopup.transactionAmount = Utils.removeTrailingZeros(amount);
|
||||
txConfirmationPopup.transactionPriority = priority;
|
||||
txConfirmationPopup.transactionDescription = description;
|
||||
|
||||
// validate amount;
|
||||
if (amount !== "(all)") {
|
||||
@ -883,31 +878,21 @@ ApplicationWindow {
|
||||
console.log("integer amount: ", amountxmr);
|
||||
console.log("integer unlocked", currentWallet.unlockedBalance())
|
||||
if (amountxmr <= 0) {
|
||||
hideProcessingSplash()
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2")
|
||||
.arg(walletManager.displayAmount(0))
|
||||
.arg(walletManager.displayAmount(currentWallet.unlockedBalance()))
|
||||
+ translationManager.emptyString
|
||||
|
||||
informationPopup.icon = StandardIcon.Critical
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open()
|
||||
txConfirmationPopup.errorText.text = qsTr("Amount is wrong: expected number from %1 to %2")
|
||||
.arg(walletManager.displayAmount(0))
|
||||
.arg(walletManager.displayAmount(currentWallet.unlockedBalance()))
|
||||
+ translationManager.emptyString;
|
||||
return;
|
||||
} else if (amountxmr > currentWallet.unlockedBalance()) {
|
||||
hideProcessingSplash()
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
informationPopup.text = qsTr("Insufficient funds. Unlocked balance: %1")
|
||||
.arg(walletManager.displayAmount(currentWallet.unlockedBalance()))
|
||||
+ translationManager.emptyString
|
||||
|
||||
informationPopup.icon = StandardIcon.Critical
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open()
|
||||
txConfirmationPopup.errorText.text = qsTr("Insufficient funds. Unlocked balance: %1")
|
||||
.arg(walletManager.displayAmount(currentWallet.unlockedBalance()))
|
||||
+ translationManager.emptyString;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
txConfirmationPopup.open();
|
||||
|
||||
if (amount === "(all)")
|
||||
currentWallet.createTransactionAllAsync(address, paymentId, mixinCount, priority);
|
||||
else
|
||||
@ -935,40 +920,27 @@ ApplicationWindow {
|
||||
function handleSweepUnmixable() {
|
||||
console.log("Creating transaction: ")
|
||||
|
||||
txConfirmationPopup.sweepUnmixable = true;
|
||||
transaction = currentWallet.createSweepUnmixableTransaction();
|
||||
if (transaction.status !== PendingTransaction.Status_Ok) {
|
||||
console.error("Can't create transaction: ", transaction.errorString);
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||
informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString
|
||||
informationPopup.icon = StandardIcon.Critical
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open();
|
||||
txConfirmationPopup.errorText.text = qsTr("Can't create transaction: ") + transaction.errorString + translationManager.emptyString
|
||||
// deleting transaction object, we don't want memleaks
|
||||
currentWallet.disposeTransaction(transaction);
|
||||
|
||||
} else if (transaction.txCount == 0) {
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString
|
||||
informationPopup.text = qsTr("No unmixable outputs to sweep") + translationManager.emptyString
|
||||
informationPopup.icon = StandardIcon.Information
|
||||
informationPopup.onCloseCallback = null
|
||||
informationPopup.open()
|
||||
console.error("No unmixable outputs to sweep");
|
||||
txConfirmationPopup.errorText.text = qsTr("No unmixable outputs to sweep") + translationManager.emptyString
|
||||
// deleting transaction object, we don't want memleaks
|
||||
currentWallet.disposeTransaction(transaction);
|
||||
} else {
|
||||
console.log("Transaction created, amount: " + walletManager.displayAmount(transaction.amount)
|
||||
+ ", fee: " + walletManager.displayAmount(transaction.fee));
|
||||
|
||||
// here we show confirmation popup;
|
||||
|
||||
transactionConfirmationPopup.title = qsTr("Confirmation") + translationManager.emptyString
|
||||
transactionConfirmationPopup.text = qsTr("Please confirm transaction:\n")
|
||||
+ qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
|
||||
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
|
||||
+ translationManager.emptyString
|
||||
transactionConfirmationPopup.icon = StandardIcon.Question
|
||||
transactionConfirmationPopup.open()
|
||||
txConfirmationPopup.transactionAmount = Utils.removeTrailingZeros(walletManager.displayAmount(transaction.amount));
|
||||
txConfirmationPopup.transactionFee = Utils.removeTrailingZeros(walletManager.displayAmount(transaction.fee));
|
||||
// committing transaction
|
||||
}
|
||||
txConfirmationPopup.open();
|
||||
}
|
||||
|
||||
// called after user confirms transaction
|
||||
@ -986,13 +958,10 @@ ApplicationWindow {
|
||||
// Store to file
|
||||
transaction.setFilename(path);
|
||||
}
|
||||
|
||||
appWindow.showProcessingSplash(qsTr("Sending transaction ..."));
|
||||
currentWallet.commitTransactionAsync(transaction);
|
||||
}
|
||||
|
||||
function onTransactionCommitted(success, transaction, txid) {
|
||||
hideProcessingSplash();
|
||||
if (!success) {
|
||||
console.log("Error committing transaction: " + transaction.errorString);
|
||||
informationPopup.title = qsTr("Error") + translationManager.emptyString
|
||||
@ -1001,13 +970,14 @@ ApplicationWindow {
|
||||
informationPopup.onCloseCallback = null;
|
||||
informationPopup.open();
|
||||
} else {
|
||||
if (transactionDescription.length > 0) {
|
||||
if (txConfirmationPopup.transactionDescription.length > 0) {
|
||||
for (var i = 0; i < txid.length; ++i)
|
||||
currentWallet.setUserNote(txid[i], transactionDescription);
|
||||
currentWallet.setUserNote(txid[i], txConfirmationPopup.transactionDescription);
|
||||
}
|
||||
|
||||
// Clear tx fields
|
||||
middlePanel.transferView.clearFields()
|
||||
txConfirmationPopup.clearFields()
|
||||
successfulTxPopup.open(txid)
|
||||
}
|
||||
currentWallet.refresh()
|
||||
@ -1459,10 +1429,11 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
// Confrirmation aka question dialog
|
||||
StandardDialog {
|
||||
// Transaction confirmation popup
|
||||
TxConfirmationDialog {
|
||||
// dynamically change onclose handler
|
||||
id: txConfirmationPopup
|
||||
z: parent.z + 1
|
||||
id: transactionConfirmationPopup
|
||||
onAccepted: {
|
||||
var handleAccepted = function() {
|
||||
// Save transaction to file if view only wallet
|
||||
@ -1768,7 +1739,7 @@ ApplicationWindow {
|
||||
anchors.fill: blurredArea
|
||||
source: blurredArea
|
||||
radius: 64
|
||||
visible: passwordDialog.visible || inputDialog.visible || splash.visible || updateDialog.visible || devicePassphraseDialog.visible || successfulTxPopup.visible
|
||||
visible: passwordDialog.visible || inputDialog.visible || splash.visible || updateDialog.visible || devicePassphraseDialog.visible || txConfirmationPopup.visible || successfulTxPopup.visible
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user