diff --git a/server.py b/server.py index bdea6a9..5bd30eb 100644 --- a/server.py +++ b/server.py @@ -606,6 +606,17 @@ async def ui_activity_detail(activity_index: int, request: Request): return HTMLResponse(base_html("Activity Not Found", content, username)) activity = activities[activity_index] + return await _render_activity_detail(activity, request) + + +async def ui_activity_detail_by_data(activity: dict, request: Request): + """Activity detail page taking activity data directly.""" + return await _render_activity_detail(activity, request) + + +async def _render_activity_detail(activity: dict, request: Request): + """Core activity detail rendering logic.""" + username = get_user_from_cookie(request) activity_type = activity.get("activity_type", "") activity_id = activity.get("activity_id", "") actor_id = activity.get("actor_id", "") @@ -2501,16 +2512,36 @@ async def get_activities(request: Request, page: int = 1, limit: int = 20): } -@app.get("/activities/{activity_index}") -async def get_activity_detail(activity_index: int, request: Request): - """Get single activity. HTML for browsers (default), JSON only if explicitly requested.""" - activities = await load_activities() +@app.get("/activities/{activity_ref}") +async def get_activity_detail(activity_ref: str, request: Request): + """Get single activity by index or activity_id. HTML for browsers (default), JSON only if explicitly requested.""" # Check if JSON explicitly requested accept = request.headers.get("accept", "") wants_json = ("application/json" in accept or "application/activity+json" in accept) and "text/html" not in accept - if activity_index < 0 or activity_index >= len(activities): + activity = None + activity_index = None + + # Check if it's a numeric index or an activity_id (hash) + if activity_ref.isdigit(): + # Numeric index (legacy) + activity_index = int(activity_ref) + activities = await load_activities() + if 0 <= activity_index < len(activities): + activity = activities[activity_index] + else: + # Activity ID (hash) - look up directly + activity = await db.get_activity(activity_ref) + if activity: + # Find index for UI rendering + activities = await load_activities() + for i, a in enumerate(activities): + if a.get("activity_id") == activity_ref: + activity_index = i + break + + if not activity: if wants_json: raise HTTPException(404, "Activity not found") content = ''' @@ -2520,13 +2551,15 @@ async def get_activity_detail(activity_index: int, request: Request): ''' return HTMLResponse(base_html("Activity Not Found", content, get_user_from_cookie(request))) - activity = activities[activity_index] - if wants_json: return activity # Default to HTML for browsers - return await ui_activity_detail(activity_index, request) + if activity_index is not None: + return await ui_activity_detail(activity_index, request) + else: + # Render activity directly if no index found + return await ui_activity_detail_by_data(activity, request) @app.get("/activity/{activity_index}")