diff options
Diffstat (limited to 'src/client/views/nodes/ImageBox.tsx')
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 154 |
1 files changed, 85 insertions, 69 deletions
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 3a9086777..ec6ce8c2a 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@mui/material'; +import { Slider, Tooltip } from '@mui/material'; import axios from 'axios'; import { Colors, Button, Type, Size } from '@dash/components'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction } from 'mobx'; @@ -44,6 +44,7 @@ import { SmartDrawHandler } from '../smartdraw/SmartDrawHandler'; import { SettingsManager } from '../../util/SettingsManager'; import { AiOutlineSend } from 'react-icons/ai'; import { FireflyImageData } from '../smartdraw/FireflyConstants'; +import { DrawingFillHandler } from '../smartdraw/DrawingFillHandler'; export class ImageEditorData { // eslint-disable-next-line no-use-before-define @@ -96,8 +97,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // variables for AI Image Editor @observable private _regenInput = ''; - @observable private _regenLoading = false; - @observable private _prevImgs: FireflyImageData[] = []; + @observable private _canInteract = true; + @observable private _regenerateLoading = false; + @observable private _prevImgs: FireflyImageData[] = StrCast(this.Document.ai_firefly_history) ? JSON.parse(StrCast(this.Document.ai_firefly_history)) : []; constructor(props: FieldViewProps) { super(props); @@ -385,8 +387,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { : UpdateIcon( this.layoutDoc[Id] + '_icon_' + new Date().getTime(), contentDiv, - usePanelDimensions ? this._props.PanelWidth() : NumCast(this.layoutDoc._width), - usePanelDimensions ? this._props.PanelHeight() : NumCast(this.layoutDoc._height), + usePanelDimensions || true ? this._props.PanelWidth() : NumCast(this.layoutDoc._width), + usePanelDimensions || true ? this._props.PanelHeight() : NumCast(this.layoutDoc._height), this._props.PanelWidth(), this._props.PanelHeight(), 0, @@ -547,82 +549,96 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { const imgs: FireflyImageData[] = this.dataDoc.ai_firefly_history ? JSON.parse(StrCast(this.dataDoc.ai_firefly_history)) : []; return ( <div className="imageBox-aiView-history"> - {imgs.length >= 2 && ( - <Button - text="Clear History" - type={Type.SEC} - style={{ marginTop: '5px' }} - size={Size.XSMALL} - onClick={action(() => { - this._prevImgs = []; - this.dataDoc.ai_firefly_history = undefined; - })} - /> - )} - {imgs.length >= 2 && - imgs.map(img => ( - <div> - <img - key={img.pathname} - className="imageBox-aiView-img" - src={img.href} - onClick={() => { - this.dataDoc[this.fieldKey] = new ImageField(img.pathname); - this.dataDoc.ai_firefly_prompt = img.prompt; - this.dataDoc.ai_firefly_seed = img.seed; - }} - /> - <text className="imageBox-aiView-caption">{img.prompt.replace(/ ~~~/g, ',')}</text> - </div> - ))} + <Button text="Clear History" type={Type.SEC} size={Size.XSMALL} /> + {this._prevImgs.map(img => ( + <div key={img.pathname}> + <img + className="imageBox-aiView-img" + src={ClientUtils.prepend(img.pathname.replace(extname(img.pathname), '_s' + extname(img.pathname)))} + onClick={() => { + this.dataDoc[this.fieldKey] = new ImageField(img.pathname); + this.dataDoc.ai_firefly_prompt = img.prompt; + this.dataDoc.ai_firefly_seed = img.seed; + }} + /> + <span>{img.prompt}</span> + </div> + ))} </div> ); }; + @observable private _fireflyRefStrength = 0; componentAIView = () => { const field = this.dataDoc[this.fieldKey] instanceof ImageField ? Cast(this.dataDoc[this.fieldKey], ImageField, null) : new ImageField(String(this.dataDoc[this.fieldKey])); - const showRegenerate = this.Document[DocData].ai; return ( <div className="imageBox-aiView"> - <text>Edit Image with AI </text> - {showRegenerate && ( - <div className="imageBox-aiView-regenerate-container"> - <div className="imageBox-aiView-regenerate"> - <input - style={{ transform: `scale(${this.uiInputScaling})` }} - className="imageBox-aiView-input" - aria-label="Edit instructions input" - type="text" - value={this._regenInput} - onChange={action(e => (this._regenInput = e.target.value))} - placeholder="Prompt (Optional)" - /> - <Button - style={{ transform: `scale(${this.uiBtnScaling})` }} - text="Regenerate Image" - type={Type.SEC} - onClick={action(async () => { - this._regenLoading = true; - SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput, true).then(newImgs => { - if (newImgs[0]) { - const url = newImgs[0].pathname; - const imgField = new ImageField(url); - this._prevImgs.length === 0 && - this._prevImgs.push({ prompt: StrCast(this.dataDoc.ai_firefly_prompt), seed: this.dataDoc.ai_firefly_seed as number, href: this.paths.lastElement(), pathname: field.url.pathname }); - this.dataDoc[this.fieldKey] = imgField; - this._prevImgs.unshift({ prompt: newImgs[0].prompt, seed: newImgs[0].seed, href: this.paths.lastElement(), pathname: url }); - this.dataDoc.ai_firefly_history = JSON.stringify(this._prevImgs); - this._regenLoading = false; - this._regenInput = ''; - } - }); - })} + <div className="imageBox-aiView-regenerate-container"> + <div className="imageBox-aiView-regenerate"> + Firefly: + <input + className="imageBox-aiView-input" + aria-label="Edit instructions input" + type="text" + value={this._regenInput} + onChange={action(e => this._canInteract && (this._regenInput = e.target.value))} + placeholder={this._regenInput || StrCast(this.Document.title)} + /> + <div className="imageBox-aiView-strength"> + <span style={{ width: 60 }}>Similarity</span> + <Slider + className="imageBox-aiView-slider" + sx={{ + '& .MuiSlider-track': { color: SettingsManager.userVariantColor }, + '& .MuiSlider-rail': { color: SettingsManager.userBackgroundColor }, + '& .MuiSlider-thumb': { color: SettingsManager.userVariantColor, '&.Mui-focusVisible, &:hover, &.Mui-active': { boxShadow: `0px 0px 0px 8px${SettingsManager.userColor.slice(0, 7)}10` } }, + }} + min={0} + max={100} + step={1} + size="small" + value={this._fireflyRefStrength} + onChange={action((e, val) => this._canInteract && (this._fireflyRefStrength = val as number))} + valueLabelDisplay="auto" /> - <Button style={{ transform: `scale(${this.uiBtnScaling})` }} text="Get Variations" type={Type.SEC} iconPlacement="right" /> </div> + <Button + text="Create" + type={Type.SEC} + // style={{ alignSelf: 'flex-end' }} + icon={this._regenerateLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />} + iconPlacement="right" + onClick={action(async () => { + this._regenerateLoading = true; + if (this._fireflyRefStrength) { + DrawingFillHandler.drawingToImage(this.props.Document, this._fireflyRefStrength, this._regenInput || StrCast(this.Document.title))?.then( + action(() => { + this._regenerateLoading = false; + }) + ); + } else + SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput || StrCast(this.Document.title), true).then( + action(newImgs => { + if (newImgs[0]) { + const url = newImgs[0].pathname; + const imgField = new ImageField(url); + this._prevImgs.length === 0 && + this._prevImgs.push({ prompt: StrCast(this.dataDoc.ai_firefly_prompt), seed: this.dataDoc.ai_firefly_seed as number, href: this.paths.lastElement(), pathname: field.url.pathname }); + this._prevImgs.unshift({ prompt: newImgs[0].prompt, seed: newImgs[0].seed, pathname: url }); + this.dataDoc.ai_firefly_history = JSON.stringify(this._prevImgs); + this.dataDoc.ai_firefly_prompt = newImgs[0].prompt; + this.dataDoc[this.fieldKey] = imgField; + this._regenerateLoading = false; + this._regenInput = ''; + } + }) + ); + })} + /> </div> - )} + </div> <div className="imageBox-aiView-options-container"> + <span className="imageBox-aiView-subtitle"> More Options: </span> <div className="imageBox-aiView-options"> {showRegenerate && ( <text className="imageBox-aiView-subtitle" style={{ transform: `scale(${this.uiBtnScaling})` }}> |
