下载图片

This commit is contained in:
fengxiangdebaozi committed 2026-06-04 19:08:52 +08:00
1 parent 77f8ded1e6
commit 788118ce3d
4 files changed
+131 -24

No files matched your search

+6 -1
View File
@@ -60,7 +60,12 @@ export async function downloadArtifactFile({
filenameFromContentDisposition(cd) ?? getFileName(filepath);
const blob = await res.blob();
const objectUrl = URL.createObjectURL(blob);
const contentType = res.headers.get("Content-Type")?.split(";")[0]?.trim();
const downloadBlob =
contentType && blob.type !== contentType
? new Blob([await blob.arrayBuffer()], { type: contentType })
: blob;
const objectUrl = URL.createObjectURL(downloadBlob);
const a = document.createElement("a");
a.href = objectUrl;
a.download = filename;
+25 -8
View File
@@ -3,9 +3,24 @@ import { useMemo } from "react";
import { useThread } from "@/components/workspace/messages/context";
import { isImageFile } from "../utils/files";
import { loadArtifactContent, loadArtifactContentFromToolCall } from "./loader";
import { updateArtifactContent } from "./api";
function isWriteFileStreamingUrl(filepath: string): boolean {
if (!filepath.startsWith("write-file:")) {
return false;
}
try {
const url = new URL(filepath);
const path = decodeURIComponent(url.pathname);
return !isImageFile(path);
} catch {
return true;
}
}
function hasToolResult(thread: ReturnType<typeof useThread>["thread"], toolCallId?: string) {
if (!toolCallId) {
return false;
@@ -70,16 +85,16 @@ export function useArtifactContent({
threadId: string;
enabled?: boolean;
}) {
const isWriteFile = useMemo(() => {
return filepath.startsWith("write-file:");
const useWriteFileStreaming = useMemo(() => {
return isWriteFileStreamingUrl(filepath);
}, [filepath]);
const { thread, isMock, publicShareCode } = useThread();
const content = useMemo(() => {
if (isWriteFile) {
if (useWriteFileStreaming) {
return loadArtifactContentFromToolCall({ url: filepath, thread });
}
return null;
}, [filepath, isWriteFile, thread]);
}, [filepath, useWriteFileStreaming, thread]);
const { data, isLoading, error } = useQuery({
queryKey: ["artifact", filepath, threadId, isMock, publicShareCode],
@@ -92,7 +107,7 @@ export function useArtifactContent({
staleTime: 5 * 60 * 1000,
});
const pendingEdit = useMemo(() => {
if (isWriteFile) {
if (useWriteFileStreaming) {
return null;
}
return applyPendingTextEdit({
@@ -100,11 +115,13 @@ export function useArtifactContent({
filepath,
thread,
});
}, [data?.content, filepath, isWriteFile, thread]);
}, [data?.content, filepath, useWriteFileStreaming, thread]);
return {
content: isWriteFile ? content : (pendingEdit?.content ?? data?.content),
url: isWriteFile ? undefined : data?.url,
content: useWriteFileStreaming
? content
: (pendingEdit?.content ?? data?.content),
url: useWriteFileStreaming ? undefined : data?.url,
isLoading,
isApplyingEdit: pendingEdit?.kind === "editing",
error,
+17
View File
@@ -151,6 +151,23 @@ export function getFileExtension(filepath: string) {
return filepath.split(".").pop()!.toLocaleLowerCase();
}
const IMAGE_EXTENSIONS = new Set([
"png",
"jpg",
"jpeg",
"gif",
"webp",
"svg",
"bmp",
"ico",
"tiff",
"heic",
]);
export function isImageFile(filepath: string): boolean {
return IMAGE_EXTENSIONS.has(getFileExtension(filepath));
}
export function checkCodeFile(
filepath: string,
):