304 lines
10 KiB
QML
304 lines
10 KiB
QML
/*
|
|
* This file is part of the Flowee project
|
|
* Copyright (C) 2024 Tom Zander <tom@flowee.org>
|
|
*
|
|
* 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 QtQuick.Layouts;
|
|
import "../mobile" as Mobile;
|
|
import "../Flowee" as Flowee;
|
|
import Flowee.org.pay;
|
|
import Flowee.org.pay.bigtransfer;
|
|
|
|
Mobile.Page {
|
|
id: root
|
|
required property QtObject transferManager;
|
|
headerText: qsTr("Verify %1 Transactions", "", reviewList.model.length)
|
|
.arg(transferManager.transactions.length);
|
|
|
|
ListView {
|
|
id: reviewList
|
|
width: parent.width
|
|
anchors.top: parent.top
|
|
anchors.bottom: infoLabel.top
|
|
anchors.bottomMargin: 20
|
|
clip: true
|
|
model: root.transferManager.transactions
|
|
delegate: Rectangle {
|
|
id: delegateRoot
|
|
width: ListView.view.width
|
|
color: (index % 2) === 0 ? palette.base : palette.alternateBase
|
|
height: Math.max(address.y + address.height, outputSelector.y + outputSelector.height) + 10
|
|
property int offset: modelData.sent ? 80 : 0
|
|
opacity: {
|
|
if (helpText.opacity > 0 && (dragItem.x === 0 || dragItem > 260))
|
|
return 0.8 - helpText.opacity / 2;
|
|
return 1;
|
|
}
|
|
Flowee.Label {
|
|
id: topRow
|
|
text: index + 1 + ")"
|
|
y: 5
|
|
x: parent.offset
|
|
}
|
|
Flowee.BitcoinAmountLabel {
|
|
id: amountLabel
|
|
y: 5
|
|
x: topRow.width + topRow.x + 6
|
|
value: modelData.value
|
|
}
|
|
|
|
Item {
|
|
id: dragItem
|
|
width: parent.width
|
|
height: parent.height
|
|
|
|
onXChanged: {
|
|
var absX = Math.abs(x);
|
|
delegateRoot.offset = x / 2
|
|
if (absX > 250) {
|
|
root.transferManager.send(modelData);
|
|
helpText.visible = false;
|
|
delegateRoot.offset = 80
|
|
}
|
|
helpText.opacity = absX / 200
|
|
}
|
|
|
|
DragHandler {
|
|
id: dragHandler
|
|
yAxis.enabled: false
|
|
xAxis.enabled: true
|
|
xAxis.maximum: 270 // swipe left
|
|
xAxis.minimum: -270 // swipe right
|
|
enabled: !modelData.sent
|
|
onActiveChanged: {
|
|
if (active) {
|
|
var rect = Qt.rect(0, 0, delegateRoot.width, delegateRoot.height);
|
|
var convertedRect = helpText.mapFromItem(delegateRoot, rect);
|
|
helpText.base = convertedRect;
|
|
helpText.visible = true;
|
|
} else {
|
|
parent.x = 0;
|
|
delegateRoot.offset = modelData.sent ? 80 : 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Flowee.GroupBox {
|
|
id: outputSelector
|
|
title: qsTr("Coins")
|
|
x: parent.x + offset + parent.width - width
|
|
y: {
|
|
if (width + amountLabel.x + amountLabel.width + 10 > root.width)
|
|
return amountLabel.y + amountLabel.height + 6
|
|
return 0;
|
|
}
|
|
|
|
collapsable: false
|
|
drawBorder: true
|
|
width: Math.max(label.width + 20, 110)
|
|
height: implicitHeight - 10
|
|
property int outputCount: modelData.outputCount
|
|
onOutputCountChanged: modelData.outputCount = outputCount;
|
|
|
|
Item {
|
|
implicitWidth: label.implicitWidth
|
|
implicitHeight: label.height - 10
|
|
Flowee.Label {
|
|
id: label
|
|
width: parent.width
|
|
text: modelData.inputCount + " ⇒ " + outputSelector.outputCount
|
|
y: -6 // digits only, so above the x-height its empty.
|
|
}
|
|
}
|
|
}
|
|
Flowee.ArrowPoint {
|
|
anchors.right: outputSelector.right
|
|
anchors.rightMargin: 8
|
|
y: outputSelector.y + outputSelector.height - label.height / 2 - height
|
|
rotation: 90
|
|
}
|
|
MouseArea {
|
|
anchors.fill: outputSelector
|
|
anchors.margins: -5
|
|
onClicked: popup.open(outputSelector)
|
|
}
|
|
|
|
Item {
|
|
id: address
|
|
width: parent.width
|
|
x: modelData.sent ? 80 : 0
|
|
y: {
|
|
// tall vs wide
|
|
if (outputSelector.width + 10 + fromLabel.implicitWidth > root.width)
|
|
return outputSelector.y + outputSelector.height + 6;
|
|
return topRow.height + 6;
|
|
}
|
|
height: fromLabel.height + 10
|
|
opacity: 1 - Math.abs(dragItem.x) / 200
|
|
|
|
Flowee.AddressLabel {
|
|
id: fromLabel
|
|
y: 5
|
|
showCopyIcon: false
|
|
width: Math.min(implicitWidth, parent.width - x)
|
|
txInfo: modelData.from
|
|
highlight: false
|
|
}
|
|
}
|
|
|
|
Flowee.ProgressCheckIcon {
|
|
broadcastStatus: modelData.broadcastStatus
|
|
transformOrigin: Item.TopLeft
|
|
visible: modelData.sent
|
|
scale: 0.4
|
|
}
|
|
}
|
|
}
|
|
|
|
Flowee.Label {
|
|
id: helpText
|
|
|
|
property rect base: Qt.rect(0, 0, 1, 1);
|
|
|
|
width: parent.width - 20
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
y: {
|
|
var baseCopy = base;
|
|
if (baseCopy.width === 1)
|
|
return 0;
|
|
if (height + 10 < baseCopy.y) // place it above
|
|
return baseCopy.y - height - 10
|
|
|
|
return baseCopy.y + baseCopy.height + 20;
|
|
}
|
|
|
|
text: qsTr("Send Now")
|
|
font.pixelSize: 100
|
|
fontSizeMode: Text.HorizontalFit
|
|
color: mainWindow.floweeGreen
|
|
opacity: 0
|
|
onOpacityChanged: if (opacity === 0) base = Qt.rect(0, 0, 1, 1); // reset
|
|
Behavior on opacity { NumberAnimation { } }
|
|
}
|
|
|
|
Flowee.Label {
|
|
id: infoLabel
|
|
width: parent.width
|
|
text: {
|
|
if (root.transferManager.unsentTxCount < 2)
|
|
return "";
|
|
return qsTr("Create and send all %1 transactions", "",
|
|
root.transferManager.unsentTxCount).arg(root.transferManager.unsentTxCount);
|
|
|
|
}
|
|
// height: text === "" ? 0 : implicitHeight
|
|
anchors.bottom: slideToApprove.top
|
|
anchors.bottomMargin: 10
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
|
|
Mobile.SlideToApprove {
|
|
id: slideToApprove
|
|
visible: root.transferManager.unsentTxCount > 0
|
|
onActivated: root.transferManager.sendAll();
|
|
anchors.bottom: parent.bottom
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.bottomMargin: 10
|
|
}
|
|
|
|
Flowee.BigCloseButton {
|
|
x: 10
|
|
visible: root.transferManager.unsentTxCount === 0
|
|
anchors.bottom: parent.bottom
|
|
anchors.bottomMargin: 10
|
|
enabled: false
|
|
onClicked: {
|
|
var mainView = thePile.get(0);
|
|
mainView.currentIndex = 0; // go to the 'main' tab.
|
|
thePile.pop();
|
|
thePile.pop();
|
|
}
|
|
}
|
|
FocusScope {
|
|
id: popup // its basically a full page overlay
|
|
height: 400
|
|
width: 200
|
|
anchors.fill: parent
|
|
visible: false
|
|
|
|
property var targetItem: null
|
|
function open(sourceItem) {
|
|
targetItem = sourceItem;
|
|
content.model = root.transferManager.outputModel;
|
|
visible = true;
|
|
popup.forceActiveFocus();
|
|
reviewList.enabled = false;
|
|
}
|
|
|
|
onVisibleChanged: {
|
|
if (!visible) {
|
|
root.forceActiveFocus();
|
|
reviewList.enabled = true;
|
|
content.model = undefined;
|
|
}
|
|
}
|
|
|
|
MouseArea {
|
|
anchors.fill: parent;
|
|
onClicked: popup.visible = false;
|
|
}
|
|
|
|
Rectangle {
|
|
color: palette.light
|
|
border.color: palette.midlight
|
|
border.width: 1
|
|
radius: 5
|
|
anchors.bottom: parent.bottom
|
|
anchors.bottomMargin: -2
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
width: 160
|
|
height: 360
|
|
ListView {
|
|
id: content
|
|
anchors.fill: parent
|
|
anchors.margins: 6
|
|
clip: true
|
|
header: Flowee.Label { text: qsTr("Target Coins", "indicates a number") + ":" }
|
|
delegate: Rectangle {
|
|
width: ListView.view.width
|
|
height: Math.max(60, label2.height + 10);
|
|
color: (index % 2) === 0 ? palette.base : palette.alternateBase
|
|
Flowee.Label {
|
|
id: label2
|
|
text: model.number
|
|
anchors.centerIn: parent
|
|
}
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: {
|
|
popup.targetItem.outputCount = model.number
|
|
popup.visible = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|