From ba13f88924e522ced9b9963a9e049e0fbd2f2e87 Mon Sep 17 00:00:00 2001 From: Christopher Chedeau Date: Sat, 25 Jan 2020 14:11:26 -0800 Subject: [PATCH] Do not trigger modal actions when not visible (#562) Right now we're running useEffect block which runs getExportCanvasPreview on every state update, even if the modal is not visible (eg: when moving the mouse around!). This puts the modal code in its own component so that it doesn't trigger useEffect when not visible. The code isn't very elegant as we're forwarding all the props, there's likely a better way to handle it (if anyone is interested, PR would be appreciated), but at least now it no longer double renders the scene. Fixes #559 --- src/components/ExportDialog.tsx | 216 ++++++++++++++++++-------------- 1 file changed, 122 insertions(+), 94 deletions(-) diff --git a/src/components/ExportDialog.tsx b/src/components/ExportDialog.tsx index 4eba444c7..0acc30ca8 100644 --- a/src/components/ExportDialog.tsx +++ b/src/components/ExportDialog.tsx @@ -28,7 +28,7 @@ type ExportCB = ( scale?: number, ) => void; -export function ExportDialog({ +function ExportModal({ elements, appState, exportPadding = 10, @@ -37,6 +37,7 @@ export function ExportDialog({ onExportToPng, onExportToClipboard, onExportToBackend, + onCloseRequest, }: { appState: AppState; elements: readonly ExcalidrawElement[]; @@ -46,10 +47,10 @@ export function ExportDialog({ onExportToPng: ExportCB; onExportToClipboard: ExportCB; onExportToBackend: ExportCB; + onCloseRequest: () => void; }) { const { t } = useTranslation(); const someElementIsSelected = elements.some(element => element.isSelected); - const [modalIsShown, setModalIsShown] = useState(false); const [scale, setScale] = useState(defaultScale); const [exportSelected, setExportSelected] = useState(someElementIsSelected); const previewRef = useRef(null); @@ -76,7 +77,6 @@ export function ExportDialog({ previewNode?.removeChild(canvas); }; }, [ - modalIsShown, exportedElements, exportBackground, exportPadding, @@ -84,10 +84,113 @@ export function ExportDialog({ scale, ]); - function handleClose() { - setModalIsShown(false); - setExportSelected(someElementIsSelected); - } + return ( +
+ + +

{t("buttons.export")}

+
+
+ + onExportToPng(exportedElements, scale)} + /> + {probablySupportsClipboard && ( + onExportToClipboard(exportedElements, scale)} + /> + )} + onExportToBackend(exportedElements)} + /> + + + {actionManager.renderAction( + "changeProjectName", + elements, + appState, + syncActionResult, + t, + )} + +
+ + {scales.map(s => ( + setScale(s)} + /> + ))} + +
+ {actionManager.renderAction( + "changeExportBackground", + elements, + appState, + syncActionResult, + t, + )} + {someElementIsSelected && ( +
+ +
+ )} +
+
+
+
+ ); +} + +export function ExportDialog({ + elements, + appState, + exportPadding = 10, + actionManager, + syncActionResult, + onExportToPng, + onExportToClipboard, + onExportToBackend, +}: { + appState: AppState; + elements: readonly ExcalidrawElement[]; + exportPadding?: number; + actionManager: ActionsManagerInterface; + syncActionResult: UpdaterFn; + onExportToPng: ExportCB; + onExportToClipboard: ExportCB; + onExportToBackend: ExportCB; +}) { + const { t } = useTranslation(); + const [modalIsShown, setModalIsShown] = useState(false); return ( <> @@ -99,93 +202,18 @@ export function ExportDialog({ title={t("buttons.export")} /> {modalIsShown && ( - -
- - -

{t("buttons.export")}

-
-
- - onExportToPng(exportedElements, scale)} - /> - {probablySupportsClipboard && ( - - onExportToClipboard(exportedElements, scale) - } - /> - )} - onExportToBackend(exportedElements)} - /> - - - {actionManager.renderAction( - "changeProjectName", - elements, - appState, - syncActionResult, - t, - )} - -
- - {scales.map(s => ( - setScale(s)} - /> - ))} - -
- {actionManager.renderAction( - "changeExportBackground", - elements, - appState, - syncActionResult, - t, - )} - {someElementIsSelected && ( -
- -
- )} -
-
-
-
+ setModalIsShown(false)}> + setModalIsShown(false)} + /> )}