From 2534e2b4256602db048253b88f546ea83f698ca8 Mon Sep 17 00:00:00 2001 From: bruno Date: Sat, 18 Jul 2026 09:34:24 -0400 Subject: [PATCH] fix: PDF viewer - wire up _render_file_viewer + URL-encode filenames MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - view_page now calls _render_file_viewer for content_format='file' pages instead of rendering the full page_editor template (which was the old path) - URL-encode filenames in file_url using urllib.parse.quote() to handle spaces and special characters correctly - Fixed in both board.py (viewer + page_data) and dashboard.py The _render_file_viewer was dead code — defined but never called. File pages were going through page_editor.html which rendered PDFs in an iframe embedded in the editor UI. Now they get a clean standalone HTML viewer. --- app/routers/board.py | 10 ++++++++-- app/routers/dashboard.py | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/routers/board.py b/app/routers/board.py index e108bfd..e2784c2 100644 --- a/app/routers/board.py +++ b/app/routers/board.py @@ -926,6 +926,10 @@ async def view_page(request: Request, page_id: int): return HTMLResponse("

Page not found

", status_code=404) page = dict(row) + # For file-type pages (PDFs, images, etc.), use the dedicated file viewer + if page.get("content_format") == "file": + return _render_file_viewer(page, request) + ws = page.get("workspace", "") parts = ws.split("/") if "/" in ws else ["", ""] owner, repo = parts[0], parts[1] if len(parts) > 1 else "" @@ -959,7 +963,8 @@ async def view_page(request: Request, page_id: int): ws_id = p.replace("workspace_", "") break filename = fp_parts[-1] if fp_parts else page.get("title", "File") - file_url = f"/api/files/{ws_id}/{filename}" if ws_id else "" + from urllib.parse import quote + file_url = f"/api/files/{ws_id}/{quote(filename, safe='')}" if ws_id else "" page_data["file_url"] = file_url page_data["file_mime"] = mime_type page_data["file_size"] = file_size @@ -1006,7 +1011,8 @@ def _render_file_viewer(page: dict, request: Request) -> HTMLResponse: break filename = parts[-1] if parts else title - file_url = f"/api/files/{ws_id}/{filename}" if ws_id else "" + from urllib.parse import quote + file_url = f"/api/files/{ws_id}/{quote(filename, safe='')}" if ws_id else "" # Determine viewer type is_image = mime_type.startswith("image/") diff --git a/app/routers/dashboard.py b/app/routers/dashboard.py index f9517e1..29d5ccd 100644 --- a/app/routers/dashboard.py +++ b/app/routers/dashboard.py @@ -270,7 +270,8 @@ async def view_page_root(request: Request, page_id: int): ws_id = p.replace("workspace_", "") break filename = fp_parts[-1] if fp_parts else page.get("title", "File") - file_url = f"/api/files/{ws_id}/{filename}" if ws_id else "" + from urllib.parse import quote + file_url = f"/api/files/{ws_id}/{quote(filename, safe='')}" if ws_id else "" page_data["file_url"] = file_url page_data["file_mime"] = mime_type page_data["file_size"] = file_size