Qt: move nostr_relays to network dialog
This commit is contained in:
@@ -28,7 +28,8 @@ from enum import IntEnum
|
||||
from PyQt6.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt6.QtWidgets import (
|
||||
QTreeWidget, QTreeWidgetItem, QMenu, QGridLayout, QComboBox, QLineEdit, QDialog, QVBoxLayout, QHeaderView,
|
||||
QCheckBox, QTabWidget, QWidget, QLabel, QPushButton, QHBoxLayout
|
||||
QCheckBox, QTabWidget, QWidget, QLabel, QPushButton, QHBoxLayout,
|
||||
QListWidget, QListWidgetItem,
|
||||
)
|
||||
from PyQt6.QtGui import QIntValidator
|
||||
|
||||
@@ -37,10 +38,11 @@ from electrum import blockchain
|
||||
from electrum.interface import ServerAddr, PREFERRED_NETWORK_PROTOCOL
|
||||
from electrum.network import Network, ProxySettings, is_valid_host, is_valid_port
|
||||
from electrum.logging import get_logger
|
||||
from electrum.util import is_valid_websocket_url
|
||||
|
||||
from .util import (
|
||||
Buttons, CloseButton, HelpButton, read_QIcon, char_width_in_lineedit, PasswordLineEdit, QtEventListener,
|
||||
qt_event_listener, Spinner
|
||||
qt_event_listener, Spinner, HelpLabel
|
||||
)
|
||||
|
||||
|
||||
@@ -56,11 +58,12 @@ class NetworkDialog(QDialog, QtEventListener):
|
||||
self.setWindowTitle(_('Network'))
|
||||
self.setMinimumSize(500, 500)
|
||||
self.tabs = tabs = QTabWidget()
|
||||
self._blockchain_tab = blockchain_tab = ServerWidget(network)
|
||||
self._proxy_tab = proxy_tab = ProxyWidget(network)
|
||||
tabs.addTab(blockchain_tab, _('Overview'))
|
||||
tabs.addTab(proxy_tab, _('Proxy'))
|
||||
|
||||
self._blockchain_tab = ServerWidget(network)
|
||||
self._proxy_tab = ProxyWidget(network)
|
||||
self._nostr_tab = NostrWidget(network)
|
||||
tabs.addTab(self._blockchain_tab, _('Electrum servers'))
|
||||
tabs.addTab(self._nostr_tab, _('Nostr'))
|
||||
tabs.addTab(self._proxy_tab, _('Proxy'))
|
||||
vbox = QVBoxLayout(self)
|
||||
vbox.addWidget(self.tabs)
|
||||
vbox.addLayout(Buttons(CloseButton(self)))
|
||||
@@ -360,6 +363,7 @@ class ProxyWidget(QWidget):
|
||||
|
||||
|
||||
class ServerWidget(QWidget, QtEventListener):
|
||||
|
||||
def __init__(self, network: Network, parent=None):
|
||||
super().__init__(parent)
|
||||
self.network = network
|
||||
@@ -502,3 +506,55 @@ class ServerWidget(QWidget, QtEventListener):
|
||||
net_params = net_params._replace(server=server,
|
||||
auto_connect=self.autoconnect_cb.isChecked())
|
||||
self.network.run_from_another_thread(self.network.set_parameters(net_params))
|
||||
|
||||
|
||||
class NostrWidget(QWidget, QtEventListener):
|
||||
|
||||
def __init__(self, network: Network, parent=None):
|
||||
super().__init__(parent)
|
||||
self.network = network
|
||||
self.config = network.config
|
||||
vbox = QVBoxLayout()
|
||||
self.setLayout(vbox)
|
||||
nostr_relays_label = HelpLabel.from_configvar(self.config.cv.NOSTR_RELAYS)
|
||||
self.relays_list = QListWidget()
|
||||
self.relay_edit = QLineEdit()
|
||||
self.relay_edit.textChanged.connect(self.on_relay_edited)
|
||||
vbox.addWidget(nostr_relays_label)
|
||||
vbox.addWidget(self.relays_list)
|
||||
vbox.addStretch()
|
||||
self.add_button = QPushButton(_('Add'))
|
||||
self.add_button.clicked.connect(self.add_relay)
|
||||
self.add_button.setEnabled(False)
|
||||
remove_button = QPushButton(_('Remove'))
|
||||
remove_button.clicked.connect(self.remove_relay)
|
||||
reset_button = QPushButton(_('Reset'))
|
||||
reset_button.clicked.connect(self.reset_relays)
|
||||
buttons = Buttons(self.relay_edit, self.add_button, remove_button, reset_button)
|
||||
vbox.addLayout(buttons)
|
||||
self.update_list()
|
||||
|
||||
def on_relay_edited(self, text):
|
||||
self.add_button.setEnabled(is_valid_websocket_url(text))
|
||||
|
||||
def update_list(self):
|
||||
self.relays_list.clear()
|
||||
for relay in self.config.get_nostr_relays():
|
||||
item = QListWidgetItem(relay)
|
||||
self.relays_list.addItem(item)
|
||||
|
||||
def add_relay(self):
|
||||
relay = self.relay_edit.text()
|
||||
self.config.add_nostr_relay(relay)
|
||||
self.update_list()
|
||||
|
||||
def remove_relay(self):
|
||||
item = self.relays_list.currentItem()
|
||||
if item is None:
|
||||
return
|
||||
self.config.remove_nostr_relay(item.text())
|
||||
self.update_list()
|
||||
|
||||
def reset_relays(self):
|
||||
self.config.NOSTR_RELAYS = None
|
||||
self.update_list()
|
||||
|
||||
@@ -32,7 +32,7 @@ from PyQt6.QtWidgets import (QComboBox, QTabWidget, QDialog, QSpinBox, QCheckB
|
||||
|
||||
from electrum.i18n import _, languages
|
||||
from electrum import util
|
||||
from electrum.util import base_units_list, event_listener, is_valid_websocket_url
|
||||
from electrum.util import base_units_list, event_listener
|
||||
|
||||
from electrum.gui import messages
|
||||
|
||||
@@ -176,22 +176,6 @@ class SettingsDialog(QDialog, QtEventListener):
|
||||
self.set_alias_color()
|
||||
self.alias_e.editingFinished.connect(self.on_alias_edit)
|
||||
|
||||
nostr_relays_label = HelpLabel.from_configvar(self.config.cv.NOSTR_RELAYS)
|
||||
nostr_relays = self.config.NOSTR_RELAYS
|
||||
self.nostr_relays_e = QLineEdit(nostr_relays)
|
||||
|
||||
def on_nostr_edit():
|
||||
relays: Dict[str, None] = dict() # dicts keep insertion order
|
||||
for url in self.nostr_relays_e.text().split(','):
|
||||
url = url.strip()
|
||||
if url and is_valid_websocket_url(url):
|
||||
relays[url] = None
|
||||
if relays.keys():
|
||||
self.config.NOSTR_RELAYS = ",".join(relays.keys())
|
||||
else: # if no valid relays are given, assign default relays from config
|
||||
self.config.NOSTR_RELAYS = None
|
||||
self.nostr_relays_e.setText(self.config.NOSTR_RELAYS)
|
||||
self.nostr_relays_e.editingFinished.connect(on_nostr_edit)
|
||||
|
||||
msat_cb = checkbox_from_configvar(self.config.cv.BTC_AMOUNTS_PREC_POST_SAT)
|
||||
msat_cb.setChecked(self.config.BTC_AMOUNTS_PREC_POST_SAT > 0)
|
||||
@@ -402,7 +386,6 @@ class SettingsDialog(QDialog, QtEventListener):
|
||||
misc_widgets = []
|
||||
misc_widgets.append((updatecheck_cb, None))
|
||||
misc_widgets.append((filelogging_cb, None))
|
||||
misc_widgets.append((nostr_relays_label, self.nostr_relays_e))
|
||||
misc_widgets.append((alias_label, self.alias_e))
|
||||
misc_widgets.append((qr_label, qr_combo))
|
||||
|
||||
|
||||
@@ -1,30 +1,23 @@
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
import os
|
||||
import stat
|
||||
from decimal import Decimal
|
||||
from typing import Union, Optional, Dict, Sequence, Tuple, Any, Set, Callable, AbstractSet
|
||||
from numbers import Real
|
||||
from typing import Union, Optional, Dict, Sequence, Any, Set, Callable, AbstractSet
|
||||
from functools import cached_property
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
from . import util
|
||||
from . import constants
|
||||
from . import invoices
|
||||
from .util import base_units, base_unit_name_to_decimal_point, decimal_point_to_base_unit_name, UnknownBaseUnit, DECIMAL_POINT_DEFAULT
|
||||
from .util import format_satoshis, format_fee_satoshis, os_chmod
|
||||
from .util import user_dir, make_dir
|
||||
from .util import is_valid_websocket_url
|
||||
from .lnutil import LN_MAX_FUNDING_SAT_LEGACY
|
||||
from .i18n import _
|
||||
from .logging import get_logger, Logger
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
@@ -182,7 +175,6 @@ class SimpleConfig(Logger):
|
||||
# a thread-safe way.
|
||||
self.lock = threading.RLock()
|
||||
|
||||
|
||||
# The following two functions are there for dependency injection when
|
||||
# testing.
|
||||
if read_user_config_function is None:
|
||||
@@ -401,14 +393,12 @@ class SimpleConfig(Logger):
|
||||
def convert_version_3(self):
|
||||
if not self._is_upgrade_method_needed(2, 2):
|
||||
return
|
||||
|
||||
base_unit = self.user_config.get('base_unit')
|
||||
if isinstance(base_unit, str):
|
||||
self._set_key_in_user_config('base_unit', None)
|
||||
map_ = {'btc':8, 'mbtc':5, 'ubtc':2, 'bits':2, 'sat':0}
|
||||
map_ = {'btc': 8, 'mbtc': 5, 'ubtc': 2, 'bits': 2, 'sat': 0}
|
||||
decimal_point = map_.get(base_unit.lower())
|
||||
self._set_key_in_user_config('decimal_point', decimal_point)
|
||||
|
||||
self.set_key('config_version', 3)
|
||||
|
||||
def _is_upgrade_method_needed(self, min_version, max_version):
|
||||
@@ -557,6 +547,26 @@ class SimpleConfig(Logger):
|
||||
def get_decimal_point(self):
|
||||
return self.decimal_point
|
||||
|
||||
def get_nostr_relays(self) -> Sequence[str]:
|
||||
relays = []
|
||||
for url in self.NOSTR_RELAYS.split(','):
|
||||
url = url.strip()
|
||||
if url and is_valid_websocket_url(url):
|
||||
relays.append(url)
|
||||
return relays
|
||||
|
||||
def add_nostr_relay(self, relay: str):
|
||||
l = self.get_nostr_relays()
|
||||
if is_valid_websocket_url(relay) and relay not in l:
|
||||
l.append(relay)
|
||||
self.NOSTR_RELAYS = ','.join(l)
|
||||
|
||||
def remove_nostr_relay(self, relay: str):
|
||||
l = self.get_nostr_relays()
|
||||
if relay in l:
|
||||
l.remove(relay)
|
||||
self.NOSTR_RELAYS = ','.join(l)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
"""Disallows setting instance attributes outside __init__.
|
||||
|
||||
@@ -719,9 +729,9 @@ Warning: setting this to too low will result in lots of payment failures."""),
|
||||
TEST_SHUTDOWN_FEE_RANGE = ConfigVar('test_shutdown_fee_range', default=None)
|
||||
TEST_SHUTDOWN_LEGACY = ConfigVar('test_shutdown_legacy', default=False, type_=bool)
|
||||
|
||||
FEE_POLICY = ConfigVar('fee_policy', default='eta:2', type_=str) # exposed to GUI
|
||||
FEE_POLICY_LIGHTNING = ConfigVar('fee_policy_lightning', default='eta:2', type_=str) # for txbatcher (sweeping)
|
||||
FEE_POLICY_SWAPS = ConfigVar('fee_policy_swaps', default='eta:2', type_=str) # for txbatcher (sweeping and sending if we are a swapserver)
|
||||
FEE_POLICY = ConfigVar('fee_policy', default='eta:2', type_=str) # exposed to GUI
|
||||
FEE_POLICY_LIGHTNING = ConfigVar('fee_policy_lightning', default='eta:2', type_=str) # for txbatcher (sweeping)
|
||||
FEE_POLICY_SWAPS = ConfigVar('fee_policy_swaps', default='eta:2', type_=str) # for txbatcher (sweeping and sending if we are a swapserver)
|
||||
|
||||
RPC_USERNAME = ConfigVar('rpcuser', default=None, type_=str)
|
||||
RPC_PASSWORD = ConfigVar('rpcpassword', default=None, type_=str)
|
||||
|
||||
Reference in New Issue
Block a user