From e7db6f3490968fd2dcfbe879b991f326dbb5a3d7 Mon Sep 17 00:00:00 2001 From: Sophie Zhang Date: Sun, 28 Apr 2024 13:12:24 -0400 Subject: save prog --- src/client/apis/gpt/customization.ts | 24 +++- src/client/views/nodes/trails/PresBox.scss | 5 +- src/client/views/nodes/trails/PresBox.tsx | 186 ++++++++++++++++++++++------- 3 files changed, 170 insertions(+), 45 deletions(-) (limited to 'src') 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,17 +121,57 @@ export class PresBox extends ViewBoxBaseComponent() { // 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; @@ -366,6 +406,41 @@ export class PresBox extends ViewBoxBaseComponent() { // this._inputref.setSelectionRange(newCursorPosition, newCursorPosition); }; + @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'; @@ -2176,35 +2251,26 @@ export class PresBox extends ViewBoxBaseComponent() {

Customize with GPT

-
+
{ + e.stopPropagation(); + }}> (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(); }} /> - } - onClick={() => { - if (!this.isRecording) { - this.recordDictation(); - } else { - this.stopDictation(true); - } - }} - />
{/* Preview Animations */} -
-
- -
-
-
-
- -
-
-
-
-
-
- -
-
+
+
+
+ +
+
+
+
+ +
+
+
-
- -
-
+
+
+ +
+
+
+
+ +
+
+
-- cgit v1.2.3-70-g09d2