Import and export library from/to a file (#1940)

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Mohammed Salman 2020-07-27 15:29:19 +03:00 committed by GitHub
parent 7eff6893c5
commit ee8fa6aaad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 199 additions and 39 deletions

View file

@ -9,12 +9,8 @@ import { showSelectedShapeActions } from "../element";
import { calculateScrollCenter, getSelectedElements } from "../scene";
import { exportCanvas } from "../data";
import { AppState, LibraryItems } from "../types";
import {
NonDeletedExcalidrawElement,
ExcalidrawElement,
NonDeleted,
} from "../element/types";
import { AppState, LibraryItems, LibraryItem } from "../types";
import { NonDeletedExcalidrawElement } from "../element/types";
import { ActionManager } from "../actions/manager";
import { Island } from "./Island";
@ -37,13 +33,16 @@ import { ErrorDialog } from "./ErrorDialog";
import { ShortcutsDialog } from "./ShortcutsDialog";
import { LoadingMessage } from "./LoadingMessage";
import { CLASSES } from "../constants";
import { shield } from "./icons";
import { shield, exportFile, load } from "./icons";
import { GitHubCorner } from "./GitHubCorner";
import { Tooltip } from "./Tooltip";
import "./LayerUI.scss";
import { LibraryUnit } from "./LibraryUnit";
import { loadLibrary, saveLibrary } from "../data/localStorage";
import { ToolButton } from "./ToolButton";
import { saveLibraryAsJSON, importLibraryFromJSON } from "../data/json";
import { muteFSAbortError } from "../utils";
interface LayerUIProps {
actionManager: ActionManager;
@ -55,7 +54,7 @@ interface LayerUIProps {
onUsernameChange: (username: string) => void;
onRoomDestroy: () => void;
onLockToggle: () => void;
onInsertShape: (elements: readonly NonDeleted<ExcalidrawElement>[]) => void;
onInsertShape: (elements: LibraryItem) => void;
zenModeEnabled: boolean;
toggleZenMode: () => void;
lng: string;
@ -95,13 +94,15 @@ const LibraryMenuItems = ({
onAddToLibrary,
onInsertShape,
pendingElements,
setAppState,
}: {
library: LibraryItems;
pendingElements: NonDeleted<ExcalidrawElement>[];
pendingElements: LibraryItem;
onClickOutside: (event: MouseEvent) => void;
onRemoveFromLibrary: (index: number) => void;
onInsertShape: (elements: readonly NonDeleted<ExcalidrawElement>[]) => void;
onAddToLibrary: (elements: NonDeleted<ExcalidrawElement>[]) => void;
onInsertShape: (elements: LibraryItem) => void;
onAddToLibrary: (elements: LibraryItem) => void;
setAppState: any;
}) => {
const isMobile = useIsMobile();
const numCells = library.length + (pendingElements.length > 0 ? 1 : 0);
@ -110,6 +111,44 @@ const LibraryMenuItems = ({
const rows = [];
let addedPendingElements = false;
rows.push(
<Stack.Row align="center" gap={1} key={"actions"}>
<ToolButton
key="import"
type="button"
title={t("buttons.load")}
aria-label={t("buttons.load")}
icon={load}
onClick={() => {
importLibraryFromJSON()
.then(() => {
// Maybe we should close and open the menu so that the items get updated.
// But for now we just close the menu.
setAppState({ isLibraryOpen: false });
})
.catch(muteFSAbortError)
.catch((error) => {
setAppState({ errorMessage: error.message });
});
}}
/>
<ToolButton
key="export"
type="button"
title={t("buttons.export")}
aria-label={t("buttons.export")}
icon={exportFile}
onClick={() => {
saveLibraryAsJSON()
.catch(muteFSAbortError)
.catch((error) => {
setAppState({ errorMessage: error.message });
});
}}
/>
</Stack.Row>,
);
for (let row = 0; row < numRows; row++) {
const i = CELLS_PER_ROW * row;
const children = [];
@ -156,11 +195,13 @@ const LibraryMenu = ({
onInsertShape,
pendingElements,
onAddToLibrary,
setAppState,
}: {
pendingElements: NonDeleted<ExcalidrawElement>[];
pendingElements: LibraryItem;
onClickOutside: (event: MouseEvent) => void;
onInsertShape: (elements: readonly NonDeleted<ExcalidrawElement>[]) => void;
onInsertShape: (elements: LibraryItem) => void;
onAddToLibrary: () => void;
setAppState: any;
}) => {
const ref = useRef<HTMLDivElement | null>(null);
useOnClickOutside(ref, onClickOutside);
@ -202,7 +243,7 @@ const LibraryMenu = ({
}, []);
const addToLibrary = useCallback(
async (elements: NonDeleted<ExcalidrawElement>[]) => {
async (elements: LibraryItem) => {
const items = await loadLibrary();
const nextItems = [...items, elements];
onAddToLibrary();
@ -226,6 +267,7 @@ const LibraryMenu = ({
onAddToLibrary={addToLibrary}
onInsertShape={onInsertShape}
pendingElements={pendingElements}
setAppState={setAppState}
/>
)}
</Island>
@ -372,6 +414,7 @@ const LayerUI = ({
onClickOutside={closeLibrary}
onInsertShape={onInsertShape}
onAddToLibrary={deselectItems}
setAppState={setAppState}
/>
) : null;