aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/generativeFill/GenerativeFill.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/generativeFill/GenerativeFill.tsx')
-rw-r--r--src/client/views/nodes/generativeFill/GenerativeFill.tsx115
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);
}}
/>
))}