diff options
| author | bobzel <zzzman@gmail.com> | 2025-01-21 10:16:51 -0500 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2025-01-21 10:16:51 -0500 |
| commit | caf384bb374c47118296aa397446e85d3121116b (patch) | |
| tree | da270043f88d6cfa0d6b8f1838a55f6faba35bfa /src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | |
| parent | 22daafa9c505eb9bffb8604be0924a7450d20113 (diff) | |
| parent | a6a6929501b7ce9b3ceed73c7e8141a8d8f0c7dc (diff) | |
Merge branch 'master' into alyssa-agent
Diffstat (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')
| -rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 168 |
1 files changed, 138 insertions, 30 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index f2a5780c5..796949378 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 '@dash/components'; import { Property } from 'csstype'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -55,7 +55,7 @@ import { FocusViewOptions } from '../../nodes/FocusViewOptions'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { OpenWhere } from '../../nodes/OpenWhere'; import { PinDocView, PinProps } from '../../PinFuncs'; -import { AnnotationPalette } from '../../smartdraw/AnnotationPalette'; +import { StickerPalette } from '../../smartdraw/StickerPalette'; import { DrawingOptions, SmartDrawHandler } from '../../smartdraw/SmartDrawHandler'; import { StyleProp } from '../../StyleProp'; import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; @@ -67,6 +67,11 @@ 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'; +import { Slider } from '@mui/material'; +import { AiOutlineSend } from 'react-icons/ai'; +import { DrawingFillHandler } from '../../smartdraw/DrawingFillHandler'; @observer class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> { @@ -98,6 +103,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection const parent = CollectionFreeFormDocumentView.from(dv)?._props.reactParent; return parent instanceof CollectionFreeFormView ? parent : undefined; } + /** + * The Freeformview below the cursor at the start of a gesture (that receives the pointerDown event). Used by GestureOverlay to determine the doc a gesture should apply to. + */ + // eslint-disable-next-line no-use-before-define + public static DownFfview: CollectionFreeFormView | undefined; // the first DocView that receives a pointerdown event. used by GestureOverlay to determine the doc a gesture should apply to. private _clusters = new CollectionFreeFormClusters(this); private _oldWheel: HTMLDivElement | null = null; @@ -477,11 +487,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection // do nothing if link is dropped into any freeform view parent of dragged document const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, x, y, title: 'dropped annotation' }); const added = !!this._props.addDocument?.(source); - de.complete.linkDocument = DocUtils.MakeLink(linkDragData.linkSourceGetAnchor(), source, { link_relationship: 'annotated by:annotation of' }); - if (de.complete.linkDocument) { - de.complete.linkDocument.layout_isSvg = true; - this.addDocument(de.complete.linkDocument); - } + de.complete.linkDocument = DocUtils.MakeLink(linkDragData.linkSourceGetAnchor(), source, { layout_isSvg: true, link_relationship: 'annotated by:annotation of' }); + de.complete.linkDocument && this.addDocument(de.complete.linkDocument); e.stopPropagation(); !added && e.preventDefault(); return added; @@ -500,6 +507,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @action onPointerDown = (e: React.PointerEvent): void => { + if (!CollectionFreeFormView.DownFfview) CollectionFreeFormView.DownFfview = this; + this._downX = this._lastX = e.pageX; this._downY = this._lastY = e.pageY; this._downTime = Date.now(); @@ -1225,7 +1234,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection SmartDrawHandler.Instance.CreateDrawingDoc = this.createDrawingDoc; SmartDrawHandler.Instance.RemoveDrawing = this.removeDrawing; SmartDrawHandler.Instance.AddDrawing = this.addDrawing; - SmartDrawHandler.Instance.displaySmartDrawHandler(x, y); + SmartDrawHandler.Instance.displaySmartDrawHandler(x, y, NumCast(this.layoutDoc[this.scaleFieldKey])); }; _drawing: Doc[] = []; @@ -1285,12 +1294,13 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection addDrawing = (doc: Doc, opts: DrawingOptions, gptRes: string) => { const docData = doc[DocData]; docData.title = opts.text.match(/^(.*?)~~~.*$/)?.[1] || opts.text; - docData.width = opts.size; - docData.drawingInput = opts.text; - docData.drawingComplexity = opts.complexity; - docData.drawingColored = opts.autoColor; - docData.drawingSize = opts.size; - docData.drawingData = gptRes; + docData._width = opts.size; + docData.ai_drawing_input = opts.text; + docData.ai_drawing_complexity = opts.complexity; + docData.ai_drawing_colored = opts.autoColor; + docData.ai_drawing_size = opts.size; + docData.ai_drawing_data = gptRes; + docData.ai = 'gpt'; this._drawingContainer = doc; this.addDocument(doc); this._batch?.end(); @@ -1320,6 +1330,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection this.Document[this.scaleFieldKey] = Math.abs(safeScale); this.setPan(-localTransform.TranslateX / safeScale, (this._props.originTopLeft ? undefined : NumCast(this.Document.layout_scrollTop) * safeScale) || -localTransform.TranslateY / safeScale, undefined, allowScroll); } + SmartDrawHandler.Instance.hideSmartDrawHandler(); }; @action @@ -1860,14 +1871,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection } updateIcon = (usePanelDimensions?: boolean) => { - const contentDiv = this.DocumentView?.().ContentDiv; + const contentDiv = this._mainCont; return !contentDiv ? new Promise<void>(res => res()) : 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, @@ -1987,20 +1998,21 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection }), icon: 'eye', }); + this.layoutDoc.drawingData != undefined && + optionItems.push({ + description: 'Regenerate AI Drawing', + event: action(() => { + SmartDrawHandler.Instance.CreateDrawingDoc = this.createDrawingDoc; + SmartDrawHandler.Instance.AddDrawing = this.addDrawing; + SmartDrawHandler.Instance.RemoveDrawing = this.removeDrawing; + !SmartDrawHandler.Instance.ShowRegenerate ? SmartDrawHandler.Instance.displayRegenerate(this._downX, this._downY - 10) : SmartDrawHandler.Instance.hideRegenerate(); + }), + icon: 'pen-to-square', + }); optionItems.push({ - description: 'Show Drawing Editor', - event: action(() => { - SmartDrawHandler.Instance.CreateDrawingDoc = this.createDrawingDoc; - SmartDrawHandler.Instance.AddDrawing = this.addDrawing; - SmartDrawHandler.Instance.RemoveDrawing = this.removeDrawing; - !SmartDrawHandler.Instance.ShowRegenerate ? SmartDrawHandler.Instance.displayRegenerate(this._downX, this._downY - 10) : SmartDrawHandler.Instance.hideRegenerate(); - }), - icon: 'pen-to-square', - }); - optionItems.push({ - description: this.Document.savedAsAnno ? 'Saved as Annotation!' : 'Save to Annotation Palette', - event: action(undoable(async () => await AnnotationPalette.addToPalette(this.Document), 'save to palette')), - icon: this.Document.savedAsAnno ? 'clipboard-check' : 'file-arrow-down', + description: this.Document.savedAsSticker ? 'Sticker Saved!' : 'Save to Stickers', + event: action(undoable(async () => await StickerPalette.addToPalette(this.Document), 'save to palette')), + icon: this.Document.savedAsSticker ? 'clipboard-check' : 'file-arrow-down', }); this._props.renderDepth && optionItems.push({ @@ -2179,6 +2191,102 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection </div> ); } + + @observable private _regenInput = ''; + @observable private _drawingFillInput = ''; + @observable private _regenLoading = false; + @observable private _drawingFillLoading = false; + @observable private _fireflyRefStrength = 50; + + componentAIView = () => { + return ( + <div className="collectionfreeformview-aiView" onPointerDown={e => e.stopPropagation()}> + <div className="collectionfreeformview-aiView-options-container"> + <span className="collectionfreeformview-aiView-subtitle">Firefly:</span> + <div className="collectionfreeformview-aiView-options"> + <input + className="collectionfreeformview-aiView-prompt" + placeholder={this._drawingFillInput || StrCast(this.Document.title) || 'Describe image'} + type="text" + value={this._drawingFillInput} + onChange={action(e => { + this._drawingFillInput = e.target.value; + })} + /> + <div className="collectionFreeFormView-aiView-strength"> + <span className="collectionFreeFormView-aiView-similarity">Similarity</span> + <Slider + className="collectionfreeformview-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={1} + max={100} + step={1} + size="small" + value={this._fireflyRefStrength} + onChange={action((e, val) => (this._fireflyRefStrength = val as number))} + valueLabelDisplay="auto" + /> + </div> + <div className="collectionFreeFormView-aiView-send"> + <Button + text="Send" + type={Type.SEC} + icon={this._drawingFillLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />} + iconPlacement="right" + onClick={undoable( + action(() => { + this._drawingFillLoading = true; + DrawingFillHandler.drawingToImage(this.props.Document, this._fireflyRefStrength, this._drawingFillInput || StrCast(this.Document.title))?.then( + action(() => { + this._drawingFillLoading = false; + }) + ); + }), + 'create image' + )} + /> + </div> + </div> + </div> + <div className="collectionfreeformview-aiView-regenerate-container"> + <span className="collectionfreeformview-aiView-subtitle">Regenerate</span> + <div className="collectionfreeformview-aiView-regenerate"> + <input + className="collectionfreeformview-aiView-input" + aria-label="Edit instructions input" + type="text" + value={this._regenInput} + onChange={action(e => { + this._regenInput = e.target.value; + })} + placeholder="..under development.." + /> + <div className="collectionFreeFormView-aiView-regenBtn"> + <Button + text="Regenerate" + type={Type.SEC} + icon={this._regenLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />} + iconPlacement="right" + // onClick={action(async () => { + // this._regenLoading = true; + // SmartDrawHandler.Instance.CreateDrawingDoc = this.createDrawingDoc; + // SmartDrawHandler.Instance.AddDrawing = this.addDrawing; + // SmartDrawHandler.Instance.RemoveDrawing = this.removeDrawing; + // await SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput, true); + // this._regenLoading = false; + // })} + /> + </div> + </div> + </div> + </div> + ); + }; + render() { TraceMobx(); return ( |
