refactoring useUndoRedo component

This commit is contained in:
2025-10-27 16:10:47 +05:30
parent 8a4d677b02
commit a7ead0d8d1
5 changed files with 33 additions and 15 deletions

View File

@@ -1,4 +1,4 @@
import { UndoRedoProvider } from "./UndoRedoContext"; import { UndoRedoProvider } from "./components/undoRedo/UndoRedoContext";
import SceneView from "./pages/SceneView"; import SceneView from "./pages/SceneView";
import "./styles/main.scss"; import "./styles/main.scss";

View File

@@ -4,7 +4,7 @@ import TreeNode from "./TreeNode";
import Search from "./Search"; import Search from "./Search";
import { AddIcon, ChevronIcon, CollapseAllIcon } from "../../icons/ExportIcons"; import { AddIcon, ChevronIcon, CollapseAllIcon } from "../../icons/ExportIcons";
import type { OutlinePanelProps } from "./OutlinePanel"; import type { OutlinePanelProps } from "./OutlinePanel";
import { useUndoRedo } from "../../useUndoRedo"; import { useUndoRedo } from "../undoRedo/useUndoRedo";
import { DEFAULT_PRAMS, type AssetGroupChild } from "../../data/OutlineListData"; import { DEFAULT_PRAMS, type AssetGroupChild } from "../../data/OutlineListData";
@@ -21,7 +21,7 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
width, width,
search, search,
data, data,
onDrop, // onDrop,
onDragOver, onDragOver,
onRename, onRename,
onDragStart, onDragStart,
@@ -104,23 +104,32 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
setDraggedNode(null); setDraggedNode(null);
return; return;
} }
const prevHierarchy = structuredClone(hierarchy); const prevHierarchy = structuredClone(hierarchy);
const updatedHierarchy = [...hierarchy]; const updatedHierarchy = structuredClone(hierarchy);
if (!removeFromHierarchy(draggedItem, updatedHierarchy)) return; // ✅ Determine which items to move
const itemsToMove =
selectedObjects && selectedObjects.length > 1 ? selectedObjects : [draggedItem];
if (!insertByDropAction(draggedItem, targetId, dropAction, updatedHierarchy)) { // ✅ Remove and insert each dragged item
updatedHierarchy.push(draggedItem); for (const item of itemsToMove) {
if (!removeFromHierarchy(item, updatedHierarchy)) continue;
if (!insertByDropAction(item, targetId, dropAction, updatedHierarchy)) {
updatedHierarchy.push(item);
}
} }
addAction({ addAction({
do: () => setHierarchy(updatedHierarchy), do: () => setHierarchy(updatedHierarchy),
undo: () => setHierarchy(prevHierarchy), undo: () => setHierarchy(prevHierarchy),
}); });
setHierarchy(updatedHierarchy); setHierarchy(updatedHierarchy);
if (onDrop) onDrop(updatedHierarchy);
setDraggedNode(null); setDraggedNode(null);
clearAllHighlights(); clearAllHighlights();
setSelectedObject(null);
setSelectedObjects([]);
}; };
const getDropZone = (y: number): DropAction => { const getDropZone = (y: number): DropAction => {
@@ -252,12 +261,14 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
}); });
const newHierarchy = updateNodeName(structuredClone(hierarchy)); const newHierarchy = updateNodeName(structuredClone(hierarchy));
setHierarchy(newHierarchy);
if (onRename) onRename(id, newName); if (onRename) onRename(id, newName);
addAction({ addAction({
do: () => setHierarchy(newHierarchy), do: () => setHierarchy(newHierarchy),
undo: () => setHierarchy(prevHierarchy), undo: () => setHierarchy(prevHierarchy),
}); });
}; };
useEffect(() => { useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => { const handleKeyDown = (e: KeyboardEvent) => {
if (e.ctrlKey && e.key.toLowerCase() === "z") { if (e.ctrlKey && e.key.toLowerCase() === "z") {

View File

@@ -10,6 +10,7 @@ import {
LockIcon, LockIcon,
} from "../../icons/ExportIcons"; } from "../../icons/ExportIcons";
import { DEFAULT_PRAMS, type AssetGroupChild } from "../../data/OutlineListData"; import { DEFAULT_PRAMS, type AssetGroupChild } from "../../data/OutlineListData";
import { useUndoRedo } from "../undoRedo/useUndoRedo";
interface TreeNodeProps { interface TreeNodeProps {
item: AssetGroupChild; item: AssetGroupChild;
@@ -30,7 +31,6 @@ interface TreeNodeProps {
setSelectedObjects: React.Dispatch<React.SetStateAction<AssetGroupChild[] | []>>; setSelectedObjects: React.Dispatch<React.SetStateAction<AssetGroupChild[] | []>>;
setHierarchy: React.Dispatch<React.SetStateAction<AssetGroupChild[] | []>>; setHierarchy: React.Dispatch<React.SetStateAction<AssetGroupChild[] | []>>;
setDraggedItems: React.Dispatch<React.SetStateAction<AssetGroupChild[] | []>>; setDraggedItems: React.Dispatch<React.SetStateAction<AssetGroupChild[] | []>>;
pushHistory?: (newHierarchy: AssetGroupChild[]) => void;
} }
const TreeNode: React.FC<TreeNodeProps> = ({ const TreeNode: React.FC<TreeNodeProps> = ({
@@ -50,7 +50,6 @@ const TreeNode: React.FC<TreeNodeProps> = ({
selectedObjects, selectedObjects,
setDraggedItems, setDraggedItems,
draggedItems, draggedItems,
pushHistory,
setHierarchy, setHierarchy,
hierarchy, hierarchy,
}) => { }) => {
@@ -59,7 +58,7 @@ const TreeNode: React.FC<TreeNodeProps> = ({
const [isExpanded, setIsExpanded] = useState(item.isExpanded || false); const [isExpanded, setIsExpanded] = useState(item.isExpanded || false);
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const [name, setName] = useState(item.groupName || item.modelName); const [name, setName] = useState(item.groupName || item.modelName);
const { addAction } = useUndoRedo();
const handleDragStart = (e: React.DragEvent) => { const handleDragStart = (e: React.DragEvent) => {
e.stopPropagation(); e.stopPropagation();
onDragStart(item); onDragStart(item);
@@ -141,7 +140,7 @@ const TreeNode: React.FC<TreeNodeProps> = ({
const handleToggleVisibility = (e: React.MouseEvent) => { const handleToggleVisibility = (e: React.MouseEvent) => {
e.stopPropagation(); e.stopPropagation();
const prevHierarchy = structuredClone(hierarchy);
const updatedHierarchy = structuredClone(hierarchy); const updatedHierarchy = structuredClone(hierarchy);
const targetIds = selectedObjects.length const targetIds = selectedObjects.length
? selectedObjects.map((obj) => obj.modelUuid || obj.groupUuid) ? selectedObjects.map((obj) => obj.modelUuid || obj.groupUuid)
@@ -158,12 +157,16 @@ const TreeNode: React.FC<TreeNodeProps> = ({
}; };
toggleVisibilityRecursive(updatedHierarchy); toggleVisibilityRecursive(updatedHierarchy);
pushHistory?.(updatedHierarchy);
setHierarchy(updatedHierarchy); setHierarchy(updatedHierarchy);
addAction({
do: () => setHierarchy(updatedHierarchy),
undo: () => setHierarchy(prevHierarchy),
});
}; };
const handleToggleLock = (e: React.MouseEvent) => { const handleToggleLock = (e: React.MouseEvent) => {
e.stopPropagation(); e.stopPropagation();
const prevHierarchy = structuredClone(hierarchy);
const updatedHierarchy = structuredClone(hierarchy); const updatedHierarchy = structuredClone(hierarchy);
const targetIds = selectedObjects.length const targetIds = selectedObjects.length
? selectedObjects.map((obj) => obj.modelUuid || obj.groupUuid) ? selectedObjects.map((obj) => obj.modelUuid || obj.groupUuid)
@@ -180,8 +183,12 @@ const TreeNode: React.FC<TreeNodeProps> = ({
}; };
toggleLockRecursive(updatedHierarchy); toggleLockRecursive(updatedHierarchy);
pushHistory?.(updatedHierarchy);
setHierarchy(updatedHierarchy); setHierarchy(updatedHierarchy);
addAction({
do: () => setHierarchy(updatedHierarchy),
undo: () => setHierarchy(prevHierarchy),
});
}; };
useEffect(() => { useEffect(() => {