Browse Source

qml: network status improvements

create NetworkStatusIndicator component
add forks/chaintips and lagging property to qenetwork
add synchronizing and synchronizing progress properties to qewallet
Note: new wallet synchronizing is not picked up in UI yet, missing
an is_up_to_date event at the start still..
patch-4
Sander van Grieken 3 years ago
parent
commit
623de58b7b
  1. 16
      electrum/gui/qml/components/NetworkStats.qml
  2. 58
      electrum/gui/qml/components/controls/NetworkStatusIndicator.qml
  3. 12
      electrum/gui/qml/components/main.qml
  4. 31
      electrum/gui/qml/qenetwork.py
  5. 54
      electrum/gui/qml/qewallet.py

16
electrum/gui/qml/components/NetworkStats.qml

@ -3,6 +3,8 @@ import QtQuick.Layouts 1.0
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
import "controls"
Pane {
property string title: qsTr('Network')
@ -45,17 +47,9 @@ Pane {
color: Material.primaryHighlightedTextColor;
font.bold: true
}
Image {
Layout.preferredWidth: constants.iconSizeSmall
Layout.preferredHeight: constants.iconSizeSmall
source: Network.status == 'connecting' || Network.status == 'disconnected'
? '../../icons/status_disconnected.png'
: Network.status == 'connected'
? Daemon.currentWallet && !Daemon.currentWallet.isUptodate
? '../../icons/status_lagging.png'
: '../../icons/status_connected.png'
: '../../icons/status_connected.png'
}
NetworkStatusIndicator {}
Label {
text: Network.status
}

58
electrum/gui/qml/components/controls/NetworkStatusIndicator.qml

@ -0,0 +1,58 @@
import QtQuick 2.6
Image {
id: root
sourceSize.width: constants.iconSizeMedium
sourceSize.height: constants.iconSizeMedium
property bool connected: Network.status == 'connected'
property bool lagging: connected && Network.isLagging
property bool fork: connected && Network.chaintips > 1
property bool syncing: connected && Daemon.currentWallet && Daemon.currentWallet.synchronizing
// ?: in order to keep this a binding..
source: !connected
? '../../../icons/status_disconnected.png'
: syncing
? '../../../icons/status_waiting.png'
: lagging
? fork
? '../../../icons/status_lagging_fork.png'
: '../../../icons/status_lagging.png'
: fork
? '../../../icons/status_connected_fork.png'
: '../../../icons/status_connected.png'
states: [
State {
name: 'disconnected'
when: !connected
PropertyChanges { target: root; rotation: 0 }
},
State {
name: 'normal'
when: !(syncing || fork)
PropertyChanges { target: root; rotation: 0 }
},
State {
name: 'syncing'
when: syncing
PropertyChanges { target: spin; running: true }
},
State {
name: 'forked'
when: fork
PropertyChanges { target: root; rotation: 0 }
}
]
RotationAnimation {
id: spin
target: root
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
}
}

12
electrum/gui/qml/components/main.qml

@ -88,17 +88,7 @@ ApplicationWindow
scale: 1.5
}
Image {
Layout.preferredWidth: constants.iconSizeSmall
Layout.preferredHeight: constants.iconSizeSmall
source: Network.status == 'connecting' || Network.status == 'disconnected'
? '../../icons/status_disconnected.png'
: Network.status == 'connected'
? Daemon.currentWallet && !Daemon.currentWallet.isUptodate
? '../../icons/status_lagging.png'
: '../../icons/status_connected.png'
: '../../icons/status_connected.png'
}
NetworkStatusIndicator { }
Rectangle {
color: 'transparent'

31
electrum/gui/qml/qenetwork.py

@ -10,6 +10,7 @@ class QENetwork(QObject, QtEventListener):
def __init__(self, network, parent=None):
super().__init__(parent)
self.network = network
self._height = network.get_local_height() # init here, update event can take a while
self.register_callbacks()
_logger = get_logger(__name__)
@ -22,12 +23,16 @@ class QENetwork(QObject, QtEventListener):
proxyChanged = pyqtSignal()
statusChanged = pyqtSignal()
feeHistogramUpdated = pyqtSignal()
chaintipsChanged = pyqtSignal()
isLaggingChanged = pyqtSignal()
# shared signal for static properties
dataChanged = pyqtSignal()
_height = 0
_status = ""
_chaintips = 1
_islagging = False
_fee_histogram = []
@event_listener
@ -35,7 +40,7 @@ class QENetwork(QObject, QtEventListener):
self.networkUpdated.emit()
@event_listener
def on_event_blockchain_updated(self, *args):
def on_event_blockchain_updated(self):
if self._height != self.network.get_local_height():
self._height = self.network.get_local_height()
self._logger.debug('new height: %d' % self._height)
@ -57,6 +62,16 @@ class QENetwork(QObject, QtEventListener):
if self._status != self.network.connection_status:
self._status = self.network.connection_status
self.statusChanged.emit()
chains = len(self.network.get_blockchains())
if chains != self._chaintips:
self._logger.debug('chain tips # changed: ' + chains)
self._chaintips = chains
self.chaintipsChanged.emit()
server_lag = self.network.get_local_height() - self.network.get_server_height()
if self._islagging ^ (server_lag > 1):
self._logger.debug('lagging changed: ' + (server_lag > 1))
self._islagging = server_lag > 1
self.isLaggingChanged.emit()
@event_listener
def on_event_fee_histogram(self, histogram):
@ -68,7 +83,7 @@ class QENetwork(QObject, QtEventListener):
def height(self):
return self._height
@pyqtProperty('QString', notify=defaultServerChanged)
@pyqtProperty(str, notify=defaultServerChanged)
def server(self):
return str(self.network.get_parameters().server)
@ -83,15 +98,23 @@ class QENetwork(QObject, QtEventListener):
net_params = net_params._replace(server=server)
self.network.run_from_another_thread(self.network.set_parameters(net_params))
@pyqtProperty('QString', notify=statusChanged)
@pyqtProperty(str, notify=statusChanged)
def status(self):
return self._status
@pyqtProperty(int, notify=chaintipsChanged)
def chaintips(self):
return self._chaintips
@pyqtProperty(bool, notify=isLaggingChanged)
def isLagging(self):
return self._islagging
@pyqtProperty(bool, notify=dataChanged)
def isTestNet(self):
return constants.net.TESTNET
@pyqtProperty('QString', notify=dataChanged)
@pyqtProperty(str, notify=dataChanged)
def networkName(self):
return constants.net.__name__.replace('Bitcoin','')

54
electrum/gui/qml/qewallet.py

@ -63,6 +63,10 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
_network_signal = pyqtSignal(str, object)
_isUpToDate = False
_synchronizing = False
_synchronizing_progress = ''
def __init__(self, wallet, parent=None):
super().__init__(parent)
self.wallet = wallet
@ -91,11 +95,52 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
@pyqtProperty(bool, notify=isUptodateChanged)
def isUptodate(self):
return self.wallet.is_up_to_date()
return self._isUpToDate
synchronizingChanged = pyqtSignal()
@pyqtProperty(bool, notify=synchronizingChanged)
def synchronizing(self):
return self._synchronizing
@synchronizing.setter
def synchronizing(self, synchronizing):
if self._synchronizing != synchronizing:
self._synchronizing = synchronizing
self.synchronizingChanged.emit()
synchronizingProgressChanged = pyqtSignal()
@pyqtProperty(str, notify=synchronizingProgressChanged)
def synchronizing_progress(self):
return self._synchronizing_progress
@synchronizing_progress.setter
def synchronizing_progress(self, progress):
if self._synchronizing_progress != progress:
self._synchronizing_progress = progress
self.synchronizingProgressChanged.emit()
@event_listener
def on_event_status(self, *args, **kwargs):
self.isUptodateChanged.emit()
def on_event_status(self):
self._logger.debug('status')
uptodate = self.wallet.is_up_to_date()
if self._isUpToDate != uptodate:
self._isUpToDate = uptodate
self.isUptodateChanged.emit()
if self.wallet.network.is_connected():
server_height = self.wallet.network.get_server_height()
server_lag = self.wallet.network.get_local_height() - server_height
# Server height can be 0 after switching to a new server
# until we get a headers subscription request response.
# Display the synchronizing message in that case.
if not self._isUpToDate or server_height == 0:
num_sent, num_answered = self.wallet.adb.get_history_sync_state_details()
self.synchronizing_progress = ("{} ({}/{})"
.format(_("Synchronizing..."), num_answered, num_sent))
self.synchronizing = True
else:
self.synchronizing_progress = ''
self.synchronizing = False
@event_listener
def on_event_request_status(self, wallet, key, status):
@ -116,8 +161,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
self._logger.debug(f'No invoice found for key {key}')
@qt_event_listener
def on_event_new_transaction(self, *args):
wallet, tx = args
def on_event_new_transaction(self, wallet, tx):
if wallet == self.wallet:
self.add_tx_notification(tx)
self.historyModel.init_model() # TODO: be less dramatic

Loading…
Cancel
Save