2025-06-26 00:02:57 +02:00
|
|
|
/*
|
|
|
|
|
* This file is part of the Flowee project
|
|
|
|
|
* Copyright (C) 2025 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.Basic as QQC2
|
2025-07-08 14:13:57 +02:00
|
|
|
import QtQuick.Layouts
|
2025-06-26 00:02:57 +02:00
|
|
|
import "../Flowee" as Flowee
|
|
|
|
|
import "../Utils.js" as Utils
|
|
|
|
|
import Flowee.org.pay;
|
|
|
|
|
|
|
|
|
|
Page {
|
|
|
|
|
id: root
|
|
|
|
|
headerText: qsTr("Scheduled Payment")
|
2025-08-03 17:01:20 +02:00
|
|
|
// This is an instance of the C++ SavedPayment class (SavedPaymentsHandler.h)
|
2025-06-27 01:02:10 +02:00
|
|
|
required property QtObject savedPayment;
|
|
|
|
|
property Payment payment: savedPayment.payment;
|
2025-07-08 20:34:08 +02:00
|
|
|
property bool withScheduleButton: false
|
|
|
|
|
property var acceptHandler: function handler() { thePile.pop(); }
|
2025-06-26 00:02:57 +02:00
|
|
|
|
|
|
|
|
Flickable {
|
2025-07-08 16:17:58 +02:00
|
|
|
id: scrollPane
|
2025-06-26 00:02:57 +02:00
|
|
|
anchors.fill: parent
|
|
|
|
|
contentWidth: width
|
|
|
|
|
contentHeight: column.height
|
2025-07-08 20:34:08 +02:00
|
|
|
|
2025-06-26 00:02:57 +02:00
|
|
|
Column {
|
|
|
|
|
id: column
|
|
|
|
|
width: parent.width
|
|
|
|
|
|
2025-07-08 14:13:57 +02:00
|
|
|
PageTitledBox {
|
|
|
|
|
title: qsTr("Comment")
|
|
|
|
|
width: parent.width
|
|
|
|
|
EditableLabel {
|
|
|
|
|
text: root.payment.userComment
|
|
|
|
|
width: parent.width
|
|
|
|
|
onEdited: root.payment.userComment = text
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 17:01:20 +02:00
|
|
|
PageTitledBox {
|
|
|
|
|
title: qsTr("Payment Amount")
|
|
|
|
|
id: amountsBox
|
|
|
|
|
width: parent.width
|
|
|
|
|
|
|
|
|
|
property var detail: {
|
|
|
|
|
let details = root.payment.details
|
|
|
|
|
for (let index in details) {
|
|
|
|
|
let detail = details[index];
|
|
|
|
|
if (detail.isOutput)
|
|
|
|
|
return detail;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Row {
|
|
|
|
|
spacing: 10
|
|
|
|
|
Rectangle {
|
|
|
|
|
property bool main: amountsBox.detail.fiatFollows
|
|
|
|
|
width: Math.max(priceBch.implicitWidth, 140)
|
|
|
|
|
height: 80
|
|
|
|
|
color: "#00000000"
|
|
|
|
|
radius: 6
|
|
|
|
|
border.width: 1.3
|
|
|
|
|
border.color: main ? palette.highlight : color
|
|
|
|
|
opacity: main ? 1 : 0.7
|
|
|
|
|
Image {
|
|
|
|
|
id: pinButton
|
|
|
|
|
y: -5
|
|
|
|
|
width: 28
|
|
|
|
|
height: 40
|
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
|
visible: parent.main
|
|
|
|
|
source: "qrc:/pin-green.svg";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MouseArea {
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onClicked: priceBch.forceActiveFocus()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Flowee.BitcoinValueField {
|
|
|
|
|
id: priceBch
|
|
|
|
|
value: amountsBox.detail.paymentAmount
|
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
|
anchors.top: pinButton.bottom
|
|
|
|
|
anchors.topMargin: 5
|
|
|
|
|
focus: false
|
|
|
|
|
onValueEdited: amountsBox.detail.paymentAmount = value
|
|
|
|
|
onActiveFocusChanged: {
|
|
|
|
|
if (activeFocus) {
|
|
|
|
|
amountsBox.detail.fiatFollows = true
|
|
|
|
|
numKeyboardWidget.start(money)
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-05 17:31:07 +02:00
|
|
|
activeFocusOnTab: false
|
2025-08-03 17:01:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Rectangle {
|
|
|
|
|
property bool main: !amountsBox.detail.fiatFollows
|
|
|
|
|
width: Math.max(priceFiat.implicitWidth, 140)
|
|
|
|
|
height: 80
|
|
|
|
|
color: "#00000000"
|
|
|
|
|
radius: 6
|
|
|
|
|
border.width: 1.3
|
|
|
|
|
opacity: main ? 1 : 0.7
|
|
|
|
|
border.color: main ? palette.highlight : color
|
|
|
|
|
|
|
|
|
|
Image {
|
|
|
|
|
id: pinButton2
|
|
|
|
|
y: -5
|
|
|
|
|
width: 28
|
|
|
|
|
height: 40
|
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
|
visible: parent.main
|
|
|
|
|
source: "qrc:/pin-green.svg";
|
|
|
|
|
transform: Scale { xScale: -1; yScale: 1; origin.x: 15 }
|
|
|
|
|
}
|
|
|
|
|
MouseArea {
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onClicked: priceFiat.forceActiveFocus()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Flowee.FiatValueField {
|
|
|
|
|
id: priceFiat
|
|
|
|
|
value: amountsBox.detail.paymentAmountFiat
|
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
|
anchors.top: pinButton2.bottom
|
|
|
|
|
anchors.topMargin: 5
|
|
|
|
|
focus: false
|
2025-09-05 17:31:07 +02:00
|
|
|
activeFocusOnTab: false
|
2025-08-03 17:01:20 +02:00
|
|
|
onValueEdited: amountsBox.detail.paymentAmountFiat = value
|
|
|
|
|
visible: Pay.isMainChain
|
|
|
|
|
onActiveFocusChanged: {
|
|
|
|
|
if (activeFocus) {
|
|
|
|
|
amountsBox.detail.fiatFollows = false
|
|
|
|
|
numKeyboardWidget.start(money)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
NumericKeyboardWidget {
|
|
|
|
|
id: numKeyboardWidget
|
|
|
|
|
width: parent.width
|
|
|
|
|
dataInput: ourData
|
|
|
|
|
opacity: 0
|
|
|
|
|
visible: opacity > 0
|
|
|
|
|
function start(money) {
|
|
|
|
|
ourData.editor = money;
|
|
|
|
|
if (!numKeyboardWidget.visible) {
|
|
|
|
|
var pos = valueComment.mapToItem(scrollPane.contentItem, 0, implicitHeight) // bottom of keyboard
|
|
|
|
|
numKeyboardWidget.opacity = 1 // will make the item visible
|
|
|
|
|
scrollPane.contentY = 10 + pos.y - scrollPane.height
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Item {
|
|
|
|
|
id: ourData
|
|
|
|
|
property QtObject editor: null// Item {}
|
|
|
|
|
function shake() {}
|
|
|
|
|
}
|
|
|
|
|
Behavior on opacity { NumberAnimation { } }
|
|
|
|
|
}
|
|
|
|
|
Flowee.Label {
|
|
|
|
|
id: valueComment
|
|
|
|
|
width: parent.width
|
|
|
|
|
text: qsTr("Pinned amount will be protected from exchange rate fluctuations.")
|
|
|
|
|
font.italic: true
|
|
|
|
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
|
|
|
|
focus: true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-06-27 01:02:10 +02:00
|
|
|
PageTitledBox {
|
|
|
|
|
title: qsTr("Planning")
|
|
|
|
|
width: parent.width
|
2025-08-03 20:35:31 +02:00
|
|
|
|
|
|
|
|
CalendarTextButton {
|
|
|
|
|
width: parent.width
|
|
|
|
|
text: qsTr("Next Payment") + ":"
|
|
|
|
|
date: root.savedPayment.next
|
|
|
|
|
onSelectedDateChanged: root.savedPayment.updateStartDate(selectedDate)
|
|
|
|
|
}
|
2025-06-27 01:02:10 +02:00
|
|
|
Repeater {
|
|
|
|
|
model: root.savedPayment.configs
|
|
|
|
|
|
|
|
|
|
Item {
|
|
|
|
|
width: column.width
|
|
|
|
|
height: planningPane.height
|
|
|
|
|
Column {
|
|
|
|
|
id: planningPane
|
|
|
|
|
width: parent.width
|
|
|
|
|
|
|
|
|
|
Flowee.RadioButton {
|
|
|
|
|
id: aRadioButton
|
2025-07-08 14:13:57 +02:00
|
|
|
focus: true
|
2025-08-13 16:04:59 +02:00
|
|
|
text: qsTr("By weekday")
|
2025-06-27 01:02:10 +02:00
|
|
|
checked: modelData.dayOfWeek !== -1
|
|
|
|
|
visible: index === 0 // don't repeat this for each config
|
|
|
|
|
width: parent.width
|
|
|
|
|
onClicked: root.savedPayment.switchToWeek();
|
|
|
|
|
}
|
|
|
|
|
Flowee.RadioButton {
|
2025-08-13 16:04:59 +02:00
|
|
|
text: qsTr("By day of month")
|
2025-07-08 14:13:57 +02:00
|
|
|
focus: true
|
2025-06-27 01:02:10 +02:00
|
|
|
checked: modelData.dayOfMonth !== -1
|
|
|
|
|
visible: index === 0// don't repeat this for each config
|
|
|
|
|
width: parent.width
|
|
|
|
|
onClicked: root.savedPayment.switchToMonth();
|
|
|
|
|
}
|
|
|
|
|
Flowee.Label {
|
|
|
|
|
id: startTimeLabel
|
|
|
|
|
x: aRadioButton.textAlignOffset
|
2025-08-03 20:35:31 +02:00
|
|
|
height: Math.max(50, contentHeight + 10)
|
2025-07-08 16:28:36 +02:00
|
|
|
verticalAlignment: Text.AlignVCenter
|
2025-06-27 01:02:10 +02:00
|
|
|
text: {
|
2025-06-27 21:03:06 +02:00
|
|
|
let loc = Qt.locale();
|
2025-06-27 01:02:10 +02:00
|
|
|
var day = modelData.dayOfWeek;
|
|
|
|
|
if (day >= 0) {
|
2025-06-27 21:03:06 +02:00
|
|
|
return loc.standaloneDayName(day, Locale.LongFormat);
|
2025-06-27 01:02:10 +02:00
|
|
|
}
|
|
|
|
|
day = modelData.dayOfMonth;
|
|
|
|
|
if (day > 0)
|
2025-06-27 21:03:06 +02:00
|
|
|
return loc.toString(modelData.next, loc.dateFormat(Locale.ShortFormat));
|
2025-06-27 01:02:10 +02:00
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
MouseArea {
|
|
|
|
|
width: root.width / 2
|
|
|
|
|
x: -5
|
|
|
|
|
y: -5
|
|
|
|
|
height: parent.height + 10
|
|
|
|
|
onClicked: picker.startDayPicker();
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-06-27 21:03:06 +02:00
|
|
|
Flow {
|
2025-08-03 17:01:20 +02:00
|
|
|
id: repeatIntervalFlow
|
2025-06-27 01:02:10 +02:00
|
|
|
spacing: 6
|
2025-06-27 21:03:06 +02:00
|
|
|
width: parent.width - x
|
2025-06-27 01:02:10 +02:00
|
|
|
Flowee.Label {
|
2025-07-08 16:28:36 +02:00
|
|
|
id: repeatLabel
|
2025-06-27 01:02:10 +02:00
|
|
|
text: qsTr("Repeat Interval") + ":"
|
|
|
|
|
font.bold: true
|
2025-08-03 20:35:31 +02:00
|
|
|
height: Math.max(50, contentHeight + 10)
|
2025-07-08 16:28:36 +02:00
|
|
|
verticalAlignment: Text.AlignVCenter
|
2025-06-27 01:02:10 +02:00
|
|
|
MouseArea {
|
2025-08-03 17:01:20 +02:00
|
|
|
width: root.width - 10
|
|
|
|
|
height: parent.height
|
2025-06-27 01:02:10 +02:00
|
|
|
x: -5
|
|
|
|
|
onClicked: picker.startRepeatPicker();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Flowee.Label {
|
2025-07-08 16:28:36 +02:00
|
|
|
height: repeatLabel.height
|
|
|
|
|
verticalAlignment: Text.AlignVCenter
|
2025-08-03 17:01:20 +02:00
|
|
|
text: {
|
2025-06-27 01:02:10 +02:00
|
|
|
var week = modelData.dayOfWeek;
|
|
|
|
|
if (week >= 0) {
|
|
|
|
|
let interval = modelData.weekInterval
|
2025-07-08 16:28:36 +02:00
|
|
|
if (interval <= 1)
|
2025-06-27 01:02:10 +02:00
|
|
|
return qsTr("Every week", "repetition");
|
2025-06-30 21:06:48 +02:00
|
|
|
return qsTr("Once every %1 weeks", "repetition", interval).arg(interval);
|
2025-06-27 01:02:10 +02:00
|
|
|
}
|
|
|
|
|
var month = modelData.dayOfMonth
|
|
|
|
|
if (month >= 0) {
|
|
|
|
|
let interval = modelData.monthInterval
|
|
|
|
|
if (interval <= 0)
|
|
|
|
|
return qsTr("Every month", "repetition");
|
2025-06-30 21:06:48 +02:00
|
|
|
return qsTr("Once every %1 months", "repetition", interval).arg(interval);
|
2025-06-27 01:02:10 +02:00
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-03 20:35:31 +02:00
|
|
|
CalendarTextButton {
|
2025-08-03 17:01:20 +02:00
|
|
|
width: parent.width
|
|
|
|
|
visible: index === 0 // don't repeat this for each config
|
2025-08-03 20:35:31 +02:00
|
|
|
text: qsTr("End Date") + ":"
|
|
|
|
|
date: root.payment.repeat.sunset
|
|
|
|
|
onSelectedDateChanged: root.payment.repeat.sunset = selectedDate
|
2025-08-03 17:01:20 +02:00
|
|
|
}
|
|
|
|
|
|
2025-06-27 01:02:10 +02:00
|
|
|
ListView {
|
|
|
|
|
id: calendarsList
|
|
|
|
|
width: parent.width
|
2025-07-08 16:28:36 +02:00
|
|
|
height: 90
|
2025-06-27 01:02:10 +02:00
|
|
|
orientation: ListView.Horizontal
|
|
|
|
|
model: 12
|
|
|
|
|
property QtObject config: modelData
|
|
|
|
|
spacing: 10
|
2025-06-27 21:03:06 +02:00
|
|
|
delegate: Item {
|
2025-06-27 01:02:10 +02:00
|
|
|
width: miniCalendar.width
|
|
|
|
|
height: miniCalendar.height
|
|
|
|
|
MiniCalendarWidget {
|
|
|
|
|
id: miniCalendar
|
|
|
|
|
month: {
|
|
|
|
|
var date = new Date(); // now
|
|
|
|
|
date.setDate(1);
|
|
|
|
|
date.setMonth(date.getMonth() + index);
|
|
|
|
|
return date;
|
|
|
|
|
}
|
|
|
|
|
highlights: {
|
2025-06-27 21:03:06 +02:00
|
|
|
var hls = [];
|
|
|
|
|
var source = calendarsList.config.predictedPayments
|
|
|
|
|
|
|
|
|
|
var thisMonth = month;
|
|
|
|
|
for (let date of source) {
|
|
|
|
|
if (date.getFullYear() === thisMonth.getFullYear()
|
|
|
|
|
&& date.getMonth() === thisMonth.getMonth())
|
|
|
|
|
hls.push(date.getDate());
|
|
|
|
|
}
|
2025-06-27 01:02:10 +02:00
|
|
|
return hls;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Flowee.CloseIcon {
|
|
|
|
|
visible: index > 0
|
|
|
|
|
scale: 0.6
|
|
|
|
|
anchors.right: parent.right
|
|
|
|
|
anchors.rightMargin: 20
|
2025-06-30 21:06:48 +02:00
|
|
|
anchors.top: parent.top
|
2025-06-27 01:02:10 +02:00
|
|
|
anchors.bottomMargin: startTimeLabel.height + 8
|
2025-06-30 21:06:48 +02:00
|
|
|
onClicked: root.savedPayment.remove(modelData)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Rectangle {
|
2025-07-03 22:51:45 +02:00
|
|
|
color: "#00000000"
|
|
|
|
|
radius: 15
|
2025-06-30 21:06:48 +02:00
|
|
|
width: 30
|
|
|
|
|
height: 30
|
|
|
|
|
anchors.right: parent.right
|
2025-07-03 22:51:45 +02:00
|
|
|
anchors.rightMargin: 20
|
|
|
|
|
anchors.top: parent.top
|
|
|
|
|
anchors.bottomMargin: startTimeLabel.height + 8
|
2025-06-30 21:06:48 +02:00
|
|
|
visible: index === 0
|
2025-07-03 22:51:45 +02:00
|
|
|
border.width: 1
|
|
|
|
|
border.color: palette.text
|
|
|
|
|
Rectangle {
|
|
|
|
|
color: palette.text
|
|
|
|
|
width: 1
|
|
|
|
|
height: parent.height * 0.5
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
}
|
|
|
|
|
Rectangle {
|
|
|
|
|
color: palette.text
|
|
|
|
|
height: 1
|
|
|
|
|
width: parent.width * 0.5
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-30 21:06:48 +02:00
|
|
|
MouseArea {
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onClicked: root.savedPayment.add()
|
|
|
|
|
}
|
2025-06-27 01:02:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Flowee.Dialog {
|
|
|
|
|
id: picker
|
|
|
|
|
property bool isDayPicker: true
|
|
|
|
|
|
|
|
|
|
function startDayPicker() {
|
|
|
|
|
isDayPicker = true;
|
|
|
|
|
open();
|
|
|
|
|
}
|
|
|
|
|
function startRepeatPicker() {
|
|
|
|
|
isDayPicker = false;
|
|
|
|
|
open();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
property QtObject config: modelData
|
|
|
|
|
|
|
|
|
|
standardButtons: QQC2.DialogButtonBox.Cancel
|
|
|
|
|
contentComponent: Flickable {
|
2025-06-27 21:03:06 +02:00
|
|
|
width: picker.width - 40
|
2025-06-27 01:02:10 +02:00
|
|
|
height: Math.min(400, chooserColumn.height)
|
|
|
|
|
contentWidth: width
|
|
|
|
|
contentHeight: chooserColumn.height
|
|
|
|
|
clip: true
|
|
|
|
|
Column {
|
|
|
|
|
id: chooserColumn
|
|
|
|
|
width: parent.width
|
|
|
|
|
Repeater {
|
|
|
|
|
model: picker.isDayPicker ? (modelData.dayOfWeek >= 0 ? 7 : 31) : 12
|
|
|
|
|
Item {
|
2025-06-27 21:03:06 +02:00
|
|
|
width: picker.width - 40
|
2025-06-27 01:02:10 +02:00
|
|
|
height: chooserLabel.height + 12
|
|
|
|
|
Flowee.Label {
|
|
|
|
|
id: chooserLabel
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
text: {
|
2025-06-27 21:03:06 +02:00
|
|
|
if (!picker.isDayPicker || picker.config.dayOfMonth >= 0)
|
2025-06-27 01:02:10 +02:00
|
|
|
return "" + (modelData + 1);
|
|
|
|
|
return Qt.locale().standaloneDayName(modelData, Locale.LongFormat);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
MouseArea {
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
onClicked: {
|
|
|
|
|
if (picker.isDayPicker) {
|
|
|
|
|
if (picker.config.dayOfMonth >= 0)
|
|
|
|
|
picker.config.dayOfMonth = modelData + 1;
|
|
|
|
|
else
|
|
|
|
|
picker.config.dayOfWeek = modelData;
|
|
|
|
|
}
|
2025-06-30 21:06:48 +02:00
|
|
|
else { // repeat interval picker
|
2025-06-27 01:02:10 +02:00
|
|
|
if (picker.config.dayOfMonth >= 0)
|
2025-06-30 21:06:48 +02:00
|
|
|
picker.config.monthInterval = modelData + 1;
|
2025-06-27 01:02:10 +02:00
|
|
|
else
|
2025-06-30 21:06:48 +02:00
|
|
|
picker.config.weekInterval = modelData + 1;
|
2025-06-27 01:02:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
picker.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-03 22:51:45 +02:00
|
|
|
|
2025-06-26 00:02:57 +02:00
|
|
|
}
|
2025-07-08 14:13:57 +02:00
|
|
|
|
2025-07-08 19:11:13 +02:00
|
|
|
PageTitledBox {
|
|
|
|
|
title: qsTr("Wallet for Payment")
|
|
|
|
|
id: walletSelector
|
|
|
|
|
width: parent.width
|
|
|
|
|
visible: !portfolio.singleAccountSetup
|
|
|
|
|
AccountSelectorWidget {
|
|
|
|
|
onSelectedAccountChanged: payment.account = selectedAccount
|
|
|
|
|
startingAccount: root.payment.account
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-08 16:17:58 +02:00
|
|
|
|
2025-07-08 14:13:57 +02:00
|
|
|
/*
|
2025-07-08 17:42:52 +02:00
|
|
|
TODO time of day for the payment
|
|
|
|
|
|
2025-06-26 00:02:57 +02:00
|
|
|
PageTitledBox {
|
|
|
|
|
title: qsTr("Advanced")
|
|
|
|
|
Flowee.Label {
|
|
|
|
|
text: "Fee per byte: " + root.payment.feePerByte
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-08 14:13:57 +02:00
|
|
|
*/
|
2025-07-08 20:34:08 +02:00
|
|
|
|
|
|
|
|
Item { width: 1; height: 20; visible: scheduleButton.visible } // spacer
|
|
|
|
|
Flowee.BigButton {
|
|
|
|
|
id: scheduleButton
|
|
|
|
|
width: parent.width * 0.75
|
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
|
isMainButton: true
|
|
|
|
|
text: qsTr("Schedule")
|
|
|
|
|
visible: root.withScheduleButton
|
|
|
|
|
onClicked: {
|
|
|
|
|
Pay.addRepeatPayment(root.payment);
|
|
|
|
|
root.acceptHandler();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Item { width: 1; height: 20 } // spacer
|
2025-06-26 00:02:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
2025-07-08 16:17:58 +02:00
|
|
|
Keys.onPressed: (event)=> {
|
|
|
|
|
if ((event.key === Qt.Key_Escape || event.key === Qt.Key_Back)
|
|
|
|
|
&& numKeyboardWidget.visible) {
|
|
|
|
|
valueComment.forceActiveFocus(); // move focus away from the input widgets to avoid blinking cursor
|
|
|
|
|
numKeyboardWidget.opacity = 0;
|
|
|
|
|
event.accepted = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-06-26 00:02:57 +02:00
|
|
|
}
|