fix(crop): return cropOverlayRef instead of .current to fix null timing

The cropOverlay was created asynchronously inside a polling interval but
returned synchronously as .current (null). By returning the ref itself,
Editor.tsx reads .current at call time when the overlay actually exists.
This commit is contained in:
Hiren Kangad
2026-03-11 17:39:34 +05:30
parent 01f22c9d43
commit 3413d58f83
2 changed files with 7 additions and 7 deletions
+1 -1
View File
@@ -458,5 +458,5 @@ export function useCanvasSetup(deps: CanvasSetupDeps) {
}; };
}, [boardData, resolvedBoardId, user, isPublicView, onCanvasChange, showToast, canvasRef, selectionRef, undoRef, syncRef, inboxZoneRef, uploadManager, setOnlineUsers, setSelectedLayerIds]); }, [boardData, resolvedBoardId, user, isPublicView, onCanvasChange, showToast, canvasRef, selectionRef, undoRef, syncRef, inboxZoneRef, uploadManager, setOnlineUsers, setSelectedLayerIds]);
return { annotationStore: annotationStoreRef.current, pinOverlay: pinOverlayRef.current, textEditor: textEditorRef.current, cropOverlay: cropOverlayRef.current }; return { annotationStore: annotationStoreRef.current, pinOverlay: pinOverlayRef.current, textEditor: textEditorRef.current, cropOverlayRef };
} }
+6 -6
View File
@@ -169,7 +169,7 @@ export default function Editor({ isPublicView }: EditorProps) {
}); });
// Canvas setup (selection, undo, sync, socket, drag/drop, paste, inbox, annotations) // Canvas setup (selection, undo, sync, socket, drag/drop, paste, inbox, annotations)
const { annotationStore, pinOverlay, textEditor, cropOverlay } = useCanvasSetup({ const { annotationStore, pinOverlay, textEditor, cropOverlayRef } = useCanvasSetup({
boardData, resolvedBoardId, user, isPublicView, boardData, resolvedBoardId, user, isPublicView,
canvasRef, selectionRef, undoRef, syncRef, inboxZoneRef, canvasContainerRef, canvasRef, selectionRef, undoRef, syncRef, inboxZoneRef, canvasContainerRef,
uploadManager, onCanvasChange, showToast, setOnlineUsers, setSelectedLayerIds, uploadManager, onCanvasChange, showToast, setOnlineUsers, setSelectedLayerIds,
@@ -296,14 +296,14 @@ export default function Editor({ isPublicView }: EditorProps) {
setShowGrid, setShowHelp, setFocusMode, setReviewMode, setShowGrid, setShowHelp, setFocusMode, setReviewMode,
startCrop: () => { startCrop: () => {
const selection = selectionRef.current; const selection = selectionRef.current;
if (!selection || !cropOverlay) return; if (!selection || !cropOverlayRef.current) return;
const items = selection.getSelectedItems(); const items = selection.getSelectedItems();
if (items.length !== 1 || items[0].type !== 'image') { if (items.length !== 1 || items[0].type !== 'image') {
showToast('Select a single image to crop'); showToast('Select a single image to crop');
return; return;
} }
selection.setEnabled(false); selection.setEnabled(false);
cropOverlay.start(items[0]); cropOverlayRef.current.start(items[0]);
}, },
}); });
@@ -327,14 +327,14 @@ export default function Editor({ isPublicView }: EditorProps) {
fitAll: () => canvasRef.current?.fitAll(), fitAll: () => canvasRef.current?.fitAll(),
startCrop: () => { startCrop: () => {
const selection = selectionRef.current; const selection = selectionRef.current;
if (!selection || !cropOverlay) return; if (!selection || !cropOverlayRef.current) return;
const items = selection.getSelectedItems(); const items = selection.getSelectedItems();
if (items.length !== 1 || items[0].type !== 'image') return; if (items.length !== 1 || items[0].type !== 'image') return;
selection.setEnabled(false); selection.setEnabled(false);
cropOverlay.start(items[0]); cropOverlayRef.current.start(items[0]);
}, },
}); });
}, [writeCanvasToClipboard, onCanvasChange, handleGroup, handleUngroup, refreshLayers, cropOverlay]); }, [writeCanvasToClipboard, onCanvasChange, handleGroup, handleUngroup, refreshLayers]);
// Save on page unload (only for users with edit access) // Save on page unload (only for users with edit access)
useEffect(() => { useEffect(() => {