refactor(canvas): 重构画布图像设置组件为独立面板

- 将图像设置弹层提取为独立的 CanvasImageSettingsPopover 组件
- 在节点对话框中集成新的紧凑图像设置面板
- 移除旧的 ImageSettingsPopover 内联实现
- 更新画布助手面板以使用新组件
- 修复节点工具栏在图像设置打开时的显示逻辑
- 调整节点配置中的质量属性继承顺序
This commit is contained in:
HouYunFei
2026-05-22 17:49:55 +08:00
parent 6049ad2df3
commit 133861590e
8 changed files with 216 additions and 70 deletions
@@ -267,6 +267,7 @@ function InfiniteCanvasPage() {
const [assetPickerTab, setAssetPickerTab] = useState<AssetPickerTab>("my-assets");
const [projectLoaded, setProjectLoaded] = useState(false);
const [toolbarNodeId, setToolbarNodeId] = useState<string | null>(null);
const [nodeImageSettingsOpen, setNodeImageSettingsOpen] = useState(false);
const [dialogNodeId, setDialogNodeId] = useState<string | null>(null);
const [editingNodeId, setEditingNodeId] = useState<string | null>(null);
const [editRequestNonce, setEditRequestNonce] = useState(0);
@@ -372,6 +373,10 @@ function InfiniteCanvasPage() {
updateProject(projectId, { nodes, connections, chatSessions, activeChatId, backgroundMode });
}, [activeChatId, backgroundMode, chatSessions, connections, nodes, projectId, projectLoaded, updateProject]);
useEffect(() => {
if (!dialogNodeId) setNodeImageSettingsOpen(false);
}, [dialogNodeId]);
useEffect(() => {
if (!projectLoaded) return;
if (viewportSaveTimerRef.current) clearTimeout(viewportSaveTimerRef.current);
@@ -444,13 +449,13 @@ function InfiniteCanvasPage() {
}, []);
const keepNodeToolbar = useCallback((nodeId: string) => {
if (nodeDraggingRef.current) return;
if (nodeDraggingRef.current || nodeImageSettingsOpen) return;
if (toolbarHideTimerRef.current) {
clearTimeout(toolbarHideTimerRef.current);
toolbarHideTimerRef.current = null;
}
setToolbarNodeId(nodeId);
}, []);
}, [nodeImageSettingsOpen]);
const hideNodeToolbar = useCallback(() => {
if (toolbarHideTimerRef.current) clearTimeout(toolbarHideTimerRef.current);
@@ -1891,6 +1896,10 @@ function InfiniteCanvasPage() {
onPromptChange={handleNodePromptChange}
onConfigChange={handleConfigNodeChange}
onGenerate={handleGenerateNode}
onImageSettingsOpenChange={(open) => {
setNodeImageSettingsOpen(open);
if (open) setToolbarNodeId(null);
}}
/>
)}
renderNodeContent={(contentNode) => (
@@ -1955,7 +1964,7 @@ function InfiniteCanvasPage() {
</InfiniteCanvas>
<CanvasNodeHoverToolbar
node={isNodeDragging ? null : toolbarNode}
node={isNodeDragging || nodeImageSettingsOpen ? null : toolbarNode}
viewport={viewport}
onKeep={keepNodeToolbar}
onLeave={hideNodeToolbar}
@@ -2370,7 +2379,7 @@ function buildGenerationConfig(config: AiConfig, node: CanvasNodeData | undefine
return {
...config,
model: node?.metadata?.model || defaultModel || config.model || defaultConfig.model,
quality: config.quality || defaultConfig.quality,
quality: node?.metadata?.quality || config.quality || defaultConfig.quality,
size: node?.metadata?.size || config.size || defaultConfig.size,
count: String(node?.metadata?.count || (mode === "image" ? 3 : config.count) || defaultConfig.count),
};