mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-25 22:21:16 +00:00
252 lines
7.4 KiB
QML
252 lines
7.4 KiB
QML
import QtQuick
|
|
import QtQuick.Controls.Basic
|
|
import QtQuick.Layouts
|
|
|
|
Popup {
|
|
id: root
|
|
|
|
property string title: qsTr("Confirm transaction")
|
|
property string cancelText: qsTr("Cancel")
|
|
property string confirmText: qsTr("Confirm")
|
|
property bool busy: false
|
|
property string busyText: qsTr("Submitting…")
|
|
property bool activityBusy: false
|
|
property string activityText: qsTr("Updating…")
|
|
property bool showInlineBusyIndicator: true
|
|
property var snapshot: ({})
|
|
property Component summary: null
|
|
property bool confirmationPending: false
|
|
property bool confirmEnabled: true
|
|
property bool roundedCancelButton: false
|
|
property bool closeWhenSettled: true
|
|
readonly property bool actionPending: root.busy || root.activityBusy
|
|
|
|
signal canceled
|
|
signal confirmed(var snapshot)
|
|
signal summaryEdited(var snapshot)
|
|
|
|
modal: true
|
|
dim: true
|
|
padding: 20
|
|
width: Math.max(0, Math.min(420, parent ? parent.width - 32 : 420))
|
|
height: Math.max(0, Math.min(implicitHeight, parent ? parent.height - 32 : implicitHeight))
|
|
x: parent ? Math.max(0, Math.round((parent.width - width) / 2)) : 0
|
|
y: parent ? Math.max(0, Math.round((parent.height - height) / 2)) : 0
|
|
closePolicy: root.busy ? Popup.NoAutoClose : Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
|
focus: true
|
|
|
|
function cloneSnapshot(value) {
|
|
if (value === undefined || value === null)
|
|
return ({})
|
|
try {
|
|
return JSON.parse(JSON.stringify(value))
|
|
} catch (_error) {
|
|
return value
|
|
}
|
|
}
|
|
|
|
function openWithSnapshot(nextSnapshot) {
|
|
root.snapshot = root.cloneSnapshot(nextSnapshot)
|
|
root.confirmationPending = false
|
|
root.open()
|
|
Qt.callLater(function() {
|
|
if (cancelButtonLoader.item)
|
|
cancelButtonLoader.item.forceActiveFocus()
|
|
})
|
|
}
|
|
|
|
function updateSnapshot(nextSnapshot) {
|
|
root.snapshot = root.cloneSnapshot(nextSnapshot)
|
|
}
|
|
|
|
function cancel() {
|
|
if (root.busy)
|
|
return
|
|
root.confirmationPending = false
|
|
root.close()
|
|
root.canceled()
|
|
}
|
|
|
|
function confirm() {
|
|
if (root.actionPending || !root.confirmEnabled)
|
|
return
|
|
root.confirmationPending = true
|
|
root.confirmed(root.snapshot)
|
|
if (!root.busy) {
|
|
root.confirmationPending = false
|
|
root.close()
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: summaryLoader.item
|
|
ignoreUnknownSignals: true
|
|
|
|
function onSnapshotEdited(snapshot) {
|
|
root.updateSnapshot(snapshot)
|
|
root.summaryEdited(root.snapshot)
|
|
}
|
|
}
|
|
|
|
onBusyChanged: {
|
|
if (!root.busy && root.confirmationPending) {
|
|
root.confirmationPending = false
|
|
if (root.closeWhenSettled)
|
|
root.close()
|
|
}
|
|
}
|
|
|
|
onSnapshotChanged: {
|
|
if (summaryLoader.item && summaryLoader.item.hasOwnProperty("snapshot"))
|
|
summaryLoader.item.snapshot = root.snapshot
|
|
}
|
|
|
|
Overlay.modal: Rectangle { color: "#99000000" }
|
|
|
|
background: Rectangle {
|
|
color: "#18181b"
|
|
border.color: "#3f3f46"
|
|
border.width: 1
|
|
radius: 8
|
|
}
|
|
|
|
contentItem: ColumnLayout {
|
|
spacing: 16
|
|
|
|
Label {
|
|
Layout.fillWidth: true
|
|
text: root.title
|
|
color: "#f4f4f5"
|
|
font.bold: true
|
|
font.pixelSize: 17
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
|
|
ScrollView {
|
|
id: summaryScroll
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
Layout.minimumHeight: 0
|
|
Layout.preferredHeight: summaryLoader.implicitHeight
|
|
clip: true
|
|
contentWidth: availableWidth
|
|
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
|
|
Loader {
|
|
id: summaryLoader
|
|
objectName: "transactionSummaryLoader"
|
|
width: summaryScroll.availableWidth
|
|
sourceComponent: root.summary
|
|
onLoaded: {
|
|
if (item && item.hasOwnProperty("snapshot"))
|
|
item.snapshot = root.snapshot
|
|
}
|
|
}
|
|
}
|
|
|
|
Item {
|
|
id: inlineBusyIndicator
|
|
|
|
property bool active: root.showInlineBusyIndicator && root.actionPending
|
|
Layout.alignment: Qt.AlignHCenter
|
|
Layout.preferredWidth: active ? busySpinner.implicitWidth : 0
|
|
Layout.preferredHeight: active ? busySpinner.implicitHeight : 0
|
|
implicitWidth: busySpinner.implicitWidth
|
|
implicitHeight: busySpinner.implicitHeight
|
|
visible: active
|
|
|
|
BusyIndicator {
|
|
id: busySpinner
|
|
|
|
anchors.centerIn: parent
|
|
running: inlineBusyIndicator.active
|
|
Accessible.name: root.busy ? root.busyText : root.activityText
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 10
|
|
|
|
Loader {
|
|
id: cancelButtonLoader
|
|
objectName: "transactionCancelButtonLoader"
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 44
|
|
sourceComponent: root.roundedCancelButton
|
|
? roundedCancelButtonComponent : defaultCancelButtonComponent
|
|
}
|
|
|
|
Button {
|
|
id: confirmButton
|
|
objectName: "transactionConfirmButton"
|
|
Layout.fillWidth: true
|
|
implicitHeight: 44
|
|
text: root.busy ? root.busyText : root.confirmText
|
|
enabled: !root.actionPending && root.confirmEnabled
|
|
Accessible.name: text
|
|
onClicked: root.confirm()
|
|
|
|
background: Rectangle {
|
|
color: confirmButton.enabled
|
|
? confirmButton.pressed ? "#d95c1e" : "#f26a21"
|
|
: "#52525b"
|
|
radius: 6
|
|
}
|
|
|
|
contentItem: Label {
|
|
text: confirmButton.text
|
|
color: "#ffffff"
|
|
font.bold: true
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: defaultCancelButtonComponent
|
|
|
|
Button {
|
|
objectName: "transactionCancelButton"
|
|
anchors.fill: parent
|
|
text: root.cancelText
|
|
enabled: !root.busy
|
|
Accessible.name: text
|
|
onClicked: root.cancel()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: roundedCancelButtonComponent
|
|
|
|
Button {
|
|
id: cancelButton
|
|
|
|
objectName: "transactionCancelButton"
|
|
anchors.fill: parent
|
|
text: root.cancelText
|
|
enabled: !root.busy
|
|
Accessible.name: text
|
|
onClicked: root.cancel()
|
|
|
|
background: Rectangle {
|
|
color: cancelButton.pressed ? "#3f3f46"
|
|
: cancelButton.hovered ? "#27272a" : "#18181b"
|
|
border.color: "#52525b"
|
|
border.width: 1
|
|
radius: 6
|
|
}
|
|
|
|
contentItem: Label {
|
|
text: cancelButton.text
|
|
color: "#f4f4f5"
|
|
font.bold: true
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
}
|
|
}
|