Skip to content

Commit 0374a51

Browse files
committed
fix(desktop): post SET_MODE on iframe load + simplify pool ref registration
Two bugs in the preview-pool rewrite: - The rewrite dropped the iframe's `onLoad` handler that (re)posted SET_MODE. The parent's currentDesignId useEffect can fire before the iframe document finishes loading, so its initial SET_MODE postMessage may land on an unready message handler. Result: comment mode sometimes failed to activate on a freshly-mounted pool iframe. Restore the per-slot onLoad, gated on `active` so background iframes don't adopt the foreground mode. - `registerIframe` closed over `currentDesignId`, so every design switch re-created the callback and React re-attached every pool iframe's ref. Simplify it to pure map bookkeeping — the existing useEffect that runs on currentDesignId change already retargets `iframeRef` by looking the active id up in the map (child ref callbacks fire before parent effects, so the map is populated by then).
1 parent 8cbcf44 commit 0374a51

1 file changed

Lines changed: 23 additions & 14 deletions

File tree

apps/desktop/src/renderer/src/components/PreviewPane.tsx

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ interface PreviewSlotProps {
122122
showCommentUi: boolean;
123123
commentHintLabel: string;
124124
pinOverlay: React.ReactNode;
125+
interactionMode: string;
125126
registerIframe: (designId: string, el: HTMLIFrameElement | null) => void;
127+
onIframeError: (message: string) => void;
126128
}
127129

128130
// One iframe per pool entry. Hidden (display:none) when not active, but kept
@@ -139,7 +141,9 @@ function PreviewSlot({
139141
showCommentUi,
140142
commentHintLabel,
141143
pinOverlay,
144+
interactionMode,
142145
registerIframe,
146+
onIframeError,
143147
}: PreviewSlotProps) {
144148
const srcDocStableKey = useMemo(() => {
145149
return html
@@ -171,6 +175,16 @@ function PreviewSlot({
171175
title={`design-preview-${designId}`}
172176
sandbox="allow-scripts"
173177
srcDoc={srcDoc}
178+
onLoad={(e) => {
179+
// Once the iframe's document has actually loaded, its in-page message
180+
// handler is ready — this is the reliable moment to (re)post SET_MODE.
181+
// The parent's currentDesignId useEffect can fire before the document
182+
// loads, so that post may be dropped. Only re-post for the active
183+
// slot so we don't redirect background iframes into comment mode.
184+
if (!active) return;
185+
const target = e.currentTarget as HTMLIFrameElement;
186+
postModeToPreviewWindow(target.contentWindow, interactionMode, onIframeError);
187+
}}
174188
className={
175189
isMobile
176190
? 'block w-full h-full bg-transparent border-0'
@@ -267,20 +281,13 @@ export function PreviewPane({ onPickStarter }: PreviewPaneProps) {
267281
const iframeRef = useRef<HTMLIFrameElement | null>(null);
268282
const iframesByDesign = useRef<Map<string, HTMLIFrameElement>>(new Map());
269283

270-
const registerIframe = useCallback(
271-
(designId: string, el: HTMLIFrameElement | null) => {
272-
if (el) {
273-
iframesByDesign.current.set(designId, el);
274-
if (designId === currentDesignId) iframeRef.current = el;
275-
} else {
276-
iframesByDesign.current.delete(designId);
277-
if (iframeRef.current && designId === currentDesignId) {
278-
iframeRef.current = null;
279-
}
280-
}
281-
},
282-
[currentDesignId],
283-
);
284+
const registerIframe = useCallback((designId: string, el: HTMLIFrameElement | null) => {
285+
if (el) {
286+
iframesByDesign.current.set(designId, el);
287+
} else {
288+
iframesByDesign.current.delete(designId);
289+
}
290+
}, []);
284291

285292
// When the active design changes, retarget iframeRef and re-broadcast the
286293
// current interaction mode. Background iframes keep their last mode — fine,
@@ -427,7 +434,9 @@ export function PreviewPane({ onPickStarter }: PreviewPaneProps) {
427434
showCommentUi={showCommentUi}
428435
commentHintLabel={t('preview.commentModeHint')}
429436
pinOverlay={pinOverlay}
437+
interactionMode={interactionMode}
430438
registerIframe={registerIframe}
439+
onIframeError={pushIframeError}
431440
/>
432441
))}
433442
{!activeHasHtml ? <EmptyState onPickStarter={onPickStarter} /> : null}

0 commit comments

Comments
 (0)