diff --git a/apps/designer/app/canvas/shared/use-designer-ready.ts b/apps/designer/app/canvas/shared/use-designer-ready.ts index 82ea83a792..1a13769ca1 100644 --- a/apps/designer/app/canvas/shared/use-designer-ready.ts +++ b/apps/designer/app/canvas/shared/use-designer-ready.ts @@ -1,9 +1,10 @@ import { useState } from "react"; -import { useSubscribe } from "~/shared/pubsub"; +import { publish, useSubscribe } from "~/shared/pubsub"; declare module "~/shared/pubsub" { export interface PubsubMap { designerReady: undefined; + designerReadyAck: undefined; } } @@ -11,6 +12,7 @@ export const useSubscribeDesignerReady = () => { const [isReady, setIsReady] = useState(false); useSubscribe("designerReady", () => { setIsReady(true); + publish({ type: "designerReadyAck" }); }); return isReady; }; diff --git a/apps/designer/app/designer/designer.tsx b/apps/designer/app/designer/designer.tsx index 5b05b89995..539cd507ba 100644 --- a/apps/designer/app/designer/designer.tsx +++ b/apps/designer/app/designer/designer.tsx @@ -34,8 +34,8 @@ import { import { useClientSettings } from "./shared/client-settings"; import { Navigator } from "./features/sidebar-left"; import { PANEL_WIDTH } from "./shared/constants"; -import { onIframeLoad } from "~/shared/dom-utils"; import { Asset } from "@webstudio-is/asset-uploader"; +import { useInterval } from "react-use"; export const links = () => { return [ @@ -81,19 +81,20 @@ const useNavigatorLayout = () => { }; const usePublishDesignerReady = (publish: Publish) => { - const [ref, setRef] = useState(null); + const [isAcknowledged, setIsAcknowledged] = useState(false); - useEffect(() => { - if (ref === null) return; - - onIframeLoad(ref).then(() => { + useInterval( + () => { // We publish this even to let canvas know that we are now listening to the events, otherwise if canvas loads faster than designer, which is possible with SSR, // we can miss the events and designer will just not connect to the canvas. publish({ type: "designerReady" }); - }); - }, [ref, publish]); + }, + isAcknowledged ? null : 100 + ); - return setRef; + useSubscribe("designerReadyAck", () => { + setIsAcknowledged(true); + }); }; type SidePanelProps = { @@ -255,16 +256,15 @@ export const Designer = ({ config, project }: DesignerProps) => { const onRefReadCanvasWidth = useUpdateCanvasWidth(); const { onRef: onRefReadCanvas, onTransitionEnd } = useReadCanvasRect(); const [dragAndDropState] = useDragAndDropState(); - const onRefIframeReady = usePublishDesignerReady(publish); + usePublishDesignerReady(publish); const iframeRefCallback = useCallback( (ref) => { publishRef.current = ref; onRefReadCanvasWidth(ref); onRefReadCanvas(ref); - onRefIframeReady(ref); }, - [publishRef, onRefReadCanvasWidth, onRefReadCanvas, onRefIframeReady] + [publishRef, onRefReadCanvasWidth, onRefReadCanvas] ); return ( diff --git a/apps/designer/app/shared/dom-utils/index.ts b/apps/designer/app/shared/dom-utils/index.ts index 1304bcc6a9..b1120b975a 100644 --- a/apps/designer/app/shared/dom-utils/index.ts +++ b/apps/designer/app/shared/dom-utils/index.ts @@ -1,2 +1 @@ export * from "./instance"; -export * from "./on-iframe-load"; diff --git a/apps/designer/app/shared/dom-utils/on-iframe-load.ts b/apps/designer/app/shared/dom-utils/on-iframe-load.ts deleted file mode 100644 index 3d85e18d39..0000000000 --- a/apps/designer/app/shared/dom-utils/on-iframe-load.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Resolve a promise when an iframe has readyState complete. - * Checks periodically for the readyState to be complete, because somttimes the load event may simply not fire for various reasons. - */ -export const onIframeLoad = (iframe: HTMLIFrameElement | null) => - new Promise((resolve) => { - if (iframe === null) return; - const check = () => { - const document = iframe.contentDocument || iframe.contentWindow?.document; - if (document?.readyState === "complete") { - clearInterval(intervalId); - resolve("complete"); - } - }; - iframe.addEventListener("load", check); - const intervalId = setInterval(check, 100); - });