mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-07-22 06:00:21 +00:00
Avoid blank previews for unsupported artifacts (#3644)
This commit is contained in:
parent
df5d90fbb1
commit
90328d5651
@ -20,6 +20,7 @@ import {
|
||||
ArtifactTitle,
|
||||
} from "@/components/ai-elements/artifact";
|
||||
import { ClipboardSafeStreamdown } from "@/components/ai-elements/streamdown";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Select, SelectItem } from "@/components/ui/select";
|
||||
import {
|
||||
SelectContent,
|
||||
@ -43,7 +44,13 @@ import { useI18n } from "@/core/i18n/hooks";
|
||||
import { findToolCallResult } from "@/core/messages/utils";
|
||||
import { installSkill } from "@/core/skills/api";
|
||||
import { streamdownPlugins } from "@/core/streamdown";
|
||||
import { checkCodeFile, getFileName } from "@/core/utils/files";
|
||||
import {
|
||||
canBrowserPreviewFile,
|
||||
checkCodeFile,
|
||||
getFileExtensionDisplayName,
|
||||
getFileIcon,
|
||||
getFileName,
|
||||
} from "@/core/utils/files";
|
||||
import { env } from "@/env";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@ -92,6 +99,9 @@ export function ArtifactFileDetail({
|
||||
}
|
||||
return checkCodeFile(filepath);
|
||||
}, [filepath, isWriteFile, isSkillFile]);
|
||||
const canPreviewInBrowser = useMemo(() => {
|
||||
return canBrowserPreviewFile(filepath);
|
||||
}, [filepath]);
|
||||
const isSupportPreview = useMemo(() => {
|
||||
return language === "html" || language === "markdown";
|
||||
}, [language]);
|
||||
@ -303,17 +313,69 @@ export function ArtifactFileDetail({
|
||||
readonly
|
||||
/>
|
||||
)}
|
||||
{!isCodeFile && (
|
||||
{!isCodeFile && canPreviewInBrowser && (
|
||||
<iframe
|
||||
className="size-full"
|
||||
src={urlOfArtifact({ filepath, threadId, isMock })}
|
||||
/>
|
||||
)}
|
||||
{!isCodeFile && !canPreviewInBrowser && (
|
||||
<ArtifactDownloadFallback
|
||||
filepath={filepath}
|
||||
threadId={threadId}
|
||||
isMock={isMock}
|
||||
/>
|
||||
)}
|
||||
</ArtifactContent>
|
||||
</Artifact>
|
||||
);
|
||||
}
|
||||
|
||||
function ArtifactDownloadFallback({
|
||||
filepath,
|
||||
threadId,
|
||||
isMock,
|
||||
}: {
|
||||
filepath: string;
|
||||
threadId: string;
|
||||
isMock?: boolean;
|
||||
}) {
|
||||
const filename = getFileName(filepath);
|
||||
const fileType = getFileExtensionDisplayName(filepath);
|
||||
|
||||
return (
|
||||
<div className="flex size-full items-center justify-center p-6">
|
||||
<div className="flex max-w-sm flex-col items-center gap-4 text-center">
|
||||
<div className="text-muted-foreground">
|
||||
{getFileIcon(filepath, "size-12")}
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<div className="font-medium break-all">{filename}</div>
|
||||
<div className="text-muted-foreground text-sm">{fileType} file</div>
|
||||
</div>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
This file type cannot be previewed in the browser.
|
||||
</p>
|
||||
<Button asChild>
|
||||
<a
|
||||
href={urlOfArtifact({
|
||||
filepath,
|
||||
threadId,
|
||||
download: true,
|
||||
isMock,
|
||||
})}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<DownloadIcon className="size-4" />
|
||||
Download
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ArtifactFilePreview({
|
||||
content,
|
||||
language,
|
||||
|
||||
@ -143,6 +143,29 @@ const extensionMap: Record<string, string> = {
|
||||
v: "v",
|
||||
};
|
||||
|
||||
const browserPreviewExtensions = new Set([
|
||||
"pdf",
|
||||
"apng",
|
||||
"avif",
|
||||
"bmp",
|
||||
"gif",
|
||||
"ico",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"png",
|
||||
"webp",
|
||||
"mp3",
|
||||
"wav",
|
||||
"ogg",
|
||||
"aac",
|
||||
"m4a",
|
||||
"flac",
|
||||
"mp4",
|
||||
"mov",
|
||||
"m4v",
|
||||
"webm",
|
||||
]);
|
||||
|
||||
export function getFileName(filepath: string) {
|
||||
return filepath.split("/").pop()!;
|
||||
}
|
||||
@ -170,6 +193,10 @@ export function checkCodeFile(
|
||||
};
|
||||
}
|
||||
|
||||
export function canBrowserPreviewFile(filepath: string) {
|
||||
return browserPreviewExtensions.has(getFileExtension(filepath));
|
||||
}
|
||||
|
||||
export function getFileExtensionDisplayName(filepath: string) {
|
||||
const fileName = getFileName(filepath);
|
||||
const extension = fileName.split(".").pop()!.toLocaleLowerCase();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user