diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/DocumentView.scss | 17 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 62 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.scss | 28 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 43 |
4 files changed, 108 insertions, 42 deletions
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 7568e3b57..9490be98c 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -242,7 +242,7 @@ .contentFittingDocumentView * { ::-webkit-scrollbar-track { - background: none; + background: none; } } @@ -270,3 +270,18 @@ position: relative; } } + +.documentView-editorView-history { + position: absolute; + left: 0; + top: 0; +} + +.documentView-editorView { + width: 100%; + overflow-y: scroll; + + .documentView-editorView-resizer { + height: 5px; + } +} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ab58023e3..f79eadde8 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -723,31 +723,43 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document const isInk = this.layoutDoc._layout_isSvg && !this._props.LayoutTemplateString; const noBackground = this.Document.isGroup && !this._componentView?.isUnstyledView?.() && (!this.layoutDoc.backgroundColor || this.layoutDoc.backgroundColor === 'transparent'); return ( - <div - className="documentView-contentsView" - style={{ - pointerEvents: (isInk || noBackground ? 'none' : this.contentPointerEvents()) ?? (this._mounted ? 'all' : 'none'), - width: this._showAIEditor ? this.rpw() : undefined, - height: this._showAIEditor ? this.rph() : this.headerMargin ? `calc(100% - ${this.headerMargin}px)` : undefined, - justifySelf: 'center', - }}> - <DocumentContentsView - {...this._props} - layoutFieldKey={StrCast(this.Document.layout_fieldKey, 'layout')} - pointerEvents={this.contentPointerEvents} - setContentViewBox={this.setContentView} - childFilters={this.childFilters} - PanelHeight={this._showAIEditor ? this.rpw : this.panelHeight} - PanelWidth={this._showAIEditor ? this.rph : this._props.PanelWidth} - setHeight={this.setHeight} - isContentActive={this.isContentActive} - ScreenToLocalTransform={this.screenToLocalContent} - rootSelected={this.rootSelected} - onClickScript={this.onClickFunc} - setTitleFocus={this.setTitleFocus} - hideClickBehaviors={BoolCast(this.Document.hideClickBehaviors)} - /> - {this._showAIEditor && (this._componentView?.componentAIView?.(this.rph()) ?? null)} + <div> + <div + className="documentView-contentsView" + style={{ + pointerEvents: (isInk || noBackground ? 'none' : this.contentPointerEvents()) ?? (this._mounted ? 'all' : 'none'), + width: this._showAIEditor ? this.rpw() : undefined, + height: this._showAIEditor ? this.rph() : this.headerMargin ? `calc(100% - ${this.headerMargin}px)` : undefined, + justifySelf: this._showAIEditor ? 'center' : undefined, + }}> + <DocumentContentsView + {...this._props} + layoutFieldKey={StrCast(this.Document.layout_fieldKey, 'layout')} + pointerEvents={this.contentPointerEvents} + setContentViewBox={this.setContentView} + childFilters={this.childFilters} + PanelHeight={this._showAIEditor ? this.rpw : this.panelHeight} + PanelWidth={this._showAIEditor ? this.rph : this._props.PanelWidth} + setHeight={this.setHeight} + isContentActive={this.isContentActive} + ScreenToLocalTransform={this.screenToLocalContent} + rootSelected={this.rootSelected} + onClickScript={this.onClickFunc} + setTitleFocus={this.setTitleFocus} + hideClickBehaviors={BoolCast(this.Document.hideClickBehaviors)} + /> + </div> + {this._showAIEditor && ( + <div className="documentView-editorView-history" style={{ height: this.rph(), width: this.rpw() / 2 }}> + {this._componentView?.componentAIViewHistory?.() ?? null} + </div> + )} + {this._showAIEditor && ( + <div className="documentView-editorView" style={{ height: this.panelHeight() - this.rph() }}> + <div className="documentView-editorView-resizer" /> + {this._componentView?.componentAIView?.() ?? null} + </div> + )} </div> ); } diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 03314e90f..9f1ac11ef 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -140,15 +140,29 @@ opacity: 0; } -.imageBox-aiView { +.imageBox-aiView-history { + display: flex; + flex-direction: column; + align-items: center; padding: 5px; - position: absolute; - overflow: scroll; + gap: 5px; + overflow-y: scroll; + + .imageBox-aiView-img { + width: 100%; + } +} + +.imageBox-aiView { + overflow-y: scroll; text-align: center; font-weight: bold; - margin-top: 5px; + align-content: center; + height: 100%; .imageBox-aiView-subtitle { + position: relative; + left: 5px; align-self: start; } @@ -156,6 +170,8 @@ .imageBox-aiView-options-container { font-weight: normal; text-align: start; + margin: 5px; + padding-left: 5px; } .imageBox-aiView-regenerate, @@ -166,4 +182,8 @@ flex-direction: row; gap: 5px; } + + .imageBox-aiView-input { + width: 50%; + } } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index f00580d77..fc8b7bc27 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -7,8 +7,8 @@ import { observer } from 'mobx-react'; import { extname } from 'path'; import * as React from 'react'; import ReactLoading from 'react-loading'; -import { ClientUtils, DashColor, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../ClientUtils'; -import { Doc, DocListCast, Opt } from '../../../fields/Doc'; +import { ClientUtils, DashColor, returnEmptyFilter, returnEmptyString, returnFalse, returnOne, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../ClientUtils'; +import { Doc, DocListCast, Opt, returnEmptyDoclist } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; @@ -34,7 +34,7 @@ import { AnchorMenu } from '../pdf/AnchorMenu'; import { PinDocView, PinProps } from '../PinFuncs'; import { StickerPalette } from '../smartdraw/StickerPalette'; import { StyleProp } from '../StyleProp'; -import { DocumentView } from './DocumentView'; +import { DocumentView, DocumentViewInternal } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { FocusViewOptions } from './FocusViewOptions'; import './ImageBox.scss'; @@ -44,6 +44,7 @@ import { SmartDrawHandler } from '../smartdraw/SmartDrawHandler'; import { Button } from 'browndash-components'; import { SettingsManager } from '../../util/SettingsManager'; import { AiOutlineSend } from 'react-icons/ai'; +import { returnEmptyDocViewList } from '../StyleProvider'; export class ImageEditorData { // eslint-disable-next-line no-use-before-define @@ -532,18 +533,30 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @observable private _regenInput = ''; @observable private _canInteract = true; @observable private _regenerateLoading = false; + @observable private _prevImgUrls: string[] = []; - componentAIView = (top: number) => { + componentAIViewHistory = () => { + return ( + <div className="imageBox-aiView-history"> + {this._prevImgUrls.map((url: string) => ( + <img className="imageBox-aiView-img" src={url} onClick={() => (this.dataDoc[this.fieldKey] = new ImageField(url))} /> + ))} + </div> + ); + }; + + componentAIView = () => { const field = Cast(this.dataDoc[this.fieldKey], ImageField); const showRegenerate = this.Document[DocData].ai; return ( - <div className="imageBox-aiView" style={{ top: top, width: NumCast(this.Document.width), height: NumCast(this.Document.width) - top }}> + <div className="imageBox-aiView"> Edit Image with AI {showRegenerate && ( <div className="imageBox-aiView-regenerate-container"> <text className="imageBox-aiView-subtitle">Regenerate AI Image</text> <div className="imageBox-aiView-regenerate"> <input + className="imageBox-aiView-input" aria-label="Edit instructions input" // className="smartdraw-input" type="text" @@ -556,14 +569,20 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { text="Regenerate" type={Type.SEC} // style={{ alignSelf: 'flex-end' }} - icon={this._regenerateLoading && this._regenInput !== '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />} + icon={this._regenerateLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />} iconPlacement="right" - onClick={action(async () => { - this._regenerateLoading = true; - await SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput); - this._regenerateLoading = false; - this._regenInput = ''; - })} + onClick={undoable( + action(async () => { + this._regenerateLoading = true; + SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput, true).then(newDocs => { + this._prevImgUrls.push(this.paths.lastElement()); + this.dataDoc[this.fieldKey] = new ImageField(newDocs[0]); + this._regenerateLoading = false; + this._regenInput = ''; + }); + }), + 'regenerate image' + )} /> <Button // style={{ alignSelf: 'flex-end' }} |
