From f2d6f8723a80040dbd6dbf1324fea8a448180f6d Mon Sep 17 00:00:00 2001 From: Michael Woods Date: Sun, 28 Dec 2025 19:25:14 -0500 Subject: [PATCH] message pagination --- packetserver/http/routers/messages.py | 78 +++++++++++-- packetserver/http/templates/message_list.html | 103 +++++++++++++----- 2 files changed, 143 insertions(+), 38 deletions(-) diff --git a/packetserver/http/routers/messages.py b/packetserver/http/routers/messages.py index c2e1cc1..ba381db 100644 --- a/packetserver/http/routers/messages.py +++ b/packetserver/http/routers/messages.py @@ -164,23 +164,77 @@ async def mark_message_retrieved( @html_router.get("/messages", response_class=HTMLResponse) async def message_list_page( - db: DbDependency, request: Request, - type: str = Query("received", alias="msg_type"), # matches your filter links - limit: Optional[int] = Query(50, le=100), - current_user: HttpUser = Depends(get_current_http_user) + db: DbDependency, + current_user: HttpUser = Depends(get_current_http_user), + msg_type: str = Query("received", alias="type"), # Change alias to "type" for cleaner URLs + search: Optional[str] = Query(None), + page: int = Query(1, ge=1), + per_page: int = Query(50, ge=1, le=200), ): - from packetserver.http.server import templates - # Directly call the existing API endpoint function - api_resp = await get_messages(db, current_user=current_user, type=type, limit=limit, since=None) - messages = api_resp["messages"] + from packetserver.http.server import templates # Local import – safe from circular + + username = current_user.username.upper().strip() + + valid_types = {"received", "sent", "all"} + if msg_type not in valid_types: + msg_type = "received" + + with db.transaction() as conn: + root = conn.root() + mailbox = root.get("messages", {}).get(username, []) + + # Build full list of message dicts (similar to API) + messages = [] + for msg in mailbox: + messages.append({ + "id": str(msg.msg_id), + "from": msg.msg_from, + "to": list(msg.msg_to) if isinstance(msg.msg_to, tuple) else [msg.msg_to], + "sent_at": msg.sent_at.isoformat() + "Z", + "text": msg.text, + "has_attachments": len(msg.attachments) > 0, + "retrieved": msg.retrieved, + }) + + # Type filter + if msg_type == "received": + filtered = [m for m in messages if username in m["to"]] + elif msg_type == "sent": + filtered = [m for m in messages if m["from"] == username] + else: + filtered = messages + + # Search filter (case-insensitive across from/to/text) + if search: + search_lower = search.strip().lower() + filtered = [ + m for m in filtered + if search_lower in m["from"].lower() + or any(search_lower in t.lower() for t in m["to"]) + or search_lower in m["text"].lower() + ] + + # Sort newest first + filtered.sort(key=lambda m: m["sent_at"], reverse=True) + + # Pagination + total = len(filtered) + start = (page - 1) * per_page + paginated = filtered[start:start + per_page] + total_pages = (total + per_page - 1) // per_page if total > 0 else 1 return templates.TemplateResponse( "message_list.html", { "request": request, - "messages": messages, - "msg_type": type, - "current_user": current_user.username - } + "messages": paginated, + "current_type": msg_type, # For tabs/links + "current_search": search, # For preserving/clearing search + "total": total, + "page": page, + "per_page": per_page, + "total_pages": total_pages, + "current_user": current_user, + }, ) \ No newline at end of file diff --git a/packetserver/http/templates/message_list.html b/packetserver/http/templates/message_list.html index 376916b..5781aeb 100644 --- a/packetserver/http/templates/message_list.html +++ b/packetserver/http/templates/message_list.html @@ -1,38 +1,89 @@ -{% extends "base.html" %} - -{% block title %}Messages - PacketServer{% endblock %} - -{% block content %}

Messages

-
+ +
+
+ + +
+ +
+ +
+ + + +
+ {% if current_search %} + Clear + {% endif %} + + +
-
- Received - Sent - All -
+{% if total > 0 %} +

+ Showing {{ ((page-1)*per_page) + 1 }}–{{ page*per_page if page*per_page < total else total }} of {{ total }} messages +

+{% else %} +

No messages

+{% endif %} {% if messages %} {% else %} -

No messages found.

+
+ {% if current_search %}No messages found matching "{{ current_search }}".{% else %}No messages yet.{% endif %} +
{% endif %} -

← Back to Dashboard

-{% endblock %} \ No newline at end of file + +{% if total_pages > 1 %} + +{% endif %} + +

← Back to Dashboard

\ No newline at end of file