fix(canvas): render assistant video blocks in chat bubble
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-02-18 22:46:50 +08:00
parent b194f1a7e2
commit 26dea0141c

View File

@ -3273,13 +3273,22 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
const hasAssistantImages = assistantTextParts.some((part: any) =>
extractImageUrls(part.text || "").length > 0
);
const hasAssistantVideos = assistantTextParts.some((part: any) =>
extractVideoUrls(part.text || "").length > 0
);
const hasAssistantText = assistantTextParts.some((part: any) => {
const textWithoutImages = (part.text || "")
.replace(/!\[(?:thumb)?\|\|\|[^|]+\|\|\|[^\]]*\]\([^)]+\)/g, "")
.replace(/<video[\s\S]*?<\/video>/gi, "")
.replace(/\[[^\]]*]\((https?:\/\/[^)\s]+\.mp4(?:\?[^)\s]*)?)\)/gi, "")
.replace(/https?:\/\/[^\s"'<>]+\.mp4(?:\?[^\s"'<>]+)?/gi, "")
.trim();
return textWithoutImages.length > 0;
});
const isImageOnlyAssistant = message.role === "assistant" && hasAssistantImages && !hasAssistantText;
const isImageOnlyAssistant =
message.role === "assistant" &&
(hasAssistantImages || hasAssistantVideos) &&
!hasAssistantText;
return (
<div
@ -3409,10 +3418,15 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
<div className="w-full min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere] leading-relaxed">
{cleanedMessage.parts?.map((part: any, i: number) => {
if (part.type === 'text') {
// 提取并显示图片
const imageUrls = extractImageUrls(part.text || '');
const textWithoutImages = (part.text || '')
// 提取并显示图片/视频
const rawText = part.text || '';
const imageUrls = extractImageUrls(rawText);
const videoUrls = extractVideoUrls(rawText);
const textWithoutImages = rawText
.replace(/!\[(?:thumb)?\|\|\|[^|]+\|\|\|[^\]]*\]\([^)]+\)/g, '')
.replace(/<video[\s\S]*?<\/video>/gi, '')
.replace(/\[[^\]]*]\((https?:\/\/[^)\s]+\.mp4(?:\?[^)\s]*)?)\)/gi, '')
.replace(/https?:\/\/[^\s"'<>]+\.mp4(?:\?[^\s"'<>]+)?/gi, '')
.trim();
return (
@ -3449,6 +3463,31 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
))}
</div>
)}
{videoUrls.length > 0 && (
<div className={cn("space-y-2", textWithoutImages || imageUrls.length > 0 ? "mt-3" : "mt-0")}>
{videoUrls.map((url, idx) => (
<div
key={`video-${idx}`}
className="overflow-hidden rounded-2xl border border-black/10 bg-black/5 p-2"
>
<video
src={url}
controls
className="block w-full rounded-xl bg-black"
style={{ maxHeight: "320px" }}
/>
<a
href={url}
target="_blank"
rel="noreferrer"
className="mt-2 inline-flex text-xs text-blue-600 hover:underline"
>
下载视频
</a>
</div>
))}
</div>
)}
</div>
);
}