fix: add timeout protection for loading placeholder and improve image content detection

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Your Name 2026-01-31 22:17:18 +08:00
parent 2e62d17317
commit 390ab1b935

View File

@ -126,6 +126,8 @@ function PureMessages({
// 控制等待动画延迟消失(Gemini 图片模型延迟 4 秒,其他模型 6 秒)
const [showThinkingWithDelay, setShowThinkingWithDelay] = useState(false);
// 🆕 记录占位图开始显示的时间,用于超时保护
const thinkingStartTimeRef = useRef<number | null>(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]);
// 🆕 监听新消息添加,当用户发送带图片的消息或添加加载消息时,强制滚动到底部