mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Action duplication binding fix 1st iter
This commit is contained in:
parent
99d8bff175
commit
9cc4ea6ba6
2 changed files with 107 additions and 8 deletions
|
@ -2,7 +2,6 @@ import { ToolButton } from "../components/ToolButton";
|
||||||
import { DuplicateIcon } from "../components/icons";
|
import { DuplicateIcon } from "../components/icons";
|
||||||
import { DEFAULT_GRID_SIZE } from "../constants";
|
import { DEFAULT_GRID_SIZE } from "../constants";
|
||||||
import { duplicateElement, getNonDeletedElements } from "../element";
|
import { duplicateElement, getNonDeletedElements } from "../element";
|
||||||
import { fixBindingsAfterDuplication } from "../element/binding";
|
|
||||||
import {
|
import {
|
||||||
bindTextToShapeAfterDuplication,
|
bindTextToShapeAfterDuplication,
|
||||||
getBoundTextElement,
|
getBoundTextElement,
|
||||||
|
@ -10,6 +9,8 @@ import {
|
||||||
} from "../element/textElement";
|
} from "../element/textElement";
|
||||||
import {
|
import {
|
||||||
hasBoundTextElement,
|
hasBoundTextElement,
|
||||||
|
isArrowElement,
|
||||||
|
isBindableElement,
|
||||||
isBoundToContainer,
|
isBoundToContainer,
|
||||||
isFrameLikeElement,
|
isFrameLikeElement,
|
||||||
} from "../element/typeChecks";
|
} from "../element/typeChecks";
|
||||||
|
@ -40,11 +41,18 @@ import {
|
||||||
invariant,
|
invariant,
|
||||||
} from "../utils";
|
} from "../utils";
|
||||||
|
|
||||||
|
import { type ElementUpdate, mutateElement } from "../element/mutateElement";
|
||||||
|
|
||||||
import { register } from "./register";
|
import { register } from "./register";
|
||||||
|
|
||||||
import type { ActionResult } from "./types";
|
import type { ActionResult } from "./types";
|
||||||
import type { ExcalidrawElement } from "../element/types";
|
import type {
|
||||||
|
BoundElement,
|
||||||
|
ExcalidrawArrowElement,
|
||||||
|
ExcalidrawElement,
|
||||||
|
} from "../element/types";
|
||||||
import type { AppState } from "../types";
|
import type { AppState } from "../types";
|
||||||
|
import type { Mutable } from "../utility-types";
|
||||||
|
|
||||||
export const actionDuplicateSelection = register({
|
export const actionDuplicateSelection = register({
|
||||||
name: "duplicateSelection",
|
name: "duplicateSelection",
|
||||||
|
@ -325,11 +333,103 @@ const duplicateElements = (
|
||||||
oldElements,
|
oldElements,
|
||||||
oldIdToDuplicatedId,
|
oldIdToDuplicatedId,
|
||||||
);
|
);
|
||||||
fixBindingsAfterDuplication(
|
// fixBindingsAfterDuplication(
|
||||||
elementsWithClones,
|
// elementsWithClones,
|
||||||
oldElements,
|
// oldElements,
|
||||||
oldIdToDuplicatedId,
|
// oldIdToDuplicatedId,
|
||||||
);
|
// );
|
||||||
|
|
||||||
|
newElements
|
||||||
|
.map((element) => {
|
||||||
|
oldElements.includes(element) && console.error("oldElements", element);
|
||||||
|
|
||||||
|
if (isArrowElement(element)) {
|
||||||
|
const updates: Mutable<ElementUpdate<ExcalidrawArrowElement>> = {};
|
||||||
|
|
||||||
|
if (element.startBinding) {
|
||||||
|
const startCloneElementId = oldIdToDuplicatedId.get(
|
||||||
|
element.startBinding.elementId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (startCloneElementId) {
|
||||||
|
// The connected element was duplicated, so we need to update the binding
|
||||||
|
updates.startBinding = {
|
||||||
|
...element.startBinding,
|
||||||
|
elementId: startCloneElementId,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// The connected element was not duplicated, so we need to remove the binding
|
||||||
|
updates.startBinding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.endBinding) {
|
||||||
|
const endCloneElementId = oldIdToDuplicatedId.get(
|
||||||
|
element.endBinding.elementId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (endCloneElementId) {
|
||||||
|
// The connected element was duplicated, so we need to update the binding
|
||||||
|
updates.endBinding = {
|
||||||
|
...element.endBinding,
|
||||||
|
elementId: endCloneElementId,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// The connected element was not duplicated, so we need to remove the binding
|
||||||
|
updates.endBinding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(updates).length > 0) {
|
||||||
|
// Only update the element if there are updates to apply
|
||||||
|
return {
|
||||||
|
element,
|
||||||
|
updates,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (isBindableElement(element)) {
|
||||||
|
if (element.boundElements?.length) {
|
||||||
|
const clonedBoundElements = element.boundElements
|
||||||
|
?.map((definition) => {
|
||||||
|
const clonedBoundElementId = oldIdToDuplicatedId.get(
|
||||||
|
definition.id,
|
||||||
|
);
|
||||||
|
if (clonedBoundElementId) {
|
||||||
|
// The connected element was duplicated, so we need to update the binding
|
||||||
|
return {
|
||||||
|
...definition,
|
||||||
|
id: clonedBoundElementId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// The connected element was not duplicated, so we need to remove the binding
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.filter(
|
||||||
|
(definition): definition is BoundElement => definition !== null,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (clonedBoundElements?.length) {
|
||||||
|
return {
|
||||||
|
element,
|
||||||
|
updates: {
|
||||||
|
boundElements: clonedBoundElements,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.forEach((change) => {
|
||||||
|
if (!change) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutateElement(change.element, change.updates);
|
||||||
|
});
|
||||||
|
|
||||||
bindElementsToFramesAfterDuplication(
|
bindElementsToFramesAfterDuplication(
|
||||||
elementsWithClones,
|
elementsWithClones,
|
||||||
oldElements,
|
oldElements,
|
||||||
|
|
|
@ -658,7 +658,6 @@ export const duplicateElement = <TElement extends ExcalidrawElement>(
|
||||||
}
|
}
|
||||||
|
|
||||||
copy.id = regenerateId();
|
copy.id = regenerateId();
|
||||||
copy.boundElements = null;
|
|
||||||
copy.updated = getUpdatedTimestamp();
|
copy.updated = getUpdatedTimestamp();
|
||||||
copy.seed = randomInteger();
|
copy.seed = randomInteger();
|
||||||
copy.groupIds = getNewGroupIdsForDuplication(
|
copy.groupIds = getNewGroupIdsForDuplication(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue