diff options
Diffstat (limited to 'src/client/views/nodes/generativeFill/GenerativeFill.tsx')
-rw-r--r-- | src/client/views/nodes/generativeFill/GenerativeFill.tsx | 103 |
1 files changed, 51 insertions, 52 deletions
diff --git a/src/client/views/nodes/generativeFill/GenerativeFill.tsx b/src/client/views/nodes/generativeFill/GenerativeFill.tsx index 2b3cfb920..f8f9fe077 100644 --- a/src/client/views/nodes/generativeFill/GenerativeFill.tsx +++ b/src/client/views/nodes/generativeFill/GenerativeFill.tsx @@ -3,21 +3,19 @@ import React = require('react'); import { useEffect, useRef, useState } from 'react'; import { APISuccess, ImageUtility } from './generativeFillUtils/ImageHandler'; import { BrushHandler } from './generativeFillUtils/BrushHandler'; -import { IconButton, TextField } from '@mui/material'; +import { Box, 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'; -import { BsBrush, BsEraser, BsX } from 'react-icons/bs'; -import { AiOutlineUpload } from 'react-icons/ai'; +import { BsEraser, BsX } from 'react-icons/bs'; import { CiUndo, CiRedo } from 'react-icons/ci'; import Buttons from './GenerativeFillButtons'; -import { EditableText } from 'browndash-components'; import { MainView } from '../../MainView'; import { Doc } from '../../../../fields/Doc'; import { Networking } from '../../../Network'; import { Utils } from '../../../../Utils'; import { DocUtils, Docs } from '../../../documents/Documents'; -import { DocCast, NumCast } from '../../../../fields/Types'; +import { Cast, DocCast, NumCast } from '../../../../fields/Types'; import { CollectionDockingView } from '../../collections/CollectionDockingView'; import { OpenWhere, OpenWhereMod } from '../DocumentView'; import { Oval } from 'react-loader-spinner'; @@ -25,12 +23,11 @@ import { Oval } from 'react-loader-spinner'; /** * For images not 1024x1024 fill in the rest in solid black, or a * reflected version of the image. + * + * add a branch from image directly checkbox */ /** - * TODO: Look into img onload, sometimes the canvas doesn't update properly - * - * Ref: * * * CollectionDockingView.AddSplit(Doc.MakeCopy(DocCast(Doc.UserDoc().emptyPane)), OpenWhereMod.right); @@ -88,12 +85,13 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD const freeformPosition = useRef<number[]>([0, 0]); // which urls were already saved to canvas - const savedSrcs = useRef<string[]>([]); + const savedSrcs = useRef<Set<string>>(new Set()); // references to keep track of tree structure 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 = () => { @@ -250,18 +248,6 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD })); }; - // File upload - const uploadImg = (e: React.ChangeEvent<HTMLInputElement>) => { - if (e.target.files) { - const file = e.target.files[0]; - const image = new Image(); - const imgUrl = URL.createObjectURL(file); - image.src = imgUrl; - ImageUtility.drawImgToCanvas(image, canvasRef); - currImg.current = image; - } - }; - // Get AI Edit const getEdit = async () => { const img = currImg.current; @@ -280,6 +266,8 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD // create first image if (!newCollectionRef.current) { + if (addToExistingCollection.current) { + } if (!(originalImg.current && imageRootDoc)) return; console.log('creating first image'); // create new collection and add it to the view @@ -292,7 +280,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD }); DocUtils.MakeLink(imageRootDoc, newCollectionRef.current, { link_relationship: 'Image Edit Version History', link_displayLine: false }); // add the doc to the main freeform - addDoc?.(newCollectionRef.current); + // addDoc?.(newCollectionRef.current); await createNewImgDoc(originalImg.current, true); } else { parentDoc.current = childrenDocs.current[childrenDocs.current.length - 1]; @@ -321,7 +309,6 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD if (!parentDoc.current) return; const startY = NumCast(parentDoc.current.y); const len = childrenDocs.current.length; - console.log(len); let initialYPositions: number[] = []; for (let i = 0; i < len; i++) { initialYPositions.push(startY + i * offsetDistanceY); @@ -398,9 +385,10 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD }; const handleViewClose = () => { - // if (newCollectionRef.current) { - // CollectionDockingView.AddSplit(newCollectionRef.current, OpenWhereMod.right); - // } + if (newCollectionRef.current) { + newCollectionRef.current.fitContentOnce = true; + CollectionDockingView.AddSplit(newCollectionRef.current, OpenWhereMod.right); + } MainView.Instance.setImageEditorOpen(false); MainView.Instance.setImageEditorSource(''); setEdits([]); @@ -409,12 +397,17 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD return ( <div className="generativeFillContainer" style={{ display: imageEditorOpen ? 'flex' : 'none' }}> <div className="generativeFillControls"> - <h1>Generative Fill</h1> + <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} /> <IconButton onClick={handleViewClose}> <BsX color={activeColor} /> </IconButton> + {saveLoading && ( + <span style={{ height: '100%', display: 'flex', alignItems: 'center', gap: '8px' }}> + Saving image... <Oval height={20} width={20} color="#000000" visible={true} ariaLabel="oval-loading" secondaryColor="#ffffff89" strokeWidth={3} strokeWidthSecondary={3} /> + </span> + )} </div> </div> {/* Main canvas for editing */} @@ -439,20 +432,11 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD </div> {/* Icons */} <div className="iconContainer"> - <input ref={fileRef} type="file" accept="image/*" onChange={uploadImg} style={{ display: 'none' }} /> - <IconButton - onClick={() => { - if (fileRef.current) { - fileRef.current.click(); - } - }}> - <AiOutlineUpload /> - </IconButton> <IconButton onClick={() => { setBrushStyle(BrushStyle.ADD); }}> - <BsBrush color={brushStyle === BrushStyle.ADD ? activeColor : 'inherit'} /> + <BsEraser color={brushStyle === BrushStyle.ADD ? activeColor : 'inherit'} /> </IconButton> {/* Undo and Redo */} <IconButton @@ -475,6 +459,28 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD }}> <CiRedo /> </IconButton> + <Box + sx={{ + height: 225, + width: '100%', + display: 'flex', + justifyContent: 'center', + }}> + <Slider + sx={{ + '& input[type="range"]': { + WebkitAppearance: 'slider-vertical', + }, + }} + orientation="vertical" + min={10} + max={500} + defaultValue={150} + onChange={(e, val) => { + setCursorData(prev => ({ ...prev, width: val as number })); + }} + /> + </Box> </div> {/* Edits thumbnails*/} <div className="editsBox"> @@ -484,12 +490,14 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD width={100} height={100} src={edit} - onClick={() => { + onClick={async () => { + // if (savedSrcs.current.has(edit)) return; const img = new Image(); img.src = edit; ImageUtility.drawImgToCanvas(img, canvasRef); currImg.current = img; - onSave(); + savedSrcs.current.add(edit); + await onSave(); }} /> ))} @@ -521,14 +529,6 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD currImg.current = img; }} /> - <div - style={{ - position: 'absolute', - top: 10, - right: 10, - }}> - {saveLoading && <Oval height={20} width={20} color="#ffffff" visible={true} ariaLabel="oval-loading" secondaryColor="#ffffff89" strokeWidth={3} strokeWidthSecondary={3} />} - </div> </div> )} </div> @@ -541,15 +541,14 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD type="text" label="Prompt" placeholder="Prompt..." - InputLabelProps={{ style: { fontSize: '1.5rem' } }} - inputProps={{ style: { fontSize: '1.5rem' } }} + InputLabelProps={{ style: { fontSize: '16px' } }} + inputProps={{ style: { fontSize: '16px' } }} sx={{ backgroundColor: '#ffffff', position: 'absolute', - bottom: '1rem', + bottom: '16px', transform: 'translateX(calc(50vw - 50%))', - width: 'calc(100vw - 4rem)', - scale: 1.2, + width: 'calc(100vw - 64px)', }} /> </div> |