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
This commit is contained in:
@@ -31,177 +31,213 @@ Pane {
|
||||
clip:true
|
||||
interactive: height < contentHeight
|
||||
|
||||
GridLayout {
|
||||
ColumnLayout {
|
||||
id: rootLayout
|
||||
width: parent.width
|
||||
columns: 2
|
||||
|
||||
Heading {
|
||||
Layout.columnSpan: 2
|
||||
// Layout.columnSpan: 2
|
||||
text: !channeldetails.isBackup ? qsTr('Lightning Channel') : qsTr('Channel Backup')
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: channeldetails.name
|
||||
text: qsTr('Node name')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: channeldetails.name
|
||||
text: channeldetails.name
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Short channel ID')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: channeldetails.short_cid
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('State')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: channeldetails.state
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Initiator')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: channeldetails.initiator
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Capacity')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
FormattedAmount {
|
||||
amount: channeldetails.capacity
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Can send')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: channeldetails.isOpen
|
||||
FormattedAmount {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: !channeldetails.isOpen
|
||||
text: qsTr('n/a (channel not open)')
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Can Receive')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: channeldetails.isOpen
|
||||
FormattedAmount {
|
||||
visible: !channeldetails.frozenForReceiving
|
||||
amount: channeldetails.canReceive
|
||||
singleLine: false
|
||||
}
|
||||
|
||||
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)')
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Channel type')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: channeldetails.channelType
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Remote node ID')
|
||||
Layout.columnSpan: 2
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
TextHighlightPane {
|
||||
Layout.columnSpan: 2
|
||||
GridLayout {
|
||||
// id: rootLayout
|
||||
// width: parent.width
|
||||
Layout.fillWidth: true
|
||||
columns: 2
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
Label {
|
||||
text: channeldetails.pubkey
|
||||
font.pixelSize: constants.fontSizeLarge
|
||||
font.family: FixedFont
|
||||
Layout.fillWidth: true
|
||||
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 {
|
||||
visible: channeldetails.name
|
||||
text: qsTr('Node name')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
visible: channeldetails.name
|
||||
text: channeldetails.name
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Short channel ID')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: channeldetails.short_cid
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('State')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: channeldetails.state
|
||||
color: channeldetails.state == 'OPEN'
|
||||
? constants.colorChannelOpen
|
||||
: Material.foreground
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Initiator')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: channeldetails.initiator
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Channel type')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
text: channeldetails.channelType
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Remote node ID')
|
||||
Layout.columnSpan: 2
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
TextHighlightPane {
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
Label {
|
||||
text: channeldetails.pubkey
|
||||
font.pixelSize: constants.fontSizeLarge
|
||||
font.family: FixedFont
|
||||
Layout.fillWidth: true
|
||||
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 {
|
||||
text: qsTr('Capacity and ratio')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
TextHighlightPane {
|
||||
Layout.fillWidth: true
|
||||
padding: constants.paddingLarge
|
||||
|
||||
GridLayout {
|
||||
width: parent.width
|
||||
columns: 2
|
||||
rowSpacing: constants.paddingSmall
|
||||
|
||||
ChannelBar {
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: constants.paddingLarge
|
||||
Layout.bottomMargin: constants.paddingXLarge
|
||||
capacity: channeldetails.capacity
|
||||
localCapacity: channeldetails.localCapacity
|
||||
remoteCapacity: channeldetails.remoteCapacity
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Capacity')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
FormattedAmount {
|
||||
amount: channeldetails.capacity
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Can send')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: channeldetails.isOpen
|
||||
FormattedAmount {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: !channeldetails.isOpen
|
||||
text: qsTr('n/a (channel not open)')
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr('Can Receive')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: channeldetails.isOpen
|
||||
FormattedAmount {
|
||||
visible: !channeldetails.frozenForReceiving
|
||||
amount: channeldetails.canReceive
|
||||
singleLine: false
|
||||
}
|
||||
|
||||
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
Normal file
48
electrum/gui/qml/components/controls/ChannelBar.qml
Normal file
@@ -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'
|
||||
}
|
||||
}
|
||||
@@ -105,44 +105,14 @@ ItemDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: chviz
|
||||
visible: !_closed
|
||||
ChannelBar {
|
||||
Layout.fillWidth: true
|
||||
height: 10
|
||||
onWidthChanged: {
|
||||
var cap = model.capacity.satsInt * 1000
|
||||
var twocap = cap * 2
|
||||
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'
|
||||
}
|
||||
visible: !_closed
|
||||
capacity: model.capacity
|
||||
localCapacity: model.local_capacity
|
||||
remoteCapacity: model.remote_capacity
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: _closed
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -33,6 +33,12 @@ class QEChannelDetails(QObject, QtEventListener):
|
||||
self._channelid = 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.destroyed.connect(lambda: self.on_destroy())
|
||||
|
||||
@@ -101,23 +107,31 @@ class QEChannelDetails(QObject, QtEventListener):
|
||||
|
||||
@pyqtProperty(QEAmount, notify=channelChanged)
|
||||
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
|
||||
|
||||
@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)
|
||||
def canSend(self):
|
||||
if self._channel.is_backup():
|
||||
self._can_send = QEAmount()
|
||||
else:
|
||||
self._can_send = QEAmount(amount_sat=self._channel.available_to_spend(LOCAL)/1000)
|
||||
if not self._channel.is_backup():
|
||||
self._can_send.copyFrom(QEAmount(amount_msat=self._channel.available_to_spend(LOCAL)))
|
||||
return self._can_send
|
||||
|
||||
@pyqtProperty(QEAmount, notify=channelChanged)
|
||||
def canReceive(self):
|
||||
if self._channel.is_backup():
|
||||
self._can_receive = QEAmount()
|
||||
else:
|
||||
self._can_receive = QEAmount(amount_sat=self._channel.available_to_spend(REMOTE)/1000)
|
||||
if not self._channel.is_backup():
|
||||
self._can_receive.copyFrom(QEAmount(amount_msat=self._channel.available_to_spend(REMOTE)))
|
||||
return self._can_receive
|
||||
|
||||
@pyqtProperty(bool, notify=channelChanged)
|
||||
|
||||
Reference in New Issue
Block a user