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.tsx90
1 files changed, 61 insertions, 29 deletions
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 55474cb7e..d122ca5b0 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -36,7 +36,7 @@ import { OverlayView } from '../OverlayView';
import { AnchorMenu } from '../pdf/AnchorMenu';
import { PinDocView, PinProps } from '../PinFuncs';
import { DrawingFillHandler } from '../smartdraw/DrawingFillHandler';
-import { FireflyImageData, isFireflyImageData } from '../smartdraw/FireflyConstants';
+import { FireflyImageData, FireflyImageDimensions, isFireflyImageData } from '../smartdraw/FireflyConstants';
import { SmartDrawHandler } from '../smartdraw/SmartDrawHandler';
import { StickerPalette } from '../smartdraw/StickerPalette';
import { StyleProp } from '../StyleProp';
@@ -45,6 +45,7 @@ import { FieldView, FieldViewProps } from './FieldView';
import { FocusViewOptions } from './FocusViewOptions';
import './ImageBox.scss';
import { OpenWhere } from './OpenWhere';
+import { RichTextField } from '../../../fields/RichTextField';
export class ImageEditorData {
// eslint-disable-next-line no-use-before-define
@@ -83,6 +84,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
private _disposers: { [name: string]: IReactionDisposer } = {};
private _getAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
private _overlayIconRef = React.createRef<HTMLDivElement>();
+ private _regenerateIconRef = React.createRef<HTMLDivElement>();
private _mainCont: HTMLDivElement | null = null;
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
imageRef: HTMLImageElement | null = null; // <video> ref
@@ -196,36 +198,47 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
this._searchInput = selection;
};
- drop = undoable((e: Event, de: DragManager.DropEvent) => {
- if (de.complete.docDragData) {
- let added: boolean | undefined;
- const targetIsBullseye = (ele: HTMLElement): boolean => {
- if (!ele) return false;
- if (ele === this._overlayIconRef.current) return true;
- return targetIsBullseye(ele.parentElement as HTMLElement);
- };
- if (de.metaKey || targetIsBullseye(e.target as HTMLElement)) {
- added = de.complete.docDragData.droppedDocuments.reduce((last: boolean, drop: Doc) => {
- this.layoutDoc[this.fieldKey + '_usePath'] = 'alternate:hover';
- return last && Doc.AddDocToList(this.dataDoc, this.fieldKey + '_alternates', drop);
- }, true);
- } else if (de.altKey || !this.dataDoc[this.fieldKey]) {
- const layoutDoc = de.complete.docDragData?.draggedDocuments[0];
- const targetField = Doc.LayoutFieldKey(layoutDoc);
- const targetDoc = layoutDoc[DocData];
- if (targetDoc[targetField] instanceof ImageField) {
- added = true;
- this.dataDoc[this.fieldKey] = ObjectField.MakeCopy(targetDoc[targetField] as ImageField);
- Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(targetDoc), this.fieldKey);
- Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(targetDoc), this.fieldKey);
+ drop = undoable(
+ action((e: Event, de: DragManager.DropEvent) => {
+ if (de.complete.docDragData) {
+ let added: boolean | undefined;
+ const hitDropTarget = (ele: HTMLElement, dropTarget: HTMLDivElement | null): boolean => {
+ if (!ele) return false;
+ if (ele === dropTarget) return true;
+ return hitDropTarget(ele.parentElement as HTMLElement, dropTarget);
+ };
+ if (de.metaKey || hitDropTarget(e.target as HTMLElement, this._overlayIconRef.current)) {
+ added = de.complete.docDragData.droppedDocuments.reduce((last: boolean, drop: Doc) => {
+ this.layoutDoc[this.fieldKey + '_usePath'] = 'alternate:hover';
+ return last && Doc.AddDocToList(this.dataDoc, this.fieldKey + '_alternates', drop);
+ }, true);
+ } else if (hitDropTarget(e.target as HTMLElement, this._regenerateIconRef.current)) {
+ this._regenerateLoading = true;
+ const drag = de.complete.docDragData.draggedDocuments.lastElement();
+ const dragField = drag[Doc.LayoutFieldKey(drag)];
+ const oldPrompt = StrCast(this.Document.ai_firefly_prompt, StrCast(this.Document.title));
+ const newPrompt = (text: string) => (oldPrompt ? `${oldPrompt} ~~~ ${text}` : text);
+ DrawingFillHandler.drawingToImage(this.Document, 100, newPrompt(dragField instanceof RichTextField ? dragField.Text : ''), drag)?.then(action(() => (this._regenerateLoading = false)));
+ added = false;
+ } else if (de.altKey || !this.dataDoc[this.fieldKey]) {
+ const layoutDoc = de.complete.docDragData?.draggedDocuments[0];
+ const targetField = Doc.LayoutFieldKey(layoutDoc);
+ const targetDoc = layoutDoc[DocData];
+ if (targetDoc[targetField] instanceof ImageField) {
+ added = true;
+ this.dataDoc[this.fieldKey] = ObjectField.MakeCopy(targetDoc[targetField] as ImageField);
+ Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(targetDoc), this.fieldKey);
+ Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(targetDoc), this.fieldKey);
+ }
}
+ added === false && e.preventDefault();
+ added !== undefined && e.stopPropagation();
+ return added;
}
- added === false && e.preventDefault();
- added !== undefined && e.stopPropagation();
- return added;
- }
- return false;
- }, 'image drop');
+ return false;
+ }),
+ 'image drop'
+ );
@undoBatch
resolution = () => {
@@ -485,6 +498,24 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
</Tooltip>
);
}
+ @computed get regenerateImageIcon() {
+ return (
+ <div
+ className="imageBox-regenerateDropTarget"
+ ref={this._regenerateIconRef}
+ onClick={() => DocumentView.showDocument(DocCast(this.Document.ai_firefly_generatedDocs), { openLocation: OpenWhere.addRight })}
+ style={{
+ display: (this._props.isContentActive() && (SnappingManager.CanEmbed || this.Document.ai_firefly_generatedDocs)) || this._regenerateLoading ? 'block' : 'none',
+ transform: `scale(${this.uiBtnScaling})`,
+ width: this._sideBtnWidth,
+ height: this._sideBtnWidth,
+ background: 'transparent',
+ // color: SettingsManager.userBackgroundColor,
+ }}>
+ {this._regenerateLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width="100%" height="100%" /> : <FontAwesomeIcon icon="portrait" color={SettingsManager.userColor} size="lg" />}
+ </div>
+ );
+ }
@computed get paths() {
const field = this.dataDoc[this.fieldKey] instanceof ImageField ? Cast(this.dataDoc[this.fieldKey], ImageField, null) : new ImageField(String(this.dataDoc[this.fieldKey])); // retrieve the primary image URL that is being rendered from the data doc
@@ -807,6 +838,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
<ReactLoading type="spin" height={50} width={50} color={'blue'} />
</div>
) : null}
+ {this.regenerateImageIcon}
{this.overlayImageIcon}
{this.annotationLayer}
{!this._mainCont || !this.DocumentView || !this._annotationLayer.current ? null : (