fix: rehydrate canvas chat history reliably on initial open
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 21:30:47 +08:00
parent 2ce9ef0d1f
commit d8d62edf53

View File

@ -597,6 +597,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
const autoContextRef = useRef<string | null>(null);
const pendingLaunchRef = useRef<CanvasLaunchPayload | null>(null);
const sessionMenuRef = useRef<HTMLDivElement>(null);
const historyScrollTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
// 🆕 标签悬停预览状态
const [tagPreview, setTagPreview] = useState<TagPreviewInfo | null>(null);
@ -1597,15 +1598,41 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
}
}, [selectedModelId, status, sendMessage, clearSelection]);
// 当历史消息加载完成后,更新消息列表
const hasLoadedHistory = useRef(false);
// 当历史消息加载完成后,更新消息列表(支持同一会话的增量刷新)
const loadedHistorySignatureRef = useRef<string>("");
useEffect(() => {
if (historyData && !hasLoadedHistory.current) {
hasLoadedHistory.current = true;
setMessages(historyData.messages || []);
console.log('[CanvasChat] 已加载历史消息:', historyData.messages?.length || 0);
if (historyScrollTimerRef.current) {
clearTimeout(historyScrollTimerRef.current);
historyScrollTimerRef.current = null;
}
}, [historyData, setMessages]);
if (!historyData || !rawChatId) return;
if (status === "streaming" || status === "submitted") return;
const historyMessages = historyData.messages || [];
const lastMessageId = historyMessages.at(-1)?.id || "none";
const signature = `${rawChatId}:${historyMessages.length}:${lastMessageId}`;
if (loadedHistorySignatureRef.current === signature) return;
loadedHistorySignatureRef.current = signature;
setMessages(historyMessages);
console.log("[CanvasChat] 已同步历史消息:", historyMessages.length, signature);
requestAnimationFrame(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "auto", block: "end" });
});
historyScrollTimerRef.current = setTimeout(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "auto", block: "end" });
historyScrollTimerRef.current = null;
}, 160);
return () => {
if (historyScrollTimerRef.current) {
clearTimeout(historyScrollTimerRef.current);
historyScrollTimerRef.current = null;
}
};
}, [historyData, rawChatId, setMessages, status]);
// 监听消息变化,提取图片并添加到画布
// 只处理新生成的图片,不处理历史消息中的图片
@ -1613,7 +1640,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
const isInitialLoad = useRef(true);
useEffect(() => {
hasLoadedHistory.current = false;
loadedHistorySignatureRef.current = "";
processedMessageIds.current.clear();
isInitialLoad.current = true;
hiddenPromptRef.current = null;
@ -3175,6 +3202,14 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
}
return part;
});
const fallbackContent =
typeof (message as any).content === "string"
? (message as any).content.trim()
: "";
if (cleanedParts.length === 0 && fallbackContent) {
cleanedParts.push({ type: "text", text: fallbackContent } as any);
}
// 检查清理后是否有实际内容(更严格的检查)
let hasContent = false;