Skip to content

Commit

Permalink
Library MVP (excalidraw#1787)
Browse files Browse the repository at this point in the history
Co-authored-by: dwelle <[email protected]>
  • Loading branch information
petehunt and dwelle authored Jul 10, 2020
1 parent 7ab0c1a commit 6428b59
Show file tree
Hide file tree
Showing 18 changed files with 599 additions and 20 deletions.
23 changes: 23 additions & 0 deletions src/actions/actionAddToLibrary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { register } from "./register";
import { getSelectedElements } from "../scene";
import { getNonDeletedElements } from "../element";
import { deepCopyElement } from "../element/newElement";
import { loadLibrary, saveLibrary } from "../data/localStorage";

export const actionAddToLibrary = register({
name: "addToLibrary",
perform: (elements, appState) => {
const selectedElements = getSelectedElements(
getNonDeletedElements(elements),
appState,
);

loadLibrary().then((items) => {
saveLibrary([...items, selectedElements.map(deepCopyElement)]);
});

return false;
},
contextMenuOrder: 6,
contextItemLabel: "labels.addToLibrary",
});
2 changes: 2 additions & 0 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,5 @@ export {
export { actionGroup, actionUngroup } from "./actionGroup";

export { actionGoToCollaborator } from "./actionNavigate";

export { actionAddToLibrary } from "./actionAddToLibrary";
3 changes: 2 additions & 1 deletion src/actions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export type ActionName =
| "toggleShortcuts"
| "group"
| "ungroup"
| "goToCollaborator";
| "goToCollaborator"
| "addToLibrary";

export interface Action {
name: ActionName;
Expand Down
2 changes: 2 additions & 0 deletions src/appState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const getDefaultAppState = (): AppState => {
selectedGroupIds: {},
width: window.innerWidth,
height: window.innerHeight,
isLibraryOpen: false,
};
};

Expand All @@ -76,6 +77,7 @@ export const clearAppStateForLocalStorage = (appState: AppState) => {
errorMessage,
showShortcutsDialog,
editingLinearElement,
isLibraryOpen,
...exportedState
} = appState;
return exportedState;
Expand Down
25 changes: 23 additions & 2 deletions src/components/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,21 @@ export const SelectedShapeActions = ({
);
};

const LIBRARY_ICON = (
// fa-th-large
<svg viewBox="0 0 512 512">
<path d="M296 32h192c13.255 0 24 10.745 24 24v160c0 13.255-10.745 24-24 24H296c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24zm-80 0H24C10.745 32 0 42.745 0 56v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24zM0 296v160c0 13.255 10.745 24 24 24h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24zm296 184h192c13.255 0 24-10.745 24-24V296c0-13.255-10.745-24-24-24H296c-13.255 0-24 10.745-24 24v160c0 13.255 10.745 24 24 24z" />
</svg>
);

export const ShapesSwitcher = ({
elementType,
setAppState,
isLibraryOpen,
}: {
elementType: ExcalidrawElement["type"];
setAppState: any;
setAppState: (appState: Partial<AppState>) => void;
isLibraryOpen: boolean;
}) => (
<>
{SHAPES.map(({ value, icon, key }, index) => {
Expand Down Expand Up @@ -119,9 +128,21 @@ export const ShapesSwitcher = ({
setCursorForShape(value);
setAppState({});
}}
></ToolButton>
/>
);
})}
<ToolButton
type="button"
icon={LIBRARY_ICON}
name="editor-library"
keyBindingLabel="9"
aria-keyshortcuts="9"
title={`${capitalizeString(t("toolBar.library"))} — 9`}
aria-label={capitalizeString(t("toolBar.library"))}
onClick={() => {
setAppState({ isLibraryOpen: !isLibraryOpen });
}}
/>
</>
);

Expand Down
28 changes: 25 additions & 3 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ class App extends React.Component<ExcalidrawProps, AppState> {
});
}}
onLockToggle={this.toggleLock}
onInsertShape={(elements) =>
this.addElementsFromPasteOrLibrary(elements)
}
zenModeEnabled={zenModeEnabled}
toggleZenMode={this.toggleZenMode}
lng={getLanguage().lng}
Expand Down Expand Up @@ -870,7 +873,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
if (data.error) {
alert(data.error);
} else if (data.elements) {
this.addElementsFromPaste(data.elements);
this.addElementsFromPasteOrLibrary(data.elements);
} else if (data.text) {
this.addTextFromPaste(data.text);
}
Expand All @@ -879,16 +882,18 @@ class App extends React.Component<ExcalidrawProps, AppState> {
},
);

private addElementsFromPaste = (
private addElementsFromPasteOrLibrary = (
clipboardElements: readonly ExcalidrawElement[],
clientX = cursorX,
clientY = cursorY,
) => {
const [minX, minY, maxX, maxY] = getCommonBounds(clipboardElements);

const elementsCenterX = distance(minX, maxX) / 2;
const elementsCenterY = distance(minY, maxY) / 2;

const { x, y } = viewportCoordsToSceneCoords(
{ clientX: cursorX, clientY: cursorY },
{ clientX, clientY },
this.state,
this.canvas,
window.devicePixelRatio,
Expand All @@ -911,6 +916,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
]);
history.resumeRecording();
this.setState({
isLibraryOpen: false,
selectedElementIds: newElements.reduce((map, element) => {
map[element.id] = true;
return map;
Expand Down Expand Up @@ -1355,6 +1361,10 @@ class App extends React.Component<ExcalidrawProps, AppState> {
return;
}

if (event.code === "Digit9") {
this.setState({ isLibraryOpen: !this.state.isLibraryOpen });
}

const shape = findShapeByKey(event.key);

if (isArrowKey(event.key)) {
Expand Down Expand Up @@ -3135,6 +3145,18 @@ class App extends React.Component<ExcalidrawProps, AppState> {
};

private handleCanvasOnDrop = (event: React.DragEvent<HTMLCanvasElement>) => {
const libraryShapes = event.dataTransfer.getData(
"application/vnd.excalidraw.json",
);
if (libraryShapes !== "") {
this.addElementsFromPasteOrLibrary(
JSON.parse(libraryShapes),
event.clientX,
event.clientY,
);
return;
}

const file = event.dataTransfer?.files[0];
if (
file?.type === "application/json" ||
Expand Down
17 changes: 17 additions & 0 deletions src/components/LayerUI.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
@import "open-color/open-color";

.layer-ui__library {
margin: auto;
display: flex;
align-items: center;
justify-content: center;
}

.layer-ui__library-message {
padding: 10px 20px;
max-width: 200px;
}

.layer-ui__library-items {
max-height: 50vh;
overflow: auto;
}

.layer-ui__wrapper {
.encrypted-icon {
position: relative;
Expand Down
Loading

0 comments on commit 6428b59

Please sign in to comment.