2023-05-24 16:40:20 +02:00
|
|
|
import React, { useCallback } from "react";
|
2022-10-18 06:59:14 +02:00
|
|
|
import Library, {
|
|
|
|
distributeLibraryItemsOnSquareGrid,
|
|
|
|
libraryItemsAtom,
|
|
|
|
} from "../data/library";
|
2021-11-17 23:53:43 +05:30
|
|
|
import { t } from "../i18n";
|
|
|
|
import { randomId } from "../random";
|
2023-05-08 10:14:02 +02:00
|
|
|
import {
|
|
|
|
LibraryItems,
|
|
|
|
LibraryItem,
|
|
|
|
ExcalidrawProps,
|
|
|
|
UIAppState,
|
|
|
|
} from "../types";
|
2021-11-17 23:53:43 +05:30
|
|
|
import LibraryMenuItems from "./LibraryMenuItems";
|
2022-03-28 14:46:40 +02:00
|
|
|
import { trackEvent } from "../analytics";
|
2023-05-04 19:33:31 +02:00
|
|
|
import { atom, useAtom } from "jotai";
|
2022-04-20 14:40:03 +02:00
|
|
|
import { jotaiScope } from "../jotai";
|
|
|
|
import Spinner from "./Spinner";
|
2022-10-18 06:59:14 +02:00
|
|
|
import {
|
2023-05-04 19:33:31 +02:00
|
|
|
useApp,
|
|
|
|
useAppProps,
|
2022-10-18 06:59:14 +02:00
|
|
|
useExcalidrawElements,
|
|
|
|
useExcalidrawSetAppState,
|
|
|
|
} from "./App";
|
|
|
|
import { getSelectedElements } from "../scene";
|
2023-05-04 19:33:31 +02:00
|
|
|
import { useUIAppState } from "../context/ui-appState";
|
2021-11-17 23:53:43 +05:30
|
|
|
|
2023-05-04 19:33:31 +02:00
|
|
|
import "./LibraryMenu.scss";
|
|
|
|
import { LibraryMenuControlButtons } from "./LibraryMenuControlButtons";
|
2021-11-17 23:53:43 +05:30
|
|
|
|
2023-05-04 19:33:31 +02:00
|
|
|
export const isLibraryMenuOpenAtom = atom(false);
|
2021-11-17 23:53:43 +05:30
|
|
|
|
2023-05-04 19:33:31 +02:00
|
|
|
const LibraryMenuWrapper = ({ children }: { children: React.ReactNode }) => {
|
|
|
|
return <div className="layer-ui__library">{children}</div>;
|
2021-11-17 23:53:43 +05:30
|
|
|
};
|
|
|
|
|
2022-10-18 06:59:14 +02:00
|
|
|
export const LibraryMenuContent = ({
|
2022-05-11 15:51:02 +02:00
|
|
|
onInsertLibraryItems,
|
2021-11-17 23:53:43 +05:30
|
|
|
pendingElements,
|
|
|
|
onAddToLibrary,
|
|
|
|
setAppState,
|
|
|
|
libraryReturnUrl,
|
|
|
|
library,
|
|
|
|
id,
|
|
|
|
appState,
|
|
|
|
}: {
|
|
|
|
pendingElements: LibraryItem["elements"];
|
2022-05-11 15:51:02 +02:00
|
|
|
onInsertLibraryItems: (libraryItems: LibraryItems) => void;
|
2021-11-17 23:53:43 +05:30
|
|
|
onAddToLibrary: () => void;
|
2023-05-08 10:14:02 +02:00
|
|
|
setAppState: React.Component<any, UIAppState>["setState"];
|
2021-11-17 23:53:43 +05:30
|
|
|
libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"];
|
|
|
|
library: Library;
|
|
|
|
id: string;
|
2023-05-08 10:14:02 +02:00
|
|
|
appState: UIAppState;
|
2021-11-17 23:53:43 +05:30
|
|
|
}) => {
|
2022-10-18 06:59:14 +02:00
|
|
|
const [libraryItemsData] = useAtom(libraryItemsAtom, jotaiScope);
|
2021-11-17 23:53:43 +05:30
|
|
|
|
2022-10-18 06:59:14 +02:00
|
|
|
const addToLibrary = useCallback(
|
|
|
|
async (elements: LibraryItem["elements"], libraryItems: LibraryItems) => {
|
|
|
|
trackEvent("element", "addToLibrary", "ui");
|
|
|
|
if (elements.some((element) => element.type === "image")) {
|
|
|
|
return setAppState({
|
|
|
|
errorMessage: "Support for adding images to the library coming soon!",
|
|
|
|
});
|
|
|
|
}
|
|
|
|
const nextItems: LibraryItems = [
|
|
|
|
{
|
|
|
|
status: "unpublished",
|
|
|
|
elements,
|
|
|
|
id: randomId(),
|
|
|
|
created: Date.now(),
|
|
|
|
},
|
|
|
|
...libraryItems,
|
|
|
|
];
|
|
|
|
onAddToLibrary();
|
|
|
|
library.setLibrary(nextItems).catch(() => {
|
|
|
|
setAppState({ errorMessage: t("alerts.errorAddingToLibrary") });
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[onAddToLibrary, library, setAppState],
|
|
|
|
);
|
|
|
|
|
|
|
|
if (
|
|
|
|
libraryItemsData.status === "loading" &&
|
|
|
|
!libraryItemsData.isInitialized
|
|
|
|
) {
|
|
|
|
return (
|
|
|
|
<LibraryMenuWrapper>
|
|
|
|
<div className="layer-ui__library-message">
|
2022-11-01 17:29:58 +01:00
|
|
|
<div>
|
|
|
|
<Spinner size="2em" />
|
|
|
|
<span>{t("labels.libraryLoadingMessage")}</span>
|
|
|
|
</div>
|
2022-10-18 06:59:14 +02:00
|
|
|
</div>
|
|
|
|
</LibraryMenuWrapper>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-11-01 17:29:58 +01:00
|
|
|
const showBtn =
|
|
|
|
libraryItemsData.libraryItems.length > 0 || pendingElements.length > 0;
|
|
|
|
|
2022-10-18 06:59:14 +02:00
|
|
|
return (
|
|
|
|
<LibraryMenuWrapper>
|
|
|
|
<LibraryMenuItems
|
|
|
|
isLoading={libraryItemsData.status === "loading"}
|
|
|
|
libraryItems={libraryItemsData.libraryItems}
|
|
|
|
onAddToLibrary={(elements) =>
|
|
|
|
addToLibrary(elements, libraryItemsData.libraryItems)
|
|
|
|
}
|
|
|
|
onInsertLibraryItems={onInsertLibraryItems}
|
|
|
|
pendingElements={pendingElements}
|
2022-11-01 17:29:58 +01:00
|
|
|
id={id}
|
|
|
|
libraryReturnUrl={libraryReturnUrl}
|
|
|
|
theme={appState.theme}
|
2022-10-18 06:59:14 +02:00
|
|
|
/>
|
2022-11-01 17:29:58 +01:00
|
|
|
{showBtn && (
|
2023-05-04 19:33:31 +02:00
|
|
|
<LibraryMenuControlButtons
|
2023-05-13 13:18:14 +02:00
|
|
|
className="library-menu-control-buttons--at-bottom"
|
2023-05-04 19:33:31 +02:00
|
|
|
style={{ padding: "16px 12px 0 12px" }}
|
2022-11-01 17:29:58 +01:00
|
|
|
id={id}
|
|
|
|
libraryReturnUrl={libraryReturnUrl}
|
|
|
|
theme={appState.theme}
|
|
|
|
/>
|
|
|
|
)}
|
2022-10-18 06:59:14 +02:00
|
|
|
</LibraryMenuWrapper>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2023-05-04 19:33:31 +02:00
|
|
|
/**
|
|
|
|
* This component is meant to be rendered inside <Sidebar.Tab/> inside our
|
|
|
|
* <DefaultSidebar/> or host apps Sidebar components.
|
|
|
|
*/
|
|
|
|
export const LibraryMenu = () => {
|
|
|
|
const { library, id, onInsertElements } = useApp();
|
|
|
|
const appProps = useAppProps();
|
|
|
|
const appState = useUIAppState();
|
2022-10-18 06:59:14 +02:00
|
|
|
const setAppState = useExcalidrawSetAppState();
|
|
|
|
const elements = useExcalidrawElements();
|
|
|
|
|
2023-05-24 16:40:20 +02:00
|
|
|
const onAddToLibrary = useCallback(() => {
|
|
|
|
// deselect canvas elements
|
2022-10-18 06:59:14 +02:00
|
|
|
setAppState({
|
|
|
|
selectedElementIds: {},
|
|
|
|
selectedGroupIds: {},
|
|
|
|
});
|
|
|
|
}, [setAppState]);
|
2021-11-17 23:53:43 +05:30
|
|
|
|
2022-04-20 14:40:03 +02:00
|
|
|
return (
|
2023-05-04 19:33:31 +02:00
|
|
|
<LibraryMenuContent
|
|
|
|
pendingElements={getSelectedElements(elements, appState, true)}
|
|
|
|
onInsertLibraryItems={(libraryItems) => {
|
|
|
|
onInsertElements(distributeLibraryItemsOnSquareGrid(libraryItems));
|
2022-10-18 06:59:14 +02:00
|
|
|
}}
|
2023-05-24 16:40:20 +02:00
|
|
|
onAddToLibrary={onAddToLibrary}
|
2023-05-04 19:33:31 +02:00
|
|
|
setAppState={setAppState}
|
|
|
|
libraryReturnUrl={appProps.libraryReturnUrl}
|
|
|
|
library={library}
|
|
|
|
id={id}
|
|
|
|
appState={appState}
|
|
|
|
/>
|
2021-11-17 23:53:43 +05:30
|
|
|
);
|
|
|
|
};
|