qml: add expiry timers to update status string in InvoiceDialog and ReceiveDialog
This commit is contained in:
@@ -207,10 +207,17 @@ ElDialog {
|
|||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: 2
|
columns: 2
|
||||||
visible: request.message || !request.amount.isEmpty
|
// visible: request.message || !request.amount.isEmpty
|
||||||
Layout.maximumWidth: buttons.width
|
Layout.maximumWidth: buttons.width
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr('Status')
|
||||||
|
color: Material.accentColor
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
text: request.status_str
|
||||||
|
}
|
||||||
Label {
|
Label {
|
||||||
visible: request.message
|
visible: request.message
|
||||||
text: qsTr('Message')
|
text: qsTr('Message')
|
||||||
@@ -234,7 +241,7 @@ ElDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: request.message || !request.amount.isEmpty
|
// visible: request.message || !request.amount.isEmpty
|
||||||
height: 1
|
height: 1
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.preferredWidth: buttons.width
|
Layout.preferredWidth: buttons.width
|
||||||
|
|||||||
@@ -2,14 +2,14 @@ import threading
|
|||||||
import asyncio
|
import asyncio
|
||||||
from urllib.parse import urlparse
|
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 bitcoin
|
||||||
from electrum import lnutil
|
from electrum import lnutil
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
from electrum.invoices import Invoice
|
from electrum.invoices import Invoice
|
||||||
from electrum.invoices import (PR_UNPAID, PR_EXPIRED, PR_UNKNOWN, PR_PAID, PR_INFLIGHT,
|
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.lnaddr import LnInvoiceException
|
||||||
from electrum.logging import get_logger
|
from electrum.logging import get_logger
|
||||||
from electrum.transaction import PartialTxOutput
|
from electrum.transaction import PartialTxOutput
|
||||||
@@ -20,6 +20,7 @@ from electrum.bitcoin import COIN
|
|||||||
|
|
||||||
from .qetypes import QEAmount
|
from .qetypes import QEAmount
|
||||||
from .qewallet import QEWallet
|
from .qewallet import QEWallet
|
||||||
|
from .util import status_update_timer_interval
|
||||||
|
|
||||||
class QEInvoice(QObject):
|
class QEInvoice(QObject):
|
||||||
class Type:
|
class Type:
|
||||||
@@ -140,6 +141,10 @@ class QEInvoiceParser(QEInvoice):
|
|||||||
self._amount = QEAmount()
|
self._amount = QEAmount()
|
||||||
self._userinfo = ''
|
self._userinfo = ''
|
||||||
|
|
||||||
|
self._timer = QTimer(self)
|
||||||
|
self._timer.setSingleShot(True)
|
||||||
|
self._timer.timeout.connect(self.updateStatusString)
|
||||||
|
|
||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
@pyqtProperty(int, notify=invoiceChanged)
|
@pyqtProperty(int, notify=invoiceChanged)
|
||||||
@@ -190,6 +195,10 @@ class QEInvoiceParser(QEInvoice):
|
|||||||
self.determine_can_pay()
|
self.determine_can_pay()
|
||||||
self.invoiceChanged.emit()
|
self.invoiceChanged.emit()
|
||||||
|
|
||||||
|
@pyqtProperty('quint64', notify=invoiceChanged)
|
||||||
|
def time(self):
|
||||||
|
return self._effectiveInvoice.time if self._effectiveInvoice else 0
|
||||||
|
|
||||||
@pyqtProperty('quint64', notify=invoiceChanged)
|
@pyqtProperty('quint64', notify=invoiceChanged)
|
||||||
def expiration(self):
|
def expiration(self):
|
||||||
return self._effectiveInvoice.exp if self._effectiveInvoice else 0
|
return self._effectiveInvoice.exp if self._effectiveInvoice else 0
|
||||||
@@ -268,6 +277,21 @@ class QEInvoiceParser(QEInvoice):
|
|||||||
self.invoiceChanged.emit()
|
self.invoiceChanged.emit()
|
||||||
self.statusChanged.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):
|
def determine_can_pay(self):
|
||||||
self.canPay = False
|
self.canPay = False
|
||||||
self.userinfo = ''
|
self.userinfo = ''
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
from time import time
|
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, Q_ENUMS
|
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, Q_ENUMS
|
||||||
|
|
||||||
from electrum.logging import get_logger
|
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 .qewallet import QEWallet
|
||||||
from .qetypes import QEAmount
|
from .qetypes import QEAmount
|
||||||
from .util import QtEventListener, event_listener
|
from .util import QtEventListener, event_listener, status_update_timer_interval
|
||||||
|
|
||||||
class QERequestDetails(QObject, QtEventListener):
|
class QERequestDetails(QObject, QtEventListener):
|
||||||
|
|
||||||
@@ -38,6 +36,10 @@ class QERequestDetails(QObject, QtEventListener):
|
|||||||
self._timer = None
|
self._timer = None
|
||||||
self._amount = None
|
self._amount = None
|
||||||
|
|
||||||
|
self._timer = QTimer(self)
|
||||||
|
self._timer.setSingleShot(True)
|
||||||
|
self._timer.timeout.connect(self.updateStatusString)
|
||||||
|
|
||||||
self.register_callbacks()
|
self.register_callbacks()
|
||||||
self.destroyed.connect(lambda: self.on_destroy())
|
self.destroyed.connect(lambda: self.on_destroy())
|
||||||
|
|
||||||
@@ -134,31 +136,16 @@ class QERequestDetails(QObject, QtEventListener):
|
|||||||
self._amount = QEAmount(from_invoice=self._req)
|
self._amount = QEAmount(from_invoice=self._req)
|
||||||
|
|
||||||
self.detailsChanged.emit()
|
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.status == PR_UNPAID:
|
||||||
if self.expiration > 0 and self.expiration != LN_EXPIRY_NEVER:
|
if self.expiration > 0 and self.expiration != LN_EXPIRY_NEVER:
|
||||||
self._timer = QTimer(self)
|
self._logger.debug(f'set_status_timer, expiration={self.expiration}')
|
||||||
self._timer.setSingleShot(True)
|
interval = status_update_timer_interval(self.expiration)
|
||||||
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
|
|
||||||
|
|
||||||
if interval > 0:
|
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.setInterval(interval) # msec
|
||||||
self._timer.start()
|
self._timer.start()
|
||||||
|
|
||||||
@@ -166,5 +153,5 @@ class QERequestDetails(QObject, QtEventListener):
|
|||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def updateStatusString(self):
|
def updateStatusString(self):
|
||||||
self.statusChanged.emit()
|
self.statusChanged.emit()
|
||||||
self.initStatusStringTimer()
|
self.set_status_timer()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from time import time
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal
|
from PyQt5.QtCore import pyqtSignal
|
||||||
|
|
||||||
@@ -27,3 +28,22 @@ def qt_event_listener(func):
|
|||||||
def decorator(self, *args):
|
def decorator(self, *args):
|
||||||
self.qt_callback_signal.emit( (func,) + args)
|
self.qt_callback_signal.emit( (func,) + args)
|
||||||
return decorator
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user