Browse Source

qml: allow pay while amount in edit mode

master
Sander van Grieken 3 years ago
parent
commit
a571451179
  1. 48
      electrum/gui/qml/components/InvoiceDialog.qml
  2. 38
      electrum/gui/qml/qeinvoice.py
  3. 8
      electrum/gui/qml/qetypes.py

48
electrum/gui/qml/components/InvoiceDialog.qml

@ -214,15 +214,10 @@ ElDialog {
}
ToolButton {
visible: !amountContainer.editmode && invoice.canPay
visible: !amountContainer.editmode
icon.source: '../../icons/pen.png'
icon.color: 'transparent'
onClicked: {
amountBtc.text = invoice.amount.satsInt == 0 ? '' : Config.formatSats(invoice.amount)
amountMax.checked = invoice.amount.isMax
amountContainer.editmode = true
amountBtc.focus = true
}
onClicked: enterAmountEdit()
}
GridLayout {
visible: amountContainer.editmode
@ -232,6 +227,9 @@ ElDialog {
id: amountBtc
fiatfield: amountFiat
enabled: !amountMax.checked
onTextAsSatsChanged: {
invoice.amountOverride = textAsSats
}
}
Label {
@ -250,7 +248,7 @@ ElDialog {
checked: false
onCheckedChanged: {
if (activeFocus)
invoice.amount.isMax = checked
invoice.amountOverride.isMax = checked
}
}
@ -269,22 +267,18 @@ ElDialog {
}
}
ToolButton {
visible: amountContainer.editmode
Layout.fillWidth: false
visible: amountContainer.editmode
icon.source: '../../icons/confirmed.png'
icon.color: 'transparent'
onClicked: {
amountContainer.editmode = false
invoice.amount = amountMax.checked ? MAX : Config.unitsToSats(amountBtc.text)
invoiceAmountChanged()
}
onClicked: applyAmountEdit()
}
ToolButton {
visible: amountContainer.editmode
Layout.fillWidth: false
visible: amountContainer.editmode
icon.source: '../../icons/closebutton.png'
icon.color: 'transparent'
onClicked: amountContainer.editmode = false
onClicked: cancelAmountEdit()
}
}
@ -438,8 +432,10 @@ ElDialog {
Layout.preferredWidth: 1
text: qsTr('Pay')
icon.source: '../../icons/confirmed.png'
enabled: invoice.invoiceType != Invoice.Invalid && invoice.canPay && !amountContainer.editmode
enabled: invoice.invoiceType != Invoice.Invalid && invoice.canPay
onClicked: {
if (amountContainer.editmode)
applyAmountEdit()
if (invoice_key == '') // save invoice if not retrieved from key
invoice.save_invoice()
dialog.close()
@ -450,6 +446,24 @@ ElDialog {
}
function enterAmountEdit() {
amountBtc.text = invoice.amount.satsInt == 0 ? '' : Config.formatSats(invoice.amount)
amountMax.checked = invoice.amount.isMax
amountContainer.editmode = true
amountBtc.focus = true
}
function applyAmountEdit() {
amountContainer.editmode = false
invoice.amount = amountMax.checked ? MAX : Config.unitsToSats(amountBtc.text)
invoiceAmountChanged()
}
function cancelAmountEdit() {
amountContainer.editmode = false
invoice.amountOverride.clear()
}
Component.onCompleted: {
if (invoice_key != '') {
invoice.initFromKey(invoice_key)

38
electrum/gui/qml/qeinvoice.py

@ -135,6 +135,8 @@ class QEInvoiceParser(QEInvoice):
lnurlRetrieved = pyqtSignal()
lnurlError = pyqtSignal([str,str], arguments=['code', 'message'])
amountOverrideChanged = pyqtSignal()
_bip70PrResolvedSignal = pyqtSignal([PaymentRequest], arguments=['pr'])
def __init__(self, parent=None):
@ -151,6 +153,9 @@ class QEInvoiceParser(QEInvoice):
self._timer.setSingleShot(True)
self._timer.timeout.connect(self.updateStatusString)
self._amountOverride = QEAmount()
self._amountOverride.valueChanged.connect(self._on_amountoverride_value_changed)
self._bip70PrResolvedSignal.connect(self._bip70_payment_request_resolved)
self.clear()
@ -203,6 +208,22 @@ class QEInvoiceParser(QEInvoice):
self.determine_can_pay()
self.invoiceChanged.emit()
@pyqtProperty(QEAmount, notify=amountOverrideChanged)
def amountOverride(self):
return self._amountOverride
@amountOverride.setter
def amountOverride(self, new_amount):
self._logger.debug(f'set new override amount {repr(new_amount)}')
self._amountOverride.copyFrom(new_amount)
self.determine_can_pay()
self.amountOverrideChanged.emit()
@pyqtSlot()
def _on_amountoverride_value_changed(self):
self.determine_can_pay()
@pyqtProperty('quint64', notify=invoiceChanged)
def time(self):
return self._effectiveInvoice.time if self._effectiveInvoice else 0
@ -316,18 +337,23 @@ class QEInvoiceParser(QEInvoice):
self.canPay = False
self.userinfo = ''
if self.amount.isEmpty: # unspecified amount
if not self.amountOverride.isEmpty:
amount = self.amountOverride
else:
amount = self.amount
if amount.isEmpty: # unspecified amount
return
if self.invoiceType == QEInvoice.Type.LightningInvoice:
if self.status in [PR_UNPAID, PR_FAILED]:
if self.get_max_spendable_lightning() >= self.amount.satsInt:
if self.get_max_spendable_lightning() >= amount.satsInt:
lnaddr = self._effectiveInvoice._lnaddr
if lnaddr.amount and self.amount.satsInt < lnaddr.amount * COIN:
if lnaddr.amount and amount.satsInt < lnaddr.amount * COIN:
self.userinfo = _('Cannot pay less than the amount specified in the invoice')
else:
self.canPay = True
elif self.address and self.get_max_spendable_onchain() > self.amount.satsInt:
elif self.address and self.get_max_spendable_onchain() > amount.satsInt:
# TODO: validate address?
# TODO: subtract fee?
self.canPay = True
@ -343,10 +369,10 @@ class QEInvoiceParser(QEInvoice):
}[self.status]
elif self.invoiceType == QEInvoice.Type.OnchainInvoice:
if self.status in [PR_UNPAID, PR_FAILED]:
if self.amount.isMax and self.get_max_spendable_onchain() > 0:
if amount.isMax and self.get_max_spendable_onchain() > 0:
# TODO: dust limit?
self.canPay = True
elif self.get_max_spendable_onchain() >= self.amount.satsInt:
elif self.get_max_spendable_onchain() >= amount.satsInt:
# TODO: subtract fee?
self.canPay = True
else:

8
electrum/gui/qml/qetypes.py

@ -77,10 +77,12 @@ class QEAmount(QObject):
def isEmpty(self):
return not(self._is_max or self._amount_sat or self._amount_msat)
@pyqtSlot()
def clear(self):
self.satsInt = 0
self.msatsInt = 0
self.isMax = False
self._amount_sat = 0
self._amount_msat = 0
self._is_max = False
self.valueChanged.emit()
def copyFrom(self, amount):
if not amount:

Loading…
Cancel
Save