feat: support libraryReturnUrl when installing libraries (#3227)

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
This commit is contained in:
David Luzar 2021-03-13 12:35:35 +01:00 committed by GitHub
parent 47c26cd4cf
commit 91c8b6ecbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 3 deletions

View File

@ -458,6 +458,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
showExitZenModeBtn={ showExitZenModeBtn={
typeof this.props?.zenModeEnabled === "undefined" && zenModeEnabled typeof this.props?.zenModeEnabled === "undefined" && zenModeEnabled
} }
libraryReturnUrl={this.props.libraryReturnUrl}
/> />
<div className="excalidraw-textEditorContainer" /> <div className="excalidraw-textEditorContainer" />
{this.state.showStats && ( {this.state.showStats && (
@ -588,7 +589,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
private importLibraryFromUrl = async (url: string) => { private importLibraryFromUrl = async (url: string) => {
window.history.replaceState({}, APP_NAME, window.location.origin); window.history.replaceState({}, APP_NAME, window.location.origin);
try { try {
const request = await fetch(url); const request = await fetch(decodeURIComponent(url));
const blob = await request.blob(); const blob = await request.blob();
const json = JSON.parse(await blob.text()); const json = JSON.parse(await blob.text());
if (!isValidLibrary(json)) { if (!isValidLibrary(json)) {

View File

@ -17,7 +17,7 @@ import { Language, t } from "../i18n";
import useIsMobile from "../is-mobile"; import useIsMobile from "../is-mobile";
import { calculateScrollCenter, getSelectedElements } from "../scene"; import { calculateScrollCenter, getSelectedElements } from "../scene";
import { ExportType } from "../scene/types"; import { ExportType } from "../scene/types";
import { AppState, LibraryItem, LibraryItems } from "../types"; import { AppState, ExcalidrawProps, LibraryItem, LibraryItems } from "../types";
import { muteFSAbortError } from "../utils"; import { muteFSAbortError } from "../utils";
import { SelectedShapeActions, ShapesSwitcher, ZoomActions } from "./Actions"; import { SelectedShapeActions, ShapesSwitcher, ZoomActions } from "./Actions";
import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle"; import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle";
@ -63,6 +63,7 @@ interface LayerUIProps {
) => void; ) => void;
renderCustomFooter?: (isMobile: boolean) => JSX.Element; renderCustomFooter?: (isMobile: boolean) => JSX.Element;
viewModeEnabled: boolean; viewModeEnabled: boolean;
libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"];
} }
const useOnClickOutside = ( const useOnClickOutside = (
@ -101,6 +102,7 @@ const LibraryMenuItems = ({
pendingElements, pendingElements,
setAppState, setAppState,
setLibraryItems, setLibraryItems,
libraryReturnUrl,
}: { }: {
library: LibraryItems; library: LibraryItems;
pendingElements: LibraryItem; pendingElements: LibraryItem;
@ -109,6 +111,7 @@ const LibraryMenuItems = ({
onAddToLibrary: (elements: LibraryItem) => void; onAddToLibrary: (elements: LibraryItem) => void;
setAppState: React.Component<any, AppState>["setState"]; setAppState: React.Component<any, AppState>["setState"];
setLibraryItems: (library: LibraryItems) => void; setLibraryItems: (library: LibraryItems) => void;
libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"];
}) => { }) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const numCells = library.length + (pendingElements.length > 0 ? 1 : 0); const numCells = library.length + (pendingElements.length > 0 ? 1 : 0);
@ -117,6 +120,8 @@ const LibraryMenuItems = ({
const rows = []; const rows = [];
let addedPendingElements = false; let addedPendingElements = false;
const referrer = libraryReturnUrl || window.location.origin;
rows.push( rows.push(
<div className="layer-ui__library-header"> <div className="layer-ui__library-header">
<ToolButton <ToolButton
@ -166,7 +171,10 @@ const LibraryMenuItems = ({
}} }}
/> />
<a href="https://libraries.excalidraw.com" target="_excalidraw_libraries"> <a
href={`https://libraries.excalidraw.com?referrer=${referrer}`}
target="_excalidraw_libraries"
>
{t("labels.libraries")} {t("labels.libraries")}
</a> </a>
</div>, </div>,
@ -219,12 +227,14 @@ const LibraryMenu = ({
pendingElements, pendingElements,
onAddToLibrary, onAddToLibrary,
setAppState, setAppState,
libraryReturnUrl,
}: { }: {
pendingElements: LibraryItem; pendingElements: LibraryItem;
onClickOutside: (event: MouseEvent) => void; onClickOutside: (event: MouseEvent) => void;
onInsertShape: (elements: LibraryItem) => void; onInsertShape: (elements: LibraryItem) => void;
onAddToLibrary: () => void; onAddToLibrary: () => void;
setAppState: React.Component<any, AppState>["setState"]; setAppState: React.Component<any, AppState>["setState"];
libraryReturnUrl: ExcalidrawProps["libraryReturnUrl"];
}) => { }) => {
const ref = useRef<HTMLDivElement | null>(null); const ref = useRef<HTMLDivElement | null>(null);
useOnClickOutside(ref, (event) => { useOnClickOutside(ref, (event) => {
@ -297,6 +307,7 @@ const LibraryMenu = ({
pendingElements={pendingElements} pendingElements={pendingElements}
setAppState={setAppState} setAppState={setAppState}
setLibraryItems={setLibraryItems} setLibraryItems={setLibraryItems}
libraryReturnUrl={libraryReturnUrl}
/> />
)} )}
</Island> </Island>
@ -319,6 +330,7 @@ const LayerUI = ({
onExportToBackend, onExportToBackend,
renderCustomFooter, renderCustomFooter,
viewModeEnabled, viewModeEnabled,
libraryReturnUrl,
}: LayerUIProps) => { }: LayerUIProps) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@ -482,6 +494,7 @@ const LayerUI = ({
onInsertShape={onInsertElements} onInsertShape={onInsertElements}
onAddToLibrary={deselectItems} onAddToLibrary={deselectItems}
setAppState={setAppState} setAppState={setAppState}
libraryReturnUrl={libraryReturnUrl}
/> />
) : null; ) : null;

View File

@ -12,6 +12,16 @@ The change should be grouped under one of the below section and must contain PR
Please add the latest change on the top under the correct section. Please add the latest change on the top under the correct section.
--> -->
## Unreleased
## Excalidraw API
### Features
- Support `libraryReturnUrl` prop to indicate what URL to install libraries to [#3227](https://github.com/excalidraw/excalidraw/pull/3227).
---
## 0.4.3 ## 0.4.3
## Excalidraw API ## Excalidraw API

View File

@ -376,6 +376,7 @@ export default function IndexPage() {
| [`viewModeEnabled`](#viewModeEnabled) | boolean | | This implies if the app is in view mode. | | [`viewModeEnabled`](#viewModeEnabled) | boolean | | This implies if the app is in view mode. |
| [`zenModeEnabled`](#zenModeEnabled) | boolean | | This implies if the zen mode is enabled | | [`zenModeEnabled`](#zenModeEnabled) | boolean | | This implies if the zen mode is enabled |
| [`gridModeEnabled`](#gridModeEnabled) | boolean | | This implies if the grid mode is enabled | | [`gridModeEnabled`](#gridModeEnabled) | boolean | | This implies if the grid mode is enabled |
| [`libraryReturnUrl`](#libraryReturnUrl) | string | | What URL should [libraries.excalidraw.com](https://libraries.excalidraw.com) be installed to |
#### `width` #### `width`
@ -533,6 +534,10 @@ This prop indicates whether the app is in `zen mode`. When supplied, the value t
This prop indicates whether the shows the grid. When supplied, the value takes precedence over `intialData.appState.gridModeEnabled`, the grid will be fully controlled by the host app, and users won't be able to toggle it from within the app. This prop indicates whether the shows the grid. When supplied, the value takes precedence over `intialData.appState.gridModeEnabled`, the grid will be fully controlled by the host app, and users won't be able to toggle it from within the app.
### `libraryReturnUrl`
If supplied, this URL will be used when user tries to install a library from [libraries.excalidraw.com](https://libraries.excalidraw.com). Default to `window.location.origin`.
### Extra API's ### Extra API's
#### `getSceneVersion` #### `getSceneVersion`

View File

@ -29,6 +29,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
viewModeEnabled, viewModeEnabled,
zenModeEnabled, zenModeEnabled,
gridModeEnabled, gridModeEnabled,
libraryReturnUrl,
} = props; } = props;
useEffect(() => { useEffect(() => {
@ -69,6 +70,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
viewModeEnabled={viewModeEnabled} viewModeEnabled={viewModeEnabled}
zenModeEnabled={zenModeEnabled} zenModeEnabled={zenModeEnabled}
gridModeEnabled={gridModeEnabled} gridModeEnabled={gridModeEnabled}
libraryReturnUrl={libraryReturnUrl}
/> />
</IsMobileProvider> </IsMobileProvider>
</InitializeApp> </InitializeApp>

View File

@ -189,6 +189,7 @@ export interface ExcalidrawProps {
viewModeEnabled?: boolean; viewModeEnabled?: boolean;
zenModeEnabled?: boolean; zenModeEnabled?: boolean;
gridModeEnabled?: boolean; gridModeEnabled?: boolean;
libraryReturnUrl?: string;
} }
export type SceneData = { export type SceneData = {