mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Make data restoration functions immutable
- Make mutations in App component
This commit is contained in:
parent
2ef809fe5d
commit
642a11e380
2 changed files with 63 additions and 39 deletions
|
@ -106,10 +106,16 @@ export class App extends React.Component<{}, AppState> {
|
||||||
document.addEventListener("keydown", this.onKeyDown, false);
|
document.addEventListener("keydown", this.onKeyDown, false);
|
||||||
window.addEventListener("resize", this.onResize, false);
|
window.addEventListener("resize", this.onResize, false);
|
||||||
|
|
||||||
const appState = restoreFromLocalStorage(elements);
|
const { elements: newElements, appState } = restoreFromLocalStorage();
|
||||||
|
|
||||||
|
if (newElements) {
|
||||||
|
elements = newElements;
|
||||||
|
}
|
||||||
|
|
||||||
if (appState) {
|
if (appState) {
|
||||||
this.setState(appState);
|
this.setState(appState);
|
||||||
|
} else {
|
||||||
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +518,10 @@ export class App extends React.Component<{}, AppState> {
|
||||||
}
|
}
|
||||||
onSaveScene={() => saveAsJSON(elements, this.state.name)}
|
onSaveScene={() => saveAsJSON(elements, this.state.name)}
|
||||||
onLoadScene={() =>
|
onLoadScene={() =>
|
||||||
loadFromJSON(elements).then(() => this.forceUpdate())
|
loadFromJSON().then(({ elements: newElements }) => {
|
||||||
|
elements = newElements;
|
||||||
|
this.forceUpdate();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,6 +22,11 @@ function saveFile(name: string, data: string) {
|
||||||
link.remove();
|
link.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DataState {
|
||||||
|
elements: ExcalidrawElement[];
|
||||||
|
appState: any;
|
||||||
|
}
|
||||||
|
|
||||||
export function saveAsJSON(elements: ExcalidrawElement[], name: string) {
|
export function saveAsJSON(elements: ExcalidrawElement[], name: string) {
|
||||||
const serialized = JSON.stringify({
|
const serialized = JSON.stringify({
|
||||||
version: 1,
|
version: 1,
|
||||||
|
@ -35,7 +40,7 @@ export function saveAsJSON(elements: ExcalidrawElement[], name: string) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadFromJSON(elements: ExcalidrawElement[]) {
|
export function loadFromJSON() {
|
||||||
const input = document.createElement("input");
|
const input = document.createElement("input");
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
input.type = "file";
|
input.type = "file";
|
||||||
|
@ -52,12 +57,17 @@ export function loadFromJSON(elements: ExcalidrawElement[]) {
|
||||||
|
|
||||||
input.click();
|
input.click();
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise<DataState>(resolve => {
|
||||||
reader.onloadend = () => {
|
reader.onloadend = () => {
|
||||||
if (reader.readyState === FileReader.DONE) {
|
if (reader.readyState === FileReader.DONE) {
|
||||||
const data = JSON.parse(reader.result as string);
|
let elements = [];
|
||||||
restore(elements, data.elements, null);
|
try {
|
||||||
resolve();
|
const data = JSON.parse(reader.result as string);
|
||||||
|
elements = data.elements || [];
|
||||||
|
} catch (e) {
|
||||||
|
// Do nothing because elements array is already empty
|
||||||
|
}
|
||||||
|
resolve(restore(elements, null));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -130,43 +140,48 @@ export function exportAsPNG(
|
||||||
}
|
}
|
||||||
|
|
||||||
function restore(
|
function restore(
|
||||||
elements: ExcalidrawElement[],
|
savedElements: ExcalidrawElement[],
|
||||||
savedElements: string | ExcalidrawElement[] | null,
|
savedState: any
|
||||||
savedState: string | null
|
): DataState {
|
||||||
) {
|
return {
|
||||||
try {
|
elements: savedElements.map(element => ({
|
||||||
if (savedElements) {
|
...element,
|
||||||
elements.splice(
|
id: element.id || nanoid(),
|
||||||
0,
|
fillStyle: element.fillStyle || "hachure",
|
||||||
elements.length,
|
strokeWidth: element.strokeWidth || 1,
|
||||||
...(typeof savedElements === "string"
|
roughness: element.roughness || 1,
|
||||||
? JSON.parse(savedElements)
|
opacity:
|
||||||
: savedElements)
|
element.opacity === null || element.opacity === undefined
|
||||||
);
|
? 100
|
||||||
elements.forEach((element: ExcalidrawElement) => {
|
: element.opacity
|
||||||
element.id = element.id || nanoid();
|
})),
|
||||||
element.fillStyle = element.fillStyle || "hachure";
|
appState: savedState
|
||||||
element.strokeWidth = element.strokeWidth || 1;
|
};
|
||||||
element.roughness = element.roughness || 1;
|
|
||||||
element.opacity =
|
|
||||||
element.opacity === null || element.opacity === undefined
|
|
||||||
? 100
|
|
||||||
: element.opacity;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return savedState ? JSON.parse(savedState) : null;
|
|
||||||
} catch (e) {
|
|
||||||
elements.splice(0, elements.length);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function restoreFromLocalStorage(elements: ExcalidrawElement[]) {
|
export function restoreFromLocalStorage() {
|
||||||
const savedElements = localStorage.getItem(LOCAL_STORAGE_KEY);
|
const savedElements = localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||||
const savedState = localStorage.getItem(LOCAL_STORAGE_KEY_STATE);
|
const savedState = localStorage.getItem(LOCAL_STORAGE_KEY_STATE);
|
||||||
|
|
||||||
return restore(elements, savedElements, savedState);
|
let elements = [];
|
||||||
|
if (savedElements) {
|
||||||
|
try {
|
||||||
|
elements = JSON.parse(savedElements);
|
||||||
|
} catch (e) {
|
||||||
|
// Do nothing because elements array is already empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let appState = null;
|
||||||
|
if (savedState) {
|
||||||
|
try {
|
||||||
|
appState = JSON.parse(savedState);
|
||||||
|
} catch (e) {
|
||||||
|
// Do nothing because appState is already null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return restore(elements, appState);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function saveToLocalStorage(
|
export function saveToLocalStorage(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue