Browse Source

qml: keep QEAmount instances in qechanneldetails,

use millisat amounts for local/remote capacity and can send/receive,
refactor channel capacity graphic to ChannelBar and use that as well
in ChannelDetails
master
Sander van Grieken 3 years ago
parent
commit
1a263b46be
  1. 292
      electrum/gui/qml/components/ChannelDetails.qml
  2. 48
      electrum/gui/qml/components/controls/ChannelBar.qml
  3. 42
      electrum/gui/qml/components/controls/ChannelDelegate.qml
  4. 32
      electrum/gui/qml/qechanneldetails.py

292
electrum/gui/qml/components/ChannelDetails.qml

@ -31,177 +31,213 @@ Pane {
clip:true clip:true
interactive: height < contentHeight interactive: height < contentHeight
GridLayout { ColumnLayout {
id: rootLayout id: rootLayout
width: parent.width width: parent.width
columns: 2
Heading { Heading {
Layout.columnSpan: 2 // Layout.columnSpan: 2
text: !channeldetails.isBackup ? qsTr('Lightning Channel') : qsTr('Channel Backup') text: !channeldetails.isBackup ? qsTr('Lightning Channel') : qsTr('Channel Backup')
} }
Label { GridLayout {
visible: channeldetails.name // id: rootLayout
text: qsTr('Node name') // width: parent.width
color: Material.accentColor Layout.fillWidth: true
} columns: 2
Label {
visible: channeldetails.name
text: channeldetails.name
}
Label { Label {
text: qsTr('Short channel ID') visible: channeldetails.name
color: Material.accentColor text: qsTr('Node name')
} color: Material.accentColor
}
Label { Label {
text: channeldetails.short_cid Layout.fillWidth: true
} visible: channeldetails.name
text: channeldetails.name
}
Label { Label {
text: qsTr('State') text: qsTr('Short channel ID')
color: Material.accentColor color: Material.accentColor
} }
Label { Label {
text: channeldetails.state text: channeldetails.short_cid
} }
Label { Label {
text: qsTr('Initiator') text: qsTr('State')
color: Material.accentColor color: Material.accentColor
} }
Label { Label {
text: channeldetails.initiator text: channeldetails.state
} color: channeldetails.state == 'OPEN'
? constants.colorChannelOpen
: Material.foreground
}
Label { Label {
text: qsTr('Capacity') text: qsTr('Initiator')
color: Material.accentColor color: Material.accentColor
} }
FormattedAmount { Label {
amount: channeldetails.capacity text: channeldetails.initiator
} }
Label { Label {
text: qsTr('Can send') text: qsTr('Channel type')
color: Material.accentColor color: Material.accentColor
} }
RowLayout { Label {
visible: channeldetails.isOpen text: channeldetails.channelType
FormattedAmount {
visible: !channeldetails.frozenForSending
amount: channeldetails.canSend
singleLine: false
} }
Label { Label {
visible: channeldetails.frozenForSending text: qsTr('Remote node ID')
text: qsTr('n/a (frozen)') Layout.columnSpan: 2
color: Material.accentColor
} }
Item {
TextHighlightPane {
Layout.columnSpan: 2
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 1
} RowLayout {
Pane { width: parent.width
background: Rectangle { color: Material.dialogColor } Label {
padding: 0 text: channeldetails.pubkey
FlatButton { font.pixelSize: constants.fontSizeLarge
Layout.minimumWidth: implicitWidth font.family: FixedFont
text: channeldetails.frozenForSending ? qsTr('Unfreeze') : qsTr('Freeze') Layout.fillWidth: true
onClicked: channeldetails.freezeForSending() wrapMode: Text.Wrap
}
ToolButton {
icon.source: '../../icons/share.png'
icon.color: 'transparent'
onClicked: {
var dialog = app.genericShareDialog.createObject(root,
{ title: qsTr('Channel node ID'), text: channeldetails.pubkey }
)
dialog.open()
}
}
} }
} }
} }
Label { Label {
visible: !channeldetails.isOpen text: qsTr('Capacity and ratio')
text: qsTr('n/a (channel not open)')
}
Label {
text: qsTr('Can Receive')
color: Material.accentColor color: Material.accentColor
} }
RowLayout { TextHighlightPane {
visible: channeldetails.isOpen Layout.fillWidth: true
FormattedAmount { padding: constants.paddingLarge
visible: !channeldetails.frozenForReceiving
amount: channeldetails.canReceive
singleLine: false
}
Label { GridLayout {
visible: channeldetails.frozenForReceiving width: parent.width
text: qsTr('n/a (frozen)') columns: 2
} rowSpacing: constants.paddingSmall
Item {
Layout.fillWidth: true ChannelBar {
Layout.preferredHeight: 1 Layout.columnSpan: 2
} Layout.fillWidth: true
Pane { Layout.topMargin: constants.paddingLarge
background: Rectangle { color: Material.dialogColor } Layout.bottomMargin: constants.paddingXLarge
padding: 0 capacity: channeldetails.capacity
FlatButton { localCapacity: channeldetails.localCapacity
Layout.minimumWidth: implicitWidth remoteCapacity: channeldetails.remoteCapacity
text: channeldetails.frozenForReceiving ? qsTr('Unfreeze') : qsTr('Freeze')
onClicked: channeldetails.freezeForReceiving()
} }
}
}
Label { Label {
visible: !channeldetails.isOpen text: qsTr('Capacity')
text: qsTr('n/a (channel not open)') color: Material.accentColor
} }
Label { FormattedAmount {
text: qsTr('Channel type') amount: channeldetails.capacity
color: Material.accentColor }
}
Label { Label {
text: channeldetails.channelType text: qsTr('Can send')
} color: Material.accentColor
}
Label { RowLayout {
text: qsTr('Remote node ID') visible: channeldetails.isOpen
Layout.columnSpan: 2 FormattedAmount {
color: Material.accentColor visible: !channeldetails.frozenForSending
} amount: channeldetails.canSend
singleLine: false
}
Label {
visible: channeldetails.frozenForSending
text: qsTr('n/a (frozen)')
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: 1
}
Pane {
background: Rectangle { color: Material.dialogColor }
padding: 0
FlatButton {
Layout.minimumWidth: implicitWidth
text: channeldetails.frozenForSending ? qsTr('Unfreeze') : qsTr('Freeze')
onClicked: channeldetails.freezeForSending()
}
}
}
TextHighlightPane { Label {
Layout.columnSpan: 2 visible: !channeldetails.isOpen
Layout.fillWidth: true text: qsTr('n/a (channel not open)')
}
RowLayout {
width: parent.width
Label { Label {
text: channeldetails.pubkey text: qsTr('Can Receive')
font.pixelSize: constants.fontSizeLarge color: Material.accentColor
font.family: FixedFont
Layout.fillWidth: true
wrapMode: Text.Wrap
} }
ToolButton {
icon.source: '../../icons/share.png' RowLayout {
icon.color: 'transparent' visible: channeldetails.isOpen
onClicked: { FormattedAmount {
var dialog = app.genericShareDialog.createObject(root, visible: !channeldetails.frozenForReceiving
{ title: qsTr('Channel node ID'), text: channeldetails.pubkey } amount: channeldetails.canReceive
) singleLine: false
dialog.open() }
Label {
visible: channeldetails.frozenForReceiving
text: qsTr('n/a (frozen)')
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: 1
} }
Pane {
background: Rectangle { color: Material.dialogColor }
padding: 0
FlatButton {
Layout.minimumWidth: implicitWidth
text: channeldetails.frozenForReceiving ? qsTr('Unfreeze') : qsTr('Freeze')
onClicked: channeldetails.freezeForReceiving()
}
}
}
Label {
visible: !channeldetails.isOpen
text: qsTr('n/a (channel not open)')
} }
} }
}
}
} }
} }

48
electrum/gui/qml/components/controls/ChannelBar.qml

@ -0,0 +1,48 @@
import QtQuick 2.6
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls.Material 2.0
import org.electrum 1.0
Item {
property Amount capacity
property Amount localCapacity
property Amount remoteCapacity
height: 10
implicitWidth: 100
onWidthChanged: {
var cap = capacity.satsInt * 1000
var twocap = cap * 2
b1.width = width * (cap - localCapacity.msatsInt) / twocap
b2.width = width * localCapacity.msatsInt / twocap
b3.width = width * remoteCapacity.msatsInt / twocap
b4.width = width * (cap - remoteCapacity.msatsInt) / twocap
}
Rectangle {
id: b1
x: 0
height: parent.height
color: 'gray'
}
Rectangle {
id: b2
anchors.left: b1.right
height: parent.height
color: constants.colorLightningLocal
}
Rectangle {
id: b3
anchors.left: b2.right
height: parent.height
color: constants.colorLightningRemote
}
Rectangle {
id: b4
anchors.left: b3.right
height: parent.height
color: 'gray'
}
}

42
electrum/gui/qml/components/controls/ChannelDelegate.qml

@ -105,44 +105,14 @@ ItemDelegate {
} }
} }
Item { ChannelBar {
id: chviz
visible: !_closed
Layout.fillWidth: true Layout.fillWidth: true
height: 10 visible: !_closed
onWidthChanged: { capacity: model.capacity
var cap = model.capacity.satsInt * 1000 localCapacity: model.local_capacity
var twocap = cap * 2 remoteCapacity: model.remote_capacity
b1.width = width * (cap - model.local_capacity.msatsInt) / twocap
b2.width = width * model.local_capacity.msatsInt / twocap
b3.width = width * model.remote_capacity.msatsInt / twocap
b4.width = width * (cap - model.remote_capacity.msatsInt) / twocap
}
Rectangle {
id: b1
x: 0
height: parent.height
color: 'gray'
}
Rectangle {
id: b2
anchors.left: b1.right
height: parent.height
color: constants.colorLightningLocal
}
Rectangle {
id: b3
anchors.left: b2.right
height: parent.height
color: constants.colorLightningRemote
}
Rectangle {
id: b4
anchors.left: b3.right
height: parent.height
color: 'gray'
}
} }
Item { Item {
visible: _closed visible: _closed
Layout.fillWidth: true Layout.fillWidth: true

32
electrum/gui/qml/qechanneldetails.py

@ -33,6 +33,12 @@ class QEChannelDetails(QObject, QtEventListener):
self._channelid = None self._channelid = None
self._channel = None self._channel = None
self._capacity = QEAmount()
self._local_capacity = QEAmount()
self._remote_capacity = QEAmount()
self._can_receive = QEAmount()
self._can_send = QEAmount()
self.register_callbacks() self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy()) self.destroyed.connect(lambda: self.on_destroy())
@ -101,23 +107,31 @@ class QEChannelDetails(QObject, QtEventListener):
@pyqtProperty(QEAmount, notify=channelChanged) @pyqtProperty(QEAmount, notify=channelChanged)
def capacity(self): def capacity(self):
self._capacity = QEAmount(amount_sat=self._channel.get_capacity()) self._capacity.copyFrom(QEAmount(amount_sat=self._channel.get_capacity()))
return self._capacity return self._capacity
@pyqtProperty(QEAmount, notify=channelChanged)
def localCapacity(self):
if not self._channel.is_backup():
self._local_capacity = QEAmount(amount_msat=self._channel.balance(LOCAL))
return self._local_capacity
@pyqtProperty(QEAmount, notify=channelChanged)
def remoteCapacity(self):
if not self._channel.is_backup():
self._remote_capacity.copyFrom(QEAmount(amount_msat=self._channel.balance(REMOTE)))
return self._remote_capacity
@pyqtProperty(QEAmount, notify=channelChanged) @pyqtProperty(QEAmount, notify=channelChanged)
def canSend(self): def canSend(self):
if self._channel.is_backup(): if not self._channel.is_backup():
self._can_send = QEAmount() self._can_send.copyFrom(QEAmount(amount_msat=self._channel.available_to_spend(LOCAL)))
else:
self._can_send = QEAmount(amount_sat=self._channel.available_to_spend(LOCAL)/1000)
return self._can_send return self._can_send
@pyqtProperty(QEAmount, notify=channelChanged) @pyqtProperty(QEAmount, notify=channelChanged)
def canReceive(self): def canReceive(self):
if self._channel.is_backup(): if not self._channel.is_backup():
self._can_receive = QEAmount() self._can_receive.copyFrom(QEAmount(amount_msat=self._channel.available_to_spend(REMOTE)))
else:
self._can_receive = QEAmount(amount_sat=self._channel.available_to_spend(REMOTE)/1000)
return self._can_receive return self._can_receive
@pyqtProperty(bool, notify=channelChanged) @pyqtProperty(bool, notify=channelChanged)

Loading…
Cancel
Save