From 48e55a374a2367edb4fbcd2d58a8985b08dc562d Mon Sep 17 00:00:00 2001 From: tiger0425 Date: Wed, 10 Jun 2026 23:30:52 +0800 Subject: [PATCH] feat: add download button to PDF/image preview header Chrome's embedded PDF viewer ignores Content-Disposition headers and generates UUID-based filenames when users click its toolbar download button. This adds an explicit download button in the preview header that uses with the original filename, bypassing the viewer's internal download logic. - Hoist useBlobUrl hook to parent CodeEditorBinaryFile component so blobUrl is shared between the preview and the download button - Add download icon in headerTopBar, visible for PDF and image files - No backend changes, no new dependencies --- .../subcomponents/CodeEditorBinaryFile.tsx | 71 +++++++++++++------ 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/ui/src/components/code-editor/view/subcomponents/CodeEditorBinaryFile.tsx b/ui/src/components/code-editor/view/subcomponents/CodeEditorBinaryFile.tsx index 124e7989..b2046625 100644 --- a/ui/src/components/code-editor/view/subcomponents/CodeEditorBinaryFile.tsx +++ b/ui/src/components/code-editor/view/subcomponents/CodeEditorBinaryFile.tsx @@ -101,18 +101,16 @@ function FallbackContent({ title, message, onClose }: { title: string; message: ); } -function ImagePreview({ projectName, file, title, message, onClose }: { - projectName?: string; +function ImagePreview({ blobUrl, file, title, message, onClose }: { + blobUrl: string; file: CodeEditorFile; title: string; message: string; onClose: () => void; }) { - const { blobUrl, error, loading } = useBlobUrl(projectName, file.path, true); const [imgError, setImgError] = useState(false); - if (loading) return ; - if (error || imgError || !blobUrl) { + if (imgError || !blobUrl) { return ; } @@ -128,20 +126,10 @@ function ImagePreview({ projectName, file, title, message, onClose }: { ); } -function PdfPreview({ projectName, file, title, message, onClose }: { - projectName?: string; +function PdfPreview({ blobUrl, file }: { + blobUrl: string; file: CodeEditorFile; - title: string; - message: string; - onClose: () => void; }) { - const { blobUrl, error, loading } = useBlobUrl(projectName, file.path, true); - - if (loading) return ; - if (error || !blobUrl) { - return ; - } - return (