feat: web UI chat render, panels, presence + analytics

This commit is contained in:
hh committed 2026-05-31 19:41:37 +02:00
1 parent 75425d1bee
commit ed469ba8dd
83 files changed
+6034 -136

No files matched your search

+43 -1
View File
@@ -1,5 +1,6 @@
import asyncpg
from utils.read.message_view import load_raw
from utils.read.models import MediaVersionView, MediaView
_MEDIA_COLS = (
@@ -9,6 +10,45 @@ _MEDIA_COLS = (
_VERSION_COLS = "id, kind, storage_key, file_size, mime, observed_at"
_WEB_PAGE_MEDIA_KINDS = ("photo", "video", "animation", "document", "audio")
async def _web_page_media_stub(
pool: asyncpg.Pool, account_id: int, chat_id: int, message_id: int
) -> MediaView | None:
row = await pool.fetchrow(
"SELECT date, raw FROM messages "
"WHERE account_id = $1 AND chat_id = $2 AND message_id = $3",
account_id,
chat_id,
message_id,
)
if row is None:
return None
web_page = load_raw(row["raw"]).get("web_page")
if not isinstance(web_page, dict):
return None
kind = next(
(k for k in _WEB_PAGE_MEDIA_KINDS if isinstance(web_page.get(k), dict)), None
)
if kind is None:
return None
obj = web_page[kind]
return MediaView(
id=0,
account_id=account_id,
chat_id=chat_id,
message_id=message_id,
kind=kind,
storage_key=None,
file_size=obj.get("file_size"),
mime=obj.get("mime_type"),
ttl_seconds=None,
downloaded=False,
extracted_text=None,
created_at=row["date"],
)
async def get_media(pool: asyncpg.Pool, media_id: int) -> MediaView | None:
row = await pool.fetchrow(
@@ -28,7 +68,9 @@ async def get_message_media(
chat_id,
message_id,
)
return MediaView(**dict(row)) if row else None
if row is not None:
return MediaView(**dict(row))
return await _web_page_media_stub(pool, account_id, chat_id, message_id)
async def get_media_versions(