瀏覽代碼

feat: support `libraryReturnUrl` when installing libraries (#3227)

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
David Luzar 4 年之前
父節點
當前提交
91c8b6ecbf

+ 2 - 1
src/components/App.tsx

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

+ 15 - 2
src/components/LayerUI.tsx

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

+ 10 - 0
src/packages/excalidraw/CHANGELOG.md

@@ -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.
 -->
 
+## 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
 
 ## Excalidraw API

+ 5 - 0
src/packages/excalidraw/README.md

@@ -376,6 +376,7 @@ export default function IndexPage() {
 | [`viewModeEnabled`](#viewModeEnabled) | boolean |  | This implies if the app is in view mode. |
 | [`zenModeEnabled`](#zenModeEnabled) | boolean |  | This implies if the zen 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`
 
@@ -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.
 
+### `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
 
 #### `getSceneVersion`

+ 2 - 0
src/packages/excalidraw/index.tsx

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

+ 1 - 0
src/types.ts

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