Browse Source

qml: add expiry timers to update status string in InvoiceDialog and ReceiveDialog

master
Sander van Grieken 3 years ago
parent
commit
995754e523
  1. 11
      electrum/gui/qml/components/ReceiveDialog.qml
  2. 28
      electrum/gui/qml/qeinvoice.py
  3. 37
      electrum/gui/qml/qerequestdetails.py
  4. 20
      electrum/gui/qml/util.py

11
electrum/gui/qml/components/ReceiveDialog.qml

@ -207,10 +207,17 @@ ElDialog {
GridLayout {
columns: 2
visible: request.message || !request.amount.isEmpty
// visible: request.message || !request.amount.isEmpty
Layout.maximumWidth: buttons.width
Layout.alignment: Qt.AlignHCenter
Label {
text: qsTr('Status')
color: Material.accentColor
}
Label {
text: request.status_str
}
Label {
visible: request.message
text: qsTr('Message')
@ -234,7 +241,7 @@ ElDialog {
}
Rectangle {
visible: request.message || !request.amount.isEmpty
// visible: request.message || !request.amount.isEmpty
height: 1
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: buttons.width

28
electrum/gui/qml/qeinvoice.py

@ -2,14 +2,14 @@ import threading
import asyncio
from urllib.parse import urlparse
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, Q_ENUMS
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, Q_ENUMS, QTimer
from electrum import bitcoin
from electrum import lnutil
from electrum.i18n import _
from electrum.invoices import Invoice
from electrum.invoices import (PR_UNPAID, PR_EXPIRED, PR_UNKNOWN, PR_PAID, PR_INFLIGHT,
PR_FAILED, PR_ROUTING, PR_UNCONFIRMED)
PR_FAILED, PR_ROUTING, PR_UNCONFIRMED, LN_EXPIRY_NEVER)
from electrum.lnaddr import LnInvoiceException
from electrum.logging import get_logger
from electrum.transaction import PartialTxOutput
@ -20,6 +20,7 @@ from electrum.bitcoin import COIN
from .qetypes import QEAmount
from .qewallet import QEWallet
from .util import status_update_timer_interval
class QEInvoice(QObject):
class Type:
@ -140,6 +141,10 @@ class QEInvoiceParser(QEInvoice):
self._amount = QEAmount()
self._userinfo = ''
self._timer = QTimer(self)
self._timer.setSingleShot(True)
self._timer.timeout.connect(self.updateStatusString)
self.clear()
@pyqtProperty(int, notify=invoiceChanged)
@ -190,6 +195,10 @@ class QEInvoiceParser(QEInvoice):
self.determine_can_pay()
self.invoiceChanged.emit()
@pyqtProperty('quint64', notify=invoiceChanged)
def time(self):
return self._effectiveInvoice.time if self._effectiveInvoice else 0
@pyqtProperty('quint64', notify=invoiceChanged)
def expiration(self):
return self._effectiveInvoice.exp if self._effectiveInvoice else 0
@ -268,6 +277,21 @@ class QEInvoiceParser(QEInvoice):
self.invoiceChanged.emit()
self.statusChanged.emit()
self.set_status_timer()
def set_status_timer(self):
if self.status != PR_EXPIRED:
if self.expiration > 0 and self.expiration != LN_EXPIRY_NEVER:
interval = status_update_timer_interval(self.time + self.expiration)
if interval > 0:
self._timer.setInterval(interval) # msec
self._timer.start()
@pyqtSlot()
def updateStatusString(self):
self.statusChanged.emit()
self.set_status_timer()
def determine_can_pay(self):
self.canPay = False
self.userinfo = ''

37
electrum/gui/qml/qerequestdetails.py

@ -1,5 +1,3 @@
from time import time
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, Q_ENUMS
from electrum.logging import get_logger
@ -8,7 +6,7 @@ from electrum.invoices import (PR_UNPAID, PR_EXPIRED, PR_UNKNOWN, PR_PAID, PR_IN
from .qewallet import QEWallet
from .qetypes import QEAmount
from .util import QtEventListener, event_listener
from .util import QtEventListener, event_listener, status_update_timer_interval
class QERequestDetails(QObject, QtEventListener):
@ -38,6 +36,10 @@ class QERequestDetails(QObject, QtEventListener):
self._timer = None
self._amount = None
self._timer = QTimer(self)
self._timer.setSingleShot(True)
self._timer.timeout.connect(self.updateStatusString)
self.register_callbacks()
self.destroyed.connect(lambda: self.on_destroy())
@ -134,31 +136,16 @@ class QERequestDetails(QObject, QtEventListener):
self._amount = QEAmount(from_invoice=self._req)
self.detailsChanged.emit()
self.initStatusStringTimer()
self.statusChanged.emit()
self.set_status_timer()
def initStatusStringTimer(self):
def set_status_timer(self):
if self.status == PR_UNPAID:
if self.expiration > 0 and self.expiration != LN_EXPIRY_NEVER:
self._timer = QTimer(self)
self._timer.setSingleShot(True)
self._timer.timeout.connect(self.updateStatusString)
# very roughly according to util.time_difference
exp_in = int(self.expiration - time())
exp_in_min = int(exp_in/60)
interval = 0
if exp_in < 0:
interval = 0
if exp_in_min < 2:
interval = 1000
elif exp_in_min < 90:
interval = 1000 * 60
elif exp_in_min < 1440:
interval = 1000 * 60 * 60
self._logger.debug(f'set_status_timer, expiration={self.expiration}')
interval = status_update_timer_interval(self.expiration)
if interval > 0:
self._logger.debug(f'setting status update timer to {interval}, req expires in {exp_in} seconds')
self._logger.debug(f'setting status update timer to {interval}')
self._timer.setInterval(interval) # msec
self._timer.start()
@ -166,5 +153,5 @@ class QERequestDetails(QObject, QtEventListener):
@pyqtSlot()
def updateStatusString(self):
self.statusChanged.emit()
self.initStatusStringTimer()
self.set_status_timer()

20
electrum/gui/qml/util.py

@ -1,4 +1,5 @@
from functools import wraps
from time import time
from PyQt5.QtCore import pyqtSignal
@ -27,3 +28,22 @@ def qt_event_listener(func):
def decorator(self, *args):
self.qt_callback_signal.emit( (func,) + args)
return decorator
# return delay in msec when expiry time string should be updated
# returns 0 when expired or expires > 1 day away (no updates needed)
def status_update_timer_interval(exp):
# very roughly according to util.time_difference
exp_in = int(exp - time())
exp_in_min = int(exp_in/60)
interval = 0
if exp_in < 0:
interval = 0
elif exp_in_min < 2:
interval = 1000
elif exp_in_min < 90:
interval = 1000 * 60
elif exp_in_min < 1440:
interval = 1000 * 60 * 60
return interval

Loading…
Cancel
Save