From 0ac60e3c4e3e2bec7172c160937cd16cc17172ba Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 18 Feb 2026 20:19:32 +0800 Subject: [PATCH] fix(canvas): render video-mode user messages when attachment parts use data field --- components/canvas/CanvasChatPanel.tsx | 120 +++++++++++++++++--------- 1 file changed, 78 insertions(+), 42 deletions(-) diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 529f4d53c..87f4bb7cf 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -3179,7 +3179,13 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF hasContent = true; break; } - if ((part.type === 'file' || part.type === 'image') && part.url) { + const fileUrl = + typeof part?.url === "string" && part.url.trim() + ? part.url + : typeof part?.data === "string" && part.data.trim() + ? part.data + : ""; + if ((part.type === 'file' || part.type === 'image') && fileUrl) { hasContent = true; break; } @@ -3249,50 +3255,80 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF // 🆕 用户消息:使用图片标签样式(类似竞品,按 parts 原始顺序渲染)
- {/* 按 parts 原始顺序渲染图片标签和文字 */} - {cleanedMessage.parts?.map((part: any, idx: number) => { - if (part.type === 'file' && part.url) { - // 图片标签 - return ( - - - {part.name || 'Image'} + {(() => { + const renderedUserParts: React.ReactNode[] = []; + + cleanedMessage.parts?.forEach((part: any, idx: number) => { + const fileUrl = + typeof part?.url === "string" && part.url.trim() + ? part.url + : typeof part?.data === "string" && part.data.trim() + ? part.data + : ""; + + if (part.type === 'file' && fileUrl) { + renderedUserParts.push( + + + {part.name || 'Image'} + + ); + return; + } + + if (part.type === 'text' && part.text) { + const text = String(part.text) + .replace(/【注意:图片中有标注(箭头、圆圈、文字等)标记的区域是需要重点关注或修改的部分,请根据标注进行处理】\n?/g, '') + .trim(); + if (!text) return; + renderedUserParts.push( + {text} + ); + } + }); + + if ( + !cleanedMessage.parts?.some((p: any) => p.type === 'file') && + (message as any).attachments?.length > 0 + ) { + (message as any).attachments.forEach((att: any, idx: number) => { + if (!att?.url) return; + renderedUserParts.push( + + + {att.name || 'Image'} + + ); + }); + } + + if (renderedUserParts.length === 0) { + const fallbackText = + extractUserTextPrompt(cleanedMessage as any) || + (isVideoModel ? "已发送视频生成请求" : "已发送请求"); + renderedUserParts.push( + + {fallbackText} ); } - if (part.type === 'text' && part.text) { - // 文字(去掉标注提示前缀) - let text = part.text.replace(/【注意:图片中有标注(箭头、圆圈、文字等)标记的区域是需要重点关注或修改的部分,请根据标注进行处理】\n?/g, '').trim(); - if (!text) return null; - return ( - {text} - ); - } - return null; - })} - {/* 如果有 attachments 但没有 file parts,也显示 */} - {(!cleanedMessage.parts?.some((p: any) => p.type === 'file') && (message as any).attachments?.length > 0) && - (message as any).attachments.map((att: any, idx: number) => ( - - - {att.name || 'Image'} - - )) - } + + return renderedUserParts; + })()}
) : (