Fix many syncing issues (#952)

This commit is contained in:
Pete Hunt 2020-03-14 20:46:57 -07:00 committed by GitHub
parent b20d4539c0
commit 3f8144ef85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 176 additions and 100 deletions

View file

@ -1,3 +1,6 @@
import { ExcalidrawElement } from "./types";
import { isInvisiblySmallElement } from "./sizeHelpers";
export { newElement, newTextElement, duplicateElement } from "./newElement";
export {
getElementAbsoluteCoords,
@ -24,3 +27,28 @@ export {
normalizeDimensions,
} from "./sizeHelpers";
export { showSelectedShapeActions } from "./showSelectedShapeActions";
export function getSyncableElements(elements: readonly ExcalidrawElement[]) {
// There are places in Excalidraw where synthetic invisibly small elements are added and removed.
// It's probably best to keep those local otherwise there might be a race condition that
// gets the app into an invalid state. I've never seen it happen but I'm worried about it :)
return elements.filter(el => !isInvisiblySmallElement(el));
}
export function getElementMap(elements: readonly ExcalidrawElement[]) {
return getSyncableElements(elements).reduce(
(acc: { [key: string]: ExcalidrawElement }, element: ExcalidrawElement) => {
acc[element.id] = element;
return acc;
},
{},
);
}
export function getDrawingVersion(elements: readonly ExcalidrawElement[]) {
return elements.reduce((acc, el) => acc + el.version, 0);
}
export function hasNonDeletedElements(elements: readonly ExcalidrawElement[]) {
return elements.some(element => !element.isDeleted);
}

View file

@ -1,4 +1,5 @@
import { ExcalidrawElement, ExcalidrawTextElement } from "./types";
import { randomSeed } from "roughjs/bin/math";
type ElementUpdate<TElement extends ExcalidrawElement> = Omit<
Partial<TElement>,
@ -10,17 +11,25 @@ type ElementUpdate<TElement extends ExcalidrawElement> = Omit<
// the same drawing.
export function mutateElement(
element: ExcalidrawElement,
updates: ElementUpdate<ExcalidrawElement>,
updates?: ElementUpdate<ExcalidrawElement>,
) {
Object.assign(element, updates);
if (updates) {
Object.assign(element, updates);
}
(element as any).version++;
(element as any).versionNonce = randomSeed();
}
export function newElementWith(
element: ExcalidrawElement,
updates: ElementUpdate<ExcalidrawElement>,
): ExcalidrawElement {
return { ...element, ...updates, version: element.version + 1 };
return {
...element,
...updates,
version: element.version + 1,
versionNonce: randomSeed(),
};
}
// This function tracks updates of text elements for the purposes for collaboration.
@ -32,11 +41,17 @@ export function mutateTextElement(
): void {
Object.assign(element, updates);
(element as any).version++;
(element as any).versionNonce = randomSeed();
}
export function newTextElementWith(
element: ExcalidrawTextElement,
updates: ElementUpdate<ExcalidrawTextElement>,
): ExcalidrawTextElement {
return { ...element, ...updates, version: element.version + 1 };
return {
...element,
...updates,
version: element.version + 1,
versionNonce: randomSeed(),
};
}

View file

@ -34,6 +34,8 @@ export function newElement(
seed: randomSeed(),
points: [] as Point[],
version: 1,
versionNonce: 0,
isDeleted: false,
};
return element;
}