2023-03-11 22:44:27 +01:00
|
|
|
/*
|
|
|
|
|
* This file is part of the Flowee project
|
2025-02-09 22:56:59 +01:00
|
|
|
* Copyright (C) 2022-2025 Tom Zander <tom@flowee.org>
|
2023-03-11 22:44:27 +01: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/>.
|
|
|
|
|
*/
|
|
|
|
|
import QtQuick
|
|
|
|
|
import QtQuick.Controls as QQC2
|
|
|
|
|
import "../Flowee" as Flowee
|
2023-05-25 20:11:42 +02:00
|
|
|
import Flowee.org.pay
|
2023-03-11 22:44:27 +01:00
|
|
|
|
2023-03-12 17:21:02 +01:00
|
|
|
FocusScope {
|
2023-03-11 22:44:27 +01:00
|
|
|
id: root
|
2023-06-01 23:39:03 +02:00
|
|
|
// if true, the bitcoin value is provided by the user (or QR), and the fiat follows.
|
2023-03-11 22:44:27 +01:00
|
|
|
// if false, the user edits the fiat price and the bitcoin value is calculated.
|
|
|
|
|
// Notice that 'send all' overrules both and gets the data from the wallet-total
|
2023-06-01 23:39:03 +02:00
|
|
|
property bool fiatFollowsSats: false
|
2023-03-12 14:26:13 +01:00
|
|
|
// made available for the NumericKeyboardWidget
|
2025-03-16 22:44:07 +01:00
|
|
|
property var editor: data.fiatFollowsSats ? priceBch.money : priceFiat.money;
|
2023-05-25 20:11:42 +02:00
|
|
|
/**
|
|
|
|
|
* Payment Backend processes the fiat and satoshi based pair of payments.
|
|
|
|
|
* The default is a simple backend, notice that the Payment QML type
|
|
|
|
|
* actually provides its own backend(s), as each output is one.
|
|
|
|
|
*/
|
|
|
|
|
property QtObject paymentBackend : PaymentBackend {}
|
2023-03-11 22:44:27 +01:00
|
|
|
|
2025-03-16 22:44:07 +01:00
|
|
|
// if this is testnet, there is no fiat. Sats always lead.
|
|
|
|
|
Item {
|
|
|
|
|
id: data
|
|
|
|
|
property bool fiatFollowsSats: root.fiatFollowsSats || !Pay.isMainChain
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-13 13:33:45 +01:00
|
|
|
onFiatFollowsSatsChanged: {
|
|
|
|
|
if (!activeFocus)
|
|
|
|
|
return;
|
2023-10-17 12:00:28 +02:00
|
|
|
takeFocus();
|
2023-03-13 13:33:45 +01:00
|
|
|
}
|
|
|
|
|
|
2023-03-11 22:44:27 +01:00
|
|
|
function shake() {
|
2025-03-16 22:44:07 +01:00
|
|
|
if (data.fiatFollowsSats)
|
2023-03-11 22:44:27 +01:00
|
|
|
bchShaker.start();
|
|
|
|
|
else
|
|
|
|
|
fiatShaker.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
implicitHeight: 140
|
|
|
|
|
height: implicitHeight
|
|
|
|
|
|
2023-10-17 12:00:28 +02:00
|
|
|
function takeFocus() {
|
2025-03-16 22:44:07 +01:00
|
|
|
if (data.fiatFollowsSats)
|
2023-10-17 12:00:28 +02:00
|
|
|
priceBch.forceActiveFocus();
|
|
|
|
|
else
|
|
|
|
|
priceFiat.forceActiveFocus();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-11 22:44:27 +01:00
|
|
|
Flowee.BitcoinValueField {
|
|
|
|
|
id: priceBch
|
2025-03-16 22:44:07 +01:00
|
|
|
y: data.fiatFollowsSats ? 5 : 68
|
2023-03-12 14:26:13 +01:00
|
|
|
value: paymentBackend.paymentAmount
|
2023-03-11 22:44:27 +01:00
|
|
|
focus: true
|
|
|
|
|
fontPixelSize: size
|
2025-03-16 22:44:07 +01:00
|
|
|
property double size: data.fiatFollowsSats ? 38 : mainWindow.font.pixelSize* 0.8
|
|
|
|
|
onActiveFocusChanged: if (activeFocus) data.fiatFollowsSats = true
|
2023-03-11 22:44:27 +01:00
|
|
|
Behavior on size { NumberAnimation { } }
|
|
|
|
|
Behavior on y { NumberAnimation { } }
|
|
|
|
|
Flowee.ObjectShaker { id: bchShaker } // 'shake' to give feedback on mistakes
|
|
|
|
|
|
|
|
|
|
// this unchecks 'max' on user editing of the value
|
2023-03-12 14:26:13 +01:00
|
|
|
onValueEdited: paymentBackend.paymentAmount = value
|
2023-03-11 22:44:27 +01:00
|
|
|
}
|
|
|
|
|
MouseArea {
|
|
|
|
|
/* Since the valueField is centred but only allows clicking on its active surface,
|
|
|
|
|
we provide this one to make it possible to click on the full width and activate it.
|
|
|
|
|
*/
|
|
|
|
|
width: root.width
|
|
|
|
|
height: priceBch.height
|
|
|
|
|
y: priceBch.y
|
|
|
|
|
onClicked: priceBch.forceActiveFocus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Flowee.FiatValueField {
|
|
|
|
|
id: priceFiat
|
2023-03-12 14:26:13 +01:00
|
|
|
value: paymentBackend.paymentAmountFiat
|
2025-03-16 22:44:07 +01:00
|
|
|
y: data.fiatFollowsSats ? 68 : 5
|
2023-03-11 22:44:27 +01:00
|
|
|
focus: true
|
|
|
|
|
fontPixelSize: size
|
2025-03-16 22:44:07 +01:00
|
|
|
property double size: !data.fiatFollowsSats ? 38 : mainWindow.font.pixelSize * 0.8
|
|
|
|
|
onActiveFocusChanged: if (activeFocus) data.fiatFollowsSats = false
|
2023-03-11 22:44:27 +01:00
|
|
|
Behavior on size { NumberAnimation { } }
|
|
|
|
|
Behavior on y { NumberAnimation { } }
|
|
|
|
|
Flowee.ObjectShaker { id: fiatShaker }
|
2023-03-12 14:26:13 +01:00
|
|
|
onValueEdited: paymentBackend.paymentAmountFiat = value
|
2025-03-16 22:44:07 +01:00
|
|
|
visible: Pay.isMainChain
|
2023-03-11 22:44:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
|
id: inputChooser
|
|
|
|
|
y: 100
|
|
|
|
|
height: 40
|
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
|
border.width: 1
|
|
|
|
|
border.color: palette.midlight
|
|
|
|
|
color: palette.light
|
|
|
|
|
width: inputs.width + 20
|
2025-02-09 22:56:59 +01:00
|
|
|
radius: 9
|
2025-03-16 22:44:07 +01:00
|
|
|
visible: Pay.isMainChain
|
2023-03-11 22:44:27 +01:00
|
|
|
|
|
|
|
|
Rectangle {
|
|
|
|
|
color: palette.highlight
|
|
|
|
|
opacity: 0.3
|
|
|
|
|
radius: 6
|
2023-06-19 22:47:15 +02:00
|
|
|
width: {
|
2025-03-16 22:44:07 +01:00
|
|
|
if (data.fiatFollowsSats)
|
2023-06-19 22:47:15 +02:00
|
|
|
return 35;
|
|
|
|
|
return currencyNameShort.width + 10
|
|
|
|
|
}
|
2023-03-11 22:44:27 +01:00
|
|
|
height: parent.height - 4
|
|
|
|
|
y: 2
|
2025-03-16 22:44:07 +01:00
|
|
|
x: data.fiatFollowsSats ? 5 : 45
|
2023-03-11 22:44:27 +01:00
|
|
|
|
|
|
|
|
Behavior on x { NumberAnimation { } }
|
2023-06-19 22:47:15 +02:00
|
|
|
Behavior on width { NumberAnimation { } }
|
2023-03-11 22:44:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Row {
|
|
|
|
|
id: inputs
|
|
|
|
|
x: 10
|
|
|
|
|
y: 7.5
|
|
|
|
|
height: parent.height
|
|
|
|
|
spacing: 4
|
|
|
|
|
Image {
|
|
|
|
|
id: logo
|
|
|
|
|
source: "qrc:/bch.svg"
|
|
|
|
|
width: 25
|
|
|
|
|
height: 25
|
|
|
|
|
smooth: true
|
|
|
|
|
|
|
|
|
|
MouseArea {
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onClicked: priceBch.forceActiveFocus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Item { width: 8; height: 1 } // spacer
|
|
|
|
|
|
|
|
|
|
Flowee.Label {
|
2023-06-19 22:47:15 +02:00
|
|
|
id: currencyNameShort
|
|
|
|
|
text: (Fiat.currencySymbolPost + Fiat.currencySymbolPrefix).trim();
|
|
|
|
|
width: Math.max(24, implicitWidth)
|
2023-03-11 22:44:27 +01:00
|
|
|
font.pixelSize: 32
|
|
|
|
|
anchors.baseline: logo.bottom
|
|
|
|
|
|
|
|
|
|
MouseArea {
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onClicked: priceFiat.forceActiveFocus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Rectangle {
|
|
|
|
|
width: 1
|
|
|
|
|
y: inputs.y * -1
|
|
|
|
|
height: parent.height
|
|
|
|
|
color: palette.dark
|
|
|
|
|
}
|
2025-03-16 22:44:07 +01:00
|
|
|
Item { width: 6; height: 1 } // spacer
|
2023-03-11 22:44:27 +01:00
|
|
|
|
|
|
|
|
Flowee.HamburgerMenu {
|
2025-03-16 22:44:07 +01:00
|
|
|
y: 4
|
2023-03-11 22:44:27 +01:00
|
|
|
MouseArea {
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
anchors.margins: -12
|
|
|
|
|
anchors.rightMargin: -25
|
|
|
|
|
onClicked: languageMenu.open()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Loader {
|
|
|
|
|
id: languageMenu
|
|
|
|
|
function open() {
|
|
|
|
|
sourceComponent = languageMenuComponent
|
|
|
|
|
}
|
|
|
|
|
onLoaded: item.open();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Component {
|
|
|
|
|
id: languageMenuComponent
|
|
|
|
|
|
|
|
|
|
QQC2.Menu {
|
|
|
|
|
Repeater {
|
|
|
|
|
model: Pay.recentCountries()
|
|
|
|
|
QQC2.MenuItem {
|
|
|
|
|
text: {
|
|
|
|
|
var loc = Qt.locale(modelData);
|
|
|
|
|
return loc.currencySymbol(Locale.CurrencySymbol) + " "
|
|
|
|
|
+ loc.currencySymbol(Locale.CurrencyDisplayName);
|
|
|
|
|
}
|
|
|
|
|
onClicked: Pay.setCountry(modelData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
QQC2.MenuItem {
|
|
|
|
|
text: qsTr("All Currencies")
|
|
|
|
|
onClicked: thePile.push("./CurrencySelector.qml")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onVisibleChanged: if (!visible) languageMenu.sourceComponent = undefined; // unload us
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Item { width: 5; height: 1 } // spacer
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|