/* * This file is part of the Flowee project * Copyright (C) 2024 Tom Zander * * 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 . */ 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; } } } } } } }