diff options
Diffstat (limited to 'src/client/views/nodes/generativeFill/GenerativeFill.tsx')
-rw-r--r-- | src/client/views/nodes/generativeFill/GenerativeFill.tsx | 115 |
1 files changed, 74 insertions, 41 deletions
diff --git a/src/client/views/nodes/generativeFill/GenerativeFill.tsx b/src/client/views/nodes/generativeFill/GenerativeFill.tsx index f8f9fe077..99068d647 100644 --- a/src/client/views/nodes/generativeFill/GenerativeFill.tsx +++ b/src/client/views/nodes/generativeFill/GenerativeFill.tsx @@ -3,7 +3,7 @@ import React = require('react'); import { useEffect, useRef, useState } from 'react'; import { APISuccess, ImageUtility } from './generativeFillUtils/ImageHandler'; import { BrushHandler } from './generativeFillUtils/BrushHandler'; -import { Box, IconButton, Slider, TextField } from '@mui/material'; +import { Box, Checkbox, FormControlLabel, IconButton, Slider, TextField } from '@mui/material'; import { CursorData, Point } from './generativeFillUtils/generativeFillInterfaces'; import { activeColor, canvasSize, eraserColor, freeformRenderSize, newCollectionSize, offsetDistanceY, offsetX } from './generativeFillUtils/generativeFillConstants'; import { PointerHandler } from './generativeFillUtils/PointerHandler'; @@ -19,6 +19,7 @@ import { Cast, DocCast, NumCast } from '../../../../fields/Types'; import { CollectionDockingView } from '../../collections/CollectionDockingView'; import { OpenWhere, OpenWhereMod } from '../DocumentView'; import { Oval } from 'react-loader-spinner'; +import { CheckBox } from '../../search/CheckBox'; /** * For images not 1024x1024 fill in the rest in solid black, or a @@ -72,6 +73,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD const [input, setInput] = useState(''); const [loading, setLoading] = useState(false); const [saveLoading, setSaveLoading] = useState(false); + const [isNewCollection, setIsNewCollection] = useState(false); // the current image in the main canvas const currImg = useRef<HTMLImageElement | null>(null); // the unedited version of each generation (parent) @@ -81,9 +83,6 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD // stores redo stack const redoStack = useRef<string[]>([]); - // early stage properly, likely will get rid of - const freeformPosition = useRef<number[]>([0, 0]); - // which urls were already saved to canvas const savedSrcs = useRef<Set<string>>(new Set()); @@ -91,7 +90,6 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD const newCollectionRef = useRef<Doc | null>(null); const parentDoc = useRef<Doc | null>(null); const childrenDocs = useRef<Doc[]>([]); - const addToExistingCollection = useRef<boolean>(false); // Undo and Redo const handleUndo = () => { @@ -111,10 +109,13 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD }; const handleRedo = () => { - // TODO: handle undo as well + const ctx = ImageUtility.getCanvasContext(canvasRef); + if (!ctx || !currImg.current || !canvasRef.current) return; + const target = redoStack.current[redoStack.current.length - 1]; if (!target) { } else { + undoStack.current = [...undoStack.current, canvasRef.current?.toDataURL()]; const img = new Image(); img.src = target; ImageUtility.drawImgToCanvas(img, canvasRef); @@ -188,7 +189,6 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD ImageUtility.drawImgToCanvas(img, canvasRef); currImg.current = img; originalImg.current = img; - freeformPosition.current = [0, 0]; return () => { console.log('cleanup'); @@ -197,7 +197,6 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD childrenDocs.current = []; currImg.current = null; originalImg.current = null; - freeformPosition.current = [0, 0]; undoStack.current = []; redoStack.current = []; }; @@ -266,24 +265,25 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD // create first image if (!newCollectionRef.current) { - if (addToExistingCollection.current) { + if (!isNewCollection) { + // newcollection should stay null + } else { + if (!(originalImg.current && imageRootDoc)) return; + // create new collection and add it to the view + newCollectionRef.current = Docs.Create.FreeformDocument([], { + x: NumCast(imageRootDoc.x) + NumCast(imageRootDoc._width) + offsetX, + y: NumCast(imageRootDoc.y), + _width: newCollectionSize, + _height: newCollectionSize, + title: 'Image edit collection', + }); + DocUtils.MakeLink(imageRootDoc, newCollectionRef.current, { link_relationship: 'Image Edit Version History', link_displayLine: false }); + // add the doc to the main freeform + addDoc?.(newCollectionRef.current); + await createNewImgDoc(originalImg.current, true); } - if (!(originalImg.current && imageRootDoc)) return; - console.log('creating first image'); - // create new collection and add it to the view - newCollectionRef.current = Docs.Create.FreeformDocument([], { - x: NumCast(imageRootDoc.x) + NumCast(imageRootDoc._width) + offsetX, - y: NumCast(imageRootDoc.y), - _width: newCollectionSize, - _height: newCollectionSize, - title: 'Image edit collection', - }); - DocUtils.MakeLink(imageRootDoc, newCollectionRef.current, { link_relationship: 'Image Edit Version History', link_displayLine: false }); - // add the doc to the main freeform - // addDoc?.(newCollectionRef.current); - await createNewImgDoc(originalImg.current, true); } else { - parentDoc.current = childrenDocs.current[childrenDocs.current.length - 1]; + // parentDoc.current = childrenDocs.current[childrenDocs.current.length - 1]; childrenDocs.current = []; } @@ -292,12 +292,24 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD const { urls } = res as APISuccess; const image = new Image(); image.src = urls[0]; + + // need to crop images agh + // save to dash + + // const imageRes = await Promise.all( + // urls.map(async url => { + // const newImg = new Image(); + // newImg.src = url; + // await onSave(newImg); + // }) + // ); + + // map each url to [url, imgDoc] setEdits(urls); + ImageUtility.drawImgToCanvas(image, canvasRef); currImg.current = image; - onSave(); - freeformPosition.current[0] += 1; - freeformPosition.current[1] = 0; + // onSave(currImg.current); } catch (err) { console.log(err); } @@ -324,7 +336,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD // creates a new image document and returns its reference const createNewImgDoc = async (img: HTMLImageElement, firstDoc: boolean): Promise<Doc | undefined> => { - if (!newCollectionRef.current || !imageRootDoc) return; + if (!imageRootDoc) return; const src = img.src; const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [src] }); const source = Utils.prepend(result.accessPaths.agnostic.client); @@ -332,7 +344,6 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD if (firstDoc) { const x = 0; const initialY = 0; - console.log('first doc'); const newImg = Docs.Create.ImageDocument(source, { x: x, @@ -343,16 +354,19 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD data_nativeHeight: result.nativeHeight, }); - Doc.AddDocToList(newCollectionRef.current, undefined, newImg); + if (isNewCollection && newCollectionRef.current) { + Doc.AddDocToList(newCollectionRef.current, undefined, newImg); + } else { + addDoc?.(newImg); + } + parentDoc.current = newImg; return newImg; } else { if (!parentDoc.current) return; const x = NumCast(parentDoc.current.x) + freeformRenderSize + offsetX; // dummy position - console.log('creating child elements'); const initialY = 0; - const newImg = Docs.Create.ImageDocument(source, { x: x, y: initialY, @@ -363,21 +377,26 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD }); childrenDocs.current.push(newImg); + + if (isNewCollection && newCollectionRef.current) { + Doc.AddDocToList(newCollectionRef.current, undefined, newImg); + } else { + addDoc?.(newImg); + } + DocUtils.MakeLink(parentDoc.current, newImg, { link_relationship: 'Image Edit', link_displayLine: true }); adjustImgPositions(); - - Doc.AddDocToList(newCollectionRef.current, undefined, newImg); return newImg; } }; // need to maybe call on every img click, not just when the save btn is clicked - const onSave = async () => { + const onSave = async (img: HTMLImageElement) => { setSaveLoading(true); - if (!currImg.current || !originalImg.current || !imageRootDoc) return; + // if (!currImg.current || !originalImg.current || !imageRootDoc) return; try { console.log('creating another image'); - await createNewImgDoc(currImg.current, false); + await createNewImgDoc(img, false); } catch (err) { console.log(err); } @@ -387,7 +406,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD const handleViewClose = () => { if (newCollectionRef.current) { newCollectionRef.current.fitContentOnce = true; - CollectionDockingView.AddSplit(newCollectionRef.current, OpenWhereMod.right); + // CollectionDockingView.AddSplit(newCollectionRef.current, OpenWhereMod.right); } MainView.Instance.setImageEditorOpen(false); MainView.Instance.setImageEditorSource(''); @@ -399,7 +418,20 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD <div className="generativeFillControls"> <h1>AI Image Editor</h1> <div style={{ display: 'flex', alignItems: 'center', gap: '1.5rem' }}> - <Buttons canvasRef={canvasRef} currImg={currImg} getEdit={getEdit} loading={loading} onSave={onSave} onReset={handleReset} /> + <FormControlLabel + control={ + <Checkbox + checked={isNewCollection} + onChange={e => { + setIsNewCollection(prev => !prev); + }} + /> + } + label={'Create New Collection'} + labelPlacement="end" + sx={{ whiteSpace: 'nowrap' }} + /> + <Buttons canvasRef={canvasRef} currImg={currImg} getEdit={getEdit} loading={loading} onReset={handleReset} /> <IconButton onClick={handleViewClose}> <BsX color={activeColor} /> </IconButton> @@ -491,13 +523,14 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD height={100} src={edit} onClick={async () => { - // if (savedSrcs.current.has(edit)) return; const img = new Image(); img.src = edit; ImageUtility.drawImgToCanvas(img, canvasRef); currImg.current = img; savedSrcs.current.add(edit); - await onSave(); + undoStack.current = []; + redoStack.current = []; + await onSave(img); }} /> ))} |