diff --git a/src/backend/site/consts.py b/src/backend/site/consts.py index 581f539..e0d28d4 100644 --- a/src/backend/site/consts.py +++ b/src/backend/site/consts.py @@ -7,3 +7,5 @@ ANALYSIS_COMPLETE_MESSAGE = "Analysis complete!" running_tasks = set() status_store: dict[str, list] = defaultdict(list) result_store: dict[str, Any] = {} +# Track last message count seen by each session for incremental updates +last_message_index: dict[str, int] = defaultdict(int) diff --git a/src/backend/site/router.py b/src/backend/site/router.py index 3b8e87f..b837e4a 100644 --- a/src/backend/site/router.py +++ b/src/backend/site/router.py @@ -12,6 +12,7 @@ from backend.settings import app_settings from backend.site.consts import ( ANALYSIS_COMPLETE_MESSAGE, ANALYZING_MESSAGE, + last_message_index, result_store, running_tasks, status_store, @@ -91,26 +92,51 @@ async def analyze_url( @user_frontend.get("/status", response_class=HTMLResponse) async def get_status(request: Request): """ - Returns the current status messages + Returns new status messages since last poll (incremental updates) + First poll returns all messages + container, subsequent polls return + only new items with HTMX OOB swap :param request: :return: """ - context = {"request": request, "messages": [], "result": False} session_id = request.session.get("analysis_id") - if session_id: - # logger.info(f"Found session id! {session_id}") - messages = status_store.get(session_id, []) - result = ANALYSIS_COMPLETE_MESSAGE in messages - # logger.info( - # f"Status check - Session ID: {session_id}, Messages: " - # f"{messages}", - # ) + if not session_id: + return templates.TemplateResponse( + "status.html", {"request": request, "messages": [], "result": False} + ) - context.update({"messages": messages, "result": result}) + all_messages = status_store.get(session_id, []) + last_index = last_message_index.get(session_id, 0) + result = ANALYSIS_COMPLETE_MESSAGE in all_messages - # logger.info(context) + # First poll: return full container with all messages + if last_index == 0: + last_message_index[session_id] = len(all_messages) + return templates.TemplateResponse( + "status.html", + {"request": request, "messages": all_messages, "result": result}, + ) - return templates.TemplateResponse("status.html", context=context) + # Subsequent polls: return only new messages with OOB swap + new_messages = all_messages[last_index:] + last_message_index[session_id] = len(all_messages) + + if not new_messages: + # No new messages, return empty response + return HTMLResponse(content="", status_code=200) + + # Render new items with OOB swap + items_html = "" + for idx, message in enumerate(new_messages): + is_last = idx == len(new_messages) - 1 + item = templates.get_template("status_item.html").render( + message=message, + is_last=is_last, + result=result, + request=request, + ) + items_html += item + + return HTMLResponse(content=items_html, status_code=200) @user_frontend.get("/result", response_class=HTMLResponse) diff --git a/src/frontend/templates/home.html b/src/frontend/templates/home.html index 671fbbe..5b77221 100644 --- a/src/frontend/templates/home.html +++ b/src/frontend/templates/home.html @@ -102,13 +102,13 @@
- +
+ +
+
+ {{ status_label }} +
+
+ {{ message }} +
+
+ \ No newline at end of file