diff --git a/electrum/gui/qml/components/ChannelDetails.qml b/electrum/gui/qml/components/ChannelDetails.qml index ede5a5a97..16a71c8eb 100644 --- a/electrum/gui/qml/components/ChannelDetails.qml +++ b/electrum/gui/qml/components/ChannelDetails.qml @@ -271,6 +271,7 @@ Pane { RowLayout { Layout.fillWidth: true + visible: channeldetails.isOpen FlatButton { Layout.fillWidth: true diff --git a/electrum/gui/qml/components/CloseChannelDialog.qml b/electrum/gui/qml/components/CloseChannelDialog.qml index 1ebae766d..c5b332170 100644 --- a/electrum/gui/qml/components/CloseChannelDialog.qml +++ b/electrum/gui/qml/components/CloseChannelDialog.qml @@ -121,7 +121,7 @@ ElDialog { RadioButton { ButtonGroup.group: closetypegroup property string closetype: 'local_force' - enabled: !closing && channeldetails.canForceClose + enabled: !closing && channeldetails.canForceClose && !channeldetails.isBackup text: qsTr('Local Force-close') } } diff --git a/electrum/gui/qml/components/controls/ChannelDelegate.qml b/electrum/gui/qml/components/controls/ChannelDelegate.qml index 4ae0ffd49..345a2f35c 100644 --- a/electrum/gui/qml/components/controls/ChannelDelegate.qml +++ b/electrum/gui/qml/components/controls/ChannelDelegate.qml @@ -36,7 +36,11 @@ ItemDelegate { Image { id: walleticon - source: model.is_trampoline ? '../../../icons/kangaroo.png' : '../../../icons/lightning.png' + source: model.is_backup + ? '../../../icons/nocloud.png' + : model.is_trampoline + ? '../../../icons/kangaroo.png' + : '../../../icons/lightning.png' fillMode: Image.PreserveAspectFit Layout.rowSpan: 3 Layout.preferredWidth: constants.iconSizeLarge diff --git a/electrum/gui/qml/qechanneldetails.py b/electrum/gui/qml/qechanneldetails.py index 935073aee..f7cdf1c65 100644 --- a/electrum/gui/qml/qechanneldetails.py +++ b/electrum/gui/qml/qechanneldetails.py @@ -67,9 +67,8 @@ class QEChannelDetails(QObject, QtEventListener): self.channelidChanged.emit() def load(self): - lnchannels = self._wallet.wallet.lnworker.channels + lnchannels = self._wallet.wallet.lnworker.get_channel_objects() for channel in lnchannels.values(): - #self._logger.debug('%s == %s ?' % (self._channelid, channel.channel_id)) if self._channelid == channel.channel_id.hex(): self._channel = channel self.channelChanged.emit() @@ -94,6 +93,8 @@ class QEChannelDetails(QObject, QtEventListener): @pyqtProperty(str, notify=channelChanged) def initiator(self): + if self._channel.is_backup(): + return '' return 'Local' if self._channel.constraints.is_initiator else 'Remote' @pyqtProperty(QEAmount, notify=channelChanged) @@ -103,12 +104,18 @@ class QEChannelDetails(QObject, QtEventListener): @pyqtProperty(QEAmount, notify=channelChanged) def canSend(self): - self._can_send = QEAmount(amount_sat=self._channel.available_to_spend(LOCAL)/1000) + if self._channel.is_backup(): + self._can_send = QEAmount() + else: + self._can_send = QEAmount(amount_sat=self._channel.available_to_spend(LOCAL)/1000) return self._can_send @pyqtProperty(QEAmount, notify=channelChanged) def canReceive(self): - self._can_receive = QEAmount(amount_sat=self._channel.available_to_spend(REMOTE)/1000) + if self._channel.is_backup(): + self._can_receive = QEAmount() + else: + self._can_receive = QEAmount(amount_sat=self._channel.available_to_spend(REMOTE)/1000) return self._can_receive @pyqtProperty(bool, notify=channelChanged) @@ -121,7 +128,7 @@ class QEChannelDetails(QObject, QtEventListener): @pyqtProperty(str, notify=channelChanged) def channelType(self): - return self._channel.storage['channel_type'].name_minimal + return self._channel.storage['channel_type'].name_minimal if 'channel_type' in self._channel.storage else 'Channel Backup' @pyqtProperty(bool, notify=channelChanged) def isOpen(self): @@ -137,7 +144,7 @@ class QEChannelDetails(QObject, QtEventListener): @pyqtProperty(bool, notify=channelChanged) def canForceClose(self): - return ChanCloseOption.LOCAL_FCLOSE in self._channel.get_close_options() + return any([o in [ChanCloseOption.LOCAL_FCLOSE, ChanCloseOption.REQUEST_REMOTE_FCLOSE] for o in self._channel.get_close_options()]) @pyqtProperty(bool, notify=channelChanged) def canDelete(self): @@ -147,6 +154,10 @@ class QEChannelDetails(QObject, QtEventListener): def message_force_close(self, notify=channelChanged): return _(messages.MSG_REQUEST_FORCE_CLOSE) + @pyqtProperty(bool, notify=channelChanged) + def isBackup(self): + return self._channel.is_backup() + @pyqtSlot() def freezeForSending(self): lnworker = self._channel.lnworker diff --git a/electrum/gui/qml/qechannellistmodel.py b/electrum/gui/qml/qechannellistmodel.py index 8e0a0c435..c2d0d8aaf 100644 --- a/electrum/gui/qml/qechannellistmodel.py +++ b/electrum/gui/qml/qechannellistmodel.py @@ -15,7 +15,8 @@ class QEChannelListModel(QAbstractListModel, QtEventListener): # define listmodel rolemap _ROLE_NAMES=('cid','state','state_code','initiator','capacity','can_send', 'can_receive','l_csv_delay','r_csv_delay','send_frozen','receive_frozen', - 'type','node_id','node_alias','short_cid','funding_tx','is_trampoline') + 'type','node_id','node_alias','short_cid','funding_tx','is_trampoline', + 'is_backup') _ROLE_KEYS = range(Qt.UserRole, Qt.UserRole + len(_ROLE_NAMES)) _ROLE_MAP = dict(zip(_ROLE_KEYS, [bytearray(x.encode()) for x in _ROLE_NAMES])) _ROLE_RMAP = dict(zip(_ROLE_NAMES, _ROLE_KEYS)) @@ -72,10 +73,15 @@ class QEChannelListModel(QAbstractListModel, QtEventListener): item['short_cid'] = lnc.short_id_for_GUI() item['state'] = lnc.get_state_for_GUI() item['state_code'] = int(lnc.get_state()) - item['capacity'] = QEAmount(amount_sat=lnc.get_capacity()) - item['can_send'] = QEAmount(amount_msat=lnc.available_to_spend(LOCAL)) - item['can_receive'] = QEAmount(amount_msat=lnc.available_to_spend(REMOTE)) + item['is_backup'] = lnc.is_backup() item['is_trampoline'] = lnworker.is_trampoline_peer(lnc.node_id) + item['capacity'] = QEAmount(amount_sat=lnc.get_capacity()) + if lnc.is_backup(): + item['can_send'] = QEAmount() + item['can_receive'] = QEAmount() + else: + item['can_send'] = QEAmount(amount_msat=lnc.available_to_spend(LOCAL)) + item['can_receive'] = QEAmount(amount_msat=lnc.available_to_spend(REMOTE)) return item numOpenChannelsChanged = pyqtSignal() @@ -94,9 +100,6 @@ class QEChannelListModel(QAbstractListModel, QtEventListener): lnchannels = self.wallet.lnworker.get_channel_objects() for channel in lnchannels.values(): - if channel.is_backup(): - # not implemented - continue item = self.channel_to_model(channel) channels.append(item)