From 45e22be891331e2d6a381e988c7abd29af3e1399 Mon Sep 17 00:00:00 2001 From: eleanor-park Date: Wed, 8 Jan 2025 02:26:53 -0500 Subject: added componentAIView for collections --- .../collectionFreeForm/CollectionFreeFormView.tsx | 226 ++++++++++++++------- src/client/views/nodes/ImageBox.tsx | 33 ++- src/client/views/smartdraw/SmartDrawHandler.tsx | 2 +- 3 files changed, 168 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9af698ec7..af82724ef 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,5 +1,5 @@ import { Bezier } from 'bezier-js'; -import { Colors } from 'browndash-components'; +import { Button, Colors, Type } from 'browndash-components'; import { Property } from 'csstype'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -67,6 +67,8 @@ import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannable import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors'; import './CollectionFreeFormView.scss'; import { MarqueeView } from './MarqueeView'; +import ReactLoading from 'react-loading'; +import { SettingsManager } from '../../../util/SettingsManager'; @observer class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> { @@ -2186,84 +2188,160 @@ export class CollectionFreeFormView extends CollectionSubView ); } - render() { - TraceMobx(); + + @observable private _regenInput = ''; + @observable private _canInteract = true; + @observable private _regenerateLoading = false; + + componentAIViewHistory = () => { return ( -
{ - this.createDashEventsTarget(r); - this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel); - this._oldWheel = r; - // prevent wheel events from passivly propagating up through containers - r?.addEventListener('wheel', this.onPassiveWheel, { passive: false }); - r?.addEventListener('mouseleave', this.onMouseLeave); - r?.addEventListener('mouseenter', this.onMouseEnter); - }} - onWheel={this.onPointerWheel} - onClick={this.onClick} - onPointerDown={this.onPointerDown} - onPointerMove={this.onCursorMove} - onDrop={this.onExternalDrop} - onDragOver={e => e.preventDefault()} - onContextMenu={this.onContextMenu} - style={{ - pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : this._props.pointerEvents?.(), - textAlign: this.isAnnotationOverlay ? 'initial' : undefined, - transform: `scale(${this.nativeDimScaling})`, - width: `${100 / this.nativeDimScaling}%`, - height: this._props.getScrollHeight?.() ?? `${100 / this.nativeDimScaling}%`, - }}> - {Doc.ActiveTool === InkTool.Eraser && Doc.ActiveEraser === InkEraserTool.Radius && this._showEraserCircle && ( -
+ {/* {this._prevImgs.map(img => ( + { + this.dataDoc[this.fieldKey] = new ImageField(img.pathname); + this.dataDoc.ai_firefly_prompt = img.prompt; + this.dataDoc.ai_firefly_seed = img.seed; }} /> - )} - {this.paintFunc ? ( - // need this so that any live dashfieldviews will update the underlying text that the code eval reads - ) : this._lightboxDoc ? ( -
- + ))} */} +
+ ); + }; + + componentAIView = () => { + const showRegenerate = this.Document[DocData].ai; + return ( +
+ Edit Image with AI + {showRegenerate && ( +
+ {/* Regenerate AI Image +
+ this._canInteract && (this._regenInput = e.target.value))} + // onKeyDown={this.handleKeyPress} + placeholder="Prompt (Optional)" + /> +
*/}
- ) : ( - <> - {this._firstRender ? this.placeholder : this.marqueeView} - {this._props.noOverlay ? null : } - {!this.GroupChildDrag ? null :
} - )} +
+ {showRegenerate && Turn Drawing to Image } +
+
+
+ ); + }; + + render() { + TraceMobx(); + return ( +
+
{ + this.createDashEventsTarget(r); + this._oldWheel?.removeEventListener('wheel', this.onPassiveWheel); + this._oldWheel = r; + // prevent wheel events from passivly propagating up through containers + r?.addEventListener('wheel', this.onPassiveWheel, { passive: false }); + r?.addEventListener('mouseleave', this.onMouseLeave); + r?.addEventListener('mouseenter', this.onMouseEnter); + }} + onWheel={this.onPointerWheel} + onClick={this.onClick} + onPointerDown={this.onPointerDown} + onPointerMove={this.onCursorMove} + onDrop={this.onExternalDrop} + onDragOver={e => e.preventDefault()} + onContextMenu={this.onContextMenu} + style={{ + pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : this._props.pointerEvents?.(), + textAlign: this.isAnnotationOverlay ? 'initial' : undefined, + transform: `scale(${this.nativeDimScaling})`, + width: `${100 / this.nativeDimScaling}%`, + height: this._props.getScrollHeight?.() ?? `${100 / this.nativeDimScaling}%`, + }}> + {Doc.ActiveTool === InkTool.Eraser && Doc.ActiveEraser === InkEraserTool.Radius && this._showEraserCircle && ( +
+ )} + {this.paintFunc ? ( + // need this so that any live dashfieldviews will update the underlying text that the code eval reads + ) : this._lightboxDoc ? ( +
+ +
+ ) : ( + <> + {this._firstRender ? this.placeholder : this.marqueeView} + {this._props.noOverlay ? null : } + {!this.GroupChildDrag ? null :
} + + )} +
); } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index a1fa9a283..6b9e170c8 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -580,24 +580,21 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { // style={{ alignSelf: 'flex-end' }} icon={this._regenerateLoading ? : } iconPlacement="right" - onClick={undoable( - action(async () => { - this._regenerateLoading = 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: NumCast(this.dataDoc.ai_firefly_seed), 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._regenerateLoading = false; - this._regenInput = ''; - } - }); - }), - 'regenerate image' - )} + onClick={action(async () => { + this._regenerateLoading = 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._regenerateLoading = false; + this._regenInput = ''; + } + }); + })} />