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
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
columns: 2
|
||||||
|
|
||||||
RowLayout {
|
Label {
|
||||||
width: parent.width
|
visible: channeldetails.name
|
||||||
Label {
|
text: qsTr('Node name')
|
||||||
text: channeldetails.pubkey
|
color: Material.accentColor
|
||||||
font.pixelSize: constants.fontSizeLarge
|
}
|
||||||
font.family: FixedFont
|
|
||||||
Layout.fillWidth: true
|
Label {
|
||||||
wrapMode: Text.Wrap
|
Layout.fillWidth: true
|
||||||
}
|
visible: channeldetails.name
|
||||||
ToolButton {
|
text: channeldetails.name
|
||||||
icon.source: '../../icons/share.png'
|
}
|
||||||
icon.color: 'transparent'
|
|
||||||
onClicked: {
|
Label {
|
||||||
var dialog = app.genericShareDialog.createObject(root,
|
text: qsTr('Short channel ID')
|
||||||
{ title: qsTr('Channel node ID'), text: channeldetails.pubkey }
|
color: Material.accentColor
|
||||||
)
|
}
|
||||||
dialog.open()
|
|
||||||
|
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 {
|
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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user