fix: resolve canvas runtime crash from hook TDZ
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-21 06:15:56 +08:00
parent c147d7971b
commit 0069690be4

View File

@ -1186,6 +1186,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
const imageParamsRef = useRef(imageParams);
const videoParamsRef = useRef(videoParams);
const deepThinkingEnabledRef = useRef(deepThinkingEnabled);
const imageAutoTitleCacheRef = useRef<Map<string, string>>(new Map());
const handleTypewriterActiveChange = useCallback((typingKey: string, active: boolean) => {
setActiveTypingSections((prev) => {
@ -1206,6 +1207,60 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
);
}, []);
const autoNameGeneratedImageNode = useCallback(
async (nodeId: string, imageUrl: string) => {
if (!nodeId || !imageUrl) return;
const normalizeAutoTitle = (rawTitle: string) => {
const compact = String(rawTitle || "").replace(/\s+/g, "").trim();
if (!compact || compact === "新画布" || compact === "未命名画布" || compact.includes("画布")) {
return "图片";
}
return compact.slice(0, 12);
};
const applyNodeTitle = (title: string) => {
const storeState = useCanvasStore.getState();
const currentNode = storeState.getNode(nodeId);
if (!currentNode) return;
const currentData = ((currentNode.data as any) || {}) as Record<string, any>;
storeState.updateNode(nodeId, {
data: {
...currentData,
title,
metadata: {
...(currentData.metadata || {}),
autoTitle: title,
},
},
});
};
const cachedTitle = imageAutoTitleCacheRef.current.get(imageUrl);
if (cachedTitle) {
applyNodeTitle(cachedTitle);
return;
}
try {
const response = await fetch('/api/canvas/auto-title', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ imageUrl }),
});
const data = await response.json().catch(() => ({}));
const title = normalizeAutoTitle(String(data?.title || ""));
imageAutoTitleCacheRef.current.set(imageUrl, title);
applyNodeTitle(title);
} catch (error) {
console.warn('[CanvasChat] 自动命名图片失败:', error);
applyNodeTitle("图片");
}
},
[],
);
// 🆕 保存图片参数到 localStorage
const handleImageParamsChange = (params: ImageGenerationParams) => {
setImageParams(params);
@ -2809,7 +2864,6 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
// 标记是否已经为当前画布设置过标题(避免重复调用)
const hasSetCanvasTitle = useRef(false);
const imageAutoTitleCacheRef = useRef<Map<string, string>>(new Map());
// 🆕 Agent模式上下文(画布图片布局)
const buildAutoContext = useCallback(() => {
@ -4458,60 +4512,6 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
}
}, [chatId]);
const autoNameGeneratedImageNode = useCallback(
async (nodeId: string, imageUrl: string) => {
if (!nodeId || !imageUrl) return;
const normalizeAutoTitle = (rawTitle: string) => {
const compact = String(rawTitle || "").replace(/\s+/g, "").trim();
if (!compact || compact === "新画布" || compact === "未命名画布" || compact.includes("画布")) {
return "图片";
}
return compact.slice(0, 12);
};
const applyNodeTitle = (title: string) => {
const storeState = useCanvasStore.getState();
const currentNode = storeState.getNode(nodeId);
if (!currentNode) return;
const currentData = ((currentNode.data as any) || {}) as Record<string, any>;
storeState.updateNode(nodeId, {
data: {
...currentData,
title,
metadata: {
...(currentData.metadata || {}),
autoTitle: title,
},
},
});
};
const cachedTitle = imageAutoTitleCacheRef.current.get(imageUrl);
if (cachedTitle) {
applyNodeTitle(cachedTitle);
return;
}
try {
const response = await fetch('/api/canvas/auto-title', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ imageUrl }),
});
const data = await response.json().catch(() => ({}));
const title = normalizeAutoTitle(String(data?.title || ""));
imageAutoTitleCacheRef.current.set(imageUrl, title);
applyNodeTitle(title);
} catch (error) {
console.warn('[CanvasChat] 自动命名图片失败:', error);
applyNodeTitle("图片");
}
},
[],
);
const uploadImageFileAndAddToCanvas = useCallback(async (
file: File,
nodeIndex: number