1
0

Merge pull request #9888 from accumulator/qml_fixes

Qml fixes
This commit is contained in:
ThomasV
2025-06-03 11:11:29 +02:00
committed by GitHub
13 changed files with 122 additions and 114 deletions

View File

@@ -33,13 +33,13 @@ Pane {
text: qsTr('Lightning payment details')
}
Label {
text: qsTr('Status')
color: Material.accentColor
}
Label {
text: lnpaymentdetails.status
InfoTextArea {
Layout.columnSpan: 2
Layout.fillWidth: true
Layout.bottomMargin: constants.paddingLarge
visible: text
text: lnpaymentdetails.status ? qsTr('Paid') : ''
iconStyle: InfoTextArea.IconStyle.Done
}
Label {

View File

@@ -217,22 +217,6 @@ Pane {
text: Daemon.currentWallet.lightningNumPeers
}
Heading {
Layout.columnSpan: 2
text: qsTr('Nostr')
}
Label {
text: qsTr('Relays:')
color: Material.accentColor
}
Label {
Layout.fillWidth: true
text: Config.nostrRelays.replace(/,/g, "\n")
wrapMode: Text.Wrap
}
Heading {
Layout.columnSpan: 2
text: qsTr('Proxy')

View File

@@ -51,19 +51,15 @@ ElDialog {
Layout.leftMargin: constants.paddingLarge
Layout.rightMargin: constants.paddingLarge
RowLayout {
TextHighlightPane {
Layout.fillWidth: true
TextHighlightPane {
Layout.fillWidth: true
Label {
text: qsTr('Enter the list of Nostr relays')
width: parent.width
wrapMode: Text.Wrap
}
}
HelpButton {
heading: Config.shortDescFor('NOSTR_RELAYS')
helptext: Config.longDescFor('NOSTR_RELAYS')
Label {
text: qsTr('Enter the list of Nostr relays') + '<br/><br/>' +
qsTr('Nostr relays are used to send and receive submarine swap offers.') +
' ' + qsTr('For multisig wallets, nostr is also used to relay transactions to your co-signers.') +
' ' + qsTr('Connections to nostr are only made when required, and ephemerally.')
width: parent.width
wrapMode: Text.Wrap
}
}

View File

@@ -12,23 +12,25 @@ ElDialog {
id: dialog
title: qsTr('Receive Payment')
iconSource: Qt.resolvedUrl('../../icons/tab_receive.png')
property string key
property bool isLightning: request.isLightning
property string _bolt11: request.bolt11
property string _bip21uri: request.bip21
property string _address: request.address
property bool _render_qr: false // delay qr rendering until dialog is shown
property bool _ispaid: false
iconSource: Qt.resolvedUrl('../../icons/tab_receive.png')
signal requestPaid
padding: 0
function getPaidTxid() {
return request.paidTxid
}
ColumnLayout {
visible: !_ispaid
anchors.fill: parent
spacing: 0
@@ -40,7 +42,7 @@ ElDialog {
rightMargin: constants.paddingLarge
contentHeight: rootLayout.height
clip:true
clip: true
interactive: height < contentHeight
ColumnLayout {
@@ -186,43 +188,12 @@ ElDialog {
}
}
ColumnLayout {
visible: _ispaid
anchors.centerIn: parent
states: [
State {
name: 'paid'
when: _ispaid
}
]
transitions: [
Transition {
from: ''
to: 'paid'
NumberAnimation { target: paidIcon; properties: 'opacity'; from: 0; to: 1; duration: 200 }
NumberAnimation { target: paidIcon; properties: 'scale'; from: 0; to: 1; duration: 500; easing.type: Easing.OutBack; easing.overshoot: 10 }
}
]
Image {
id: paidIcon
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: constants.iconSizeXXLarge
Layout.preferredHeight: constants.iconSizeXXLarge
source: '../../icons/confirmed.png'
}
Label {
Layout.alignment: Qt.AlignHCenter
text: qsTr('Paid!')
font.pixelSize: constants.fontSizeXXLarge
}
}
RequestDetails {
id: request
wallet: Daemon.currentWallet
onStatusChanged: {
if (status == RequestDetails.Paid || status == RequestDetails.Unconfirmed) {
_ispaid = true
requestPaid()
}
}
}

View File

@@ -42,10 +42,8 @@ ElDialog {
text: qsTr('Ok')
icon.source: '../../icons/confirmed.png'
onClicked: {
Network.oneServer = serverconfig.auto_connect
? false
: serverconfig.one_server
Config.autoConnect = serverconfig.auto_connect
Network.oneServer = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Single
Config.autoConnect = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Autoconnect
Network.server = serverconfig.address
rootItem.close()
}

View File

@@ -75,7 +75,7 @@ Pane {
: txdetails.isRemoved ? qsTr('This transaction has been replaced or removed and is no longer valid')
: txdetails.inMempool
? qsTr('This transaction is still unconfirmed.') +
(txdetails.canBump || txdetails.canCpfp || txdetails.canCancel
(txdetails.canBump || txdetails.canCancel
? txdetails.canCancel
? '\n' + qsTr('You can bump its fee to speed up its confirmation, or cancel this transaction.')
: '\n' + qsTr('You can bump its fee to speed up its confirmation.')

View File

@@ -639,6 +639,15 @@ Item {
width: parent.width
height: parent.height
onRequestPaid: {
close()
if (isLightning) {
app.stack.push(Qt.resolvedUrl('LightningPaymentDetails.qml'), {'key': key})
} else {
let paidTxid = getPaidTxid()
app.stack.push(Qt.resolvedUrl('TxDetails.qml'), {'txid': paidTxid})
}
}
onClosed: destroy()
}
}

View File

@@ -10,9 +10,8 @@ Item {
id: root
property bool showAutoselectServer: true
property alias auto_connect: auto_server_cb.checked
property alias address: address_tf.text
property alias one_server: one_server_cb.checked
property alias serverConnectMode: server_connect_mode_cb.currentValue
implicitHeight: rootLayout.height
@@ -23,12 +22,32 @@ Item {
height: parent.height
spacing: constants.paddingLarge
CheckBox {
id: auto_server_cb
visible: showAutoselectServer
text: Config.shortDescFor('NETWORK_AUTO_CONNECT')
checked: !showAutoselectServer
enabled: !one_server_cb.checked
RowLayout {
Layout.fillWidth: true
ServerConnectModeComboBox {
id: server_connect_mode_cb
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: 1
}
HelpButton {
Layout.alignment: Qt.AlignRight
heading: qsTr('Connection mode')+':'
helptext: Config.getTranslatedMessage('MSG_CONNECTMODE_SERVER_HELP') + '<br/><br/>' +
Config.getTranslatedMessage('MSG_CONNECTMODE_NODES_HELP') + '<ul>' +
'<li><b>' + Config.getTranslatedMessage('MSG_CONNECTMODE_AUTOCONNECT') +
'</b>: ' + Config.getTranslatedMessage('MSG_CONNECTMODE_AUTOCONNECT_HELP') + '</li>' +
'<li><b>' + Config.getTranslatedMessage('MSG_CONNECTMODE_MANUAL') +
'</b>: ' + Config.getTranslatedMessage('MSG_CONNECTMODE_MANUAL_HELP') + '</li>' +
'<li><b>' + Config.getTranslatedMessage('MSG_CONNECTMODE_ONESERVER') +
'</b>: ' + Config.getTranslatedMessage('MSG_CONNECTMODE_ONESERVER_HELP') + '</li>' +
'</ul>'
}
}
Label {
@@ -41,28 +60,12 @@ Item {
TextField {
id: address_tf
enabled: !auto_server_cb.checked
enabled: server_connect_mode_cb.currentValue != ServerConnectModeComboBox.Mode.Autoconnect
width: parent.width
inputMethodHints: Qt.ImhNoPredictiveText
}
}
RowLayout {
Layout.fillWidth: true
visible: !auto_server_cb.checked && address_tf.text
CheckBox {
id: one_server_cb
Layout.fillWidth: true
text: Config.shortDescFor('NETWORK_ONESERVER')
}
HelpButton {
heading: Config.shortDescFor('NETWORK_ONESERVER')
helptext: Config.longDescFor('NETWORK_ONESERVER')
}
}
ColumnLayout {
Heading {
text: qsTr('Servers')
@@ -112,9 +115,6 @@ Item {
}
Component.onCompleted: {
root.auto_connect = Config.autoConnectDefined ? Config.autoConnect : false
root.address = Network.server
one_server_cb.checked = Network.oneServer
// TODO: initial setup should not connect already, is Network.server defined?
}
}

View File

@@ -0,0 +1,38 @@
import QtQuick
import QtQuick.Controls
import org.electrum 1.0
ElComboBox {
id: control
enum Mode {
Autoconnect,
Manual,
Single
}
textRole: 'text'
valueRole: 'value'
model: [
{ text: qsTr('Auto-connect'), value: ServerConnectModeComboBox.Mode.Autoconnect },
{ text: qsTr('Manual server selection'), value: ServerConnectModeComboBox.Mode.Manual },
{ text: qsTr('Connect only to a single server'), value: ServerConnectModeComboBox.Mode.Single }
]
Component.onCompleted: {
if (!Config.autoConnectDefined) { // initial setup
server_connect_mode_cb.currentIndex = server_connect_mode_cb.indexOfValue(
ServerConnectModeComboBox.Mode.Manual)
} else {
server_connect_mode_cb.currentIndex = server_connect_mode_cb.indexOfValue(
Config.autoConnect
? ServerConnectModeComboBox.Mode.Autoconnect
: Network.oneServer
? ServerConnectModeComboBox.Mode.Single
: ServerConnectModeComboBox.Mode.Manual
)
}
}
}

View File

@@ -10,9 +10,9 @@ WizardComponent {
title: qsTr('Server')
function apply() {
wizard_data['autoconnect'] = sc.address.trim() == ""
wizard_data['server'] = sc.address
wizard_data['one_server'] = sc.one_server
wizard_data['autoconnect'] = sc.serverConnectMode == ServerConnectModeComboBox.Mode.Autoconnect
wizard_data['one_server'] = sc.serverConnectMode == ServerConnectModeComboBox.Mode.Single
}
ColumnLayout {
@@ -21,7 +21,6 @@ WizardComponent {
ServerConfig {
id: sc
showAutoselectServer: false
Layout.fillWidth: true
Layout.fillHeight: true
}

View File

@@ -318,7 +318,7 @@ class QEConfig(AuthMixin, QObject):
@nostrRelays.setter
def nostrRelays(self, nostr_relays):
if nostr_relays != self.config.NOSTR_RELAYS:
self.config.NOSTR_RELAYS = nostr_relays
self.config.NOSTR_RELAYS = nostr_relays if nostr_relays else None
self.nostrRelaysChanged.emit()
swapServerNPubChanged = pyqtSignal()

View File

@@ -6,7 +6,7 @@ from PyQt6.QtCore import Qt, QAbstractListModel, QModelIndex
from electrum.logging import get_logger
from electrum.util import Satoshis, format_time
from electrum.invoices import BaseInvoice, PR_EXPIRED, LN_EXPIRY_NEVER, Invoice, Request
from electrum.invoices import BaseInvoice, PR_EXPIRED, LN_EXPIRY_NEVER, Invoice, Request, PR_PAID
from .util import QtEventListener, qt_event_listener, status_update_timer_interval
from .qetypes import QEAmount
@@ -247,4 +247,7 @@ class QERequestListModel(QEAbstractInvoiceListModel, QtEventListener):
@pyqtSlot(str, int)
def updateRequest(self, key, status):
self.updateInvoice(key, status)
if status == PR_PAID:
self.delete_invoice(key)
else:
self.updateInvoice(key, status)

View File

@@ -29,7 +29,7 @@ class QERequestDetails(QObject, QtEventListener):
_logger = get_logger(__name__)
detailsChanged = pyqtSignal() # generic request properties changed signal
detailsChanged = pyqtSignal() # generic request properties changed signal
statusChanged = pyqtSignal()
def __init__(self, parent=None):
@@ -95,7 +95,7 @@ class QERequestDetails(QObject, QtEventListener):
@pyqtProperty(bool, notify=detailsChanged)
def isLightning(self):
return self._req.is_lightning()
return self._req.is_lightning() if self._req else False
@pyqtProperty(str, notify=detailsChanged)
def address(self):
@@ -118,6 +118,16 @@ class QERequestDetails(QObject, QtEventListener):
def expiration(self):
return self._req.get_expiration_date()
@pyqtProperty(str, notify=statusChanged)
def paidTxid(self):
"""only used when Request status is PR_PAID"""
if not self._req:
return ''
is_paid, conf_needed, txids = self._wallet.wallet._is_onchain_invoice_paid(self._req)
if len(txids) > 0:
return txids[0]
return ''
@pyqtProperty(str, notify=detailsChanged)
def bolt11(self):
wallet = self._wallet.wallet