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

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Arnost Pleskot 2023-06-12 17:44:31 +02:00 committed by GitHub
parent 74d2fc6406
commit 3bd5d87cac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 19 deletions

View File

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

View File

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

View File

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

View File

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

View File

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