diff options
author | Sophie Zhang <sophie_zhang@brown.edu> | 2023-11-16 02:18:38 -0500 |
---|---|---|
committer | Sophie Zhang <sophie_zhang@brown.edu> | 2023-11-16 02:18:38 -0500 |
commit | 7bde1b066a68fca6202b3f42c1cb54aa85c13890 (patch) | |
tree | ff4c00ffdc6ca5b99479f7e356783a573d560a50 | |
parent | 6a4de8d05ce46dc29ac69f696c419a57e604f516 (diff) |
use image toggle
-rw-r--r-- | src/client/apis/gpt/customization.ts | 13 | ||||
-rw-r--r-- | src/client/views/PropertiesView.tsx | 37 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 45 |
3 files changed, 65 insertions, 30 deletions
diff --git a/src/client/apis/gpt/customization.ts b/src/client/apis/gpt/customization.ts index f9dabd863..38458f22c 100644 --- a/src/client/apis/gpt/customization.ts +++ b/src/client/apis/gpt/customization.ts @@ -71,8 +71,8 @@ export const gptTrailSlideCustomization = async (inputText: string) => { }; // palette / styling -export const generatePalette = async (inputData: any) => { - let prompt = 'Dash is a hypermedia web application that allows users to organize documents of different media types into collections. I want you to come up with a cohesive color palette for a collection.'; +export const generatePalette = async (inputData: any, useImageData: boolean) => { + let prompt = 'Dash is a hypermedia web application that allows users to organize documents of different media types into collections. I want you to come up with cohesive color palettes for a collection.'; prompt += 'I am going to give you a json object of this format:' + JSON.stringify({ collectionDescription: 'string', documents: 'Document[]', imageColors: 'string[]' }) + @@ -82,7 +82,10 @@ export const generatePalette = async (inputData: any) => { textSize: 'number', textContent: 'string', }) + - '. Finally, imageColors are the main hex colors of the images in the collection. You are going to generate three distinct variants of color palettes for the user to choose from based mostly on collectionDescription, and loosely on the text content and text size of the documents. You should slightly take imageColors into account, but primarly focus on crafting a palette that matches the text content. The variants should start with a light palette and grow increasingly more intense and vibrant. Return a json array of three objects in this format:' + + (useImageData ? '. Finally, imageColors are the main hex colors of the images in the collection.' : '. Ignore imageColors.') + + 'You are going to generate three distinct variants of color palettes for the user to choose from based mostly on collectionDescription, and loosely on the text content and text size of the documents.' + + (useImageData && 'You should slightly take imageColors into account, but primarly focus on crafting a palette that matches the text content.') + + 'The variants should start with a light palette and grow increasingly more intense and vibrant. Return a json array of three objects in this format:' + JSON.stringify({ collectionBackgroundColor: 'string', documentsWithColors: 'DocumentWithColor[]', @@ -92,9 +95,9 @@ export const generatePalette = async (inputData: any) => { id: 'number', color: 'string', }) + - ", and each element’s color is based on the theme of the overall color palette and also by its document’s textContent. Please pay attention to aesthetics of how each document's color complement the background and each other and choose a variety of colors when appropriate. Respond with only the JSON array."; + ", and each element’s color is based on the theme of the overall color palette and also by its document’s textContent. Please pay attention to aesthetics of how each document's color complement the background and each other and choose a variety of colors when appropriate. Important: Respond with only the JSON array and no other text."; - // console.log('Prompt', prompt); + console.log('Prompt', prompt); try { const response = await openai.createChatCompletion({ model: 'gpt-4', diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 86784d467..6c193f5a7 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -3,7 +3,7 @@ import { IconLookup } from '@fortawesome/fontawesome-svg-core'; import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, Tooltip } from '@material-ui/core'; -import { ColorPicker, Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; +import { Button, ColorPicker, Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; import { concat } from 'lodash'; import { action, computed, IReactionDisposer, observable, reaction, trace } from 'mobx'; import { observer } from 'mobx-react'; @@ -40,7 +40,7 @@ import { PropertiesSection } from './PropertiesSection'; import './PropertiesView.scss'; import { DefaultStyleProvider } from './StyleProvider'; import { FaFillDrip } from 'react-icons/fa'; -import { GeneratedResponse } from '../apis/gpt/customization'; +import { GeneratedResponse, generatePalette } from '../apis/gpt/customization'; import { ExtractColors } from './ExtractColors'; const _global = (window /* browser */ || global) /* node */ as any; @@ -95,9 +95,27 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @observable openStyling: boolean = true; // GPT styling + public styleInput: any; @observable generatedStyles: GeneratedResponse[] = []; @observable inputDocs: Doc[] = []; @observable selectedStyle: number = -1; + @observable useImageData = false; + + @action + gptStyling = async () => { + this.generatedStyles = []; + this.selectedStyle = -1; + try { + const res = await generatePalette(this.styleInput, this.useImageData); + if (typeof res === 'string') { + console.log(res); + const resObj = JSON.parse(res) as GeneratedResponse[]; + this.setGeneratedStyles(resObj); + } + } catch (err) { + console.error(err); + } + }; @action setGeneratedStyles = (responses: GeneratedResponse[]) => (this.generatedStyles = responses); @@ -1190,14 +1208,25 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <div className="propertiesView-content" style={{ position: 'relative', height: 'auto', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }}> {this.generatedStyles.length > 0 ? this.generatedStyles.map((style, i) => ( - <div className="propertiesView-palette" style={{ display: 'flex', gap: '4px', backgroundColor: this.selectedStyle === i ? StrCast(Doc.UserDoc().userVariantColor) : '#00000000' }} onClick={() => this.styleCollection(i)}> + <div + key={i} + className="propertiesView-palette" + style={{ display: 'flex', gap: '4px', backgroundColor: this.selectedStyle === i ? StrCast(Doc.UserDoc().userVariantColor) : '#00000000' }} + onClick={() => this.styleCollection(i)}> <div style={{ width: '24px', height: '24px', backgroundColor: style.collectionBackgroundColor, borderRadius: '2px' }}></div> {ExtractColors.sortColors(style.documentsWithColors.map(doc => ExtractColors.hexToFinalColor(doc.color))).map(c => ( - <div style={{ width: '24px', height: '24px', backgroundColor: c.hex, borderRadius: '2px' }}></div> + <div key={c.hex} style={{ width: '24px', height: '24px', backgroundColor: c.hex, borderRadius: '2px' }}></div> ))} </div> )) : 'Generating styles...'} + <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px' }}> + <div style={{ display: 'flex', gap: '4px', alignItems: 'center' }}> + <label>Use Images </label> + <input type="checkbox" checked={this.useImageData} onChange={action(e => (this.useImageData = e.target.checked))} /> + </div> + <Button text={'Regenerate'} type={Type.TERT} color={StrCast(Doc.UserDoc().userVariantColor)} onClick={this.gptStyling} /> + </div> </div> </PropertiesSection> ); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b0be060bd..f5ba0de96 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1819,8 +1819,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection // gpt styling @action gptStyling = async () => { + // clear it in properties instead + if (!PropertiesView.Instance) return; this.openProperties(); - PropertiesView.Instance?.setGeneratedStyles([]); + PropertiesView.Instance.setGeneratedStyles([]); + PropertiesView.Instance.selectedStyle = -1; console.log('Title', this.rootDoc.title); console.log('bgcolor', this.layoutDoc._backgroundColor); // doc.backgroundColor @@ -1847,29 +1850,29 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection const collectionDescription = StrCast(this.rootDoc.title); - console.log({ + const styleInput = { collectionDescription, documents: gptInput, - }); + imageColors: colorHexes, + }; - try { - const res = await generatePalette({ - collectionDescription, - documents: gptInput, - imageColors: colorHexes, - }); - if (typeof res === 'string') { - console.log(res); - const resObj = JSON.parse(res) as GeneratedResponse[]; - PropertiesView.Instance?.setGeneratedStyles(resObj); - // const resObj = JSON.parse(res) as GeneratedResponse; - // console.log('Result ', resObj); - // this.rootDoc.backgroundColor = resObj.collectionBackgroundColor; - // (resObj.documentsWithColors).forEach((elem, i) => (inputDocs[i].backgroundColor = elem.color)); - } - } catch (err) { - console.error(err); - } + PropertiesView.Instance.styleInput = styleInput; + PropertiesView.Instance.gptStyling(); + + // try { + // const res = await generatePalette(styleInput); + // if (typeof res === 'string') { + // console.log(res); + // const resObj = JSON.parse(res) as GeneratedResponse[]; + // PropertiesView.Instance.setGeneratedStyles(resObj); + // // const resObj = JSON.parse(res) as GeneratedResponse; + // // console.log('Result ', resObj); + // // this.rootDoc.backgroundColor = resObj.collectionBackgroundColor; + // // (resObj.documentsWithColors).forEach((elem, i) => (inputDocs[i].backgroundColor = elem.color)); + // } + // } catch (err) { + // console.error(err); + // } }; onContextMenu = (e: React.MouseEvent) => { |