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);
window.addEventListener("resize", this.onResize, false);
const appState = restoreFromLocalStorage(elements);
const { elements: newElements, appState } = restoreFromLocalStorage();
if (newElements) {
elements = newElements;
}
if (appState) {
this.setState(appState);
} else {
this.forceUpdate();
}
}
@ -512,7 +518,10 @@ export class App extends React.Component<{}, AppState> {
}
onSaveScene={() => saveAsJSON(elements, this.state.name)}
onLoadScene={() =>
loadFromJSON(elements).then(() => this.forceUpdate())
loadFromJSON().then(({ elements: newElements }) => {
elements = newElements;
this.forceUpdate();
})
}
/>
</div>

View file

@ -22,6 +22,11 @@ function saveFile(name: string, data: string) {
link.remove();
}
interface DataState {
elements: ExcalidrawElement[];
appState: any;
}
export function saveAsJSON(elements: ExcalidrawElement[], name: string) {
const serialized = JSON.stringify({
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 reader = new FileReader();
input.type = "file";
@ -52,12 +57,17 @@ export function loadFromJSON(elements: ExcalidrawElement[]) {
input.click();
return new Promise(resolve => {
return new Promise<DataState>(resolve => {
reader.onloadend = () => {
if (reader.readyState === FileReader.DONE) {
let elements = [];
try {
const data = JSON.parse(reader.result as string);
restore(elements, data.elements, null);
resolve();
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(
elements: ExcalidrawElement[],
savedElements: string | ExcalidrawElement[] | null,
savedState: string | null
) {
try {
if (savedElements) {
elements.splice(
0,
elements.length,
...(typeof savedElements === "string"
? JSON.parse(savedElements)
: 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 =
savedElements: ExcalidrawElement[],
savedState: any
): DataState {
return {
elements: savedElements.map(element => ({
...element,
id: element.id || nanoid(),
fillStyle: element.fillStyle || "hachure",
strokeWidth: element.strokeWidth || 1,
roughness: element.roughness || 1,
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;
}
: element.opacity
})),
appState: savedState
};
}
export function restoreFromLocalStorage(elements: ExcalidrawElement[]) {
export function restoreFromLocalStorage() {
const savedElements = localStorage.getItem(LOCAL_STORAGE_KEY);
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(