feat: bump element version on z-index change (#3483)

* feat: bump element version on z-index change

* update snaps

* update changelog
This commit is contained in:
David Luzar 2021-04-25 14:09:38 +02:00 committed by GitHub
parent 5cc3f7db80
commit 4ef7cb7365
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 26 deletions

View File

@ -114,3 +114,14 @@ export const newElementWith = <TElement extends ExcalidrawElement>(
versionNonce: randomInteger(),
};
};
/**
* Mutates element and updates `version` & `versionNonce`.
*
* NOTE: does not trigger re-render.
*/
export const bumpVersion = (element: Mutable<ExcalidrawElement>) => {
element.version = element.version + 1;
element.versionNonce = randomInteger();
return element;
};

View File

@ -44,9 +44,9 @@ Please add the latest change on the top under the correct section.
### Fixes
- Changing z-index of elements (sorting them below/above other elements) now updates their `version` and `versionNonce` (only applies to the selected elements). This fix will allow you account for z-index changes if you're syncing just the elements that changed (and not the whole scene) [#3483](https://github.com/excalidraw/excalidraw/pull/3483).
- Only handle cut/paste events inside excalidraw [#3484](https://github.com/excalidraw/excalidraw/pull/3484).
- Make history local to a given Excalidraw instance. This fixes a case where history was getting shared when you have multiple Excalidraw components on the same page [#3481](https://github.com/excalidraw/excalidraw/pull/3481).
- Use active Excalidraw component when editing text. This fixes a case where text editing was not working when you have multiple Excalidraw components on the same page [#3478](https://github.com/excalidraw/excalidraw/pull/3478).
- When switching theme, apply it only to the active Excalidraw component. This fixes a case where the theme was getting applied to the first Excalidraw component if you had multiple Excalidraw components on the same page [#3446](https://github.com/excalidraw/excalidraw/pull/3446)

View File

@ -287,8 +287,8 @@ Object {
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 2,
"versionNonce": 449462985,
"version": 3,
"versionNonce": 2019559783,
"width": 20,
"x": -10,
"y": 0,
@ -456,8 +456,8 @@ Object {
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 2,
"versionNonce": 449462985,
"version": 3,
"versionNonce": 2019559783,
"width": 20,
"x": -10,
"y": 0,
@ -595,8 +595,8 @@ Object {
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 2,
"versionNonce": 449462985,
"version": 3,
"versionNonce": 2019559783,
"width": 20,
"x": -10,
"y": 0,
@ -764,8 +764,8 @@ Object {
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 2,
"versionNonce": 449462985,
"version": 3,
"versionNonce": 2019559783,
"width": 20,
"x": -10,
"y": 0,
@ -2531,8 +2531,8 @@ Object {
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 2,
"versionNonce": 401146281,
"version": 3,
"versionNonce": 2019559783,
"width": 20,
"x": 20,
"y": 30,
@ -2703,8 +2703,8 @@ Object {
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 2,
"versionNonce": 401146281,
"version": 3,
"versionNonce": 2019559783,
"width": 20,
"x": 20,
"y": 30,
@ -2839,8 +2839,8 @@ Object {
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 2,
"versionNonce": 401146281,
"version": 3,
"versionNonce": 2019559783,
"width": 20,
"x": 20,
"y": 30,
@ -3011,8 +3011,8 @@ Object {
"strokeStyle": "solid",
"strokeWidth": 1,
"type": "rectangle",
"version": 2,
"versionNonce": 401146281,
"version": 3,
"versionNonce": 2019559783,
"width": 20,
"x": 20,
"y": 30,

View File

@ -1,3 +1,4 @@
import { bumpVersion } from "./element/mutateElement";
import { ExcalidrawElement } from "./element/types";
import { getElementsInGroup } from "./groups";
import { AppState } from "./types";
@ -51,7 +52,7 @@ const toContiguousGroups = (array: number[]) => {
*/
const getTargetIndex = (
appState: AppState,
elements: ExcalidrawElement[],
elements: readonly ExcalidrawElement[],
boundaryIndex: number,
direction: "left" | "right",
) => {
@ -117,12 +118,24 @@ const getTargetIndex = (
return candidateIndex;
};
const getTargetElementsMap = (
elements: readonly ExcalidrawElement[],
indices: number[],
) => {
return indices.reduce((acc, index) => {
const element = elements[index];
acc[element.id] = element;
return acc;
}, {} as Record<string, ExcalidrawElement>);
};
const shiftElements = (
appState: AppState,
elements: ExcalidrawElement[],
elements: readonly ExcalidrawElement[],
direction: "left" | "right",
) => {
const indicesToMove = getIndicesToMove(elements, appState);
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
let groupedIndices = toContiguousGroups(indicesToMove);
if (direction === "right") {
@ -175,7 +188,12 @@ const shiftElements = (
];
});
return elements;
return elements.map((element) => {
if (targetElementsMap[element.id]) {
return bumpVersion(element);
}
return element;
});
};
const shiftElementsToEnd = (
@ -184,7 +202,7 @@ const shiftElementsToEnd = (
direction: "left" | "right",
) => {
const indicesToMove = getIndicesToMove(elements, appState);
const targetElements: ExcalidrawElement[] = [];
const targetElementsMap = getTargetElementsMap(elements, indicesToMove);
const displacedElements: ExcalidrawElement[] = [];
let leadingIndex: number;
@ -222,13 +240,15 @@ const shiftElementsToEnd = (
}
for (let index = leadingIndex; index < trailingIndex + 1; index++) {
if (indicesToMove.includes(index)) {
targetElements.push(elements[index]);
} else {
if (!indicesToMove.includes(index)) {
displacedElements.push(elements[index]);
}
}
const targetElements = Object.values(targetElementsMap).map((element) => {
return bumpVersion(element);
});
const leadingElements = elements.slice(0, leadingIndex);
const trailingElements = elements.slice(trailingIndex + 1);
@ -254,14 +274,14 @@ export const moveOneLeft = (
elements: readonly ExcalidrawElement[],
appState: AppState,
) => {
return shiftElements(appState, elements.slice(), "left");
return shiftElements(appState, elements, "left");
};
export const moveOneRight = (
elements: readonly ExcalidrawElement[],
appState: AppState,
) => {
return shiftElements(appState, elements.slice(), "right");
return shiftElements(appState, elements, "right");
};
export const moveAllLeft = (