From eeff1ebf805822e71dc59079ebd49cc7b5917923 Mon Sep 17 00:00:00 2001 From: Muharrem Okutan Date: Wed, 11 Jun 2025 03:50:48 +0200 Subject: [PATCH] feat: added report download button (#78) --- .../app/chat/components/research-block.tsx | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/web/src/app/chat/components/research-block.tsx b/web/src/app/chat/components/research-block.tsx index 52779fd..4897d6a 100644 --- a/web/src/app/chat/components/research-block.tsx +++ b/web/src/app/chat/components/research-block.tsx @@ -1,7 +1,7 @@ // Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: MIT -import { Check, Copy, Headphones, Pencil, Undo2, X } from "lucide-react"; +import { Check, Copy, Headphones, Pencil, Undo2, X, Download } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { ScrollContainer } from "~/components/deer-flow/scroll-container"; @@ -64,6 +64,33 @@ export function ResearchBlock({ }, 1000); }, [reportId]); + // Download report as markdown + const handleDownload = useCallback(() => { + if (!reportId) { + return; + } + const report = useStore.getState().messages.get(reportId); + if (!report) { + return; + } + const now = new Date(); + const pad = (n: number) => n.toString().padStart(2, '0'); + const timestamp = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}_${pad(now.getHours())}-${pad(now.getMinutes())}-${pad(now.getSeconds())}`; + const filename = `research-report-${timestamp}.md`; + const blob = new Blob([report.content], { type: 'text/markdown' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + setTimeout(() => { + document.body.removeChild(a); + URL.revokeObjectURL(url); + }, 0); + }, [reportId]); + + const handleEdit = useCallback(() => { setEditing((editing) => !editing); }, []); @@ -113,6 +140,16 @@ export function ResearchBlock({ {copied ? : } + + + )}