Browse Source

qml: initial channel open progress dialog

master
Sander van Grieken 3 years ago
parent
commit
509e0fcc07
  1. 110
      electrum/gui/qml/components/ChannelOpenProgressDialog.qml
  2. 23
      electrum/gui/qml/components/OpenChannel.qml
  3. 39
      electrum/gui/qml/qechannelopener.py

110
electrum/gui/qml/components/ChannelOpenProgressDialog.qml

@ -0,0 +1,110 @@
import QtQuick 2.6
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.3
import QtQuick.Controls.Material 2.0
import org.electrum 1.0
import "controls"
ElDialog {
id: dialog
width: parent.width
height: parent.height
title: qsTr('Opening Channel...')
standardButtons: Dialog.Close
footer.visible: allowClose // work around standardButtons not really mutable to/from zero buttons
allowClose: false
modal: true
parent: Overlay.overlay
Overlay.modal: Rectangle {
color: "#aa000000"
}
property alias state: s.state
property alias error: errorText.text
property alias peer: peerText.text
Item {
id: s
state: ''
states: [
State {
name: 'success'
PropertyChanges { target: dialog; allowClose: true }
PropertyChanges { target: stateText; text: qsTr('Success!') }
PropertyChanges { target: infoText; visible: true }
PropertyChanges { target: icon; source: '../../icons/confirmed.png' }
},
State {
name: 'failed'
PropertyChanges { target: dialog; allowClose: true }
PropertyChanges { target: stateText; text: qsTr('Problem opening channel') }
PropertyChanges { target: errorText; visible: true }
PropertyChanges { target: icon; source: '../../icons/warning.png' }
}
]
}
ColumnLayout {
id: content
anchors.centerIn: parent
width: parent.width
RowLayout {
Layout.alignment: Qt.AlignHCenter
Image {
id: icon
source: ''
visible: source != ''
Layout.preferredWidth: constants.iconSizeLarge
Layout.preferredHeight: constants.iconSizeLarge
}
BusyIndicator {
id: spinner
running: visible
visible: s.state == ''
Layout.preferredWidth: constants.iconSizeLarge
Layout.preferredHeight: constants.iconSizeLarge
}
Label {
id: stateText
text: qsTr('Opening Channel...')
font.pixelSize: constants.fontSizeXXLarge
}
}
TextHighlightPane {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: dialog.width * 3/4
Label {
id: peerText
font.pixelSize: constants.fontSizeMedium
width: parent.width
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
}
}
Item {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: dialog.width * 2/3
InfoTextArea {
id: errorText
visible: false
iconStyle: InfoTextArea.IconStyle.Error
width: parent.width
}
InfoTextArea {
id: infoText
visible: false
text: qsTr('Channel will be open after 3 confirmations')
}
}
}
}

23
electrum/gui/qml/components/OpenChannel.qml

@ -157,10 +157,18 @@ Pane {
} }
} }
property var channelOpenProgressDialogInstance
Component {
id: channelOpenProgressDialog
ChannelOpenProgressDialog { }
}
ChannelOpener { ChannelOpener {
id: channelopener id: channelopener
wallet: Daemon.currentWallet wallet: Daemon.currentWallet
onAuthRequired: {
app.handleAuthRequired(channelopener, method)
}
onValidationError: { onValidationError: {
if (code == 'invalid_nodeid') { if (code == 'invalid_nodeid') {
var dialog = app.messageDialog.createObject(root, { 'text': message }) var dialog = app.messageDialog.createObject(root, { 'text': message })
@ -180,18 +188,23 @@ Pane {
}) })
dialog.open() dialog.open()
} }
onChannelOpening: {
console.log('Channel is opening')
channelOpenProgressDialogInstance = channelOpenProgressDialog.createObject(app, {peer: peer})
channelOpenProgressDialogInstance.open()
}
onChannelOpenError: { onChannelOpenError: {
var dialog = app.messageDialog.createObject(root, { 'text': message }) channelOpenProgressDialogInstance.state = 'failed'
dialog.open() channelOpenProgressDialogInstance.error = message
} }
onChannelOpenSuccess: { onChannelOpenSuccess: {
var message = 'success!' var message = 'success!'
if (!has_backup) if (!has_backup)
message = message + ' (but no backup. TODO: show QR)' message = message + ' (but no backup. TODO: show QR)'
var dialog = app.messageDialog.createObject(root, { 'text': message }) channelOpenProgressDialogInstance.state = 'success'
dialog.open() channelOpenProgressDialogInstance.error = message
channelopener.wallet.channelModel.new_channel(cid) channelopener.wallet.channelModel.new_channel(cid)
app.stack.pop() // app.stack.pop()
} }
} }

39
electrum/gui/qml/qechannelopener.py

@ -1,3 +1,5 @@
import threading
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from electrum.i18n import _ from electrum.i18n import _
@ -9,8 +11,9 @@ from electrum.gui import messages
from .qewallet import QEWallet from .qewallet import QEWallet
from .qetypes import QEAmount from .qetypes import QEAmount
from .qetxfinalizer import QETxFinalizer from .qetxfinalizer import QETxFinalizer
from .auth import AuthMixin, auth_protect
class QEChannelOpener(QObject): class QEChannelOpener(QObject, AuthMixin):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
@ -24,6 +27,7 @@ class QEChannelOpener(QObject):
validationError = pyqtSignal([str,str], arguments=['code','message']) validationError = pyqtSignal([str,str], arguments=['code','message'])
conflictingBackup = pyqtSignal([str], arguments=['message']) conflictingBackup = pyqtSignal([str], arguments=['message'])
channelOpening = pyqtSignal([str], arguments=['peer'])
channelOpenError = pyqtSignal([str], arguments=['message']) channelOpenError = pyqtSignal([str], arguments=['message'])
channelOpenSuccess = pyqtSignal([str,bool], arguments=['cid','has_backup']) channelOpenSuccess = pyqtSignal([str,bool], arguments=['cid','has_backup'])
@ -156,25 +160,32 @@ class QEChannelOpener(QObject):
self._finalizer.wallet = self._wallet self._finalizer.wallet = self._wallet
self.finalizerChanged.emit() self.finalizerChanged.emit()
@auth_protect
def do_open_channel(self, funding_tx, conn_str, password): def do_open_channel(self, funding_tx, conn_str, password):
self._logger.debug('opening channel') self._logger.debug('opening channel')
# read funding_sat from tx; converts '!' to int value # read funding_sat from tx; converts '!' to int value
funding_sat = funding_tx.output_value_for_address(ln_dummy_address()) funding_sat = funding_tx.output_value_for_address(ln_dummy_address())
lnworker = self._wallet.wallet.lnworker lnworker = self._wallet.wallet.lnworker
try:
chan, funding_tx = lnworker.open_channel(
connect_str=conn_str,
funding_tx=funding_tx,
funding_sat=funding_sat,
push_amt_sat=0,
password=password)
except Exception as e:
self._logger.exception("Problem opening channel")
self.channelOpenError.emit(_('Problem opening channel: ') + '\n' + repr(e))
return
self._logger.debug('opening channel succeeded') def open_thread():
self.channelOpenSuccess.emit(chan.channel_id.hex(), chan.has_onchain_backup()) try:
chan, _funding_tx = lnworker.open_channel(
connect_str=conn_str,
funding_tx=funding_tx,
funding_sat=funding_sat,
push_amt_sat=0,
password=password)
except Exception as e:
self._logger.exception("Problem opening channel: %s", repr(e))
self.channelOpenError.emit(repr(e))
return
self._logger.debug('opening channel succeeded')
self.channelOpenSuccess.emit(chan.channel_id.hex(), chan.has_onchain_backup())
self._logger.debug('starting open thread')
self.channelOpening.emit(conn_str)
threading.Thread(target=open_thread).start()
# TODO: it would be nice to show this before broadcasting # TODO: it would be nice to show this before broadcasting
#if chan.has_onchain_backup(): #if chan.has_onchain_backup():

Loading…
Cancel
Save