From 390ab1b935ba6b81ce097d45b1afa5ee2bd0fb04 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 31 Jan 2026 22:17:18 +0800 Subject: [PATCH] fix: add timeout protection for loading placeholder and improve image content detection Co-authored-by: Cursor --- components/messages.tsx | 42 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/components/messages.tsx b/components/messages.tsx index 471a5047c..6d39e485d 100644 --- a/components/messages.tsx +++ b/components/messages.tsx @@ -126,6 +126,8 @@ function PureMessages({ // 控制等待动画延迟消失(Gemini 图片模型延迟 4 秒,其他模型 6 秒) const [showThinkingWithDelay, setShowThinkingWithDelay] = useState(false); + // 🆕 记录占位图开始显示的时间,用于超时保护 + const thinkingStartTimeRef = useRef(null); useEffect(() => { const lastMessage = messages.length > 0 ? messages[messages.length - 1] : null; @@ -152,12 +154,22 @@ function PureMessages({ }); } - // 对于图片模型,检查是否有图片内容(包含 ![thumb| 或 ![thumb||| 标记) + // 对于图片模型,检查是否有图片内容(更全面的匹配) const hasImageContent = lastMessage?.parts && lastMessage.parts.some( (part: any) => part.type === "text" && part.text && ( part.text.includes("![thumb|") || part.text.includes("![thumb|||") || - part.text.includes("![Generated Image") + part.text.includes("![Generated Image") || + part.text.includes("![image") || + part.text.includes("![Image") || + // 🆕 匹配更多图片格式 + part.text.includes("](http") || // Markdown 图片链接 + part.text.includes(".png)") || + part.text.includes(".jpg)") || + part.text.includes(".jpeg)") || + part.text.includes(".webp)") || + part.text.includes("图片生成") || + part.text.includes("已生成") ) ); @@ -182,26 +194,52 @@ function PureMessages({ // 根据模型类型设置延迟时间(视频模型 60 秒,图片模型 4 秒,其他 6 秒) const delayTime = (isQianwenVideoModel || isVideoModel) ? 60000 : isImageGenModel ? 4000 : 6000; + // 🆕 超时保护:如果占位图显示超过 3 分钟,强制隐藏(防止卡住) + const maxShowTime = 3 * 60 * 1000; // 3 分钟 + // 如果是 submitted 状态,立即显示 if (status === "submitted") { setShowThinkingWithDelay(true); + thinkingStartTimeRef.current = Date.now(); } // 如果是 streaming 状态且没有内容,显示 else if (status === "streaming" && lastMessage?.role === "assistant" && !hasContent) { setShowThinkingWithDelay(true); + if (!thinkingStartTimeRef.current) { + thinkingStartTimeRef.current = Date.now(); + } } // 如果 AI 开始有内容了,延迟后隐藏 else if (status === "streaming" && lastMessage?.role === "assistant" && hasContent) { const timer = setTimeout(() => { setShowThinkingWithDelay(false); + thinkingStartTimeRef.current = null; }, delayTime); return () => clearTimeout(timer); } + // 🆕 如果状态是 ready(生成完成),立即隐藏 + else if (status === "ready") { + console.log("[占位图] status=ready,立即隐藏占位图"); + setShowThinkingWithDelay(false); + thinkingStartTimeRef.current = null; + } // 其他情况立即隐藏 else { setShowThinkingWithDelay(false); + thinkingStartTimeRef.current = null; } + + // 🆕 超时保护定时器 + const timeoutTimer = setTimeout(() => { + if (thinkingStartTimeRef.current && Date.now() - thinkingStartTimeRef.current > maxShowTime) { + console.warn("[占位图] ⚠️ 超时保护触发:占位图显示超过 3 分钟,强制隐藏"); + setShowThinkingWithDelay(false); + thinkingStartTimeRef.current = null; + } + }, maxShowTime); + + return () => clearTimeout(timeoutTimer); }, [status, messages, isGeminiModel, isQianwenVideoModel, isVolcanoVisionModel, isVideoModel, isAlibabaImageModel]); // 🆕 监听新消息添加,当用户发送带图片的消息或添加加载消息时,强制滚动到底部