diff options
author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-04-28 13:12:24 -0400 |
---|---|---|
committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-04-28 13:12:24 -0400 |
commit | e7db6f3490968fd2dcfbe879b991f326dbb5a3d7 (patch) | |
tree | 966b72c13a3e4dfc7ad0d5e4025d6097b6dcd137 /src | |
parent | 219f023202658414b09c5245c807c1bb6cdc4285 (diff) |
save prog
Diffstat (limited to 'src')
-rw-r--r-- | src/client/apis/gpt/customization.ts | 24 | ||||
-rw-r--r-- | src/client/views/nodes/trails/PresBox.scss | 5 | ||||
-rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 186 |
3 files changed, 170 insertions, 45 deletions
diff --git a/src/client/apis/gpt/customization.ts b/src/client/apis/gpt/customization.ts index a1ab2bd5f..9c751f8bd 100644 --- a/src/client/apis/gpt/customization.ts +++ b/src/client/apis/gpt/customization.ts @@ -39,7 +39,7 @@ const setupPresSlideCustomization = () => { setupPresSlideCustomization(); -export const getSlideTransitionSuggestions = async (inputText: string, properties: any) => { +export const getSlideTransitionSuggestions = async (inputText: string, history?: string) => { /** * Prompt: Generate an entrance animations from slower and gentler * to bouncier and more high energy @@ -56,7 +56,27 @@ export const getSlideTransitionSuggestions = async (inputText: string, propertie * } * } */ - const res = await new Promise(resolve => resolve('result')); + + const prompt = + "I want to generate four distinct types of slide effect animations. Return a json of the form {effect: string, stiffness: number, damping: number, mass: number}[] with four elements. Effect is the type of animation; its only possible values are ['Zoom', 'Fade in', 'Bounce', 'Flip', 'Rotate', 'Roll']. Stiffness, damping, and mass Stiffness, damping, and mass control the physics-based properties of spring animations. This is used to create a more natural looking timing, bouncy effects, etc. Use spring physics to adjust these parameters to animate the effect."; + + const customInput = inputText ?? 'Make them as contrasting as possible with different effects and timings ranging from gentle to energetic.'; + + try { + const response = await openai.chat.completions.create({ + model: 'gpt-4', + messages: [ + { role: 'system', content: prompt }, + { role: 'user', content: `${customInput}` }, + ], + temperature: 0, + max_tokens: 1000, + }); + return response.choices[0].message?.content; + } catch (err) { + console.log(err); + return 'Error connecting with API.'; + } }; export const gptTrailSlideCustomization = async (inputText: string, properties: any | any[], applyToWhole?: boolean) => { diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss index 09de4b0f4..7a2733146 100644 --- a/src/client/views/nodes/trails/PresBox.scss +++ b/src/client/views/nodes/trails/PresBox.scss @@ -40,11 +40,12 @@ .presBox-effect-row { display: flex; - gap: 4px; + gap: 8px; margin: 4px; } .presBox-effect-container { + cursor: pointer; overflow: hidden; position: relative; width: 80px; @@ -61,7 +62,7 @@ top: 20px; left: 20px; border-radius: 4px; - // default bg + // default bg background-color: rgb(37, 161, 255); } diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 9644935b2..67f787b1e 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -42,13 +42,13 @@ import ReactTextareaAutosize from 'react-textarea-autosize'; import { Button, Dropdown, DropdownType, IconButton, Toggle, ToggleType, Type } from 'browndash-components'; import { BiMicrophone, BiX } from 'react-icons/bi'; import { AiOutlineSend } from 'react-icons/ai'; -import { gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/customization'; +import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/customization'; import { DictationManager } from '../../../util/DictationManager'; import CubicBezierEditor, { TIMING_DEFAULT_MAPPINGS } from './CubicBezierEditor'; import Slider from '@mui/material/Slider'; import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp, FaCompressArrowsAlt } from 'react-icons/fa'; import SpringAnimationPreview from './SlideEffectPreview'; -import { effectTimings, SpringType, springMappings, effectItems, easeItems, movementItems, SpringSettings, presEffectDefaultTimings } from './SpringUtils'; +import { effectTimings, SpringType, springMappings, effectItems, easeItems, movementItems, SpringSettings, presEffectDefaultTimings, AnimationSettings } from './SpringUtils'; import SlideEffect from './SlideEffect'; export interface pinDataTypes { @@ -121,18 +121,58 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // GPT private _inputref: HTMLTextAreaElement | null = null; + private _inputref2: HTMLTextAreaElement | null = null; @observable chatActive: boolean = false; @observable chatInput: string = ''; public slideToModify: Doc | null = null; @observable isRecording: boolean = false; @observable isLoading: boolean = false; + @observable generatedAnimations: AnimationSettings[] = [ + { + effect: PresEffect.Bounce, + stiffness: 400, + damping: 15, + mass: 1, + }, + { + effect: PresEffect.Fade, + stiffness: 100, + damping: 15, + mass: 1, + }, + { + effect: PresEffect.Flip, + stiffness: 100, + damping: 15, + mass: 1, + }, + { + effect: PresEffect.Roll, + stiffness: 100, + damping: 15, + mass: 1, + }, + ]; + + @action + setGeneratedAnimations = (settings: AnimationSettings[]) => { + this.generatedAnimations = settings; + }; + + @observable animationChat: string = ''; + @action setChatInput = (input: string) => { this.chatInput = input; }; @action + setAnimationChat = (input: string) => { + this.animationChat = input; + }; + + @action setIsLoading = (isLoading: boolean) => { this.isLoading = isLoading; }; @@ -367,6 +407,41 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { }; @action + customizeAnimations = async (input: string) => { + // const testInput = 'change title to Customized Slide, transition for 2.3s with fade in effect'; + // if (!this.slideToModify) return; + this.setIsLoading(true); + + try { + const res = await getSlideTransitionSuggestions(this.animationChat); + console.log('GPT Result:', res); + if (typeof res === 'string') { + const resObj = JSON.parse(res); + console.log('Parsed GPT Result ', resObj); + // this.activeItem + this.setGeneratedAnimations(resObj as AnimationSettings[]); + // this.updateEffect(resObj.effect as PresEffect, false); + // this.updateEffectTiming(this.activeItem, { + // type: SpringType.CUSTOM, + // stiffness: resObj.stiffness, + // damping: resObj.damping, + // mass: resObj.mass, + // }); + + // for (let key in resObj) { + // if (resObj[key]) { + // console.log('typeof property', typeof resObj[key]); + // this.activeItem[key] = resObj[key]; + // } + // } + } + } catch (err) { + console.error(err); + } + this.setIsLoading(false); + }; + + @action customizeWithGPT = async (input: string) => { // const testInput = 'change title to Customized Slide, transition for 2.3s with fade in effect'; // if (!this.slideToModify) return; @@ -2176,35 +2251,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="presBox-gpt-chat"> <p>Customize with GPT</p> <div className="pres-chat"> - <div className="pres-chatbox-container"> + <div + className="pres-chatbox-container" + onClick={e => { + e.stopPropagation(); + }}> <ReactTextareaAutosize ref={r => (this._inputref = r)} minRows={1} - placeholder="Customize..." + placeholder="Get animation suggestions..." className="pres-chatbox" autoFocus={true} - value={this.chatInput} + value={this.animationChat} onChange={e => { - this.setChatInput(e.target.value); + this.setAnimationChat(e.target.value); }} onKeyDown={e => { this.stopDictation(true); e.stopPropagation(); }} /> - <IconButton - type={Type.TERT} - color={this.isRecording ? '#2bcaff' : StrCast(Doc.UserDoc().userVariantColor)} - tooltip="Record" - icon={<BiMicrophone size={'16px'} />} - onClick={() => { - if (!this.isRecording) { - this.recordDictation(); - } else { - this.stopDictation(true); - } - }} - /> </div> <Button style={{ alignSelf: 'flex-end' }} @@ -2214,34 +2280,72 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { iconPlacement="right" color={StrCast(Doc.UserDoc().userVariantColor)} onClick={() => { - this.customizeWithGPT(this.chatInput); + this.customizeAnimations(this.animationChat); }} /> </div> </div> {/* Preview Animations */} - <div className="presBox-effect-row"> - <div className="presBox-effect-container"> - <SlideEffect dir={PresEffectDirection.Left as PresEffectDirection} presEffect={PresEffect.Bounce} tension={100} friction={15} mass={1} infinite> - <div className="presBox-effect-demo-box"></div> - </SlideEffect> - </div> - <div className="presBox-effect-container"> - <SlideEffect dir={PresEffectDirection.Left as PresEffectDirection} presEffect={PresEffect.Fade} tension={100} friction={15} mass={1} infinite> - <div className="presBox-effect-demo-box" style={{ backgroundColor: '#4925ff' }}></div> - </SlideEffect> - </div> - </div> - <div className="presBox-effect-row"> - <div className="presBox-effect-container"> - <SlideEffect dir={PresEffectDirection.Left as PresEffectDirection} presEffect={PresEffect.Flip} tension={100} friction={15} mass={1} infinite> - <div className="presBox-effect-demo-box" style={{ top: 0, left: 0, backgroundColor: '#a825ff' }}></div> - </SlideEffect> + <div> + <div className="presBox-effect-row"> + <div className="presBox-effect-container"> + <SlideEffect + key={JSON.stringify(this.generatedAnimations[0])} + dir={PresEffectDirection.Left as PresEffectDirection} + presEffect={this.generatedAnimations[0].effect as PresEffect} + tension={this.generatedAnimations[0].stiffness} + friction={this.generatedAnimations[0].damping} + mass={this.generatedAnimations[0].mass} + infinite> + <div + className="presBox-effect-demo-box" + style={{ top: this.generatedAnimations[0].effect === PresEffect.Flip ? 0 : '20px', left: this.generatedAnimations[0].effect === PresEffect.Flip ? 0 : '20px' }}></div> + </SlideEffect> + </div> + <div className="presBox-effect-container"> + <SlideEffect + key={JSON.stringify(this.generatedAnimations[1])} + dir={PresEffectDirection.Left as PresEffectDirection} + presEffect={this.generatedAnimations[1].effect as PresEffect} + tension={this.generatedAnimations[1].stiffness} + friction={this.generatedAnimations[1].damping} + mass={this.generatedAnimations[1].mass} + infinite> + <div + className="presBox-effect-demo-box" + style={{ top: this.generatedAnimations[1].effect === PresEffect.Flip ? 0 : '20px', left: this.generatedAnimations[1].effect === PresEffect.Flip ? 0 : '20px', backgroundColor: '#4925ff' }}></div> + </SlideEffect> + </div> </div> - <div className="presBox-effect-container"> - <SlideEffect dir={PresEffectDirection.Left as PresEffectDirection} presEffect={PresEffect.Roll} tension={100} friction={15} mass={1} infinite> - <div className="presBox-effect-demo-box" style={{ backgroundColor: '#ff2599' }}></div> - </SlideEffect> + <div className="presBox-effect-row"> + <div className="presBox-effect-container"> + <SlideEffect + key={JSON.stringify(this.generatedAnimations[2])} + dir={PresEffectDirection.Left as PresEffectDirection} + presEffect={this.generatedAnimations[2].effect as PresEffect} + tension={this.generatedAnimations[2].stiffness} + friction={this.generatedAnimations[2].damping} + mass={this.generatedAnimations[2].mass} + infinite> + <div + className="presBox-effect-demo-box" + style={{ top: this.generatedAnimations[2].effect === PresEffect.Flip ? 0 : '20px', left: this.generatedAnimations[2].effect === PresEffect.Flip ? 0 : '20px', backgroundColor: '#a825ff' }}></div> + </SlideEffect> + </div> + <div className="presBox-effect-container"> + <SlideEffect + key={JSON.stringify(this.generatedAnimations[3])} + dir={PresEffectDirection.Left as PresEffectDirection} + presEffect={this.generatedAnimations[3].effect as PresEffect} + tension={this.generatedAnimations[3].stiffness} + friction={this.generatedAnimations[3].damping} + mass={this.generatedAnimations[3].mass} + infinite> + <div + className="presBox-effect-demo-box" + style={{ top: this.generatedAnimations[3].effect === PresEffect.Flip ? 0 : '20px', left: this.generatedAnimations[3].effect === PresEffect.Flip ? 0 : '20px', backgroundColor: '#ff2599' }}></div> + </SlideEffect> + </div> </div> </div> </div> |