|
|
|
|
@ -7,10 +7,12 @@ from typing import Any, cast
@@ -7,10 +7,12 @@ from typing import Any, cast
|
|
|
|
|
from PySide6.QtCore import QObject, QRunnable, QSize, QThreadPool, Qt, QTimer, Signal |
|
|
|
|
from PySide6.QtGui import QAction, QCloseEvent, QColor, QIcon, QPainter, QPen, QPixmap |
|
|
|
|
from PySide6.QtWidgets import ( |
|
|
|
|
QApplication, |
|
|
|
|
QComboBox, |
|
|
|
|
QDialog, |
|
|
|
|
QDialogButtonBox, |
|
|
|
|
QFormLayout, |
|
|
|
|
QHBoxLayout, |
|
|
|
|
QInputDialog, |
|
|
|
|
QLabel, |
|
|
|
|
QLineEdit, |
|
|
|
|
@ -18,6 +20,7 @@ from PySide6.QtWidgets import (
@@ -18,6 +20,7 @@ from PySide6.QtWidgets import (
|
|
|
|
|
QListWidgetItem, |
|
|
|
|
QMainWindow, |
|
|
|
|
QMessageBox, |
|
|
|
|
QProgressBar, |
|
|
|
|
QSpinBox, |
|
|
|
|
QSplitter, |
|
|
|
|
QStackedWidget, |
|
|
|
|
@ -139,6 +142,30 @@ class MainWindow(QMainWindow):
@@ -139,6 +142,30 @@ class MainWindow(QMainWindow):
|
|
|
|
|
split.setSizes([920, 280]) |
|
|
|
|
self.setCentralWidget(split) |
|
|
|
|
|
|
|
|
|
self._busy_depth = 0 |
|
|
|
|
self._awaiting_relay_cookie: int | None = None |
|
|
|
|
self._busy_wrap = QWidget() |
|
|
|
|
self._busy_wrap.setObjectName("BusyWrap") |
|
|
|
|
bh = QHBoxLayout(self._busy_wrap) |
|
|
|
|
bh.setContentsMargins(0, 0, 8, 0) |
|
|
|
|
bh.setSpacing(10) |
|
|
|
|
self._busy_label = QLabel("") |
|
|
|
|
self._busy_label.setStyleSheet(f"color: {TEXT_MUTED}; font-size: 13px;") |
|
|
|
|
self._busy_bar = QProgressBar() |
|
|
|
|
self._busy_bar.setObjectName("BusyBar") |
|
|
|
|
self._busy_bar.setRange(0, 0) |
|
|
|
|
self._busy_bar.setTextVisible(False) |
|
|
|
|
self._busy_bar.setFixedSize(132, 10) |
|
|
|
|
self._busy_bar.setMaximumHeight(12) |
|
|
|
|
bh.addWidget(self._busy_label) |
|
|
|
|
bh.addWidget(self._busy_bar) |
|
|
|
|
self._busy_wrap.hide() |
|
|
|
|
self.statusBar().addPermanentWidget(self._busy_wrap) |
|
|
|
|
self._relay_connect_timer = QTimer(self) |
|
|
|
|
self._relay_connect_timer.setSingleShot(True) |
|
|
|
|
self._relay_connect_timer.setInterval(45_000) |
|
|
|
|
self._relay_connect_timer.timeout.connect(self._on_relay_connect_timeout) |
|
|
|
|
|
|
|
|
|
self._acct_combo = QComboBox() |
|
|
|
|
self._acct_combo.setMinimumWidth(220) |
|
|
|
|
self._acct_combo.setIconSize(QSize(22, 22)) |
|
|
|
|
@ -172,8 +199,12 @@ class MainWindow(QMainWindow):
@@ -172,8 +199,12 @@ class MainWindow(QMainWindow):
|
|
|
|
|
self._on_account_changed() |
|
|
|
|
|
|
|
|
|
if not self._db.get_setting("onboarding_done") and not self._accounts: |
|
|
|
|
if run_onboarding_wizard(self, db=self._db, engine=self._engine, existing_accounts=self._accounts): |
|
|
|
|
self._db.set_setting("onboarding_done", "1") |
|
|
|
|
self.push_busy("Opening wizard…") |
|
|
|
|
try: |
|
|
|
|
if run_onboarding_wizard(self, db=self._db, engine=self._engine, existing_accounts=self._accounts): |
|
|
|
|
self._db.set_setting("onboarding_done", "1") |
|
|
|
|
finally: |
|
|
|
|
self.pop_busy() |
|
|
|
|
self._accounts = load_accounts() |
|
|
|
|
self._reload_account_combo() |
|
|
|
|
self._notif.set_accounts(self._accounts) |
|
|
|
|
@ -283,15 +314,52 @@ class MainWindow(QMainWindow):
@@ -283,15 +314,52 @@ class MainWindow(QMainWindow):
|
|
|
|
|
self._feed.reload_queue() |
|
|
|
|
self._restart_relays() |
|
|
|
|
|
|
|
|
|
def push_busy(self, message: str = "Working…") -> None: |
|
|
|
|
"""Show the status-bar spinner (supports nested push/pop).""" |
|
|
|
|
self._busy_depth += 1 |
|
|
|
|
if self._busy_depth == 1: |
|
|
|
|
self._busy_label.setText(message) |
|
|
|
|
self._busy_wrap.show() |
|
|
|
|
self.setCursor(Qt.CursorShape.WaitCursor) |
|
|
|
|
QApplication.processEvents() |
|
|
|
|
|
|
|
|
|
def pop_busy(self) -> None: |
|
|
|
|
if self._busy_depth <= 0: |
|
|
|
|
return |
|
|
|
|
self._busy_depth -= 1 |
|
|
|
|
if self._busy_depth == 0: |
|
|
|
|
self._busy_wrap.hide() |
|
|
|
|
self.unsetCursor() |
|
|
|
|
|
|
|
|
|
def _on_relay_connect_ready(self, cookie: int) -> None: |
|
|
|
|
if self._awaiting_relay_cookie != cookie: |
|
|
|
|
return |
|
|
|
|
self._awaiting_relay_cookie = None |
|
|
|
|
self._relay_connect_timer.stop() |
|
|
|
|
self.pop_busy() |
|
|
|
|
|
|
|
|
|
def _on_relay_connect_timeout(self) -> None: |
|
|
|
|
if self._awaiting_relay_cookie is None: |
|
|
|
|
return |
|
|
|
|
self._awaiting_relay_cookie = None |
|
|
|
|
self.pop_busy() |
|
|
|
|
|
|
|
|
|
def _restart_relays(self) -> None: |
|
|
|
|
self.push_busy("Connecting to relays…") |
|
|
|
|
pk = self._current_pubkey() |
|
|
|
|
resolved = resolve_for_account(self._db, pk) |
|
|
|
|
reads = augment_feed_with_trending(resolved.read_urls) |
|
|
|
|
self._engine.start_relays( |
|
|
|
|
read_urls=reads, |
|
|
|
|
user_write_urls=resolved.write_urls, |
|
|
|
|
list30000_owner=self.list_owner_pubkey_for_relays(), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
def _go() -> None: |
|
|
|
|
ck = self._engine.start_relays( |
|
|
|
|
read_urls=reads, |
|
|
|
|
user_write_urls=resolved.write_urls, |
|
|
|
|
list30000_owner=self.list_owner_pubkey_for_relays(), |
|
|
|
|
) |
|
|
|
|
self._awaiting_relay_cookie = ck |
|
|
|
|
self._relay_connect_timer.start() |
|
|
|
|
|
|
|
|
|
QTimer.singleShot(0, _go) |
|
|
|
|
self._author_bootstrap_timer.start() |
|
|
|
|
|
|
|
|
|
def _bootstrap_author_metadata_queue(self) -> None: |
|
|
|
|
@ -395,6 +463,7 @@ class MainWindow(QMainWindow):
@@ -395,6 +463,7 @@ class MainWindow(QMainWindow):
|
|
|
|
|
self._engine.event_ingested.connect(self._on_event_ingested) |
|
|
|
|
self._engine.relay_status.connect(self._relay_status_message) |
|
|
|
|
self._engine.relay_status.connect(self._relay_panel.log_line.emit) |
|
|
|
|
self._engine.relay_connect_ready.connect(self._on_relay_connect_ready) |
|
|
|
|
|
|
|
|
|
def _relay_status_message(self, s: str) -> None: |
|
|
|
|
self.statusBar().showMessage(s, 8000) |
|
|
|
|
@ -515,7 +584,11 @@ class MainWindow(QMainWindow):
@@ -515,7 +584,11 @@ class MainWindow(QMainWindow):
|
|
|
|
|
return |
|
|
|
|
if QMessageBox.question(self, "NIP-09", f"Publish deletion for {event_id[:16]}…?") != QMessageBox.StandardButton.Yes: |
|
|
|
|
return |
|
|
|
|
self._engine.publish_nip09_deletion(acc, pw, event_id) |
|
|
|
|
self.push_busy("Publishing deletion…") |
|
|
|
|
try: |
|
|
|
|
self._engine.publish_nip09_deletion(acc, pw, event_id) |
|
|
|
|
finally: |
|
|
|
|
self.pop_busy() |
|
|
|
|
QMessageBox.information(self, "NIP-09", "Deletion request published to your write relays.") |
|
|
|
|
|
|
|
|
|
def _edit_current(self) -> None: |
|
|
|
|
@ -581,7 +654,11 @@ class MainWindow(QMainWindow):
@@ -581,7 +654,11 @@ class MainWindow(QMainWindow):
|
|
|
|
|
|
|
|
|
|
def _onboarding_again(self) -> None: |
|
|
|
|
self._accounts = load_accounts() |
|
|
|
|
run_onboarding_wizard(self, db=self._db, engine=self._engine, existing_accounts=self._accounts) |
|
|
|
|
self.push_busy("Opening wizard…") |
|
|
|
|
try: |
|
|
|
|
run_onboarding_wizard(self, db=self._db, engine=self._engine, existing_accounts=self._accounts) |
|
|
|
|
finally: |
|
|
|
|
self.pop_busy() |
|
|
|
|
self._accounts = load_accounts() |
|
|
|
|
self._reload_account_combo() |
|
|
|
|
self._notif.set_accounts(self._accounts) |
|
|
|
|
@ -604,6 +681,10 @@ class MainWindow(QMainWindow):
@@ -604,6 +681,10 @@ class MainWindow(QMainWindow):
|
|
|
|
|
return acc, self._password_for(pk) |
|
|
|
|
|
|
|
|
|
def closeEvent(self, event: QCloseEvent) -> None: # noqa: N802 |
|
|
|
|
self._relay_connect_timer.stop() |
|
|
|
|
self._awaiting_relay_cookie = None |
|
|
|
|
while self._busy_depth > 0: |
|
|
|
|
self.pop_busy() |
|
|
|
|
self._relay_panel.shutdown_logging() |
|
|
|
|
self._engine.stop_relays() |
|
|
|
|
super().closeEvent(event) |
|
|
|
|
|