aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreleanor-park <eleanor_park@brown.edu>2025-01-02 22:39:25 -0500
committereleanor-park <eleanor_park@brown.edu>2025-01-02 22:39:25 -0500
commit6e7cb570f9bad527cd4772bb5c715dd588fb77df (patch)
treefe1b697f6174ae4045184d9b981705757532d315
parent383b0487d5268bd860e514feddf09f4f3eb2fe3f (diff)
tags can now be used as style presets
-rw-r--r--src/client/apis/gpt/GPT.ts2
-rw-r--r--src/client/views/DocumentButtonBar.tsx18
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/smartdraw/DrawingFillHandler.tsx10
-rw-r--r--src/client/views/smartdraw/FireflyConstants.ts22
-rw-r--r--src/server/ApiManagers/FireflyManager.ts7
6 files changed, 55 insertions, 6 deletions
diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts
index 9241eb120..4b0d58cc1 100644
--- a/src/client/apis/gpt/GPT.ts
+++ b/src/client/apis/gpt/GPT.ts
@@ -260,7 +260,7 @@ const gptDescribeImage = async (image: string): Promise<string> => {
content: [
{
type: 'text',
- text: `Identify what this drawing is, naming as many elements and their location in the drawing as possible`,
+ text: `Briefly identify what this drawing is, naming all the drawing elements and their location within the image. Do not include anything about the drawing style.`,
},
{
type: 'image_url',
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 32bf67df1..b7033af3f 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -314,6 +314,23 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
);
}
+ @computed
+ get aiEditorButton() {
+ const targetDoc = this.view0?.Document;
+ return !targetDoc ? null : (
+ <Tooltip title={<div className="dash-ai-editor-button">Edit with AI</div>}>
+ <div
+ className="documentButtonBar-icon"
+ style={{ color: 'white' }}
+ onClick={() => {
+ CalendarManager.Instance.open(this.view0, targetDoc);
+ }}>
+ <FontAwesomeIcon className="documentdecorations-icon" icon="robot" />
+ </div>
+ </Tooltip>
+ );
+ }
+
@observable _isRecording = false;
_stopFunc: () => void = emptyFunction;
@computed
@@ -484,6 +501,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
<div className="documentButtonBar-button">{this.pinButton}</div>
<div className="documentButtonBar-button">{this.recordButton}</div>
<div className="documentButtonBar-button">{this.calendarButton}</div>
+ <div className="documentButtonBar-button">{this.aiEditorButton}</div>
<div className="documentButtonBar-button">{this.keywordButton}</div>
{!Doc.UserDoc().documentLinksButton_fullMenu ? null : <div className="documentButtonBar-button">{this.shareButton}</div>}
<div className="documentButtonBar-button">{this.menuButton}</div>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8519cda3c..048b92c71 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1400,6 +1400,8 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
NativeHeight = () => this.effectiveNativeHeight;
PanelWidth = () => this.panelWidth;
PanelHeight = () => this.panelHeight;
+ ReducedPanelWidth = () => this.panelWidth / 2;
+ ReducedPanelHeight = () => this.panelWidth / 2;
NativeDimScaling = () => this.nativeScaling;
hideLinkCount = () => !!this.hideLinkButton;
isHovering = () => this._isHovering;
diff --git a/src/client/views/smartdraw/DrawingFillHandler.tsx b/src/client/views/smartdraw/DrawingFillHandler.tsx
index 7a95e27c2..52652d377 100644
--- a/src/client/views/smartdraw/DrawingFillHandler.tsx
+++ b/src/client/views/smartdraw/DrawingFillHandler.tsx
@@ -8,10 +8,13 @@ import { Docs } from '../../documents/Documents';
import { Networking } from '../../Network';
import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
import { OpenWhere } from '../nodes/OpenWhere';
-import { AspectRatioLimits, FireflyDimensionsMap, FireflyImageDimensions } from './FireflyConstants';
+import { AspectRatioLimits, FireflyDimensionsMap, FireflyImageDimensions, FireflyStylePresets } from './FireflyConstants';
export class DrawingFillHandler {
- static drawingToImage = (drawing: Doc, strength: number, prompt: string) =>
+ static drawingToImage = (drawing: Doc, strength: number, prompt: string) => {
+ const docData = drawing[DocData];
+ const tags: string[] = ((docData?.tags as unknown as string[]) ?? []).map(tag => tag.slice(1)) ?? [];
+ const styles = tags.filter(tag => FireflyStylePresets.has(tag));
DocumentView.GetDocImage(drawing)?.then(imageField => {
if (imageField) {
const aspectRatio = (drawing.width as number) / (drawing.height as number);
@@ -31,11 +34,12 @@ export class DrawingFillHandler {
imageUrlToBase64(structureUrl)
.then((hrefBase64: string) => gptDescribeImage(hrefBase64))
.then((prompt: string) => {
- Networking.PostToServer('/queryFireflyImageFromStructure', { prompt: prompt, width: dims.width, height: dims.height, structureUrl, strength }).then((info: Upload.ImageInformation) =>
+ Networking.PostToServer('/queryFireflyImageFromStructure', { prompt: prompt, width: dims.width, height: dims.height, structureUrl: structureUrl, strength: strength, styles: styles }).then((info: Upload.ImageInformation) =>
DocumentViewInternal.addDocTabFunc(Docs.Create.ImageDocument(info.accessPaths.agnostic.client, { ai_generated: true, nativeWidth: dims.width, nativeHeight: dims.height }), OpenWhere.addRight)
); // prettier-ignore
});
}
return false;
});
+ };
}
diff --git a/src/client/views/smartdraw/FireflyConstants.ts b/src/client/views/smartdraw/FireflyConstants.ts
index f51305fba..3574039e4 100644
--- a/src/client/views/smartdraw/FireflyConstants.ts
+++ b/src/client/views/smartdraw/FireflyConstants.ts
@@ -18,3 +18,25 @@ export const AspectRatioLimits = {
portrait: 0.875,
widescreen: 1.472,
};
+
+// prettier-ignore
+export const FireflyStylePresets =
+ new Set<string>(['graphic', 'wireframe',
+ 'vector_look','bw','cool_colors','golden','monochromatic','muted_color','toned_image','vibrant_colors','warm_tone','closeup',
+ 'knolling','landscape_photography','macrophotography','photographed_through_window','shallow_depth_of_field','shot_from_above',
+ 'shot_from_below','surface_detail','wide_angle','beautiful','bohemian','chaotic','dais','divine','eclectic','futuristic','kitschy',
+ 'nostalgic','simple','antique_photo','bioluminescent','bokeh','color_explosion','dark','faded_image','fisheye','gomori_photography',
+ 'grainy_film','iridescent','isometric','misty','neon','otherworldly_depiction','ultraviolet','underwater', 'backlighting',
+ 'dramatic_light', 'golden_hour', 'harsh_light','long','low_lighting','multiexposure','studio_light','surreal_lighting',
+ '3d_patterns','charcoal','claymation','fabric','fur','guilloche_patterns','layered_paper','marble_sculpture','made_of_metal',
+ 'origami','paper_mache','polka','strange_patterns','wood_carving','yarn','art_deco','art_nouveau','baroque','bauhaus',
+ 'constructivism','cubism','cyberpunk','fantasy','fauvism', 'film_noir','glitch_art','impressionism','industrialism','maximalism',
+ 'minimalism','modern_art','modernism','neo','pointillism','psychedelic','science_fiction','steampunk','surrealism','synthetism',
+ 'synthwave','vaporwave','acrylic_paint','bold_lines','chiaroscuro','color_shift_art','daguerreotype','digital_fractal',
+ 'doodle_drawing','double_exposure_portrait','fresco','geometric_pen','halftone','ink','light_painting','line_drawing','linocut',
+ 'oil_paint','paint_spattering','painting','palette_knife','photo_manipulation','scribble_texture','sketch','splattering',
+ 'stippling_drawing','watercolor','3d','anime','cartoon','cinematic','comic_book','concept_art','cyber_matrix','digital_art',
+ 'flat_design','geometric','glassmorphism','glitch_graphic','graffiti','hyper_realistic','interior_design','line_gradient',
+ 'low_poly','newspaper_collage','optical_illusion','pattern_pixel','pixel_art','pop_art','product_photo','psychedelic_background',
+ 'psychedelic_wonderland','scandinavian','splash_images','stamp','trompe_loeil'
+ ]);
diff --git a/src/server/ApiManagers/FireflyManager.ts b/src/server/ApiManagers/FireflyManager.ts
index 4c4aac5e0..cb5d7c1da 100644
--- a/src/server/ApiManagers/FireflyManager.ts
+++ b/src/server/ApiManagers/FireflyManager.ts
@@ -20,9 +20,10 @@ export default class FireflyManager extends ApiManager {
return undefined;
});
- generateImageFromStructure = (prompt: string = 'a realistic illustration of a cat coding', width: number = 2048, height: number = 2048, structureUrl: string, strength: number = 50) =>
+ generateImageFromStructure = (prompt: string = 'a realistic illustration of a cat coding', width: number = 2048, height: number = 2048, structureUrl: string, strength: number = 50, styles: string[]) =>
this.getBearerToken().then(response =>
response?.json().then((data: { access_token: string }) =>
+ //prettier-ignore
fetch('https://firefly-api.adobe.io/v3/images/generate', {
method: 'POST',
headers: [
@@ -42,6 +43,8 @@ export default class FireflyManager extends ApiManager {
source: { url: structureUrl },
},
},
+ //prettier-ignore
+ style: { presets: styles }
}),
})
.then(response2 => response2.json().then(json => JSON.stringify((json.outputs?.[0] as { image: { url: string } })?.image)))
@@ -227,7 +230,7 @@ export default class FireflyManager extends ApiManager {
subscription: '/queryFireflyImageFromStructure',
secureHandler: async ({ req, res }) =>
this.uploadImageToDropbox(req.body.structureUrl).then(uploadUrl =>
- this.generateImageFromStructure(req.body.prompt, req.body.width, req.body.height, uploadUrl, req.body.strength).then(fire =>
+ this.generateImageFromStructure(req.body.prompt, req.body.width, req.body.height, uploadUrl, req.body.strength, req.body.styles).then(fire =>
DashUploadUtils.UploadImage(JSON.parse(fire ?? '').url).then(info => {
if (info instanceof Error) _invalid(res, info.message);
else _success(res, info);