Linux native client
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

99 lines
3.6 KiB

"""Per-account notification tabs; signing identity = active tab's pubkey."""
from __future__ import annotations
from PySide6.QtCore import Qt, Signal
from PySide6.QtWidgets import QLabel, QListWidget, QListWidgetItem, QTabWidget, QVBoxLayout, QWidget
from imwald.core.accounts_store import StoredAccount
from imwald.core.database import Database
from imwald.core.md_render import markdown_plain_summary
class NotificationsPage(QWidget):
"""v1: lists DB notifications per recipient; empty until ingest fills rows."""
open_event = Signal(str)
signing_pubkey_changed = Signal(str)
def __init__(
self, db: Database, accounts: list[StoredAccount], parent: QWidget | None = None
) -> None:
super().__init__(parent)
self._db = db
self._accounts = accounts
self._tabs = QTabWidget()
self._tabs.currentChanged.connect(self._on_tab)
self._lists: dict[str, QListWidget] = {}
lay = QVBoxLayout(self)
lay.addWidget(QLabel("Notifications per saved account (signing uses the active tab)."))
lay.addWidget(self._tabs)
self._rebuild_tabs()
def set_accounts(self, accounts: list[StoredAccount]) -> None:
self._accounts = accounts
self._rebuild_tabs()
def _rebuild_tabs(self) -> None:
self._tabs.clear()
self._lists.clear()
if not self._accounts:
holder = QWidget()
hl = QVBoxLayout(holder)
hl.addWidget(QLabel("No saved accounts."))
self._tabs.addTab(holder, "")
return
for acc in self._accounts:
lw = QListWidget()
lw.itemActivated.connect(self._on_item)
self._lists[acc.pubkey] = lw
label = acc.label or acc.pubkey[:12] + ""
self._tabs.addTab(lw, label)
self._refresh_list(acc.pubkey)
self._on_tab(self._tabs.currentIndex())
def _refresh_list(self, pubkey: str) -> None:
lw = self._lists.get(pubkey)
if not lw:
return
lw.clear()
cur = self._db.conn().execute(
"""
SELECT n.source_event_id, n.kind, n.read, n.created_at, e.content AS content
FROM notifications n
LEFT JOIN events e ON e.id = n.source_event_id AND e.deleted = 0
WHERE n.recipient_pubkey=? ORDER BY n.created_at DESC LIMIT 200
""",
(pubkey,),
)
for row in cur:
snippet = markdown_plain_summary(row["content"] or "", max_len=56) if row["content"] else ""
tail = f"{snippet}" if snippet else ""
title = f"{row['kind']} {row['source_event_id'][:12]}… read={row['read']}{tail}"
it = QListWidgetItem(title)
it.setData(Qt.ItemDataRole.UserRole, row["source_event_id"])
lw.addItem(it)
if lw.count() == 0:
lw.addItem(QListWidgetItem("(no rows yet — wire mention/reply detection on ingest)"))
def refresh_all(self) -> None:
for pk in self._lists:
self._refresh_list(pk)
def _on_tab(self, index: int) -> None:
if index < 0 or not self._accounts:
return
if index >= len(self._accounts):
return
self.signing_pubkey_changed.emit(self._accounts[index].pubkey)
def _on_item(self, it: QListWidgetItem) -> None:
eid = it.data(Qt.ItemDataRole.UserRole)
if eid:
self.open_event.emit(str(eid))
def active_signing_pubkey(self) -> str | None:
idx = self._tabs.currentIndex()
if 0 <= idx < len(self._accounts):
return self._accounts[idx].pubkey
return None