Make data restoration functions immutable

- Make mutations in App component
This commit is contained in:
Gasim Gasimzada 2020-01-09 12:45:25 +04:00
parent 2ef809fe5d
commit 642a11e380
2 changed files with 63 additions and 39 deletions

View file

@ -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>

View file

@ -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) {
let elements = [];
try {
const data = JSON.parse(reader.result as string); const data = JSON.parse(reader.result as string);
restore(elements, data.elements, null); elements = data.elements || [];
resolve(); } 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)
);
elements.forEach((element: ExcalidrawElement) => {
element.id = element.id || nanoid();
element.fillStyle = element.fillStyle || "hachure";
element.strokeWidth = element.strokeWidth || 1;
element.roughness = element.roughness || 1;
element.opacity =
element.opacity === null || element.opacity === undefined element.opacity === null || element.opacity === undefined
? 100 ? 100
: element.opacity; : element.opacity
}); })),
} appState: savedState
};
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(