1
0

qml: add QERequestDetails component.

Auto binds to wallet request status update signal so qml doesn't have to.
implements timer to update status string when near expiry.
This commit is contained in:
Sander van Grieken
2022-08-23 17:13:22 +02:00
parent 4f574afe5a
commit f05ff0c9b8
5 changed files with 194 additions and 40 deletions

View File

@@ -0,0 +1,161 @@
from time import time
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer
from electrum.logging import get_logger
from electrum.invoices import PR_UNPAID, LN_EXPIRY_NEVER
from .qewallet import QEWallet
from .qetypes import QEAmount
class QERequestDetails(QObject):
_logger = get_logger(__name__)
_wallet = None
_key = None
_req = None
_timer = None
_amount = None
detailsChanged = pyqtSignal() # generic request properties changed signal
def __init__(self, parent=None):
super().__init__(parent)
def __del__(self):
if self._wallet:
self._wallet.requestStatusChanged.disconnect(self.updateRequestStatus)
if self._timer:
self._timer.stop()
self._timer = None
walletChanged = pyqtSignal()
@pyqtProperty(QEWallet, notify=walletChanged)
def wallet(self):
return self._wallet
@wallet.setter
def wallet(self, wallet: QEWallet):
if self._wallet != wallet:
if self._wallet:
self._wallet.requestStatusChanged.disconnect(self.updateRequestStatus)
self._wallet = wallet
self.walletChanged.emit()
wallet.requestStatusChanged.connect(self.updateRequestStatus)
self.initRequest()
keyChanged = pyqtSignal()
@pyqtProperty(str, notify=keyChanged)
def key(self):
return self._key
@key.setter
def key(self, key):
if self._key != key:
self._key = key
self._logger.debug(f'key={key}')
self.keyChanged.emit()
self.initRequest()
statusChanged = pyqtSignal()
@pyqtProperty(int, notify=statusChanged)
def status(self):
return self._wallet.wallet.get_request_status(self._key)
statusStringChanged = pyqtSignal()
@pyqtProperty(str, notify=statusStringChanged)
def status_str(self):
return self._req.get_status_str(self.status)
@pyqtProperty(bool, notify=detailsChanged)
def isLightning(self):
return self._req.is_lightning()
@pyqtProperty(str, notify=detailsChanged)
def address(self):
addr = self._req.get_address()
return addr if addr else ''
@pyqtProperty(str, notify=detailsChanged)
def message(self):
return self._req.get_message()
@pyqtProperty(QEAmount, notify=detailsChanged)
def amount(self):
return self._amount
@pyqtProperty(int, notify=detailsChanged)
def timestamp(self):
return self._req.get_time()
@pyqtProperty(int, notify=detailsChanged)
def expiration(self):
return self._req.get_expiration_date()
@pyqtProperty(str, notify=detailsChanged)
def bolt11(self):
return self._req.lightning_invoice
@pyqtProperty(str, notify=detailsChanged)
def bip21(self):
return self._req.get_bip21_URI()
@pyqtSlot(str, int)
def updateRequestStatus(self, key, status):
if key == self._key:
self._logger.debug(f'request with key {key} updated status ({status})')
self.statusChanged.emit()
def initRequest(self):
if self._wallet is None or self._key is None:
return
self._req = self._wallet.wallet.get_request(self._key)
if self._req is None:
self._logger.error(f'payment request key {key} unknown in wallet {self._wallet.name}')
return
self._amount = QEAmount(from_invoice=self._req)
self.initStatusStringTimer()
def initStatusStringTimer(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
if interval > 0:
self._logger.debug(f'setting status update timer to {interval}, req expires in {exp_in} seconds')
self._timer.setInterval(interval) # msec
self._timer.start()
@pyqtSlot()
def updateStatusString(self):
self.statusStringChanged.emit()
self.initStatusStringTimer()