2020-10-15 19:18:54 +02:00
/*
* This file is part of the Flowee project
2021-04-20 19:30:56 +02:00
* Copyright (C) 2020-2021 Tom Zander <tom@flowee.org>
2020-10-15 19:18:54 +02:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2021-05-23 00:27:34 +02:00
import QtQuick 2.11
import QtQuick . Controls 2.11
import QtQuick . Layouts 1.11
import QtQuick . Window 2.11
2020-10-15 19:18:54 +02:00
2020-06-11 17:41:18 +02:00
import Flowee . org . pay 1.0
2020-10-15 19:18:54 +02:00
import "./ControlColors.js" as ControlColors
2020-06-11 17:41:18 +02:00
2021-04-22 22:04:30 +02:00
Rectangle {
2020-06-11 17:41:18 +02:00
id: root
2020-10-15 19:18:54 +02:00
function reset ( ) {
// reset fields
2020-10-24 14:50:04 +02:00
bitcoinValueField . reset ( ) ;
bitcoinValueField . maxSelected = false ;
2021-04-26 21:59:22 +02:00
destination . forceLegacyOk = false ;
2020-10-24 14:50:04 +02:00
destination . text = "" ;
2021-04-26 21:59:22 +02:00
destination . updateColor ( ) ;
2021-04-26 19:50:45 +02:00
delete root . payment ;
root . payment = null ;
2020-06-11 17:41:18 +02:00
}
2021-04-22 22:04:30 +02:00
color: mainWindow . palette . window
2021-04-20 19:30:56 +02:00
2021-04-23 19:59:49 +02:00
property QtObject payment: null
2021-04-22 22:04:30 +02:00
Column {
x: 10
y: 10
spacing: 10
width: parent . width - 20
2020-10-15 19:18:54 +02:00
Label {
2021-01-29 10:27:24 +01:00
text: qsTr ( "Destination" ) + ":"
2020-06-12 23:37:32 +02:00
Layout.columnSpan: 2
2021-04-22 22:04:30 +02:00
}
RowLayout {
width: parent . width
2021-05-05 11:48:44 +02:00
FloweeTextField {
2021-04-22 22:04:30 +02:00
id: destination
focus: true
2021-07-26 15:07:38 +02:00
property bool addressOk: ( addressType === Pay . CashPKH || addressType === Pay . CashSH )
|| ( forceLegacyOk && ( addressType === Pay . LegacySH || addressType === Pay . LegacyPKH ) )
2021-04-22 22:04:30 +02:00
property var addressType: Flowee . identifyString ( text ) ;
property bool forceLegacyOk: false
placeholderText: qsTr ( "Enter Bitcoin Cash Address" )
Layout.fillWidth: true
Layout.columnSpan: 3
2021-04-26 21:59:22 +02:00
onFocusChanged: updateColor ( ) ;
onAddressOkChanged: updateColor ( )
function updateColor ( ) {
if ( ! activeFocus && text !== "" && ! addressOk )
2021-04-22 22:04:30 +02:00
color = Flowee . useDarkSkin ? "#ff6568" : "red"
2021-04-26 21:59:22 +02:00
else
color = mainWindow . palette . text
2021-04-22 22:04:30 +02:00
}
2021-04-26 21:59:22 +02:00
2021-04-22 22:04:30 +02:00
}
Label {
id: checked
color: "green"
2021-04-23 19:59:49 +02:00
2021-04-22 22:04:30 +02:00
font.pixelSize: 24
text: destination . addressOk ? "✔" : " "
}
2020-06-12 20:53:01 +02:00
}
2021-04-23 19:59:49 +02:00
Label {
id: payAmount
text: qsTr ( "Amount" ) + ":"
}
RowLayout {
2021-04-26 19:50:45 +02:00
/* TODO hook this up when we add fiat support.
2021-05-05 11:48:44 +02:00
FloweeTextField {
2021-04-22 22:04:30 +02:00
text: "0.0 EUR"
}
FloweeCheckBox {
id: amountSelector
}
2021-04-26 19:50:45 +02:00
*/
2021-04-22 22:04:30 +02:00
BitcoinValueField {
id: bitcoinValueField
property bool maxSelected: false
2021-04-26 19:50:45 +02:00
property string previousAmountString: ""
2020-06-12 23:37:32 +02:00
2021-04-22 22:04:30 +02:00
fontPtSize: payAmount . font . pointSize
onValueChanged: maxSelected = false
2021-04-26 19:50:45 +02:00
function update ( setToMax ) {
if ( setToMax ) {
// backup what the user typed there, to be used if she no longer wants 'max'
previousAmountString = bitcoinValueField . valueObject . enteredString ;
value = portfolio . current . balanceConfirmed + portfolio . current . balanceUnconfirmed
} else {
valueObject . strValue = previousAmountString
}
}
Connections {
target: portfolio
function onCurrentChanged ( ) {
var setToMax = bitcoinValueField . maxSelected
if ( setToMax ) {
bitcoinValueField . update ( setToMax ) ;
bitcoinValueField . maxSelected = setToMax ; // undo any changes in the button
}
}
}
2021-04-22 22:04:30 +02:00
}
2020-10-23 22:34:34 +02:00
Button2 {
id: sendAll
2020-10-24 14:50:04 +02:00
text: qsTr ( "Max" )
checkable: true
checked: bitcoinValueField . maxSelected
onClicked: {
var isChecked = ! bitcoinValueField . maxSelected // simply invert
2021-04-26 19:50:45 +02:00
bitcoinValueField . update ( isChecked ) ;
2020-10-24 14:50:04 +02:00
bitcoinValueField . maxSelected = isChecked
}
2020-10-23 22:34:34 +02:00
}
2021-04-22 22:04:30 +02:00
}
2021-04-23 19:59:49 +02:00
2021-04-22 22:04:30 +02:00
RowLayout {
width: parent . width
2021-04-26 19:50:45 +02:00
/* TODO future feature.
2021-04-23 19:59:49 +02:00
Button2 {
2021-04-26 19:50:45 +02:00
text: qsTr("Add Advanced Option...")
2021-04-23 19:59:49 +02:00
}
2021-04-26 19:50:45 +02:00
*/
2020-10-23 22:34:34 +02:00
Item {
width: 1 ; height: 1
Layout.fillWidth: true
}
2020-10-15 20:49:50 +02:00
Button2 {
2021-04-26 19:57:00 +02:00
id: prepareButton
2021-04-23 19:59:49 +02:00
text: qsTr ( "Prepare" )
2020-10-23 22:34:34 +02:00
enabled: ( bitcoinValueField . value > 0
|| bitcoinValueField . maxSelected ) && destination . addressOk ;
2020-06-12 23:37:32 +02:00
2021-04-26 19:57:00 +02:00
property QtObject portfolioUsed: null
2020-06-12 23:37:32 +02:00
onClicked: {
2020-10-23 22:34:34 +02:00
if ( bitcoinValueField . maxSelected )
var payment = portfolio . startPayAllToAddress ( destination . text ) ;
else
payment = portfolio . startPayToAddress ( destination . text , bitcoinValueField . valueObject ) ;
2021-04-26 19:50:45 +02:00
delete root . payment ;
2021-04-23 19:59:49 +02:00
root . payment = payment ;
2020-10-23 22:34:34 +02:00
payment . approveAndSign ( ) ;
2021-04-26 19:57:00 +02:00
portfolioUsed = portfolio . current
2020-10-15 19:18:54 +02:00
}
}
2020-06-12 23:37:32 +02:00
}
2021-04-29 16:15:05 +02:00
Label {
text: qsTr ( "Not enough funds in account to make payment!" )
2021-05-10 12:47:54 +02:00
visible: root . payment != null && ! root . payment . paymentOk
2021-04-29 16:15:05 +02:00
}
2021-04-22 22:04:30 +02:00
FloweeGroupBox {
id: txDetails
Layout.columnSpan: 4
2021-04-23 19:59:49 +02:00
title: qsTr ( "Transaction Details" )
2021-04-22 22:04:30 +02:00
width: parent . width
2020-06-12 20:53:01 +02:00
2021-04-29 16:15:05 +02:00
2021-04-23 19:59:49 +02:00
content: GridLayout {
columns: 2
2021-05-10 12:47:54 +02:00
property bool txOk: root . payment != null && root . payment . paymentOk
2020-06-12 20:53:01 +02:00
2021-04-29 16:15:05 +02:00
Label {
text: qsTr ( "Destination" ) + ":"
Layout.alignment: Qt . AlignRight
visible: finalDestination . visible
}
Label {
id: finalDestination
2021-05-10 12:47:54 +02:00
text: root . payment == null ? "" : root . payment . formattedTargetAddress
2021-04-29 16:15:05 +02:00
wrapMode: Text . WrapAnywhere
Layout.fillWidth: true
visible: text !== "" && text != destination . text
}
Label {
// no need translating this one.
text: "TxId:"
Layout.alignment: Qt . AlignRight | Qt . AlignTop
}
2020-06-12 23:37:32 +02:00
2021-05-01 12:49:07 +02:00
LabelWithClipboard {
2021-05-10 12:47:54 +02:00
text: root . payment == null ? qsTr ( "Not prepared yet" ) : root . payment . txid
2021-04-29 16:15:05 +02:00
Layout.fillWidth: true
}
2021-04-23 19:59:49 +02:00
Label {
text: qsTr ( "Fee" ) + ":"
Layout.alignment: Qt . AlignRight
2021-01-29 10:27:24 +01:00
}
2021-05-07 12:46:41 +02:00
BitcoinAmountLabel {
value: ! parent . txOk ? 0 : root . payment . assignedFee
colorize: false
2021-04-23 19:59:49 +02:00
}
Label {
text: qsTr ( "Transaction size" ) + ":"
Layout.alignment: Qt . AlignRight
}
Label {
text: {
2021-04-29 16:15:05 +02:00
if ( ! parent . txOk )
2021-04-23 19:59:49 +02:00
return "" ;
var rc = root . payment . txSize ;
return qsTr ( "%1 bytes" , "" , rc ) . arg ( rc )
}
}
Label {
text: qsTr ( "Fee per byte" ) + ":"
Layout.alignment: Qt . AlignRight
}
Label {
text: {
2021-04-29 16:15:05 +02:00
if ( ! parent . txOk )
2021-04-23 19:59:49 +02:00
return "" ;
var rc = root . payment . assignedFee / root . payment . txSize ;
2021-04-26 19:50:45 +02:00
var fee = rc . toFixed ( 3 ) ; // no more than 3 numbers behind the separator
fee = ( fee * 1.0 ) . toString ( ) ; // remove trailing zero's (1.000 => 1)
return qsTr ( "%1 sat/byte" , "fee" , rc ) . arg ( fee ) ;
2021-04-23 19:59:49 +02:00
}
2021-01-29 10:27:24 +01:00
}
2020-10-15 19:18:54 +02:00
}
}
2020-06-13 19:22:08 +02:00
2021-04-23 19:59:49 +02:00
RowLayout {
width: parent . width
Item {
width: 1 ; height: 1
Layout.fillWidth: true
}
Button2 {
id: button
text: qsTr ( "Send" )
2021-05-10 12:47:54 +02:00
enabled: root . payment != null && root . payment . paymentOk
2021-04-26 19:57:00 +02:00
&& prepareButton . portfolioUsed === portfolio . current // also make sure we prepared for the current portfolio.
2021-04-23 19:59:49 +02:00
onClicked: {
2021-04-26 19:50:45 +02:00
root . payment . sendTx ( ) ;
root . payment = null
reset ( ) ;
2020-10-23 20:20:42 +02:00
}
2020-06-12 23:37:32 +02:00
}
2021-04-23 19:59:49 +02:00
Button2 {
text: qsTr ( "Cancel" )
onClicked: root . reset ( ) ;
}
2020-06-12 20:53:01 +02:00
}
2021-04-26 21:59:22 +02:00
}
Item {
// overlay item
anchors.fill: parent
Item {
// BTC address warning.
2021-07-26 15:07:38 +02:00
visible: ( destination . addressType === Pay . LegacySH || destination . addressType === Pay . LegacyPKH )
&& destination . forceLegacyOk === false ;
2021-04-26 21:59:22 +02:00
onVisibleChanged: {
var pos = parent . mapFromItem ( destination , 0 , destination . height ) ;
// console.log("xxxx " + pos.x + ", " + pos.y);
x = pos . x + 20
2021-04-28 17:03:08 +02:00
y = pos . y + 25
2021-04-26 21:59:22 +02:00
}
2021-04-23 19:59:49 +02:00
2021-04-26 21:59:22 +02:00
width: destination . width - 40
height: warningColumn . height + 20
Rectangle {
anchors.fill: warningColumn
anchors.margins: - 10
color: warning . palette . window
border.width: 3
border.color: "red"
radius: 10
}
ArrowPoint {
x: 40
anchors.bottom: warningColumn . top
anchors.bottomMargin: 5
rotation: - 90
color: "red"
}
Column {
id: warningColumn
x: 10
width: parent . width - 20
spacing: 10
Label {
font.bold: true
font.pixelSize: warning . font . pixelSize * 1.2
text: qsTr ( "Warning" )
}
Label {
id: warning
width: parent . width
2021-04-28 17:03:08 +02:00
text: qsTr ( "This is a request to pay to a BTC address, which is an incompatible coin. Your funds could get lost and Flowee will have no way to recover them. Are you sure you want to pay to this BTC address?" )
2021-04-26 21:59:22 +02:00
wrapMode: Text . WrapAtWordBoundaryOrAnywhere
}
RowLayout {
width: parent . width
Item {
width: 1 ; height: 1
Layout.fillWidth: true
}
Button {
2021-04-28 17:03:08 +02:00
text: qsTr ( "Yes, I am sure" )
2021-04-26 21:59:22 +02:00
onClicked: destination . forceLegacyOk = true
}
Button {
text: qsTr ( "No" )
onClicked: {
destination . text = ""
destination . updateColor ( )
}
}
}
}
}
2020-06-11 17:41:18 +02:00
}
}