fix(canvas): 图片工具 - 移除独立图片编辑入口并保留连线生成

Co-authored-by: lmj15657306288-ui <lmj15657306288-ui@users.noreply.github.com>
This commit is contained in:
ddCat
2026-09-19 00:08:41 +08:00
parent 8e3692ea4b
commit 17ffdda0b8
7 changed files with 9 additions and 30 deletions

View File

@@ -4,7 +4,7 @@ import { Brush, Camera, Copy, FileText, Globe2, Grid2x2, Layers3, Lock, LockOpen
import type { CanvasNodeData } from "@/types/canvas"; import type { CanvasNodeData } from "@/types/canvas";
import type { NodeToolbarGroup } from "@/lib/canvas/tool-registry"; import type { NodeToolbarGroup } from "@/lib/canvas/tool-registry";
type ImageNodeActionToolId = "copyPrompt" | "reversePrompt" | "replace" | "resize" | "annotation" | "annotationEdit" | "textEdit" | "maskEdit" | "imageEdit" | "removeBackground" | "layerDecomposition" | "emotion" | "portraitTexture" | "crop" | "split" | "upscale" | "superResolve" | "angle" | "lighting" | "panorama" | "view"; type ImageNodeActionToolId = "copyPrompt" | "reversePrompt" | "replace" | "resize" | "annotation" | "annotationEdit" | "textEdit" | "maskEdit" | "removeBackground" | "layerDecomposition" | "emotion" | "portraitTexture" | "crop" | "split" | "upscale" | "superResolve" | "angle" | "lighting" | "panorama" | "view";
type ImageToolHandlers = { type ImageToolHandlers = {
onUpload: (node: CanvasNodeData) => void; onUpload: (node: CanvasNodeData) => void;
@@ -13,7 +13,6 @@ type ImageToolHandlers = {
onAnnotationEdit: (node: CanvasNodeData) => void; onAnnotationEdit: (node: CanvasNodeData) => void;
onTextEdit: (node: CanvasNodeData) => void; onTextEdit: (node: CanvasNodeData) => void;
onMaskEdit: (node: CanvasNodeData) => void; onMaskEdit: (node: CanvasNodeData) => void;
onImageEdit: (node: CanvasNodeData) => void;
onRemoveBackground: (node: CanvasNodeData) => void; onRemoveBackground: (node: CanvasNodeData) => void;
onLayerDecomposition: (node: CanvasNodeData) => void; onLayerDecomposition: (node: CanvasNodeData) => void;
onEmotion: (node: CanvasNodeData) => void; onEmotion: (node: CanvasNodeData) => void;
@@ -117,15 +116,6 @@ const imageToolDefinitions: ImageToolDefinition[] = [
order: 15, order: 15,
run: (node, handlers) => handlers.onTextEdit(node), run: (node, handlers) => handlers.onTextEdit(node),
}, },
{
id: "imageEdit",
label: "图片编辑",
description: "用文字描述要修改的内容,生成新图片",
icon: () => <WandSparkles className="size-3.5" />,
group: "primary",
order: 20,
run: (node, handlers) => handlers.onImageEdit(node),
},
{ {
id: "removeBackground", id: "removeBackground",
label: "去除背景", label: "去除背景",

View File

@@ -31,7 +31,7 @@ export function CanvasNodeImageEditDialog({
}, [config, open, dataUrl]); }, [config, open, dataUrl]);
return ( return (
<Modal open={open && Boolean(dataUrl)} onCancel={onClose} footer={null} centered destroyOnHidden width={860} title="图片编辑"> <Modal open={open && Boolean(dataUrl)} onCancel={onClose} footer={null} centered destroyOnHidden width={860} title={preset === "remove-background" ? "去除背景" : "图片编辑"}>
<div className="grid gap-5 md:grid-cols-[minmax(0,1fr)_300px]"> <div className="grid gap-5 md:grid-cols-[minmax(0,1fr)_300px]">
<div className="grid min-h-[320px] place-items-center overflow-hidden rounded-xl bg-black/5 p-3 dark:bg-white/[0.04]"> <div className="grid min-h-[320px] place-items-center overflow-hidden rounded-xl bg-black/5 p-3 dark:bg-white/[0.04]">
<img src={dataUrl} alt="待编辑图片" className="max-h-[58vh] max-w-full object-contain" draggable={false} /> <img src={dataUrl} alt="待编辑图片" className="max-h-[58vh] max-w-full object-contain" draggable={false} />

View File

@@ -37,7 +37,6 @@ type CanvasNodeToolbarProps = {
onDownload: (node: CanvasNodeData) => void; onDownload: (node: CanvasNodeData) => void;
onSaveAsset: (node: CanvasNodeData) => void; onSaveAsset: (node: CanvasNodeData) => void;
onMaskEdit: (node: CanvasNodeData) => void; onMaskEdit: (node: CanvasNodeData) => void;
onImageEdit: (node: CanvasNodeData) => void;
onRemoveBackground: (node: CanvasNodeData) => void; onRemoveBackground: (node: CanvasNodeData) => void;
onLayerDecomposition: (node: CanvasNodeData) => void; onLayerDecomposition: (node: CanvasNodeData) => void;
onEmotion: (node: CanvasNodeData) => void; onEmotion: (node: CanvasNodeData) => void;
@@ -103,7 +102,6 @@ export function CanvasNodeToolbar({
onDownload, onDownload,
onSaveAsset, onSaveAsset,
onMaskEdit, onMaskEdit,
onImageEdit,
onRemoveBackground, onRemoveBackground,
onLayerDecomposition, onLayerDecomposition,
onEmotion, onEmotion,
@@ -231,13 +229,13 @@ export function CanvasNodeToolbar({
} }
copyText(prompt, "提示词已复制"); copyText(prompt, "提示词已复制");
}; };
const imageTools = buildImageToolbarTools(node, { onUpload, onToggleFreeResize, onAnnotate, onAnnotationEdit, onTextEdit, onMaskEdit, onImageEdit, onRemoveBackground, onLayerDecomposition, onEmotion, onPortraitTexture, onCrop, onUpscale, onSuperResolve, onAngle, onLighting, onPanorama, onViewImage, onCopyPrompt: copyImagePrompt, onReversePrompt }); const imageTools = buildImageToolbarTools(node, { onUpload, onToggleFreeResize, onAnnotate, onAnnotationEdit, onTextEdit, onMaskEdit, onRemoveBackground, onLayerDecomposition, onEmotion, onPortraitTexture, onCrop, onUpscale, onSuperResolve, onAngle, onLighting, onPanorama, onViewImage, onCopyPrompt: copyImagePrompt, onReversePrompt });
// 构建 ToolContext——供注册表解析工具 // 构建 ToolContext——供注册表解析工具
const nodeHoverHandlers = { const nodeHoverHandlers = {
onNodeInfo: onInfo, onNodeDelete: onDelete, onNodeRetry: onRetry, onNodeEditText: onEditText, onNodeDecreaseFont: onDecreaseFont, onNodeIncreaseFont: onIncreaseFont, onNodeInfo: onInfo, onNodeDelete: onDelete, onNodeRetry: onRetry, onNodeEditText: onEditText, onNodeDecreaseFont: onDecreaseFont, onNodeIncreaseFont: onIncreaseFont,
onNodeToggleDialog: onToggleDialog, onNodeAnnotate: onAnnotate, onNodeGenerateImage: onGenerateImage, onNodeUpload: onUpload, onNodeDownload: onDownload, onNodeToggleDialog: onToggleDialog, onNodeAnnotate: onAnnotate, onNodeGenerateImage: onGenerateImage, onNodeUpload: onUpload, onNodeDownload: onDownload,
onNodeSaveAsset: onSaveAsset, onNodeMaskEdit: onMaskEdit, onNodeImageEdit: onImageEdit, onNodeRemoveBackground: onRemoveBackground, onNodeEmotion: onEmotion, onNodePortraitTexture: onPortraitTexture, onNodeCrop: onCrop, onNodeSaveAsset: onSaveAsset, onNodeMaskEdit: onMaskEdit, onNodeRemoveBackground: onRemoveBackground, onNodeEmotion: onEmotion, onNodePortraitTexture: onPortraitTexture, onNodeCrop: onCrop,
onNodeSplit: (target) => onSplit(target, { rows: 2, columns: 2 }), onNodeUpscale: onUpscale, onNodeSuperResolve: onSuperResolve, onNodeAngle: onAngle, onNodeViewImage: onViewImage, onNodeSplit: (target) => onSplit(target, { rows: 2, columns: 2 }), onNodeUpscale: onUpscale, onNodeSuperResolve: onSuperResolve, onNodeAngle: onAngle, onNodeViewImage: onViewImage,
onNodeExtractVideoFrames: onExtractVideoFrames, onNodeExtractAudioFromVideo: onExtractAudioFromVideo, onNodeTrimVideoSegments: onTrimVideoSegments, onNodeReversePrompt: onReversePrompt, onNodeToggleFreeResize: onToggleFreeResize, onNodeExtractVideoFrames: onExtractVideoFrames, onNodeExtractAudioFromVideo: onExtractAudioFromVideo, onNodeTrimVideoSegments: onTrimVideoSegments, onNodeReversePrompt: onReversePrompt, onNodeToggleFreeResize: onToggleFreeResize,
onNodeSubtitles: onSubtitles, onNodeTimeline: onTimeline, onNodeToggleLocked: onToggleLocked, onNodeCopyPrompt: copyImagePrompt, onNodeSubtitles: onSubtitles, onNodeTimeline: onTimeline, onNodeToggleLocked: onToggleLocked, onNodeCopyPrompt: copyImagePrompt,

View File

@@ -31,7 +31,7 @@ type CanvasProjectMediaDialogsProps = {
onAnnotationEdit: (node: CanvasNodeData, payload: CanvasImageAnnotationPayload) => void; onAnnotationEdit: (node: CanvasNodeData, payload: CanvasImageAnnotationPayload) => void;
onMaskEdit: (node: CanvasNodeData, payload: CanvasImageMaskEditPayload) => void; onMaskEdit: (node: CanvasNodeData, payload: CanvasImageMaskEditPayload) => void;
onUpscale: (node: CanvasNodeData, params: CanvasImageUpscaleParams) => void; onUpscale: (node: CanvasNodeData, params: CanvasImageUpscaleParams) => void;
onImageEdit: (node: CanvasNodeData, payload: CanvasImageEditPayload) => void; onImageOperation: (node: CanvasNodeData, payload: CanvasImageEditPayload) => void;
onLayerDecomposition: (node: CanvasNodeData, payload: CanvasImageLayerDecompositionPayload) => void; onLayerDecomposition: (node: CanvasNodeData, payload: CanvasImageLayerDecompositionPayload) => void;
onDetectText: () => Promise<import("@/components/canvas/canvas-node-text-edit-dialog").CanvasImageTextLine[]>; onDetectText: () => Promise<import("@/components/canvas/canvas-node-text-edit-dialog").CanvasImageTextLine[]>;
onTextEdit: (node: CanvasNodeData, payload: CanvasImageTextEditPayload) => void; onTextEdit: (node: CanvasNodeData, payload: CanvasImageTextEditPayload) => void;
@@ -61,7 +61,7 @@ export function CanvasProjectMediaDialogs({
onAnnotationEdit, onAnnotationEdit,
onMaskEdit, onMaskEdit,
onUpscale, onUpscale,
onImageEdit, onImageOperation,
onLayerDecomposition, onLayerDecomposition,
onDetectText, onDetectText,
onTextEdit, onTextEdit,
@@ -74,7 +74,7 @@ export function CanvasProjectMediaDialogs({
{annotationEditNode?.metadata?.content ? <CanvasNodeAnnotationDialog image={{ url: annotationEditNode.metadata.content, storageKey: annotationEditNode.metadata.storageKey }} editMode open onClose={onCloseAnnotationEdit} onConfirm={(payload) => { if (typeof payload !== "string") onAnnotationEdit(annotationEditNode, payload); }} /> : null} {annotationEditNode?.metadata?.content ? <CanvasNodeAnnotationDialog image={{ url: annotationEditNode.metadata.content, storageKey: annotationEditNode.metadata.storageKey }} editMode open onClose={onCloseAnnotationEdit} onConfirm={(payload) => { if (typeof payload !== "string") onAnnotationEdit(annotationEditNode, payload); }} /> : null}
{maskEditNode?.metadata?.content ? <CanvasNodeMaskEditDialog dataUrl={maskEditNode.metadata.content} config={{ ...config, model: maskEditNode.metadata.model || config.model, imageModel: maskEditNode.metadata.model || config.imageModel, size: maskEditNode.metadata.size || config.size, quality: maskEditNode.metadata.quality || config.quality, count: String(maskEditNode.metadata.count || config.count) }} open onClose={onCloseMaskEdit} onConfirm={(payload) => onMaskEdit(maskEditNode, payload)} /> : null} {maskEditNode?.metadata?.content ? <CanvasNodeMaskEditDialog dataUrl={maskEditNode.metadata.content} config={{ ...config, model: maskEditNode.metadata.model || config.model, imageModel: maskEditNode.metadata.model || config.imageModel, size: maskEditNode.metadata.size || config.size, quality: maskEditNode.metadata.quality || config.quality, count: String(maskEditNode.metadata.count || config.count) }} open onClose={onCloseMaskEdit} onConfirm={(payload) => onMaskEdit(maskEditNode, payload)} /> : null}
{upscaleNode?.metadata?.content ? <CanvasNodeUpscaleDialog dataUrl={upscaleNode.metadata.content} open onClose={onCloseUpscale} onConfirm={(params) => onUpscale(upscaleNode, params)} /> : null} {upscaleNode?.metadata?.content ? <CanvasNodeUpscaleDialog dataUrl={upscaleNode.metadata.content} open onClose={onCloseUpscale} onConfirm={(params) => onUpscale(upscaleNode, params)} /> : null}
{imageEditNode?.metadata?.content ? <CanvasNodeImageEditDialog dataUrl={imageEditNode.metadata.content} preset={imageEditPreset} config={{ ...config, model: imageEditNode.metadata.model || config.model, imageModel: imageEditNode.metadata.model || config.imageModel, size: imageEditNode.metadata.size || config.size, quality: imageEditNode.metadata.quality || config.quality }} open onClose={onCloseImageEdit} onConfirm={(payload) => onImageEdit(imageEditNode, payload)} /> : null} {imageEditNode?.metadata?.content ? <CanvasNodeImageEditDialog dataUrl={imageEditNode.metadata.content} preset={imageEditPreset} config={{ ...config, model: imageEditNode.metadata.model || config.model, imageModel: imageEditNode.metadata.model || config.imageModel, size: imageEditNode.metadata.size || config.size, quality: imageEditNode.metadata.quality || config.quality }} open onClose={onCloseImageEdit} onConfirm={(payload) => onImageOperation(imageEditNode, payload)} /> : null}
{layerDecompositionNode?.metadata?.content ? <CanvasNodeLayerDecompositionDialog dataUrl={layerDecompositionNode.metadata.content} config={{ ...config, model: layerDecompositionNode.metadata.model || config.model, imageModel: layerDecompositionNode.metadata.model || config.imageModel, size: layerDecompositionNode.metadata.size || config.size, quality: layerDecompositionNode.metadata.quality || config.quality }} open onClose={onCloseLayerDecomposition} onConfirm={(payload) => onLayerDecomposition(layerDecompositionNode, payload)} /> : null} {layerDecompositionNode?.metadata?.content ? <CanvasNodeLayerDecompositionDialog dataUrl={layerDecompositionNode.metadata.content} config={{ ...config, model: layerDecompositionNode.metadata.model || config.model, imageModel: layerDecompositionNode.metadata.model || config.imageModel, size: layerDecompositionNode.metadata.size || config.size, quality: layerDecompositionNode.metadata.quality || config.quality }} open onClose={onCloseLayerDecomposition} onConfirm={(payload) => onLayerDecomposition(layerDecompositionNode, payload)} /> : null}
{textEditNode?.metadata?.content ? <CanvasNodeTextEditDialog dataUrl={textEditNode.metadata.content} open onClose={onCloseTextEdit} onDetect={onDetectText} onConfirm={(payload) => onTextEdit(textEditNode, payload)} /> : null} {textEditNode?.metadata?.content ? <CanvasNodeTextEditDialog dataUrl={textEditNode.metadata.content} open onClose={onCloseTextEdit} onDetect={onDetectText} onConfirm={(payload) => onTextEdit(textEditNode, payload)} /> : null}
</> </>

View File

@@ -875,7 +875,6 @@ function InfiniteCanvasPage() {
setMaskEditNodeId, setMaskEditNodeId,
setImageEditNodeId, setImageEditNodeId,
setImageEditPreset, setImageEditPreset,
openImageEditNode,
openBackgroundRemoval, openBackgroundRemoval,
openLayerDecomposition, openLayerDecomposition,
decomposeImageLayers, decomposeImageLayers,
@@ -2171,7 +2170,6 @@ function InfiniteCanvasPage() {
onFocusOutput={(nodeId) => focusCanvasImageNode(nodeId)} onFocusOutput={(nodeId) => focusCanvasImageNode(nodeId)}
onReorderReferenceColumns={(fromColumnId, toColumnId) => reorderBatchReferenceColumns(contentNode.id, fromColumnId, toColumnId)} onReorderReferenceColumns={(fromColumnId, toColumnId) => reorderBatchReferenceColumns(contentNode.id, fromColumnId, toColumnId)}
onMoveReferenceCell={(sourceRowId, sourceColumnIndex, targetRowId, targetColumnIndex) => moveBatchReferenceCell(contentNode.id, sourceRowId, sourceColumnIndex, targetRowId, targetColumnIndex)} onMoveReferenceCell={(sourceRowId, sourceColumnIndex, targetRowId, targetColumnIndex) => moveBatchReferenceCell(contentNode.id, sourceRowId, sourceColumnIndex, targetRowId, targetColumnIndex)}
onReplaceReference={replaceCanvasNodeMedia}
onUploadReference={(rowId, columnIndex, file) => { void handleUploadBatchReference(contentNode.id, rowId, columnIndex, file); }} onUploadReference={(rowId, columnIndex, file) => { void handleUploadBatchReference(contentNode.id, rowId, columnIndex, file); }}
onConnectStart={(event, handleId) => handleConnectStart(event, contentNode.id, "target", handleId)} onConnectStart={(event, handleId) => handleConnectStart(event, contentNode.id, "target", handleId)}
onConnectDrop={(event, handleId) => handleConnectDrop(event, contentNode.id, handleId)} onConnectDrop={(event, handleId) => handleConnectDrop(event, contentNode.id, handleId)}
@@ -2838,7 +2836,6 @@ function InfiniteCanvasPage() {
onAnnotate={(node) => setAnnotationNodeId(node.id)} onAnnotate={(node) => setAnnotationNodeId(node.id)}
onAnnotationEdit={openAnnotationEditNode} onAnnotationEdit={openAnnotationEditNode}
onMaskEdit={(node) => setMaskEditNodeId(node.id)} onMaskEdit={(node) => setMaskEditNodeId(node.id)}
onImageEdit={openImageEditNode}
onRemoveBackground={openBackgroundRemoval} onRemoveBackground={openBackgroundRemoval}
onLayerDecomposition={openLayerDecomposition} onLayerDecomposition={openLayerDecomposition}
onTextEdit={openTextEditNode} onTextEdit={openTextEditNode}
@@ -3181,7 +3178,7 @@ function InfiniteCanvasPage() {
onAnnotate={(node, dataUrl) => void saveAnnotatedImageNode(node, dataUrl)} onAnnotate={(node, dataUrl) => void saveAnnotatedImageNode(node, dataUrl)}
onAnnotationEdit={(node, payload) => void editAnnotatedImageNode(node, payload)} onAnnotationEdit={(node, payload) => void editAnnotatedImageNode(node, payload)}
onMaskEdit={(node, payload) => void maskEditImageNode(node, payload)} onMaskEdit={(node, payload) => void maskEditImageNode(node, payload)}
onImageEdit={(node, payload) => void editImageNode(node, payload)} onImageOperation={(node, payload) => void editImageNode(node, payload)}
onLayerDecomposition={(node, payload) => void decomposeImageLayers(node, payload)} onLayerDecomposition={(node, payload) => void decomposeImageLayers(node, payload)}
onDetectText={() => { onDetectText={() => {
const node = textEditNodeId ? nodeById.get(textEditNodeId) : null; const node = textEditNodeId ? nodeById.get(textEditNodeId) : null;

View File

@@ -282,7 +282,7 @@ export default function SharedCanvasPage() {
}} onHoverStart={keepToolbar} onHoverEnd={hideToolbar} onConnectStart={unauthorized} onResize={() => undefined} onContentChange={unauthorized} onRetry={unauthorized} onOpenTaskDetails={unauthorized} onViewImage={(target) => setInfoNodeId(target.id)} onContextMenu={(event, nodeId) => openContextMenu(event, nodeId)} />)} }} onHoverStart={keepToolbar} onHoverEnd={hideToolbar} onConnectStart={unauthorized} onResize={() => undefined} onContentChange={unauthorized} onRetry={unauthorized} onOpenTaskDetails={unauthorized} onViewImage={(target) => setInfoNodeId(target.id)} onContextMenu={(event, nodeId) => openContextMenu(event, nodeId)} />)}
</InfiniteCanvas> </InfiniteCanvas>
<CanvasNodeToolbar node={dragRef.current ? null : toolbarNode} viewport={viewport} containerRef={containerRef} onKeep={keepToolbar} onLeave={hideToolbar} onInfo={(node) => setInfoNodeId(node.id)} onEditText={unauthorized} onDecreaseFont={unauthorized} onIncreaseFont={unauthorized} onToggleDialog={unauthorized} onAnnotate={unauthorized} onAnnotationEdit={unauthorized} onTextEdit={unauthorized} onGenerateImage={unauthorized} onUpload={unauthorized} onDownload={unauthorized} onSaveAsset={unauthorized} onMaskEdit={unauthorized} onImageEdit={unauthorized} onRemoveBackground={unauthorized} onLayerDecomposition={unauthorized} onEmotion={unauthorized} onPortraitTexture={unauthorized} onCrop={unauthorized} onSplit={unauthorized} onUpscale={unauthorized} onSuperResolve={unauthorized} onAngle={unauthorized} onLighting={unauthorized} onPanorama={unauthorized} onViewImage={unauthorized} onExtractVideoFrames={unauthorized} onExtractAudioFromVideo={unauthorized} onTrimVideoSegments={unauthorized} extractingVideoFrames={false} extractingAudio={false} trimmingVideo={false} onSubtitles={unauthorized} onTimeline={unauthorized} onReversePrompt={unauthorized} onRetry={unauthorized} onToggleFreeResize={unauthorized} onToggleLocked={unauthorized} onDelete={unauthorized} /> <CanvasNodeToolbar node={dragRef.current ? null : toolbarNode} viewport={viewport} containerRef={containerRef} onKeep={keepToolbar} onLeave={hideToolbar} onInfo={(node) => setInfoNodeId(node.id)} onEditText={unauthorized} onDecreaseFont={unauthorized} onIncreaseFont={unauthorized} onToggleDialog={unauthorized} onAnnotate={unauthorized} onAnnotationEdit={unauthorized} onTextEdit={unauthorized} onGenerateImage={unauthorized} onUpload={unauthorized} onDownload={unauthorized} onSaveAsset={unauthorized} onMaskEdit={unauthorized} onRemoveBackground={unauthorized} onLayerDecomposition={unauthorized} onEmotion={unauthorized} onPortraitTexture={unauthorized} onCrop={unauthorized} onSplit={unauthorized} onUpscale={unauthorized} onSuperResolve={unauthorized} onAngle={unauthorized} onLighting={unauthorized} onPanorama={unauthorized} onViewImage={unauthorized} onExtractVideoFrames={unauthorized} onExtractAudioFromVideo={unauthorized} onTrimVideoSegments={unauthorized} extractingVideoFrames={false} extractingAudio={false} trimmingVideo={false} onSubtitles={unauthorized} onTimeline={unauthorized} onReversePrompt={unauthorized} onRetry={unauthorized} onToggleFreeResize={unauthorized} onToggleLocked={unauthorized} onDelete={unauthorized} />
<div className="absolute bottom-5 left-5 z-[var(--z-panel-floating)]"><CanvasZoomControls scale={viewport.k} containerRef={containerRef} onScaleChange={setZoom} onFitContent={resetViewport} isMiniMapOpen={false} onToggleMiniMap={unauthorized} onOpenShortcuts={unauthorized} /></div> <div className="absolute bottom-5 left-5 z-[var(--z-panel-floating)]"><CanvasZoomControls scale={viewport.k} containerRef={containerRef} onScaleChange={setZoom} onFitContent={resetViewport} isMiniMapOpen={false} onToggleMiniMap={unauthorized} onOpenShortcuts={unauthorized} /></div>
<div className="pointer-events-none absolute bottom-5 right-5 z-[var(--z-panel-floating)] max-w-[340px] text-right text-xs leading-5" style={{ color: theme.node.muted }}>访客操作仅在当前页面临时生效</div> <div className="pointer-events-none absolute bottom-5 right-5 z-[var(--z-panel-floating)] max-w-[340px] text-right text-xs leading-5" style={{ color: theme.node.muted }}>访客操作仅在当前页面临时生效</div>

View File

@@ -962,11 +962,6 @@ export function useCanvasMediaTools({
} }
}, [bindGenerationTask, effectiveConfig, finishGenerationRequest, isAiConfigReady, message, nodesRef, persistMediaNodes, projectId, setConnections, setDialogNodeId, setNodes, setRunningNodeId, setSelectedConnectionId, setSelectedNodeIds, startGenerationRequest]); }, [bindGenerationTask, effectiveConfig, finishGenerationRequest, isAiConfigReady, message, nodesRef, persistMediaNodes, projectId, setConnections, setDialogNodeId, setNodes, setRunningNodeId, setSelectedConnectionId, setSelectedNodeIds, startGenerationRequest]);
const openImageEditNode = useCallback((node: CanvasNodeData) => {
setImageEditPreset(null);
setImageEditNodeId(node.id);
}, []);
const openBackgroundRemoval = useCallback((node: CanvasNodeData) => { const openBackgroundRemoval = useCallback((node: CanvasNodeData) => {
setImageEditPreset("remove-background"); setImageEditPreset("remove-background");
setImageEditNodeId(node.id); setImageEditNodeId(node.id);
@@ -1247,7 +1242,6 @@ export function useCanvasMediaTools({
setMaskEditNodeId, setMaskEditNodeId,
setImageEditNodeId, setImageEditNodeId,
setImageEditPreset, setImageEditPreset,
openImageEditNode,
openBackgroundRemoval, openBackgroundRemoval,
openLayerDecomposition, openLayerDecomposition,
decomposeImageLayers, decomposeImageLayers,