aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/ImageBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/ImageBox.tsx')
-rw-r--r--src/client/views/nodes/ImageBox.tsx113
1 files changed, 111 insertions, 2 deletions
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 7ce429f0f..f00580d77 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -1,7 +1,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import axios from 'axios';
-import { Colors } from 'browndash-components';
+import { Colors, Type } from 'browndash-components';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { extname } from 'path';
@@ -41,6 +41,9 @@ import './ImageBox.scss';
import { OpenWhere } from './OpenWhere';
import { Upload } from '../../../server/SharedMediaTypes';
import { SmartDrawHandler } from '../smartdraw/SmartDrawHandler';
+import { Button } from 'browndash-components';
+import { SettingsManager } from '../../util/SettingsManager';
+import { AiOutlineSend } from 'react-icons/ai';
export class ImageEditorData {
// eslint-disable-next-line no-use-before-define
@@ -352,7 +355,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}),
icon: 'pencil-alt',
});
- this.layoutDoc.ai_generated &&
+ this.layoutDoc.ai &&
funcs.push({
description: 'Regenerate AI Image',
event: action(e => {
@@ -526,6 +529,112 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
);
}
+ @observable private _regenInput = '';
+ @observable private _canInteract = true;
+ @observable private _regenerateLoading = false;
+
+ componentAIView = (top: number) => {
+ 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 }}>
+ 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
+ aria-label="Edit instructions input"
+ // className="smartdraw-input"
+ type="text"
+ value={this._regenInput}
+ onChange={action(e => this._canInteract && (this._regenInput = e.target.value))}
+ // onKeyDown={this.handleKeyPress}
+ placeholder="Prompt (Optional)"
+ />
+ <Button
+ 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 />}
+ iconPlacement="right"
+ onClick={action(async () => {
+ this._regenerateLoading = true;
+ await SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput);
+ this._regenerateLoading = false;
+ this._regenInput = '';
+ })}
+ />
+ <Button
+ // style={{ alignSelf: 'flex-end' }}
+ text="Get Variations"
+ type={Type.SEC}
+ // icon={this._isLoading && this._regenInput !== '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ // onClick={this.handleSendClick}
+ />
+ </div>
+ </div>
+ )}
+ <div className="imageBox-aiView-options-container">
+ {showRegenerate && <text className="imageBox-aiView-subtitle"> More Image Options </text>}
+ <div className="imageBox-aiView-options">
+ <Button
+ type={Type.TERT}
+ text="Get Text"
+ icon={<FontAwesomeIcon icon="font" />}
+ color={SettingsManager.userBackgroundColor}
+ iconPlacement="right"
+ onClick={() => {
+ Networking.PostToServer('/queryFireflyImageText', {
+ file: (file => {
+ const ext = extname(file);
+ return file.replace(ext, (this._error ? '_o' : this._curSuffix) + ext);
+ })(ImageCast(this.Document[Doc.LayoutFieldKey(this.Document)])?.url.href),
+ }).then(text => alert(text));
+ }}
+ />
+ <Button
+ type={Type.TERT}
+ text="Generative Fill"
+ icon={<FontAwesomeIcon icon="fill" />}
+ color={SettingsManager.userBackgroundColor}
+ // icon={this._isLoading && this._regenInput !== '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ onClick={action(() => {
+ ImageEditorData.Open = true;
+ ImageEditorData.Source = (field && this.choosePath(field.url)) || '';
+ ImageEditorData.AddDoc = this._props.addDocument;
+ ImageEditorData.RootDoc = this.Document;
+ })}
+ />
+ <Button
+ type={Type.TERT}
+ text="Expand"
+ icon={<FontAwesomeIcon icon="expand" />}
+ color={SettingsManager.userBackgroundColor}
+ // icon={this._isLoading && this._regenInput !== '' ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ onClick={() => {
+ Networking.PostToServer('/expandImage', {
+ prompt: 'sunny skies',
+ file: (file => {
+ const ext = extname(file);
+ return file.replace(ext, (this._error ? '_o' : this._curSuffix) + ext);
+ })(ImageCast(this.Document[Doc.LayoutFieldKey(this.Document)])?.url.href),
+ }).then((info: Upload.ImageInformation) => {
+ const img = Docs.Create.ImageDocument(info.accessPaths.agnostic.client, { title: 'expand:' + this.Document.title });
+ DocUtils.assignImageInfo(info, img);
+ this._props.addDocTab(img, OpenWhere.addRight);
+ });
+ }}
+ />
+ </div>
+ </div>
+ </div>
+ );
+ };
+
@computed get annotationLayer() {
TraceMobx();
return <div className="imageBox-annotationLayer" style={{ height: this._props.PanelHeight() }} ref={this._annotationLayer} />;