diff --git a/web/src/components/canvas/canvas-batch-table-node.tsx b/web/src/components/canvas/canvas-batch-table-node.tsx index 5286f6ed3..3ffdf3c17 100644 --- a/web/src/components/canvas/canvas-batch-table-node.tsx +++ b/web/src/components/canvas/canvas-batch-table-node.tsx @@ -1,6 +1,6 @@ -import { useCallback, useEffect, useMemo, useRef, useState, type MutableRefObject, type MouseEvent as ReactMouseEvent, type PointerEvent as ReactPointerEvent, type ReactNode } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState, type MutableRefObject, type PointerEvent as ReactPointerEvent, type ReactNode } from "react"; import { Button, Input, Select, Switch, Tooltip } from "antd"; -import { GripVertical, Image as ImageIcon, LoaderCircle, Play, Plus, RefreshCw, Rows3, Trash2, Upload } from "lucide-react"; +import { GripVertical, Image as ImageIcon, LoaderCircle, Play, Plus, RefreshCw, Rows3, Trash2, Upload, X } from "lucide-react"; import { CachedResourceImage } from "@/components/cached-resource-image"; import { BATCH_REFERENCE_HANDLE_GAP, BATCH_REFERENCE_HANDLE_TOP, MAX_BATCH_REFERENCE_COLUMNS, MAX_BATCH_TEXT_COLUMNS, batchGridTemplateColumns, batchPromptForRow, batchReferenceColumns, batchReferenceHandleId, batchTextColumns, batchTextHandleId, batchTextHandleTop } from "@/lib/canvas/canvas-batch-table"; @@ -59,7 +59,6 @@ export function CanvasBatchTableNodeContent({ node, nodes, connections, batch, t const dragStartRef = useRef<{ x: number; y: number; pointerId: number; cell: ReferenceCell } | null>(null); const lastPointerRef = useRef({ x: 0, y: 0 }); const hoveredCellRef = useRef(null); - const [contextMenu, setContextMenu] = useState<{ x: number; y: number; cell: ReferenceCell } | null>(null); const suppressClickRef = useRef(false); const uploadTargetRef = useRef<{ rowId: string; columnIndex: number } | null>(null); const uploadInputRef = useRef(null); @@ -168,13 +167,6 @@ export function CanvasBatchTableNodeContent({ node, nodes, connections, batch, t return () => window.removeEventListener("keydown", handleKeyDown, true); }, [readOnly, onRemoveReference]); - // Hide context menu on outside click - useEffect(() => { - if (!contextMenu) return; - const hide = () => setContextMenu(null); - window.addEventListener("pointerdown", hide); - return () => window.removeEventListener("pointerdown", hide); - }, [contextMenu]); const handleReferencePointerDown = useCallback((event: ReactPointerEvent, rowId: string, columnIndex: number, hasMaterial: boolean) => { if (readOnly || !hasMaterial) return; @@ -323,7 +315,6 @@ export function CanvasBatchTableNodeContent({ node, nodes, connections, batch, t hoveredCellRef={hoveredCellRef} onReplace={onReplaceReference} onRemove={() => onRemoveReference(row.id, columnIndex)} - onContextMenu={(event) => { event.preventDefault(); event.stopPropagation(); setContextMenu({ x: event.clientX, y: event.clientY, cell: { rowId: row.id, columnIndex } }); }} onUpload={() => { uploadTargetRef.current = { rowId: row.id, columnIndex }; uploadInputRef.current?.click(); }} onPointerDown={handleReferencePointerDown} onPointerMove={handleReferencePointerMove} @@ -381,23 +372,6 @@ export function CanvasBatchTableNodeContent({ node, nodes, connections, batch, t
连接图片后会自动生成任务;点击缩略图可替换素材,拖动参考图列可调整顺序。
)} - {contextMenu ? ( -
e.stopPropagation()} - > - -
- ) : null} ); } @@ -544,7 +518,7 @@ function TextNodeCell({ node, theme }: { node?: CanvasNodeData; theme: CanvasThe return
{content || "未连接文字"}
; } -function ReferenceThumbnail({ node, theme, readOnly, rowId, columnIndex, columnId, draggingColumnId, isDraggingCell, isDropTarget, suppressClickRef, hoveredCellRef, onReplace, onRemove, onContextMenu, onUpload, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onLostPointerCapture }: { +function ReferenceThumbnail({ node, theme, readOnly, rowId, columnIndex, columnId, draggingColumnId, isDraggingCell, isDropTarget, suppressClickRef, hoveredCellRef, onReplace, onRemove, onUpload, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onLostPointerCapture }: { node?: CanvasNodeData; theme: CanvasTheme; readOnly: boolean; @@ -558,7 +532,6 @@ function ReferenceThumbnail({ node, theme, readOnly, rowId, columnIndex, columnI hoveredCellRef: MutableRefObject; onReplace: (node: CanvasNodeData) => void; onRemove: () => void; - onContextMenu: (event: ReactMouseEvent) => void; onUpload: () => void; onPointerDown: (event: ReactPointerEvent, rowId: string, columnIndex: number, hasMaterial: boolean) => void; onPointerMove: (event: ReactPointerEvent) => void; @@ -580,7 +553,6 @@ function ReferenceThumbnail({ node, theme, readOnly, rowId, columnIndex, columnI onClick={(event) => { event.stopPropagation(); if (!suppressClickRef.current) onUpload(); }} onMouseEnter={() => { hoveredCellRef.current = { rowId, columnIndex }; }} onMouseLeave={() => { if (hoveredCellRef.current?.rowId === rowId && hoveredCellRef.current?.columnIndex === columnIndex) hoveredCellRef.current = null; }} - onContextMenu={onContextMenu} aria-label={`${columnId},点击上传图片`} {...cellData} onPointerDown={(event) => onPointerDown(event, rowId, columnIndex, false)} @@ -608,7 +580,6 @@ function ReferenceThumbnail({ node, theme, readOnly, rowId, columnIndex, columnI onClick={(event) => { event.stopPropagation(); if (!readOnly && !draggingColumnId && !suppressClickRef.current) onReplace(node); }} onMouseEnter={() => { hoveredCellRef.current = { rowId, columnIndex }; }} onMouseLeave={() => { if (hoveredCellRef.current?.rowId === rowId && hoveredCellRef.current?.columnIndex === columnIndex) hoveredCellRef.current = null; }} - onContextMenu={onContextMenu} {...cellData} onPointerDown={(event) => onPointerDown(event, rowId, columnIndex, true)} onPointerMove={onPointerMove} @@ -619,6 +590,17 @@ function ReferenceThumbnail({ node, theme, readOnly, rowId, columnIndex, columnI > {!readOnly ? 替换 : null} + {!readOnly ? ( + + ) : null} );