diff options
author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-02-07 19:08:38 -0500 |
---|---|---|
committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-02-07 19:08:38 -0500 |
commit | 70cf5ad795055c1f628c918b08a13a96e4ab89a6 (patch) | |
tree | 60d799c32e36549f8ffa1f67de1ba232030e8294 | |
parent | 7082d37c07575afe29818c3a286e9b981e8bc307 (diff) |
saving prog
3 files changed, 94 insertions, 3 deletions
diff --git a/src/client/apis/gpt/customization.ts b/src/client/apis/gpt/customization.ts index db91e45a7..42f112f88 100644 --- a/src/client/apis/gpt/customization.ts +++ b/src/client/apis/gpt/customization.ts @@ -84,6 +84,68 @@ export const gptTrailSlideCustomization = async (inputText: string) => { } }; +// layout +export const smartLayout = async (inputData: { width: number; height: number }[]) => { + let prompt = + 'I want to layout documents in a 2d space in a nice, grid-like fashion with nice padding of about 50 units around each document, making sure they do not overlap. Given a json array of documents containing their width and heights in this form: {width: number, height: number}[], give me a json array in this form: {x: number, y: number}[] corresponding to the documents with a nice layout. Return just the json array.'; + + let messages: ChatCompletionMessageParam[] = [ + { role: 'system', content: prompt }, + { role: 'user', content: JSON.stringify(inputData) }, + ]; + + console.log('Prompt: ', prompt); + console.log('Messages: ', messages); + + try { + const response = await openai.chat.completions.create({ + model: 'gpt-4', + messages: messages, + temperature: 0.01, + max_tokens: 2000, + }); + const content = response.choices[0].message?.content; + if (content) { + return content; + } + return 'Malformed response.'; + } catch (err) { + console.log(err); + return 'Error connecting with API.'; + } +}; + +// layout +export const smartLayout2 = async (inputData: { width: number; height: number; content: string }[]) => { + let prompt = + 'I want to layout documents in a 2d space in an organized fashion with padding of about 50 units around each document, importantly making sure they do not overlap. I also want you to group documents by their content, with space separating semantic categories. Given a json array of documents containing their width and heights in this form: {width: number, height: number, content: string}[], give me a json array in this form: {x: number, y: number}[] corresponding to the documents in the same order with a nice layout. Return just the json array.'; + + let messages: ChatCompletionMessageParam[] = [ + { role: 'system', content: prompt }, + { role: 'user', content: JSON.stringify(inputData) }, + ]; + + console.log('Prompt: ', prompt); + console.log('Messages: ', messages); + + try { + const response = await openai.chat.completions.create({ + model: 'gpt-4', + messages: messages, + temperature: 0.01, + max_tokens: 2000, + }); + const content = response.choices[0].message?.content; + if (content) { + return content; + } + return 'Malformed response.'; + } catch (err) { + console.log(err); + return 'Error connecting with API.'; + } +}; + // palette / styling export const generatePalette = async (inputData: StyleInput, useImageData: boolean, inputText: string, lastResponse?: GeneratedResponse[]) => { let prompt = 'Dash is a hypermedia web application that allows users to organize documents of different media types into collections. The user wants you to come up with cohesive color palettes for a collection.'; @@ -121,6 +183,7 @@ export const generatePalette = async (inputData: StyleInput, useImageData: boole { role: 'user', content: JSON.stringify(inputData) }, ]; + // continuing conversation if (lastResponse && inputText !== '') { messages.push({ role: 'assistant', content: JSON.stringify(lastResponse) }); messages.push({ role: 'user', content: 'Please modify the previously generated palettes with the following: ' + inputText }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 8e415a407..fb9d42bc7 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -55,7 +55,7 @@ import './CollectionFreeFormView.scss'; import { MarqueeView } from './MarqueeView'; import { PropertiesView } from '../../PropertiesView'; import { ExtractColors } from '../../ExtractColors'; -import { StyleInputDocument } from '../../../apis/gpt/customization'; +import { smartLayout, smartLayout2, StyleInputDocument } from '../../../apis/gpt/customization'; import { RichTextField } from '../../../../fields/RichTextField'; import { extname } from 'path'; @@ -1659,6 +1659,31 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection return url.href.replace(ext, '_m' + ext); } + // gpt layout + @action + gptLayout = async () => { + const docLayouts = this.childDocs.map(doc => ({ + width: NumCast(doc.width), + height: NumCast(doc.height), + content: StrCast(doc.title), + })); + console.log(docLayouts); + + const res = await smartLayout2(docLayouts); + console.log('Smart layout result', res); + // make type-safe + const resObj = JSON.parse(res) as any[]; + resObj.forEach((elem, i) => { + this.childDocs[i].x = elem.x; + this.childDocs[i].y = elem.y; + }); + + // refit collection + setTimeout(() => { + this.fitContentOnce(); + }, 500); + }; + // gpt styling @action gptStyling = async () => { @@ -1740,7 +1765,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection optionItems.push({ description: (this._showAnimTimeline ? 'Close' : 'Open') + ' Animation Timeline', event: action(() => (this._showAnimTimeline = !this._showAnimTimeline)), icon: 'eye' }); this._props.renderDepth && optionItems.push({ description: 'Use Background Color as Default', event: () => (Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor)), icon: 'palette' }); this._props.renderDepth && optionItems.push({ description: 'Fit Content Once', event: this.fitContentOnce, icon: 'object-group' }); + // Want to condense into a Smart Organize button this._props.renderDepth && optionItems.push({ description: 'Style with AI', event: this.gptStyling, icon: 'paint-brush' }); + this._props.renderDepth && optionItems.push({ description: 'Smart Layout', event: this.gptLayout, icon: 'object-group' }); if (!Doc.noviceMode) { optionItems.push({ description: (!Doc.NativeWidth(this.layoutDoc) || !Doc.NativeHeight(this.layoutDoc) ? 'Freeze' : 'Unfreeze') + ' Aspect', event: this.toggleNativeDimensions, icon: 'snowflake' }); } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index f9cef1a60..460f2a1c6 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -67,6 +67,7 @@ import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from './RichTextRules'; import { schema } from './schema_rts'; import { SummaryView } from './SummaryView'; +import { isDarkMode } from '../../../util/reportManager/reportManagerUtils'; // import * as applyDevTools from 'prosemirror-dev-tools'; @observer export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface { @@ -1153,7 +1154,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if (BoolCast(Doc.UserDoc().settingBgColor)) return; console.log('checking bg color 2'); let fontColor = '#000000'; - if (isDarkMode(StrCast(this.rootDoc._backgroundColor))) { + if (isDarkMode(StrCast(this.Document._backgroundColor))) { fontColor = '#ffffff'; } // set text to white @@ -1188,7 +1189,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps { fireImmediately: true } ); this._disposers.bgColor = reaction( - () => this.rootDoc._backgroundColor, + () => this.Document._backgroundColor, color => this.checkBackgroundColor() ); this._disposers.componentHeights = reaction( |