fix: delay image placeholder until text shows
Guard the auto image-loading placeholder so it starts only after a visible text reply and cancel pending timers when the image arrives.
This commit is contained in:
parent
b4c18bd554
commit
0cc791a71e
@ -72,6 +72,7 @@ export function Chat({
|
||||
|
||||
// 🆕 跟踪是否正在生成图片(用于占位图显示)
|
||||
const [isGeneratingImageFlag, setIsGeneratingImageFlag] = useState(false);
|
||||
const imagePlaceholderTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
|
||||
// 🆕 存储通过 data-appendMessage 添加的消息,避免与 useChat 内部状态冲突
|
||||
const [appendedMessages, setAppendedMessages] = useState<ChatMessage[]>([]);
|
||||
@ -100,6 +101,16 @@ export function Chat({
|
||||
}
|
||||
}, [pendingGeneration, initialMessages, completeGeneration, router]);
|
||||
|
||||
// 清理占位图定时器
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (imagePlaceholderTimerRef.current) {
|
||||
clearTimeout(imagePlaceholderTimerRef.current);
|
||||
imagePlaceholderTimerRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const { mutate } = useSWRConfig();
|
||||
|
||||
// Handle browser back/forward navigation
|
||||
@ -303,11 +314,25 @@ export function Chat({
|
||||
);
|
||||
if (hasGeneratingMarker) {
|
||||
console.log("[Chat] 🖼️ Detected GENERATING_IMAGE marker, will show placeholder after delay");
|
||||
const hasDisplayText = messageData.parts?.some((part: any) => {
|
||||
if (part.type !== "text" || !part.text) return false;
|
||||
const cleanedText = part.text.replace(/\n*<!-- GENERATING_IMAGE -->\n*/g, "").trim();
|
||||
return cleanedText.length > 0;
|
||||
});
|
||||
if (!hasDisplayText) {
|
||||
console.log("[Chat] ⚠️ Marker message has no display text, skip image placeholder timer");
|
||||
return;
|
||||
}
|
||||
// 🆕 延迟显示占位图,让用户先看到 AI 的文字回复
|
||||
// 消息会立即添加到 appendedMessages 并显示,3 秒后再显示动态占位图
|
||||
setTimeout(() => {
|
||||
if (imagePlaceholderTimerRef.current) {
|
||||
clearTimeout(imagePlaceholderTimerRef.current);
|
||||
imagePlaceholderTimerRef.current = null;
|
||||
}
|
||||
imagePlaceholderTimerRef.current = setTimeout(() => {
|
||||
console.log("[Chat] 🖼️ Now showing placeholder after 3s delay");
|
||||
setIsGeneratingImageFlag(true);
|
||||
imagePlaceholderTimerRef.current = null;
|
||||
}, 3000); // 延迟 3 秒,让用户有时间阅读文字
|
||||
}
|
||||
|
||||
@ -326,6 +351,10 @@ export function Chat({
|
||||
|
||||
if (hasImage) {
|
||||
console.log("[Chat] 🎉 Image generated, hiding placeholder");
|
||||
if (imagePlaceholderTimerRef.current) {
|
||||
clearTimeout(imagePlaceholderTimerRef.current);
|
||||
imagePlaceholderTimerRef.current = null;
|
||||
}
|
||||
setIsGeneratingImageFlag(false);
|
||||
}
|
||||
|
||||
|
||||
@ -472,6 +472,14 @@ function PureMessages({
|
||||
(part: any) => part.type === "text" && part.text?.includes("<!-- GENERATING_IMAGE -->")
|
||||
)
|
||||
);
|
||||
const hasAssistantTextReplyWithContent = messages.some(msg =>
|
||||
msg.role === "assistant" && msg.parts?.some((part: any) => {
|
||||
if (part.type !== "text" || !part.text) return false;
|
||||
if (!part.text.includes("<!-- GENERATING_IMAGE -->")) return false;
|
||||
const cleanedText = part.text.replace(/\n*<!-- GENERATING_IMAGE -->\n*/g, "").trim();
|
||||
return cleanedText.length > 0;
|
||||
})
|
||||
);
|
||||
|
||||
if (showVideo) return <QianwenVideoLoading />;
|
||||
if (showGemini) return <GeminiImageLoading imageCount={imageCount} />;
|
||||
@ -482,7 +490,7 @@ function PureMessages({
|
||||
if (isAutoMode && userMessageHasImage) {
|
||||
// 🆕 只用 isGeneratingImageFlag 来控制是否显示生图占位图
|
||||
// isGeneratingImageFlag 由 chat.tsx 控制:延迟 3 秒后设置为 true,收到图片后设置为 false
|
||||
if (isGeneratingImageFlag) {
|
||||
if (isGeneratingImageFlag && hasAssistantTextReplyWithContent) {
|
||||
return <ImageGenerationLoading imageCount={imageCount} maxImages={6} providerType="alibaba-image" modelName="智能处理" />;
|
||||
}
|
||||
// 否则显示思考动画(在等待 AI 分析或延迟期间)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user