aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/apis/gpt/GPT.ts10
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx1
-rw-r--r--src/client/views/nodes/trails/PresBox.scss13
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx71
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx2
5 files changed, 81 insertions, 16 deletions
diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts
index d7e7f07fa..66689f2f6 100644
--- a/src/client/apis/gpt/GPT.ts
+++ b/src/client/apis/gpt/GPT.ts
@@ -26,7 +26,7 @@ const openai = new OpenAIApi(configuration);
const gptTrailSlideCustomization = async (inputText: string) => {
const prompt =
- 'We are adding customization to a slide in a presentation. Given a natural language input, translate it into a json with the required fields: [title, presentation_transition, presentation_effect, and config_zoom]. title is the title/name of the slide. presentation_transition is a number in milliseconds for how long it should take to transition to a slide. presentation_effect is an effect applied to the slide when we transition to it. Its only possible values are: [None, Fade in, Flip, Rotate, Bounce, Roll]. config zoom is a number from 0 to 1.0 indicating the percentage we should be zooming into the slide.If the input does not contain info a specific key, please set their value to null. Please only return the json with these keys and their values.';
+ 'We are adding customization to a slide in a presentation. Given a natural language input, translate it into a json with the required fields: [title, presentation_transition, presentation_effect, and config_zoom]. title is the title/name of the slide. presentation_transition is a number in milliseconds for how long it should take to transition to a slide. presentation_effect is an effect applied to the slide when we transition to it. Its only possible values are: [None, Fade in, Flip, Rotate, Bounce, Roll]. config zoom is a number from 0 to 1.0 indicating the percentage we should be zooming into the slide. If the input does not contain info a specific key, please set their value to null. Please only return the json with these keys and their values.';
try {
const response = await openai.createChatCompletion({
@@ -55,10 +55,6 @@ const gptAPICall = async (inputText: string, callType: GPTCallType) => {
if (callType === GPTCallType.SUMMARY) inputText += '.';
const opts: GPTCallOpts = callTypeMap[callType];
try {
- // const configuration = new Configuration({
- // apiKey: process.env.OPENAI_KEY,
- // });
- // const openai = new OpenAIApi(configuration);
const response = await openai.createCompletion({
model: opts.model,
max_tokens: opts.maxTokens,
@@ -74,10 +70,6 @@ const gptAPICall = async (inputText: string, callType: GPTCallType) => {
const gptImageCall = async (prompt: string, n?: number) => {
try {
- // const configuration = new Configuration({
- // apiKey: process.env.OPENAI_KEY,
- // });
- // const openai = new OpenAIApi(configuration);
const response = await openai.createImage({
prompt: prompt,
n: n ?? 1,
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 90ebf5206..eab62c20b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -966,6 +966,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
};
breakupDictation = () => {
+ console.log('breakup');
if (this._editorView && this._recordingDictation) {
this.stopDictation(true);
this._break = true;
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss
index ac0d58368..370b155fd 100644
--- a/src/client/views/nodes/trails/PresBox.scss
+++ b/src/client/views/nodes/trails/PresBox.scss
@@ -18,8 +18,8 @@
.presBox-chatbox {
position: fixed;
bottom: 8px;
- right: 8px;
- width: 300px;
+ left: 8px;
+ width: calc(100% - 16px);
min-height: 100px;
border-radius: 16px;
padding: 16px;
@@ -31,11 +31,12 @@
background-color: #ffffff;
box-shadow: 0 2px 5px #7474748d;
- input {
- resize: vertical;
- // min-height: 125px;
- border: none;
+ .pres-chatbox {
outline: none;
+ border: none;
+ font-size: 16px;
+ letter-spacing: 1px;
+ color: #404040;
}
}
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index ebf9c211c..051a1fbfd 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -40,6 +40,9 @@ import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './Pre
import { IconButton, Type } from 'browndash-components';
import { AiOutlineSend } from 'react-icons/ai';
import { gptTrailSlideCustomization } from '../../../apis/gpt/GPT';
+import { DictationManager } from '../../../util/DictationManager';
+import { BiMicrophone, BiX } from 'react-icons/bi';
+import TextareaAutosize from 'react-textarea-autosize';
export interface pinDataTypes {
scrollable?: boolean;
@@ -112,6 +115,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable chatActive: boolean = false;
@observable chatInput: string = '';
public slideToModify: Doc | null = null;
+ @observable isRecording: boolean = false;
@action
setChatInput = (input: string) => {
@@ -123,6 +127,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.chatActive = active;
};
+ @action
+ public setIsRecording = (isRecording: boolean) => {
+ this.isRecording = isRecording;
+ };
+
@computed
get isTreeOrStack() {
return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._type_collection) as any);
@@ -260,6 +269,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
};
+ // GPT
+
+ recordDictation = () => {
+ DictationManager.Controls.listen({
+ interimHandler: this.setDictationContent,
+ continuous: { indefinite: false },
+ }).then(results => {
+ if (results && [DictationManager.Controls.Infringed].includes(results)) {
+ DictationManager.Controls.stop();
+ }
+ });
+ };
+ stopDictation = (abort: boolean) => DictationManager.Controls.stop(!abort);
+
+ setDictationContent = (value: string) => {
+ this.setChatInput(value);
+ };
+
@action
customizeWithGPT = async (input: string) => {
// const testInput = 'change title to Customized Slide, transition for 2.3s with fade in effect';
@@ -2714,9 +2741,51 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
{/* presbox chatbox */}
{this.chatActive && (
<div className="presBox-chatbox">
- <input placeholder="Customize..." value={this.chatInput} onChange={e => this.setChatInput(e.target.value)} />
<div style={{ alignSelf: 'flex-end' }}>
<IconButton
+ type={Type.PRIM}
+ color={StrCast(Doc.UserDoc().userVariantColor)}
+ tooltip="Close"
+ icon={<BiX size={'16px'} />}
+ onClick={() => {
+ this.setChatActive(false);
+ }}
+ />
+ </div>
+ <TextareaAutosize
+ minRows={3}
+ placeholder="Customize..."
+ className="pres-chatbox"
+ autoFocus={true}
+ value={this.chatInput}
+ onChange={e => {
+ this.setChatInput(e.target.value);
+ }}
+ onSelect={e => {
+ this.stopDictation(true);
+ }}
+ onKeyDown={e => e.stopPropagation()}
+ onKeyPress={e => e.stopPropagation()}
+ onPointerDown={e => e.stopPropagation()}
+ onClick={e => e.stopPropagation()}
+ onPointerUp={e => e.stopPropagation()}
+ />
+ {/* <input className="chatbox" placeholder="Customize..." value={this.chatInput} onChange={e => this.setChatInput(e.target.value)} /> */}
+ <div style={{ alignSelf: 'flex-end', display: 'flex', gap: '8px' }}>
+ <IconButton
+ type={Type.TERT}
+ color={this.isRecording ? 'red' : StrCast(Doc.UserDoc().userVariantColor)}
+ tooltip="Record"
+ icon={<BiMicrophone size={'16px'} />}
+ onClick={() => {
+ if (!this.isRecording) {
+ this.recordDictation();
+ } else {
+ this.stopDictation(true);
+ }
+ }}
+ />
+ <IconButton
type={Type.TERT}
color={StrCast(Doc.UserDoc().userVariantColor)}
tooltip="Send"
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 534a0f2aa..482d38f59 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -29,6 +29,7 @@ import { TreeView } from '../../collections/TreeView';
import { BranchingTrailManager } from '../../../util/BranchingTrailManager';
import { MultiToggle, Type } from 'browndash-components';
import { gptTrailSlideCustomization } from '../../../apis/gpt/GPT';
+import { DictationManager } from '../../../util/DictationManager';
/**
* This class models the view a document added to presentation will have in the presentation.
* It involves some functionality for its buttons and options.
@@ -566,6 +567,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
onClick={() => {
PresBox.Instance.setChatActive(true);
PresBox.Instance.slideToModify = this.rootDoc;
+ PresBox.Instance.recordDictation();
// this.customizeWithGPT('');
}}>
<FontAwesomeIcon icon={'message'} onPointerDown={e => e.stopPropagation()} />