From 490862d09662d550eadf131279d5f5d2d7a75e50 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Wed, 30 Mar 2022 17:37:22 +0200 Subject: [PATCH] add RequestDialog, open request on create, and implement UI delete request --- electrum/gui/qml/components/Receive.qml | 176 ++++++++++++++---------- electrum/gui/qml/qerequestlistmodel.py | 19 ++- electrum/gui/qml/qewallet.py | 7 +- 3 files changed, 122 insertions(+), 80 deletions(-) diff --git a/electrum/gui/qml/components/Receive.qml b/electrum/gui/qml/components/Receive.qml index dbb213db3..bbc1a1139 100644 --- a/electrum/gui/qml/components/Receive.qml +++ b/electrum/gui/qml/components/Receive.qml @@ -2,6 +2,7 @@ import QtQuick 2.6 import QtQuick.Layouts 1.0 import QtQuick.Controls 2.14 import QtQuick.Controls.Material 2.0 +import QtQml.Models 2.1 import org.electrum 1.0 @@ -182,91 +183,99 @@ Pane { } ListView { + id: listview Layout.fillHeight: true Layout.fillWidth: true clip: true - model: Daemon.currentWallet.requestModel + model: DelegateModel { + id: delegateModel + model: Daemon.currentWallet.requestModel - delegate: ItemDelegate { - id: root - height: item.height - width: ListView.view.width + delegate: ItemDelegate { + id: root + height: item.height + width: ListView.view.width - onClicked: console.log('Request ' + index + ' clicked') - - font.pixelSize: constants.fontSizeSmall // set default font size for child controls - - GridLayout { - id: item - - anchors { - left: parent.left - right: parent.right - leftMargin: constants.paddingSmall - rightMargin: constants.paddingSmall - } - - columns: 5 - - Rectangle { - Layout.columnSpan: 5 - Layout.fillWidth: true - Layout.preferredHeight: constants.paddingTiny - color: 'transparent' - } - Image { - Layout.rowSpan: 2 - Layout.preferredWidth: 32 - Layout.preferredHeight: 32 - source: model.type == 0 ? "../../icons/bitcoin.png" : "../../icons/lightning.png" - } - Label { - Layout.fillWidth: true - Layout.columnSpan: 2 - text: model.message - elide: Text.ElideRight - font.pixelSize: constants.fontSizeLarge + onClicked: { + var dialog = requestdialog.createObject(app, {'modelItem': model}) + dialog.open() } - Label { - text: qsTr('Amount: ') - } - Label { - id: amount - text: Config.formatSats(model.amount, true) - font.family: FixedFont + font.pixelSize: constants.fontSizeSmall // set default font size for child controls + + GridLayout { + id: item + + anchors { + left: parent.left + right: parent.right + leftMargin: constants.paddingSmall + rightMargin: constants.paddingSmall + } + + columns: 5 + + Rectangle { + Layout.columnSpan: 5 + Layout.fillWidth: true + Layout.preferredHeight: constants.paddingTiny + color: 'transparent' + } + Image { + Layout.rowSpan: 2 + Layout.preferredWidth: constants.iconSizeLarge + Layout.preferredHeight: constants.iconSizeLarge + source: model.type == 0 ? "../../icons/bitcoin.png" : "../../icons/lightning.png" + } + Label { + Layout.fillWidth: true + Layout.columnSpan: 2 + text: model.message + elide: Text.ElideRight + font.pixelSize: constants.fontSizeLarge + } + + Label { + text: qsTr('Amount: ') + } + Label { + id: amount + text: Config.formatSats(model.amount, true) + font.family: FixedFont + } + + Label { + text: qsTr('Timestamp: ') + } + Label { + text: model.timestamp + } + + Label { + text: qsTr('Status: ') + } + Label { + text: model.status + } + Rectangle { + Layout.columnSpan: 5 + Layout.fillWidth: true + Layout.preferredHeight: constants.paddingTiny + color: 'transparent' + } } - Label { - text: qsTr('Timestamp: ') - } - Label { - text: model.timestamp + Connections { + target: Config + function onBaseUnitChanged() { + amount.text = Config.formatSats(model.amount, true) + } + function onThousandsSeparatorChanged() { + amount.text = Config.formatSats(model.amount, true) + } } - Label { - text: qsTr('Status: ') - } - Label { - text: model.status - } - Rectangle { - Layout.columnSpan: 5 - Layout.fillWidth: true - Layout.preferredHeight: constants.paddingTiny - color: 'transparent' - } - } - - Connections { - target: Config - function onBaseUnitChanged() { - amount.text = Config.formatSats(model.amount, true) - } - function onThousandsSeparatorChanged() { - amount.text = Config.formatSats(model.amount, true) - } } } @@ -280,6 +289,14 @@ Pane { NumberAnimation { properties: 'opacity'; to: 1.0; duration: 700 * (1-from) } } + remove: Transition { + NumberAnimation { properties: 'scale'; to: 0; duration: 400 } + NumberAnimation { properties: 'opacity'; to: 0; duration: 300 } + } + removeDisplaced: Transition { + SpringAnimation { properties: 'y'; duration: 100; spring: 5; damping: 0.5; mass: 2 } + } + ScrollIndicator.vertical: ScrollIndicator { } } } @@ -294,9 +311,14 @@ Pane { FocusScope { id: parkFocus } } + Component { + id: requestdialog + RequestDialog {} + } + function createRequest(ignoreGaplimit = false) { var a = Config.unitsToSats(amount.text) - Daemon.currentWallet.create_invoice(a, message.text, expires.currentValue, false, ignoreGaplimit) + Daemon.currentWallet.create_request(a, message.text, expires.currentValue, false, ignoreGaplimit) } Connections { @@ -304,8 +326,10 @@ Pane { function onRequestCreateSuccess() { message.text = '' amount.text = '' -// var dialog = app.showAsQrDialog.createObject(app, {'text': 'test'}) -// dialog.open() + var dialog = requestdialog.createObject(app, { + 'modelItem': delegateModel.items.get(0).model + }) + dialog.open() } function onRequestCreateError(code, error) { if (code == 'gaplimit') { diff --git a/electrum/gui/qml/qerequestlistmodel.py b/electrum/gui/qml/qerequestlistmodel.py index 667b93865..f0cb65fb6 100644 --- a/electrum/gui/qml/qerequestlistmodel.py +++ b/electrum/gui/qml/qerequestlistmodel.py @@ -14,7 +14,7 @@ class QERequestListModel(QAbstractListModel): _logger = get_logger(__name__) # define listmodel rolemap - _ROLE_NAMES=('type','timestamp','message','amount','status') + _ROLE_NAMES=('key','type','timestamp','message','amount','status','address') _ROLE_KEYS = range(Qt.UserRole + 1, Qt.UserRole + 1 + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) @@ -49,8 +49,11 @@ class QERequestListModel(QAbstractListModel): item['timestamp'] = format_time(timestamp) item['amount'] = req.get_amount_sat() item['message'] = req.message - - #amount_str = self.parent.format_amount(amount) if amount else "" + if req.type == 0: # OnchainInvoice + item['key'] = item['address'] = req.get_address() + elif req.type == 2: # LNInvoice + #item['key'] = req.getrhash() + pass return item @@ -74,3 +77,13 @@ class QERequestListModel(QAbstractListModel): self.beginInsertRows(QModelIndex(), 0, 0) self.requests.insert(0, item) self.endInsertRows() + + def delete_request(self, key: str): + i = 0 + for request in self.requests: + if request['key'] == key: + self.beginRemoveRows(QModelIndex(), i, i) + self.requests.pop(i) + self.endRemoveRows() + break + i = i + 1 diff --git a/electrum/gui/qml/qewallet.py b/electrum/gui/qml/qewallet.py index e694e8894..59a134ad3 100644 --- a/electrum/gui/qml/qewallet.py +++ b/electrum/gui/qml/qewallet.py @@ -164,7 +164,7 @@ class QEWallet(QObject): @pyqtSlot(int, 'QString', int) @pyqtSlot(int, 'QString', int, bool) @pyqtSlot(int, 'QString', int, bool, bool) - def create_invoice(self, amount: int, message: str, expiration: int, is_lightning: bool = False, ignore_gap: bool = False): + def create_request(self, amount: int, message: str, expiration: int, is_lightning: bool = False, ignore_gap: bool = False): expiry = expiration #TODO: self.config.get('request_expiry', PR_DEFAULT_EXPIRATION_WHEN_CREATING) try: if is_lightning: @@ -190,3 +190,8 @@ class QEWallet(QObject): #content = r.invoice if r.is_lightning() else r.get_address() #title = _('Invoice') if is_lightning else _('Address') #self.do_copy(content, title=title) + + @pyqtSlot('QString') + def delete_request(self, key: str): + self.wallet.delete_request(key) + self._requestModel.delete_request(key)