qml: offer same choices as desktop; Open, Discard, Save to wallet
This commit is contained in:
@@ -36,14 +36,12 @@ from electrum.util import EventListener, event_listener
|
||||
|
||||
from electrum.gui.qml.qewallet import QEWallet
|
||||
|
||||
from .psbt_nostr import PsbtNostrPlugin, CosignerWallet, now
|
||||
from .psbt_nostr import PsbtNostrPlugin, CosignerWallet
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from electrum.wallet import Abstract_Wallet
|
||||
from electrum.gui.qml import ElectrumQmlApplication
|
||||
|
||||
USER_PROMPT_COOLDOWN = 10
|
||||
|
||||
|
||||
class QReceiveSignalObject(QObject):
|
||||
def __init__(self, plugin: 'Plugin'):
|
||||
@@ -73,12 +71,23 @@ class QReceiveSignalObject(QObject):
|
||||
return
|
||||
cosigner_wallet.send_psbt(tx_from_any(tx, deserialize=True), label)
|
||||
|
||||
@pyqtSlot(QEWallet, str)
|
||||
def acceptPsbt(self, wallet: 'QEWallet', event_id: str):
|
||||
@pyqtSlot(QEWallet, str, str)
|
||||
def saveTxLabel(self, wallet: 'QEWallet', tx: str, label: str):
|
||||
cosigner_wallet = self._plugin.cosigner_wallets.get(wallet.wallet)
|
||||
if not cosigner_wallet:
|
||||
return
|
||||
cosigner_wallet.accept_psbt(event_id)
|
||||
cosigner_wallet.save_tx_label(tx_from_any(tx, deserialize=True), label)
|
||||
|
||||
@pyqtSlot(QEWallet, str)
|
||||
@pyqtSlot(QEWallet, str, bool)
|
||||
def acceptPsbt(self, wallet: 'QEWallet', event_id: str, save_to_wallet: bool = False):
|
||||
cosigner_wallet = self._plugin.cosigner_wallets.get(wallet.wallet)
|
||||
if not cosigner_wallet:
|
||||
return
|
||||
cosigner_wallet.accept_psbt(event_id, save_to_wallet)
|
||||
if save_to_wallet:
|
||||
# let GUI update view through wallet_updated callback
|
||||
util.trigger_callback('wallet_updated', wallet.wallet)
|
||||
|
||||
@pyqtSlot(QEWallet, str)
|
||||
def rejectPsbt(self, wallet: 'QEWallet', event_id: str):
|
||||
@@ -124,17 +133,12 @@ class QmlCosignerWallet(EventListener, CosignerWallet):
|
||||
self.register_callbacks()
|
||||
|
||||
self.tx = None
|
||||
self.user_prompt_cooldown = None
|
||||
|
||||
@event_listener
|
||||
def on_event_psbt_nostr_received(self, wallet, pubkey, event_id, tx: 'PartialTransaction', label: str):
|
||||
if self.wallet == wallet:
|
||||
self.tx = tx
|
||||
if not (self.user_prompt_cooldown and self.user_prompt_cooldown > now()):
|
||||
self.plugin.so.cosignerReceivedPsbt.emit(pubkey, event_id, tx.serialize(), label)
|
||||
else:
|
||||
self.mark_pending_event_rcvd(event_id)
|
||||
self.add_transaction_to_wallet(self.tx, label=label, on_failure=self.on_add_fail)
|
||||
self.plugin.so.cosignerReceivedPsbt.emit(pubkey, event_id, tx.serialize(), label)
|
||||
|
||||
def close(self):
|
||||
super().close()
|
||||
@@ -158,13 +162,16 @@ class QmlCosignerWallet(EventListener, CosignerWallet):
|
||||
except Exception as e:
|
||||
self.plugin.so.sendPsbtFailed.emit(str(e))
|
||||
|
||||
def accept_psbt(self, event_id):
|
||||
def save_tx_label(self, tx, label):
|
||||
self.wallet.set_label(tx.txid(), label)
|
||||
|
||||
def accept_psbt(self, event_id, save: bool = False):
|
||||
if save:
|
||||
self.add_transaction_to_wallet(self.tx, on_failure=self.on_add_fail)
|
||||
self.mark_pending_event_rcvd(event_id)
|
||||
|
||||
def reject_psbt(self, event_id):
|
||||
self.user_prompt_cooldown = now() + USER_PROMPT_COOLDOWN
|
||||
self.mark_pending_event_rcvd(event_id)
|
||||
self.add_transaction_to_wallet(self.tx, on_failure=self.on_add_fail)
|
||||
|
||||
def on_add_fail(self):
|
||||
self.logger.error('failed to add tx to wallet')
|
||||
|
||||
91
electrum/plugins/psbt_nostr/qml/PsbtReceiveDialog.qml
Normal file
91
electrum/plugins/psbt_nostr/qml/PsbtReceiveDialog.qml
Normal file
@@ -0,0 +1,91 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
|
||||
import "../../../gui/qml/components/controls"
|
||||
|
||||
ElDialog {
|
||||
id: dialog
|
||||
title: qsTr("PSBT received")
|
||||
iconSource: Qt.resolvedUrl('../../../gui/icons/question.png')
|
||||
|
||||
enum Choice {
|
||||
None,
|
||||
Open,
|
||||
Save
|
||||
}
|
||||
|
||||
property string tx_label
|
||||
property int choice: PsbtReceiveDialog.Choice.None
|
||||
|
||||
// TODO: it might be better to defer popup until no dialogs are shown
|
||||
z: 1 // raise z so it also covers dialogs using overlay as parent
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
padding: 0
|
||||
|
||||
width: rootLayout.width
|
||||
|
||||
ColumnLayout {
|
||||
id: rootLayout
|
||||
width: dialog.parent.width * 2/3
|
||||
|
||||
ColumnLayout {
|
||||
Layout.margins: constants.paddingMedium
|
||||
Layout.fillWidth: true
|
||||
|
||||
TextArea {
|
||||
id: message
|
||||
Layout.fillWidth: true
|
||||
readOnly: true
|
||||
wrapMode: TextInput.WordWrap
|
||||
textFormat: TextEdit.RichText
|
||||
background: Rectangle {
|
||||
color: 'transparent'
|
||||
}
|
||||
|
||||
text: [
|
||||
tx_label
|
||||
? qsTr('A transaction was received from your cosigner with label: <br/><b>%1</b><br/>').arg(tx_label)
|
||||
: qsTr('A transaction was received from your cosigner.'),
|
||||
qsTr('Do you want to open it now?')
|
||||
].join('<br/>')
|
||||
}
|
||||
}
|
||||
|
||||
ButtonContainer {
|
||||
Layout.fillWidth: true
|
||||
|
||||
FlatButton {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: 1
|
||||
text: qsTr('Open')
|
||||
icon.source: Qt.resolvedUrl('../../../gui/icons/confirmed.png')
|
||||
onClicked: {
|
||||
choice = PsbtReceiveDialog.Choice.Open
|
||||
doAccept()
|
||||
}
|
||||
}
|
||||
|
||||
FlatButton {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: 1
|
||||
text: qsTr('Discard')
|
||||
icon.source: Qt.resolvedUrl('../../../gui/icons/closebutton.png')
|
||||
onClicked: doReject()
|
||||
}
|
||||
FlatButton {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: 1
|
||||
text: qsTr('Save to Wallet')
|
||||
icon.source: Qt.resolvedUrl('../../../gui/icons/wallet.png')
|
||||
onClicked: {
|
||||
choice = PsbtReceiveDialog.Choice.Save
|
||||
doAccept()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,23 +8,25 @@ Item {
|
||||
Connections {
|
||||
target: AppController ? AppController.plugin('psbt_nostr') : null
|
||||
function onCosignerReceivedPsbt(pubkey, event, tx, label) {
|
||||
var dialog = app.messageDialog.createObject(app, {
|
||||
text: [
|
||||
label
|
||||
? qsTr('A transaction was received from your cosigner with label: <br/><br/><b>%1</b>').arg(label)
|
||||
: qsTr('A transaction was received from your cosigner.'),
|
||||
qsTr('Do you want to open it now?')
|
||||
].join('<br/><br/>'),
|
||||
yesno: true,
|
||||
richText: true
|
||||
var dialog = psbtReceiveDialog.createObject(app, {
|
||||
tx_label: label
|
||||
})
|
||||
dialog.accepted.connect(function () {
|
||||
var page = app.stack.push(Qt.resolvedUrl('../../../gui/qml/components/TxDetails.qml'), {
|
||||
rawtx: tx
|
||||
})
|
||||
page.closed.connect(function () {
|
||||
target.acceptPsbt(Daemon.currentWallet, event)
|
||||
})
|
||||
if (dialog.choice == PsbtReceiveDialog.Choice.Open) {
|
||||
console.log('label:' + label)
|
||||
console.log('tx:' + tx)
|
||||
target.saveTxLabel(Daemon.currentWallet, tx, label)
|
||||
var page = app.stack.push(Qt.resolvedUrl('../../../gui/qml/components/TxDetails.qml'), {
|
||||
rawtx: tx
|
||||
})
|
||||
page.closed.connect(function () {
|
||||
target.acceptPsbt(Daemon.currentWallet, event)
|
||||
})
|
||||
} else if (dialog.choice == PsbtReceiveDialog.Choice.Save) {
|
||||
target.acceptPsbt(Daemon.currentWallet, event, true)
|
||||
} else {
|
||||
console.log('choice not set')
|
||||
}
|
||||
})
|
||||
dialog.rejected.connect(function () {
|
||||
target.rejectPsbt(Daemon.currentWallet, event)
|
||||
@@ -33,6 +35,13 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: psbtReceiveDialog
|
||||
PsbtReceiveDialog {
|
||||
onClosed: destroy()
|
||||
}
|
||||
}
|
||||
|
||||
property variant export_tx_button: Component {
|
||||
FlatButton {
|
||||
id: psbt_nostr_send_button
|
||||
|
||||
Reference in New Issue
Block a user