mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
feat(frontend): Add minimum movement threshold for node position history tracking (#11481)
This PR implements a minimum movement threshold of 50 pixels for node position changes before they are logged to the history system. This prevents the undo/redo history from being cluttered with minor, unintentional movements that occur when users interact with block inputs or accidentally nudge nodes. ### Changes 🏗️ - **Added movement threshold for history tracking**: Implemented a 50px minimum movement requirement before logging node position changes to history - **Prevents history spam**: Stops small, unintentional movements (like clicking on inputs inside blocks) from cluttering the undo/redo history - **Tracks drag start positions**: Maintains initial positions when dragging begins to accurately calculate total movement distance - **Improved history management**: Only significant node movements are now recorded, matching the behavior of the old builder - **Memory efficient**: Cleans up tracked positions after drag operations complete ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Drag a node less than 50px and verify no history entry is created - [x] Drag a node more than 50px and verify history entry is created - [x] Click on inputs inside blocks and verify no history entries are created - [x] Test undo/redo functionality works correctly with the threshold - [x] Verify adding/removing nodes still creates history entries - [x] Test multiple nodes being dragged simultaneously
This commit is contained in:
@@ -13,6 +13,13 @@ import { useHistoryStore } from "./historyStore";
|
||||
import { useEdgeStore } from "./edgeStore";
|
||||
import { BlockUIType } from "../components/types";
|
||||
|
||||
// Minimum movement (in pixels) required before logging position change to history
|
||||
// Prevents spamming history with small movements when clicking on inputs inside blocks
|
||||
const MINIMUM_MOVE_BEFORE_LOG = 50;
|
||||
|
||||
// Track initial positions when drag starts (outside store to avoid re-renders)
|
||||
const dragStartPositions: Record<string, XYPosition> = {};
|
||||
|
||||
type NodeStore = {
|
||||
nodes: CustomNode[];
|
||||
nodeCounter: number;
|
||||
@@ -61,12 +68,44 @@ export const useNodeStore = create<NodeStore>((set, get) => ({
|
||||
nodes: get().nodes,
|
||||
edges: useEdgeStore.getState().edges,
|
||||
};
|
||||
const shouldTrack = changes.some(
|
||||
(change) =>
|
||||
change.type === "remove" ||
|
||||
change.type === "add" ||
|
||||
(change.type === "position" && change.dragging === false),
|
||||
|
||||
// Track initial positions when drag starts
|
||||
changes.forEach((change) => {
|
||||
if (change.type === "position" && change.dragging === true) {
|
||||
if (!dragStartPositions[change.id]) {
|
||||
const node = get().nodes.find((n) => n.id === change.id);
|
||||
if (node) {
|
||||
dragStartPositions[change.id] = { ...node.position };
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Check if we should track this change in history
|
||||
let shouldTrack = changes.some(
|
||||
(change) => change.type === "remove" || change.type === "add",
|
||||
);
|
||||
|
||||
// For position changes, only track if movement exceeds threshold
|
||||
if (!shouldTrack) {
|
||||
changes.forEach((change) => {
|
||||
if (change.type === "position" && change.dragging === false) {
|
||||
const startPos = dragStartPositions[change.id];
|
||||
if (startPos && change.position) {
|
||||
const distanceMoved = Math.sqrt(
|
||||
Math.pow(change.position.x - startPos.x, 2) +
|
||||
Math.pow(change.position.y - startPos.y, 2),
|
||||
);
|
||||
if (distanceMoved > MINIMUM_MOVE_BEFORE_LOG) {
|
||||
shouldTrack = true;
|
||||
}
|
||||
}
|
||||
// Clean up tracked position after drag ends
|
||||
delete dragStartPositions[change.id];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
set((state) => ({
|
||||
nodes: applyNodeChanges(changes, state.nodes),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user