aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/ContextMenuItem.tsx10
-rw-r--r--src/client/views/PropertiesView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx3
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
-rw-r--r--src/client/views/nodes/ImageBox.tsx3
-rw-r--r--src/client/views/smartdraw/DrawingFillHandler.tsx70
-rw-r--r--src/server/ApiManagers/FireflyManager.ts132
7 files changed, 82 insertions, 144 deletions
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 6f8f41bdd..218718b18 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -1,6 +1,6 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, makeObservable, observable, runInAction } from 'mobx';
+import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { SnappingManager } from '../util/SnappingManager';
@@ -26,7 +26,7 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
_hoverTimeout?: NodeJS.Timeout;
_overPosY = 0;
_overPosX = 0;
- @observable _items: ContextMenuProps[] = [];
+ @observable.shallow _items: ContextMenuProps[] = [];
@observable _overItem = false;
constructor(props: ContextMenuProps & { selected?: boolean }) {
@@ -34,8 +34,8 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
makeObservable(this);
}
- componentDidMount() {
- runInAction(() => this._items.push(...(this._props.subitems ?? [])));
+ @computed get items() {
+ return this._items.concat(this._props.subitems ?? []);
}
handleEvent = async (e: React.MouseEvent<HTMLDivElement>) => {
@@ -91,7 +91,7 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
};
render() {
- const submenu = this._items.map(prop => <ContextMenuItem {...prop} key={prop.description} closeMenu={this._props.closeMenu} />);
+ const submenu = this.items.map(prop => <ContextMenuItem {...prop} key={prop.description} closeMenu={this._props.closeMenu} />);
return this.props.event || this._props.noexpand ? this.renderItem(submenu) : <div className="contextMenu-inlineMenu">{submenu}</div>;
}
}
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 4e12e0b2d..aefdeee17 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -995,9 +995,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
align="flex-start"
fillWidth
toggleType={ToggleType.BUTTON}
- onClick={undoable(() => {
- DrawingFillHandler.drawingToImage(targetDoc, 'fill in the details of this image');
- }, 'createImage')}
+ onClick={undoable(() => DrawingFillHandler.drawingToImage(targetDoc, 'fill in the details of this image'), 'createImage')}
/>
</div>
<div className="color">
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 79aad0ef2..272c13546 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -102,7 +102,6 @@ export function computePassLayout(poolData: Map<string, PoolData>, pivotDoc: Doc
replica: '',
});
});
- // eslint-disable-next-line no-use-before-define
return normalizeResults(panelDim, 12, docMap, poolData, viewDefsToJSX, [], 0, []);
}
@@ -272,7 +271,6 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
payload: pivotColumnGroups.get(key)?.filters,
}));
groupNames.push(...dividers);
- // eslint-disable-next-line no-use-before-define
return normalizeResults(panelDim, maxText, docMap, poolData, viewDefsToJSX, groupNames, 0, []);
}
@@ -347,7 +345,6 @@ export function computeTimelineLayout(poolData: Map<string, PoolData>, pivotDoc:
if (!stack && (curTime === undefined || Math.abs(x - (curTime - minTime) * scaling) > pivotAxisWidth)) {
groupNames.push({ type: 'text', text: toLabel(key), x: x, y: stack * 25, height: fontHeight, fontSize, payload: undefined });
}
- // eslint-disable-next-line no-use-before-define
layoutDocsAtTime(keyDocs, key);
});
if (sortedKeys.length && curTime !== undefined && curTime > sortedKeys[sortedKeys.length - 1]) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4bfa7fc92..8519cda3c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -52,6 +52,7 @@ import { FormattedTextBox } from './formattedText/FormattedTextBox';
import { PresEffect, PresEffectDirection } from './trails/PresEnums';
import SpringAnimation from './trails/SlideEffect';
import { SpringType, springMappings } from './trails/SpringUtils';
+import { DrawingFillHandler } from '../smartdraw/DrawingFillHandler';
export interface DocumentViewProps extends FieldViewSharedProps {
hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected
@@ -551,6 +552,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => DocumentView.SetLightboxDoc(this.Document), icon: 'external-link-alt' });
}
appearanceItems.push({ description: 'Pin', event: () => this._props.pinToPres(this.Document, {}), icon: 'map-pin' });
+ appearanceItems.push({ description: 'Make Image', event: () => DrawingFillHandler.drawingToImage(this.Document, StrCast(this.Document.title)), icon: 'map-pin' });
!Doc.noviceMode && templateDoc && appearanceItems.push({ description: 'Open Template ', event: () => this._props.addDocTab(templateDoc, OpenWhere.addRight), icon: 'eye' });
!appearance && appearanceItems.length && cm.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'compass' });
@@ -1072,7 +1074,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
public static GetDocImage(doc: Doc) {
return DocumentView.getDocumentView(doc)
?.ComponentView?.updateIcon?.()
- .then(() => ImageCast(DocCast(doc).icon));
+ .then(() => ImageCast(doc?.icon, ImageCast(doc[Doc.LayoutFieldKey(doc)])));
}
public get displayName() { return 'DocumentView(' + (this.Document?.title??"") + ')'; } // prettier-ignore
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index d847b7940..03d417e4e 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -40,7 +40,6 @@ import { FocusViewOptions } from './FocusViewOptions';
import './ImageBox.scss';
import { OpenWhere } from './OpenWhere';
import { Upload } from '../../../server/SharedMediaTypes';
-import { ImageUtils } from '../../util/Import & Export/ImageUtils';
export class ImageEditorData {
// eslint-disable-next-line no-use-before-define
@@ -361,6 +360,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
};
+ updateIcon = () => new Promise<void>(res => res());
+
choosePath = (url: URL) => {
if (!url?.href) return '';
const lower = url.href.toLowerCase();
diff --git a/src/client/views/smartdraw/DrawingFillHandler.tsx b/src/client/views/smartdraw/DrawingFillHandler.tsx
index 6f111e95b..32416cec5 100644
--- a/src/client/views/smartdraw/DrawingFillHandler.tsx
+++ b/src/client/views/smartdraw/DrawingFillHandler.tsx
@@ -1,50 +1,22 @@
-// import { action, makeObservable } from 'mobx';
-// import { observer } from 'mobx-react';
-// import React from 'react';
-// import { Doc } from '../../../fields/Doc';
-// import { ImageCast } from '../../../fields/Types';
-// import { ImageField } from '../../../fields/URLField';
-// import { Docs } from '../../documents/Documents';
-// import { Networking } from '../../Network';
-// import { makeUserTemplateButtonOrImage } from '../../util/DropConverter';
-// import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
-// import { ImageUtility } from '../nodes/imageEditor/imageEditorUtils/ImageHandler';
-// import { OpenWhere } from '../nodes/OpenWhere';
-// import { ObservableReactComponent } from '../ObservableReactComponent';
+import { Doc } from '../../../fields/Doc';
+import { ImageCast } from '../../../fields/Types';
+import { Upload } from '../../../server/SharedMediaTypes';
+import { Docs } from '../../documents/Documents';
+import { Networking } from '../../Network';
+import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
+import { OpenWhere } from '../nodes/OpenWhere';
-// export class DrawingFillHandler {
-// static drawingToImage = async (drawing: Doc, prompt: string) => {
-// const imageField = await DocumentView.GetDocImage(drawing);
-// if (!imageField) return;
-// const { href } = ImageCast(imageField).url;
-// const hrefParts = href.split('.');
-// const hrefComplete = `${hrefParts[0]}_o.${hrefParts[1]}`;
-// try {
-// const response = await fetch(hrefComplete);
-// const blob: Blob = await response.blob();
-// const strength: number = 100;
-// const img = await Networking.PostToServer('/oldQueryFireflyImage', { prompt, blob, strength });
-// DocumentViewInternal.addDocTabFunc(Docs.Create.ImageDocument(img, {}), OpenWhere.addRight);
-// // Networking.PostToServer('/oldQueryFireflyImage', { prompt, blob, strength }).then(img => DocumentViewInternal.addDocTabFunc(Docs.Create.ImageDocument(img, {}), OpenWhere.addRight));
-// } catch (error) {
-// console.error('Error fetching image:', error);
-// return;
-// }
-
-// // const image = new Image();
-// // image.src = imageField.url?.href;
-// // // image.onload = async () => {
-// // const canvas = document.createElement('canvas');
-// // canvas.width = image.width;
-// // canvas.height = image.height;
-// // const ctx = canvas.getContext('2d');
-// // if (!ctx) return;
-// // ctx.globalCompositeOperation = 'source-over';
-// // ctx.clearRect(0, 0, image.width, image.height);
-// // ctx.drawImage(image, 0, 0);
-// // const blob: Blob = await ImageUtility.canvasToBlob(canvas);
-// // const strength: number = 100;
-// // Networking.PostToServer('/oldQueryFireflyImage', { prompt, blob, strength }).then(img => DocumentViewInternal.addDocTabFunc(Docs.Create.ImageDocument(img, {}), OpenWhere.addRight));
-// // };
-// };
-// }
+export class DrawingFillHandler {
+ static drawingToImage = (drawing: Doc, prompt: string) =>
+ DocumentView.GetDocImage(drawing)?.then(imageField => {
+ if (imageField) {
+ const { href } = ImageCast(imageField).url;
+ const hrefParts = href.split('.');
+ const structureUrl = `${hrefParts[0]}_o.${hrefParts[1]}`;
+ const strength: number = 100;
+ Networking.PostToServer('/queryFireflyImageFromStructure', { prompt, structureUrl, strength }).then((info: Upload.ImageInformation) =>
+ DocumentViewInternal.addDocTabFunc(Docs.Create.ImageDocument(info.accessPaths.agnostic.client, {}), OpenWhere.addRight)) // prettier-ignore
+ }
+ return false;
+ });
+}
diff --git a/src/server/ApiManagers/FireflyManager.ts b/src/server/ApiManagers/FireflyManager.ts
index 73cf94206..c84e9e8fa 100644
--- a/src/server/ApiManagers/FireflyManager.ts
+++ b/src/server/ApiManagers/FireflyManager.ts
@@ -20,21 +20,10 @@ export default class FireflyManager extends ApiManager {
return undefined;
});
- askFireflyOld = (prompt: string = 'a realistic illustration of a cat coding', uploadId: string, strength: number) => {
- const fetched = this.getBearerToken().then(response =>
- response?.json().then((data: { access_token: string }) => {
- const body: any = {
- prompt: prompt,
- structure: {
- strength: strength,
- imageReference: {
- source: {
- uploadId: uploadId,
- },
- },
- },
- };
- return fetch('https://firefly-api.adobe.io/v3/images/generate', {
+ generateImageFromStructure = (prompt: string = 'a realistic illustration of a cat coding', structureUrl: string, strength: number) =>
+ this.getBearerToken().then(response =>
+ response?.json().then((data: { access_token: string }) =>
+ fetch('https://firefly-api.adobe.io/v3/images/generate', {
method: 'POST',
headers: [
['Content-Type', 'application/json'],
@@ -42,40 +31,40 @@ export default class FireflyManager extends ApiManager {
['x-api-key', process.env._CLIENT_FIREFLY_CLIENT_ID ?? ''],
['Authorization', `Bearer ${data.access_token}`],
],
- body: JSON.stringify(body),
+ body: JSON.stringify({
+ prompt,
+ structure: !structureUrl
+ ? undefined
+ : {
+ strength,
+ imageReference: {
+ source: { url: structureUrl },
+ },
+ },
+ }),
})
- .then(response => response.json().then(json => JSON.stringify((json.outputs?.[0] as { image: { url: string } })?.image)))
+ .then(response2 => response2.json().then(json => JSON.stringify((json.outputs?.[0] as { image: { url: string } })?.image)))
.catch(error => {
console.error('Error:', error);
return '';
+ })
+ )
+ );
+
+ uploadImageToDropbox = (fileUrl: string, dbx = new Dropbox({ accessToken: process.env.DROPBOX_TOKEN })) =>
+ new Promise<string>((res, rej) =>
+ fs.readFile(path.join(filesDirectory, `${Directory.images}/${path.basename(fileUrl)}`), undefined, (err, contents) => {
+ if (err) {
+ console.log('Error: ', err);
+ rej();
+ } else {
+ dbx.filesUpload({ path: `/Apps/browndash/${path.basename(fileUrl)}`, contents }).then(response => {
+ dbx.filesGetTemporaryLink({ path: response.result.path_display ?? '' }).then(link => res(link.result.link));
});
+ }
})
);
- return fetched;
- };
- uploadImageToFirefly = (image: Blob) => {
- const fetched = this.getBearerToken().then(response =>
- response?.json().then((data: { access_token: string }) =>
- fetch('https://firefly-api.adobe.io/v3/uploads', {
- method: 'POST',
- headers: [
- ['Content-Type', image.type],
- ['x-api-key', process.env._CLIENT_FIREFLY_CLIENT_ID ?? ''],
- ['Authorization', `Bearer ${data.access_token}`],
- ],
- body: image,
- })
- .then(response => response.json())
- .then(data => data.uploadId) // Extract the uploadId from the response
- .catch(error => {
- console.error('Error:', error);
- return '';
- })
- )
- );
- return fetched;
- };
generateImage = (prompt: string = 'a realistic illustration of a cat coding') => {
const fetched = this.getBearerToken().then(response =>
response?.json().then((data: { access_token: string }) =>
@@ -222,17 +211,16 @@ export default class FireflyManager extends ApiManager {
protected initialize(register: Registration): void {
register({
method: Method.POST,
- subscription: '/oldQueryFireflyImage',
- secureHandler: async ({ req, res }) => {
- const { prompt, imageBlob, strength = 0.5 } = req.body;
- const uploadId = imageBlob ? await this.uploadImageToFirefly(imageBlob) : null;
- this.askFireflyOld(prompt, uploadId, strength).then(fire =>
- DashUploadUtils.UploadImage(JSON.parse(fire ?? '').url).then(info => {
- if (info instanceof Error) _invalid(res, info.message);
- else _success(res, info);
- })
- );
- },
+ subscription: '/queryFireflyImageFromStructure',
+ secureHandler: async ({ req, res }) =>
+ this.uploadImageToDropbox(req.body.structureUrl).then(uploadUrl =>
+ this.generateImageFromStructure(req.body.prompt, uploadUrl, req.body.strength).then(fire =>
+ DashUploadUtils.UploadImage(JSON.parse(fire ?? '').url).then(info => {
+ if (info instanceof Error) _invalid(res, info.message);
+ else _success(res, info);
+ })
+ )
+ ),
});
register({
method: Method.POST,
@@ -263,36 +251,16 @@ export default class FireflyManager extends ApiManager {
method: Method.POST,
subscription: '/expandImage',
secureHandler: ({ req, res }) =>
- new Promise<void>((resolve, reject) => {
- const dbx = new Dropbox({ accessToken: process.env.DROPBOX_TOKEN });
- fs.readFile(path.join(filesDirectory, `${Directory.images}/${path.basename(req.body.file)}`), undefined, (err, contents) => {
- if (err) {
- console.log('Error: ', err);
- reject();
- } else {
- dbx.filesUpload({ path: `/Apps/browndash/${path.basename(req.body.file)}`, contents })
- .then(response => {
- dbx.filesGetTemporaryLink({ path: response.result.path_display ?? '' }).then(link => {
- console.log(link.result);
- this.expandImage(link.result.link, req.body.prompt).then(text => {
- if (text.error_code) _error(res, text.message);
- else
- DashUploadUtils.UploadImage(text.outputs[0].image.url).then(info => {
- if (info instanceof Error) _invalid(res, info.message);
- else _success(res, info);
- resolve();
- });
- });
- });
- })
- .catch(uploadErr => {
- console.log(uploadErr);
- _error(res, 'upload to dropbox failed');
- reject();
- });
- }
- });
- }),
+ this.uploadImageToDropbox(req.body.file).then(uploadUrl =>
+ this.expandImage(uploadUrl, req.body.prompt).then(text => {
+ if (text.error_code) _error(res, text.message);
+ else
+ DashUploadUtils.UploadImage(text.outputs[0].image.url).then(info => {
+ if (info instanceof Error) _invalid(res, info.message);
+ else _success(res, info);
+ });
+ })
+ ),
});
}
}