From 30ec70722678eba318fb7521a8b2bd642328bf54 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 23 Feb 2025 16:34:40 -0500
Subject: added option+maximize to open in doc editor view (currently only for
 images).  fixed imageEditor to generate edits the first time through.

---
 src/client/views/nodes/imageEditor/ImageEditor.tsx | 83 ++++++++++------------
 1 file changed, 36 insertions(+), 47 deletions(-)

(limited to 'src/client/views/nodes/imageEditor/ImageEditor.tsx')

diff --git a/src/client/views/nodes/imageEditor/ImageEditor.tsx b/src/client/views/nodes/imageEditor/ImageEditor.tsx
index 6b1d05031..3c0ab3da5 100644
--- a/src/client/views/nodes/imageEditor/ImageEditor.tsx
+++ b/src/client/views/nodes/imageEditor/ImageEditor.tsx
@@ -90,18 +90,8 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
      * @param type The new tool type we are changing to
      */
     const changeTool = (type: ImageToolType) => {
-        switch (type) {
-            case ImageToolType.GenerativeFill:
-                setCurrTool(genFillTool);
-                setCursorData(prev => ({ ...prev, width: genFillTool.sliderDefault as number }));
-                break;
-            case ImageToolType.Cut:
-                setCurrTool(cutTool);
-                setCursorData(prev => ({ ...prev, width: cutTool.sliderDefault as number }));
-                break;
-            default:
-                break;
-        }
+        setCurrToolType(type);
+        setCursorData(prev => ({ ...prev, width: currTool().sliderDefault as number }));
     };
     // Undo and Redo
     const handleUndo = () => {
@@ -171,9 +161,8 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
 
     // handles brushing on pointer movement
     useEffect(() => {
-        if (!isBrushing) return undefined;
         const canvas = canvasRef.current;
-        if (!canvas) return undefined;
+        if (!isBrushing || !canvas) return undefined;
         const ctx = ImageUtility.getCanvasContext(canvasRef);
         if (!ctx) return undefined;
 
@@ -188,33 +177,29 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
         };
 
         drawingAreaRef.current?.addEventListener('pointermove', handlePointerMove);
-        return () => {
-            drawingAreaRef.current?.removeEventListener('pointermove', handlePointerMove);
-        };
+        return () => drawingAreaRef.current?.removeEventListener('pointermove', handlePointerMove);
     }, [isBrushing]);
 
     // first load
     useEffect(() => {
-        const loadInitial = async () => {
-            if (!imageEditorSource || imageEditorSource === '') return;
-            const img = new Image();
-            const res = await ImageUtility.urlToBase64(imageEditorSource);
-            if (!res) return;
-            img.src = `data:image/png;base64,${res}`;
-
-            img.onload = () => {
-                currImg.current = img;
-                originalImg.current = img;
-                const imgWidth = img.naturalWidth;
-                const imgHeight = img.naturalHeight;
-                const scale = Math.min(canvasSize / imgWidth, canvasSize / imgHeight);
-                const width = imgWidth * scale;
-                const height = imgHeight * scale;
-                setCanvasDims({ width, height });
-            };
-        };
-
-        loadInitial();
+        if (imageEditorSource && imageEditorSource) {
+            ImageUtility.urlToBase64(imageEditorSource).then(res => {
+                if (res) {
+                    const img = new Image();
+                    img.src = `data:image/png;base64,${res}`;
+                    img.onload = () => {
+                        currImg.current = img;
+                        originalImg.current = img;
+                        const imgWidth = img.naturalWidth;
+                        const imgHeight = img.naturalHeight;
+                        const scale = Math.min(canvasSize / imgWidth, canvasSize / imgHeight);
+                        const width = imgWidth * scale;
+                        const height = imgHeight * scale;
+                        setCanvasDims({ width, height });
+                    };
+                }
+            });
+        }
 
         // cleanup
         return () => {
@@ -300,7 +285,7 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
             if (!canvasMask) return;
             const maskBlob = await ImageUtility.canvasToBlob(canvasMask);
             const imgBlob = await ImageUtility.canvasToBlob(canvasOriginalImg);
-            const res = await ImageUtility.getEdit(imgBlob, maskBlob, input !== '' ? input + ' in the same style' : 'Fill in the image in the same style', 2);
+            const res = await ImageUtility.getEdit(imgBlob, maskBlob, input || 'Fill in the image in the same style', 2);
 
             // create first image
             if (!newCollectionRef.current) {
@@ -569,11 +554,15 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
         setIsFirstDoc(true);
     };
 
+    function currTool() {
+        return imageEditTools.find(tool => tool.type === currToolType) ?? genFillTool;
+    }
+
     // defines the tools and sets current tool
-    const genFillTool: ImageEditTool = { type: ImageToolType.GenerativeFill, name: 'Generative Fill', btnText: 'GET EDITS', icon: 'fill', applyFunc: getEdit, sliderMin: 25, sliderMax: 500, sliderDefault: 150 };
-    const cutTool: ImageEditTool = { type: ImageToolType.Cut, name: 'Cut', btnText: 'CUT IMAGE', icon: 'scissors', applyFunc: cutImage, sliderMin: 1, sliderMax: 50, sliderDefault: 5 };
+    const genFillTool: ImageEditTool = { type: ImageToolType.GenerativeFill, btnText: 'GET EDITS', icon: 'fill', applyFunc: getEdit, sliderMin: 25, sliderMax: 500, sliderDefault: 150 };
+    const cutTool: ImageEditTool = { type: ImageToolType.Cut, btnText: 'CUT IMAGE', icon: 'scissors', applyFunc: cutImage, sliderMin: 1, sliderMax: 50, sliderDefault: 5 };
     const imageEditTools: ImageEditTool[] = [genFillTool, cutTool];
-    const [currTool, setCurrTool] = useState<ImageEditTool>(genFillTool);
+    const [currToolType, setCurrToolType] = useState<ImageToolType>(ImageToolType.GenerativeFill);
 
     // the top controls for making a new collection, resetting, and applying edits,
     function renderControls() {
@@ -595,7 +584,7 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
                         labelPlacement="end"
                         sx={{ whiteSpace: 'nowrap' }}
                     />
-                    <ApplyFuncButtons onClick={() => currTool.applyFunc(cutType, cursorData.width, edits, isFirstDoc)} loading={loading} onReset={handleReset} btnText={currTool.btnText} />
+                    <ApplyFuncButtons onClick={() => currTool().applyFunc(cutType, cursorData.width, edits, isFirstDoc)} loading={loading} onReset={handleReset} btnText={currTool().btnText} />
                     <IconButton color={activeColor} tooltip="close" icon={<CgClose size="16px" />} onClick={handleViewClose} />
                 </div>
             </div>
@@ -607,8 +596,8 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
         return (
             <div className="sideControlsContainer" style={{ backgroundColor: bgColor }}>
                 <div className="sideControls">
-                    <div className="imageToolsContainer">{imageEditTools.map(tool => ImageToolButton(tool, tool.type === currTool.type, changeTool))}</div>
-                    {currTool.type == ImageToolType.Cut && (
+                    <div className="imageToolsContainer">{imageEditTools.map(tool => ImageToolButton(tool, tool.type === currTool().type, changeTool))}</div>
+                    {currTool().type == ImageToolType.Cut && (
                         <div className="cutToolsContainer">
                             <Button style={{ width: '100%' }} text="Keep in" type={Type.TERT} color={cutType == CutMode.IN ? SettingsManager.userColor : bgColor} onClick={() => setCutType(CutMode.IN)} />
                             <Button style={{ width: '100%' }} text="Keep out" type={Type.TERT} color={cutType == CutMode.OUT ? SettingsManager.userColor : bgColor} onClick={() => setCutType(CutMode.OUT)} />
@@ -617,7 +606,7 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
                         </div>
                     )}
                     <div className="sliderContainer" onPointerDown={e => e.stopPropagation()}>
-                        {currTool.type === ImageToolType.GenerativeFill && (
+                        {currTool().type === ImageToolType.GenerativeFill && (
                             <Slider
                                 sx={{
                                     '& input[type="range"]': {
@@ -633,7 +622,7 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
                                 onChange={(e, val) => setCursorData(prev => ({ ...prev, width: val as number }))}
                             />
                         )}
-                        {currTool.type === ImageToolType.Cut && (
+                        {currTool().type === ImageToolType.Cut && (
                             <Slider
                                 sx={{
                                     '& input[type="range"]': {
@@ -780,7 +769,7 @@ const ImageEditor = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addDoc
                 {renderSideIcons()}
                 {renderEditThumbnails()}
             </div>
-            {currTool.type === ImageToolType.GenerativeFill && renderPromptBox()}
+            {currTool().type === ImageToolType.GenerativeFill && renderPromptBox()}
         </div>
     );
 };
-- 
cgit v1.2.3-70-g09d2

