Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions packages/x-flow/src/XFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const XFlow: FC<FlowProps> = memo(props => {
setCandidateNode,
isAddingNode,
setMousePosition,
copyNodes,
} = useStore(
s => ({
nodes: s.nodes,
Expand All @@ -80,6 +81,7 @@ const XFlow: FC<FlowProps> = memo(props => {
onNodesChange: s.onNodesChange,
onEdgesChange: s.onEdgesChange,
onConnect: s.onConnect,
copyNodes: s.copyNodes,
}),
shallow
);
Expand All @@ -98,6 +100,10 @@ const XFlow: FC<FlowProps> = memo(props => {
setAutoFreeze(false);
return () => {
setAutoFreeze(true);
const { copyTimeoutId } = storeApi.getState();
if (copyTimeoutId) {
clearTimeout(copyTimeoutId);
}
};
}, []);

Expand Down Expand Up @@ -125,6 +131,17 @@ const XFlow: FC<FlowProps> = memo(props => {
pasteNodeSimple();
e.preventDefault();
}
else if (copyNodes.length > 0) {
// 只在有复制节点时才检查其他操作
const { copyTimeoutId } = storeApi.getState();
if (copyTimeoutId) {
clearTimeout(copyTimeoutId);
storeApi.setState({
copyTimeoutId: null,
isAddingNode: false,
});
}
}
});

useEventListener(
Expand All @@ -143,8 +160,33 @@ const XFlow: FC<FlowProps> = memo(props => {
},
{
target: workflowContainerRef.current,
// enable: isAddingNode,
enable: true, // 复制粘贴的时候需要监听鼠标位置
enable: isAddingNode,
// enable: true, // 复制粘贴的时候需要监听鼠标位置
}
);

// 监听点击事件,当用户点击其他地方时清除复制状态
useEventListener(
'click',
e => {
// 如果点击的不是节点或候选节点,清除复制状态
const target = e.target as HTMLElement;
const isClickingNode = target.closest('.xflow-node-container') || target.closest('.candidate-node');

if (!isClickingNode) {
const { copyTimeoutId, copyNodes } = storeApi.getState();
if (copyTimeoutId && copyNodes?.length > 0) {
clearTimeout(copyTimeoutId);
storeApi.setState({
copyTimeoutId: null,
isAddingNode: false,
});
}
}
},
{
target: workflowContainerRef.current,
enable: copyNodes?.length > 0,
}
);

Expand Down
1 change: 1 addition & 0 deletions packages/x-flow/src/components/CandidateNode/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const CandidateNode = () => {

return (
<div
className="candidate-node"
style={{
left: mousePosition?.elementX,
top: mousePosition?.elementY,
Expand Down
1 change: 0 additions & 1 deletion packages/x-flow/src/components/NodeContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export default memo((props: any) => {
const hasBody = !!children;
const hasDesc = !!desc && !hideDesc;
const gradientHeight = _gradientHeight || (hasBody || hasDesc || NodeWidget ? '20%' : '100%');
debugger;

return (
<div
Expand Down
34 changes: 34 additions & 0 deletions packages/x-flow/src/hooks/useFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,37 @@ export const useFlow = () => {
const copyNodes = generateCopyNodes(
storeApi.getState().nodes.find((node) => node.id === nodeId),
);

// 清除之前的超时定时器
if (storeApi.getState().copyTimeoutId) {
clearTimeout(storeApi.getState().copyTimeoutId);
}

// 设置isAddingNode为true,开启mousemove监听
storeApi.getState().setIsAddingNode(true);

// 设置30秒超时,自动关闭mousemove监听
const timeoutId = setTimeout(() => {
storeApi.getState().setIsAddingNode(false);
storeApi.setState({ copyTimeoutId: null });
}, 30000);

storeApi.setState({
copyNodes,
copyTimeoutId: timeoutId,
});
});

const pasteNode = useMemoizedFn((nodeId: string, data: any) => {
if (storeApi.getState().copyNodes.length > 0) {
// 清除超时定时器
if (storeApi.getState().copyTimeoutId) {
clearTimeout(storeApi.getState().copyTimeoutId);
}

// 关闭mousemove监听
storeApi.getState().setIsAddingNode(false);

const newEdges = {
id: uuid(),
source: nodeId,
Expand All @@ -117,6 +141,7 @@ export const useFlow = () => {
storeApi.getState().addEdges(newEdges);
storeApi.setState({
copyNodes: [],
copyTimeoutId: null,
});
}else{
message.warning('请先复制节点!')
Expand All @@ -126,6 +151,14 @@ export const useFlow = () => {
const pasteNodeSimple = useMemoizedFn(() => {
const mousePosition = storeApi.getState().mousePosition;
if (storeApi.getState().copyNodes.length > 0) {
// 清除超时定时器
if (storeApi.getState().copyTimeoutId) {
clearTimeout(storeApi.getState().copyTimeoutId);
}

// 关闭mousemove监听
storeApi.getState().setIsAddingNode(false);

const flowPos = screenToFlowPosition({
x: mousePosition.elementX,
y: mousePosition.elementY,
Expand All @@ -142,6 +175,7 @@ export const useFlow = () => {
// 将清空剪贴板的操作也加入记录,使其可撤销
storeApi.setState({
copyNodes: [],
copyTimeoutId: null,
});
});
} else {
Expand Down
6 changes: 6 additions & 0 deletions packages/x-flow/src/models/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export type FlowState = {
isAddingNode?: boolean;
candidateNode: any;
mousePosition: any;
copyTimeoutId: NodeJS.Timeout | null; // 添加超时定时器ID
onNodesChange: OnNodesChange<FlowNode>;
onEdgesChange: OnEdgesChange;
onConnect: OnConnect;
Expand All @@ -45,6 +46,7 @@ export type FlowState = {
setIsAddingNode: (payload: boolean) => void;
setCandidateNode: (candidateNode: any) => void;
setMousePosition: (mousePosition: any) => void;
setCopyTimeoutId: (timeoutId: NodeJS.Timeout | null) => void; // 添加设置超时定时器的方法
};

const createStore = (initProps?: Partial<FlowProps>) => {
Expand All @@ -64,6 +66,7 @@ const createStore = (initProps?: Partial<FlowProps>) => {
copyEdges: [],
isAddingNode: false,
candidateNode: null,
copyTimeoutId: null, // 添加超时定时器ID初始值
// nodeMenus: [],
mousePosition: { pageX: 0, pageY: 0, elementX: 0, elementY: 0 },
onNodesChange: changes => {
Expand Down Expand Up @@ -106,6 +109,9 @@ const createStore = (initProps?: Partial<FlowProps>) => {
setMousePosition: (mousePosition: any) => {
set({ mousePosition });
},
setCopyTimeoutId: (timeoutId: NodeJS.Timeout | null) => {
set({ copyTimeoutId: timeoutId });
},
setLayout: (layout: 'LR' | 'TB') => {
if (!layout) {
return;
Expand Down
Loading