|
|
|
|
@ -9,7 +9,7 @@ from typing import cast
@@ -9,7 +9,7 @@ from typing import cast
|
|
|
|
|
|
|
|
|
|
from PySide6 import Shiboken |
|
|
|
|
from PySide6.QtCore import QObject, QRunnable, QSize, Qt, QThreadPool, Signal, QUrl |
|
|
|
|
from PySide6.QtGui import QDesktopServices, QMouseEvent, QPainter, QPainterPath, QPixmap, QResizeEvent |
|
|
|
|
from PySide6.QtGui import QDesktopServices, QMouseEvent, QPainter, QPainterPath, QPixmap, QResizeEvent, QShowEvent |
|
|
|
|
from PySide6.QtWidgets import QFrame, QLabel, QSizePolicy, QSplitter, QTabWidget, QVBoxLayout, QWidget |
|
|
|
|
|
|
|
|
|
from imwald.core.database import Database |
|
|
|
|
@ -366,18 +366,20 @@ class ProfilePage(QWidget):
@@ -366,18 +366,20 @@ class ProfilePage(QWidget):
|
|
|
|
|
left_lay.addWidget(self._left_body, 1) |
|
|
|
|
split = QSplitter(Qt.Orientation.Horizontal, self) |
|
|
|
|
split.setObjectName("ProfileSplit") |
|
|
|
|
self._col_split = split |
|
|
|
|
split.setChildrenCollapsible(False) |
|
|
|
|
split.addWidget(self._left_column) |
|
|
|
|
split.addWidget(self._feed_body) |
|
|
|
|
split.addWidget(self._interact_body) |
|
|
|
|
# Metadata (narrow) · posts (widest) · activity (medium). |
|
|
|
|
split.setStretchFactor(0, 2) |
|
|
|
|
split.setStretchFactor(1, 4) |
|
|
|
|
split.setStretchFactor(2, 2) |
|
|
|
|
split.setSizes([300, 640, 280]) |
|
|
|
|
self._left_column.setMinimumWidth(260) |
|
|
|
|
self._feed_body.setMinimumWidth(240) |
|
|
|
|
self._interact_body.setMinimumWidth(220) |
|
|
|
|
# Three main columns: equal stretch so resizes stay even; initial widths set in showEvent. |
|
|
|
|
split.setStretchFactor(0, 1) |
|
|
|
|
split.setStretchFactor(1, 1) |
|
|
|
|
split.setStretchFactor(2, 1) |
|
|
|
|
equal_min = 220 |
|
|
|
|
self._left_column.setMinimumWidth(equal_min) |
|
|
|
|
self._feed_body.setMinimumWidth(equal_min) |
|
|
|
|
self._interact_body.setMinimumWidth(equal_min) |
|
|
|
|
self._profile_cols_equalized = False |
|
|
|
|
lay = QVBoxLayout(self) |
|
|
|
|
lay.setContentsMargins(0, 0, 0, 0) |
|
|
|
|
lay.addWidget(split) |
|
|
|
|
@ -397,11 +399,36 @@ class ProfilePage(QWidget):
@@ -397,11 +399,36 @@ class ProfilePage(QWidget):
|
|
|
|
|
# resetting placeholders + bumping fetch generations on every refresh() while ingest runs. |
|
|
|
|
self._cover_banner_http_key: str | None = None |
|
|
|
|
self._cover_avatar_http_key: str | None = None |
|
|
|
|
# LNURL-pay HTML: cache so ingest-driven refresh() does not reset to “Loading…” every tick. |
|
|
|
|
self._lnurl_urls_key: str | None = None |
|
|
|
|
self._lnurl_html_cache: str | None = None |
|
|
|
|
self._lnurl_fetch_inflight = False |
|
|
|
|
self._left_panel_sig: object | None = None |
|
|
|
|
self._feed_panel_sig: object | None = None |
|
|
|
|
self._interact_panel_sig: object | None = None |
|
|
|
|
self.refresh() |
|
|
|
|
|
|
|
|
|
def showEvent(self, event: QShowEvent) -> None: |
|
|
|
|
super().showEvent(event) |
|
|
|
|
self._maybe_equalize_profile_columns() |
|
|
|
|
|
|
|
|
|
def resizeEvent(self, event: QResizeEvent) -> None: |
|
|
|
|
super().resizeEvent(event) |
|
|
|
|
if not self._profile_cols_equalized: |
|
|
|
|
self._maybe_equalize_profile_columns() |
|
|
|
|
|
|
|
|
|
def _maybe_equalize_profile_columns(self) -> None: |
|
|
|
|
if self._profile_cols_equalized: |
|
|
|
|
return |
|
|
|
|
sp = self._col_split |
|
|
|
|
w = sp.width() |
|
|
|
|
if w < 360: |
|
|
|
|
return |
|
|
|
|
third = max(w // 3, self._left_column.minimumWidth()) |
|
|
|
|
rem = max(w - 2 * third, self._interact_body.minimumWidth()) |
|
|
|
|
sp.setSizes([third, third, rem]) |
|
|
|
|
self._profile_cols_equalized = True |
|
|
|
|
|
|
|
|
|
def tab_title(self) -> str: |
|
|
|
|
row = self._db.get_latest_kind0_profile(self._pubkey) |
|
|
|
|
p = parse_kind0_profile(row["content"] if row else "") |
|
|
|
|
@ -442,14 +469,34 @@ class ProfilePage(QWidget):
@@ -442,14 +469,34 @@ class ProfilePage(QWidget):
|
|
|
|
|
lud06_s = lud06_raw.strip() if isinstance(lud06_raw, str) else "" |
|
|
|
|
lud16_s = lud16_raw.strip() if isinstance(lud16_raw, str) else "" |
|
|
|
|
lnurls = collect_unique_lnurlp_urls(lud06_s or None, lud16_s or None) |
|
|
|
|
lnurl_key = "\n".join(sorted(lnurls)) if lnurls else "" |
|
|
|
|
live_lnurl = "" |
|
|
|
|
if from_lnurl and lnurl_html is not None: |
|
|
|
|
self._lnurl_html_cache = lnurl_html |
|
|
|
|
self._lnurl_fetch_inflight = False |
|
|
|
|
if lnurl_key: |
|
|
|
|
self._lnurl_urls_key = lnurl_key |
|
|
|
|
live_lnurl = lnurl_html |
|
|
|
|
elif not from_lnurl and lnurls: |
|
|
|
|
elif not lnurls: |
|
|
|
|
self._lnurl_urls_key = None |
|
|
|
|
self._lnurl_html_cache = None |
|
|
|
|
self._lnurl_fetch_inflight = False |
|
|
|
|
elif self._lnurl_html_cache is not None and self._lnurl_urls_key == lnurl_key: |
|
|
|
|
live_lnurl = self._lnurl_html_cache |
|
|
|
|
else: |
|
|
|
|
if self._lnurl_urls_key != lnurl_key: |
|
|
|
|
self._lnurl_urls_key = lnurl_key |
|
|
|
|
self._lnurl_html_cache = None |
|
|
|
|
self._lnurl_fetch_inflight = False |
|
|
|
|
self._lnurl_gen += 1 |
|
|
|
|
live_lnurl = ( |
|
|
|
|
f"<p style='color:{TEXT_DIM};font-size:14px;margin:8px 0 0 0'><i>Loading tip details…</i></p>" |
|
|
|
|
) |
|
|
|
|
if not self._lnurl_fetch_inflight: |
|
|
|
|
self._lnurl_fetch_inflight = True |
|
|
|
|
self._lnurl_gen += 1 |
|
|
|
|
gen = self._lnurl_gen |
|
|
|
|
self._lnurl_pool.start(_ProfileLnurlRunnable(lnurls, gen, self._lnurl_sigs)) |
|
|
|
|
live_lnurl = f"<p style='color:{TEXT_DIM};font-size:14px;margin:8px 0 0 0'><i>Loading tip details…</i></p>" |
|
|
|
|
tech_dl: list[str] = [] |
|
|
|
|
if lud06_s: |
|
|
|
|
tech_dl.append( |
|
|
|
|
|