Browse Source

feat: disable collab feature when running in iframe (#6646)

Co-authored-by: dwelle <[email protected]>
Arnost Pleskot 2 năm trước cách đây
mục cha
commit
3bd5d87cac

+ 2 - 1
src/excalidraw-app/collab/Collab.tsx

@@ -157,6 +157,8 @@ class Collab extends PureComponent<Props, CollabState> {
     window.addEventListener("offline", this.onOfflineStatusToggle);
     window.addEventListener(EVENT.UNLOAD, this.onUnload);
 
+    this.onOfflineStatusToggle();
+
     const collabAPI: CollabAPI = {
       isCollaborating: this.isCollaborating,
       onPointerUpdate: this.onPointerUpdate,
@@ -168,7 +170,6 @@ class Collab extends PureComponent<Props, CollabState> {
     };
 
     appJotaiStore.set(collabAPIAtom, collabAPI);
-    this.onOfflineStatusToggle();
 
     if (
       process.env.NODE_ENV === ENV.TEST ||

+ 7 - 4
src/excalidraw-app/components/AppMainMenu.tsx

@@ -6,6 +6,7 @@ import { LanguageList } from "./LanguageList";
 export const AppMainMenu: React.FC<{
   setCollabDialogShown: (toggle: boolean) => any;
   isCollaborating: boolean;
+  isCollabEnabled: boolean;
 }> = React.memo((props) => {
   return (
     <MainMenu>
@@ -13,10 +14,12 @@ export const AppMainMenu: React.FC<{
       <MainMenu.DefaultItems.SaveToActiveFile />
       <MainMenu.DefaultItems.Export />
       <MainMenu.DefaultItems.SaveAsImage />
-      <MainMenu.DefaultItems.LiveCollaborationTrigger
-        isCollaborating={props.isCollaborating}
-        onSelect={() => props.setCollabDialogShown(true)}
-      />
+      {props.isCollabEnabled && (
+        <MainMenu.DefaultItems.LiveCollaborationTrigger
+          isCollaborating={props.isCollaborating}
+          onSelect={() => props.setCollabDialogShown(true)}
+        />
+      )}
 
       <MainMenu.DefaultItems.Help />
       <MainMenu.DefaultItems.ClearCanvas />

+ 6 - 3
src/excalidraw-app/components/AppWelcomeScreen.tsx

@@ -6,6 +6,7 @@ import { isExcalidrawPlusSignedUser } from "../app_constants";
 
 export const AppWelcomeScreen: React.FC<{
   setCollabDialogShown: (toggle: boolean) => any;
+  isCollabEnabled: boolean;
 }> = React.memo((props) => {
   const { t } = useI18n();
   let headingContent;
@@ -46,9 +47,11 @@ export const AppWelcomeScreen: React.FC<{
         <WelcomeScreen.Center.Menu>
           <WelcomeScreen.Center.MenuItemLoadScene />
           <WelcomeScreen.Center.MenuItemHelp />
-          <WelcomeScreen.Center.MenuItemLiveCollaborationTrigger
-            onSelect={() => props.setCollabDialogShown(true)}
-          />
+          {props.isCollabEnabled && (
+            <WelcomeScreen.Center.MenuItemLiveCollaborationTrigger
+              onSelect={() => props.setCollabDialogShown(true)}
+            />
+          )}
           {!isExcalidrawPlusSignedUser && (
             <WelcomeScreen.Center.MenuItemLink
               href="https://plus.excalidraw.com/plus?utm_source=excalidraw&utm_medium=app&utm_content=welcomeScreenGuest"

+ 22 - 11
src/excalidraw-app/index.tsx

@@ -42,6 +42,7 @@ import {
   preventUnload,
   ResolvablePromise,
   resolvablePromise,
+  isRunningInIframe,
 } from "../utils";
 import {
   FIREBASE_STORAGE_PREFIXES,
@@ -98,7 +99,7 @@ languageDetector.init({
 });
 
 const initializeScene = async (opts: {
-  collabAPI: CollabAPI;
+  collabAPI: CollabAPI | null;
   excalidrawAPI: ExcalidrawImperativeAPI;
 }): Promise<
   { scene: ExcalidrawInitialDataState | null } & (
@@ -183,7 +184,7 @@ const initializeScene = async (opts: {
     }
   }
 
-  if (roomLinkData) {
+  if (roomLinkData && opts.collabAPI) {
     const { excalidrawAPI } = opts;
 
     const scene = await opts.collabAPI.startCollaboration(roomLinkData);
@@ -237,6 +238,7 @@ export const appLangCodeAtom = atom(
 const ExcalidrawWrapper = () => {
   const [errorMessage, setErrorMessage] = useState("");
   const [langCode, setLangCode] = useAtom(appLangCodeAtom);
+  const isCollabDisabled = isRunningInIframe();
 
   // initial state
   // ---------------------------------------------------------------------------
@@ -272,7 +274,7 @@ const ExcalidrawWrapper = () => {
   });
 
   useEffect(() => {
-    if (!collabAPI || !excalidrawAPI) {
+    if (!excalidrawAPI || (!isCollabDisabled && !collabAPI)) {
       return;
     }
 
@@ -283,7 +285,7 @@ const ExcalidrawWrapper = () => {
       if (!data.scene) {
         return;
       }
-      if (collabAPI.isCollaborating()) {
+      if (collabAPI?.isCollaborating()) {
         if (data.scene.elements) {
           collabAPI
             .fetchImageFilesFromFirebase({
@@ -353,7 +355,7 @@ const ExcalidrawWrapper = () => {
       const libraryUrlTokens = parseLibraryTokensFromUrl();
       if (!libraryUrlTokens) {
         if (
-          collabAPI.isCollaborating() &&
+          collabAPI?.isCollaborating() &&
           !isCollaborationLink(window.location.href)
         ) {
           collabAPI.stopCollaboration(false);
@@ -382,7 +384,10 @@ const ExcalidrawWrapper = () => {
       if (isTestEnv()) {
         return;
       }
-      if (!document.hidden && !collabAPI.isCollaborating()) {
+      if (
+        !document.hidden &&
+        ((collabAPI && !collabAPI.isCollaborating()) || isCollabDisabled)
+      ) {
         // don't sync if local state is newer or identical to browser state
         if (isBrowserStorageStateNewer(STORAGE_KEYS.VERSION_DATA_STATE)) {
           const localDataState = importFromLocalStorage();
@@ -398,7 +403,7 @@ const ExcalidrawWrapper = () => {
           excalidrawAPI.updateLibrary({
             libraryItems: getLibraryItemsFromStorage(),
           });
-          collabAPI.setUsername(username || "");
+          collabAPI?.setUsername(username || "");
         }
 
         if (isBrowserStorageStateNewer(STORAGE_KEYS.VERSION_FILES)) {
@@ -466,7 +471,7 @@ const ExcalidrawWrapper = () => {
       );
       clearTimeout(titleTimeout);
     };
-  }, [collabAPI, excalidrawAPI, setLangCode]);
+  }, [isCollabDisabled, collabAPI, excalidrawAPI, setLangCode]);
 
   useEffect(() => {
     const unloadHandler = (event: BeforeUnloadEvent) => {
@@ -649,7 +654,7 @@ const ExcalidrawWrapper = () => {
         autoFocus={true}
         theme={theme}
         renderTopRightUI={(isMobile) => {
-          if (isMobile) {
+          if (isMobile || !collabAPI || isCollabDisabled) {
             return null;
           }
           return (
@@ -663,15 +668,21 @@ const ExcalidrawWrapper = () => {
         <AppMainMenu
           setCollabDialogShown={setCollabDialogShown}
           isCollaborating={isCollaborating}
+          isCollabEnabled={!isCollabDisabled}
+        />
+        <AppWelcomeScreen
+          setCollabDialogShown={setCollabDialogShown}
+          isCollabEnabled={!isCollabDisabled}
         />
-        <AppWelcomeScreen setCollabDialogShown={setCollabDialogShown} />
         <AppFooter />
         {isCollaborating && isOffline && (
           <div className="collab-offline-warning">
             {t("alerts.collabOfflineWarning")}
           </div>
         )}
-        {excalidrawAPI && <Collab excalidrawAPI={excalidrawAPI} />}
+        {excalidrawAPI && !isCollabDisabled && (
+          <Collab excalidrawAPI={excalidrawAPI} />
+        )}
       </Excalidraw>
       {errorMessage && (
         <ErrorDialog onClose={() => setErrorMessage("")}>

+ 2 - 0
src/utils.ts

@@ -748,6 +748,8 @@ export const getFrame = () => {
   }
 };
 
+export const isRunningInIframe = () => getFrame() === "iframe";
+
 export const isPromiseLike = (
   value: any,
 ): value is Promise<ResolutionType<typeof value>> => {