diff --git a/electrum/gui/qml/components/CloseChannelDialog.qml b/electrum/gui/qml/components/CloseChannelDialog.qml index 529ce1c0e..6c7279baa 100644 --- a/electrum/gui/qml/components/CloseChannelDialog.qml +++ b/electrum/gui/qml/components/CloseChannelDialog.qml @@ -19,6 +19,7 @@ ElDialog { iconSource: Qt.resolvedUrl('../../icons/lightning_disconnected.png') property bool _closing: false + property string _closing_method closePolicy: Popup.NoAutoClose @@ -163,12 +164,50 @@ ElDialog { icon.source: '../../icons/closebutton.png' enabled: !_closing onClicked: { - _closing = true - channeldetails.closeChannel(closetypegroup.checkedButton.closetype) + if (closetypegroup.checkedButton.closetype == 'local_force') { + showBackupThenConfirmClose() + } else { + doCloseChannel() + } } - } + } + function showBackupThenConfirmClose() { + var sharedialog = app.genericShareDialog.createObject(app, { + title: qsTr('Save channel backup and force close'), + text_qr: channeldetails.channelBackup(), + text_help: channeldetails.messageForceCloseBackup, + helpTextIconStyle: InfoTextArea.IconStyle.Warn + }) + sharedialog.closed.connect(function() { + confirmCloseChannel() + }) + sharedialog.open() + } + + function confirmCloseChannel() { + var confirmdialog = app.messageDialog.createObject(app, { + title: qsTr('Confirm force close?'), + yesno: true + }) + confirmdialog.accepted.connect(function() { + doCloseChannel() + }) + confirmdialog.open() + } + + function doCloseChannel() { + _closing = true + _closing_method = closetypegroup.checkedButton.closetype + channeldetails.closeChannel(_closing_method) + } + + function showCloseMessage(text) { + var msgdialog = app.messageDialog.createObject(app, { + text: text + }) + msgdialog.open() } ChannelDetails { @@ -176,7 +215,10 @@ ElDialog { wallet: Daemon.currentWallet channelid: dialog.channelid - onChannelChanged : { + onChannelChanged: { + if (!channeldetails.canClose) + return + // init default choice if (channeldetails.canCoopClose) closetypeCoop.checked = true @@ -186,6 +228,13 @@ ElDialog { onChannelCloseSuccess: { _closing = false + if (_closing_method == 'local_force') { + showCloseMessage(qsTr('Channel closed. You may need to wait at least %1 blocks, because of CSV delays').arg(channeldetails.toSelfDelay)) + } else if (_closing_method == 'remote_force') { + showCloseMessage(qsTr('Request sent')) + } else if (_closing_method == 'cooperative') { + showCloseMessage(qsTr('Channel closed')) + } dialog.close() } diff --git a/electrum/gui/qml/components/GenericShareDialog.qml b/electrum/gui/qml/components/GenericShareDialog.qml index 8a9b8e49c..aa85a12e2 100644 --- a/electrum/gui/qml/components/GenericShareDialog.qml +++ b/electrum/gui/qml/components/GenericShareDialog.qml @@ -12,6 +12,7 @@ ElDialog { property string text_qr // if text_qr is undefined text will be used property string text_help + property int helpTextIconStyle: InfoTextArea.IconStyle.Info title: '' @@ -65,6 +66,7 @@ ElDialog { InfoTextArea { Layout.leftMargin: constants.paddingMedium Layout.rightMargin: constants.paddingMedium + iconStyle: helpTextIconStyle visible: dialog.text_help text: dialog.text_help Layout.fillWidth: true diff --git a/electrum/gui/qml/qechanneldetails.py b/electrum/gui/qml/qechanneldetails.py index 233a67731..48585e9a9 100644 --- a/electrum/gui/qml/qechanneldetails.py +++ b/electrum/gui/qml/qechanneldetails.py @@ -13,6 +13,7 @@ from .qewallet import QEWallet from .qetypes import QEAmount from .util import QtEventListener, qt_event_listener, event_listener + class QEChannelDetails(QObject, QtEventListener): _logger = get_logger(__name__) @@ -171,13 +172,26 @@ class QEChannelDetails(QObject, QtEventListener): return self._channel.can_be_deleted() @pyqtProperty(str, notify=channelChanged) - def messageForceClose(self, notify=channelChanged): + def messageForceClose(self): return messages.MSG_REQUEST_FORCE_CLOSE.strip() + @pyqtProperty(str, notify=channelChanged) + def messageForceCloseBackup(self): + return ' '.join([ + _('If you force-close this channel, the funds you have in it will not be available for {} blocks.').format(self.toSelfDelay), + _('During that time, funds will not be recoverable from your seed, and may be lost if you lose your device.'), + _('To prevent that, please save this channel backup.'), + _('It may be imported in another wallet with the same seed.') + ]) + @pyqtProperty(bool, notify=channelChanged) def isBackup(self): return self._channel.is_backup() + @pyqtProperty(int, notify=channelChanged) + def toSelfDelay(self): + return self._channel.config[REMOTE].to_self_delay + @pyqtSlot() def freezeForSending(self): lnworker = self._channel.lnworker