diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 669c41431..31829deeb 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -323,6 +323,8 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF }); const [videoParams, setVideoParams] = useState(null); const [videoSlotUploading, setVideoSlotUploading] = useState(null); + const [lastImageModelId, setLastImageModelId] = useState("auto"); + const [lastVideoModelId, setLastVideoModelId] = useState(null); // 🆕 保存图片参数到 localStorage const handleImageParamsChange = (params: ImageGenerationParams) => { @@ -872,6 +874,11 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF if (videoParams.mode === "first-frame") return ["首帧"] as string[]; return [] as string[]; }, [isVideoModel, videoParams]); + + const firstVideoModelId = useMemo( + () => allModels.find((model) => VIDEO_PROVIDER_TYPES.has(model.providerType))?.id || null, + [allModels] + ); // 默认选择模型(根据系统设置) useEffect(() => { @@ -920,6 +927,43 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF }); }, [isVideoModel, videoFrameSlots.length]); + useEffect(() => { + if (!currentModel) return; + if (isVideoModel) { + setLastVideoModelId(currentModel.id); + return; + } + setLastImageModelId(currentModel.id); + }, [currentModel, isVideoModel]); + + const handleToggleGenerateMode = useCallback(() => { + if (isVideoModel) { + const preferredImageModelId = + allModels.find( + (model) => model.id === lastImageModelId && !VIDEO_PROVIDER_TYPES.has(model.providerType) + )?.id || "auto"; + setSelectedModelId(preferredImageModelId); + return; + } + + const preferredVideoModelId = + allModels.find( + (model) => model.id === lastVideoModelId && VIDEO_PROVIDER_TYPES.has(model.providerType) + )?.id || firstVideoModelId; + + if (!preferredVideoModelId) { + toast.error("当前没有可用的视频模型"); + return; + } + setSelectedModelId(preferredVideoModelId); + }, [ + allModels, + firstVideoModelId, + isVideoModel, + lastImageModelId, + lastVideoModelId, + ]); + useEffect(() => { if (videoFrameSlots.length === 0) return; const editableDiv = textareaRef.current as HTMLDivElement | null; @@ -2361,10 +2405,7 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF > {/* 混合输入区域:使用 contenteditable 实现真正的混合编辑 */}
0 ? "pb-40" : "pb-12" - )} + className="relative px-4 pt-3 pb-12 min-h-[60px]" >
{isVideoModel && videoFrameSlots.length > 0 && ( -
+
{videoFrameSlots.map((label, index) => { const slotAttachment = attachments[index]; @@ -2502,11 +2543,12 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF