refactor: improve types around dataState and libraryData (#3427)

This commit is contained in:
David Luzar 2021-04-10 19:17:49 +02:00 committed by GitHub
parent c19c8ecd27
commit a7cbe68ae8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 84 additions and 55 deletions

View file

@ -7,7 +7,7 @@ import { calculateScrollCenter } from "../scene";
import { AppState } from "../types";
import { isValidExcalidrawData } from "./json";
import { restore } from "./restore";
import { LibraryData } from "./types";
import { ImportedLibraryData } from "./types";
const parseFileContents = async (blob: Blob | File) => {
let contents: string;
@ -114,7 +114,7 @@ export const loadFromBlob = async (
export const loadLibraryFromBlob = async (blob: Blob) => {
const contents = await parseFileContents(blob);
const data: LibraryData = JSON.parse(contents);
const data: ImportedLibraryData = JSON.parse(contents);
if (data.type !== EXPORT_DATA_TYPES.excalidrawLibrary) {
throw new Error(t("alerts.couldNotLoadInvalidFile"));
}

View file

@ -1,28 +1,31 @@
import { fileOpen, fileSave } from "browser-fs-access";
import { cleanAppStateForExport } from "../appState";
import { EXPORT_DATA_TYPES, MIME_TYPES } from "../constants";
import { EXPORT_DATA_TYPES, EXPORT_SOURCE, MIME_TYPES } from "../constants";
import { clearElementsForExport } from "../element";
import { ExcalidrawElement } from "../element/types";
import { AppState } from "../types";
import { loadFromBlob } from "./blob";
import { Library } from "./library";
import { ImportedDataState } from "./types";
import {
ExportedDataState,
ImportedDataState,
ExportedLibraryData,
} from "./types";
export const serializeAsJSON = (
elements: readonly ExcalidrawElement[],
appState: AppState,
): string =>
JSON.stringify(
{
type: EXPORT_DATA_TYPES.excalidraw,
version: 2,
source: window.location.origin,
elements: clearElementsForExport(elements),
appState: cleanAppStateForExport(appState),
},
null,
2,
);
): string => {
const data: ExportedDataState = {
type: EXPORT_DATA_TYPES.excalidraw,
version: 2,
source: EXPORT_SOURCE,
elements: clearElementsForExport(elements),
appState: cleanAppStateForExport(appState),
};
return JSON.stringify(data, null, 2);
};
export const saveAsJSON = async (
elements: readonly ExcalidrawElement[],
@ -87,15 +90,13 @@ export const isValidLibrary = (json: any) => {
export const saveLibraryAsJSON = async () => {
const library = await Library.loadLibrary();
const serialized = JSON.stringify(
{
type: EXPORT_DATA_TYPES.excalidrawLibrary,
version: 1,
library,
},
null,
2,
);
const data: ExportedLibraryData = {
type: EXPORT_DATA_TYPES.excalidrawLibrary,
version: 1,
source: EXPORT_SOURCE,
library,
};
const serialized = JSON.stringify(data, null, 2);
const fileName = "library.excalidrawlib";
const blob = new Blob([serialized], {
type: MIME_TYPES.excalidrawlib,

View file

@ -4,7 +4,7 @@ import {
ExcalidrawSelectionElement,
} from "../element/types";
import { AppState, NormalizedZoomValue } from "../types";
import { DataState, ImportedDataState } from "./types";
import { ImportedDataState } from "./types";
import { isInvisiblySmallElement, getNormalizedDimensions } from "../element";
import { isLinearElementType } from "../element/typeChecks";
import { randomId } from "../random";
@ -16,6 +16,16 @@ import {
} from "../constants";
import { getDefaultAppState } from "../appState";
type RestoredAppState = Omit<
AppState,
"offsetTop" | "offsetLeft" | "width" | "height"
>;
export type RestoredDataState = {
elements: ExcalidrawElement[];
appState: RestoredAppState;
};
const getFontFamilyByName = (fontFamilyName: string): FontFamily => {
for (const [id, fontFamilyString] of Object.entries(FONT_FAMILY)) {
if (fontFamilyString.includes(fontFamilyName)) {
@ -144,7 +154,7 @@ export const restoreElements = (
export const restoreAppState = (
appState: ImportedDataState["appState"],
localAppState: Partial<AppState> | null,
): DataState["appState"] => {
): RestoredAppState => {
appState = appState || {};
const defaultAppState = getDefaultAppState();
@ -186,7 +196,7 @@ export const restore = (
* Supply `null` if you can't get access to it.
*/
localAppState: Partial<AppState> | null | undefined,
): DataState => {
): RestoredDataState => {
return {
elements: restoreElements(data?.elements),
appState: restoreAppState(data?.appState, localAppState || null),

View file

@ -1,26 +1,29 @@
import { ExcalidrawElement } from "../element/types";
import { AppState, LibraryItems } from "../types";
import type { cleanAppStateForExport } from "../appState";
export interface DataState {
type?: string;
version?: string;
source?: string;
export interface ExportedDataState {
type: string;
version: number;
source: string;
elements: readonly ExcalidrawElement[];
appState: Omit<AppState, "offsetTop" | "offsetLeft" | "width" | "height">;
appState: ReturnType<typeof cleanAppStateForExport>;
}
export interface ImportedDataState {
type?: string;
version?: string;
version?: number;
source?: string;
elements?: DataState["elements"] | null;
appState?: Partial<DataState["appState"]> | null;
elements?: readonly ExcalidrawElement[] | null;
appState?: Readonly<Partial<AppState>> | null;
scrollToContent?: boolean;
}
export interface LibraryData {
type?: string;
version?: number;
source?: string;
library?: LibraryItems;
export interface ExportedLibraryData {
type: string;
version: number;
source: string;
library: LibraryItems;
}
export interface ImportedLibraryData extends Partial<ExportedLibraryData> {}