From 414abda35b79c2d670451df8938740bd891881e1 Mon Sep 17 00:00:00 2001
From: Sophie Zhang <sophie_zhang@brown.edu>
Date: Thu, 19 Oct 2023 02:14:16 -0400
Subject: fixed key events (chatbox)

---
 src/client/views/nodes/trails/PresBox.tsx | 81 +++++++++++++++++++++++++------
 1 file changed, 67 insertions(+), 14 deletions(-)

(limited to 'src/client/views/nodes/trails/PresBox.tsx')

diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 051a1fbfd..0d5edcd83 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -36,6 +36,7 @@ import { DocFocusOptions, DocumentView, OpenWhere, OpenWhereMod } from '../Docum
 import { FieldView, FieldViewProps } from '../FieldView';
 import { ScriptingBox } from '../ScriptingBox';
 import './PresBox.scss';
+import ReactLoading from 'react-loading';
 import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
 import { IconButton, Type } from 'browndash-components';
 import { AiOutlineSend } from 'react-icons/ai';
@@ -112,16 +113,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @observable _forceKeyEvents: boolean = false;
 
     // GPT
+    private _inputref: HTMLTextAreaElement | null = null;
     @observable chatActive: boolean = false;
     @observable chatInput: string = '';
     public slideToModify: Doc | null = null;
     @observable isRecording: boolean = false;
+    @observable isLoading: boolean = false;
 
     @action
     setChatInput = (input: string) => {
         this.chatInput = input;
     };
 
+    @action
+    setIsLoading = (isLoading: boolean) => {
+        this.isLoading = isLoading;
+    };
+
     @action
     public setChatActive = (active: boolean) => {
         this.chatActive = active;
@@ -272,6 +280,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     // GPT
 
     recordDictation = () => {
+        this.setIsRecording(true);
+        this.setChatInput('');
         DictationManager.Controls.listen({
             interimHandler: this.setDictationContent,
             continuous: { indefinite: false },
@@ -281,17 +291,38 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             }
         });
     };
-    stopDictation = (abort: boolean) => DictationManager.Controls.stop(!abort);
+    stopDictation = (abort: boolean) => {
+        this.setIsRecording(false);
+        DictationManager.Controls.stop(!abort);
+    };
 
     setDictationContent = (value: string) => {
         this.setChatInput(value);
+        // // Get the current cursor position
+        // if (!this._inputref) return;
+        // const cursorPosition = this._inputref.selectionStart;
+        // const currentValue = this.chatInput;
+
+        // // split before and after
+        // const textBeforeCursor = currentValue.slice(0, cursorPosition);
+        // const textAfterCursor = currentValue.slice(cursorPosition);
+
+        // // insertion
+        // const updatedText = textBeforeCursor + value + textAfterCursor;
+
+        // // Update the textarea value
+        // this.setChatInput(updatedText);
+
+        // // set new cursor pos
+        // const newCursorPosition = cursorPosition + value.length;
+        // this._inputref.setSelectionRange(newCursorPosition, newCursorPosition);
     };
 
     @action
     customizeWithGPT = 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 gptTrailSlideCustomization(input);
             if (typeof res === 'string') {
@@ -307,6 +338,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         } catch (err) {
             console.error(err);
         }
+        this.setIsLoading(false);
     };
 
     //TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time
@@ -1280,6 +1312,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @action
     keyEvents = (e: KeyboardEvent) => {
         if (e.target instanceof HTMLInputElement) return;
+        if (e.target instanceof HTMLTextAreaElement) return;
         let handled = false;
         const anchorNode = document.activeElement as HTMLDivElement;
         if (anchorNode && anchorNode.className?.includes('lm_title')) return;
@@ -2742,17 +2775,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 {this.chatActive && (
                     <div className="presBox-chatbox">
                         <div style={{ alignSelf: 'flex-end' }}>
-                            <IconButton
-                                type={Type.PRIM}
-                                color={StrCast(Doc.UserDoc().userVariantColor)}
-                                tooltip="Close"
-                                icon={<BiX size={'16px'} />}
-                                onClick={() => {
-                                    this.setChatActive(false);
-                                }}
-                            />
+                            {this.isLoading ? (
+                                <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} width={14} height={14} />
+                            ) : (
+                                <IconButton
+                                    type={Type.PRIM}
+                                    color={StrCast(Doc.UserDoc().userVariantColor)}
+                                    tooltip="Close"
+                                    icon={<BiX size={'16px'} />}
+                                    onClick={() => {
+                                        this.setChatActive(false);
+                                    }}
+                                />
+                            )}
                         </div>
+                        {/* <div
+                            contentEditable={true}
+                            onInput={e => {
+                                const newContent = e.currentTarget.innerHTML;
+                                console.log('content', newContent);
+                                this.setChatInput(newContent);
+                            }}>
+                            {this.chatInput}
+                        </div> */}
                         <TextareaAutosize
+                            ref={r => (this._inputref = r)}
                             minRows={3}
                             placeholder="Customize..."
                             className="pres-chatbox"
@@ -2761,10 +2808,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                             onChange={e => {
                                 this.setChatInput(e.target.value);
                             }}
-                            onSelect={e => {
+                            // onSelect={e => {
+                            //     this.stopDictation(true);
+                            // }}
+                            onKeyDown={e => {
+                                // if (e.key === 'Enter') {
+                                //     this.customizeWithGPT(this.chatInput);
+                                // }
                                 this.stopDictation(true);
+                                e.stopPropagation();
                             }}
-                            onKeyDown={e => e.stopPropagation()}
                             onKeyPress={e => e.stopPropagation()}
                             onPointerDown={e => e.stopPropagation()}
                             onClick={e => e.stopPropagation()}
@@ -2787,7 +2840,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                             />
                             <IconButton
                                 type={Type.TERT}
-                                color={StrCast(Doc.UserDoc().userVariantColor)}
+                                color={!this.isLoading ? StrCast(Doc.UserDoc().userVariantColor) : '#7c7c7c'}
                                 tooltip="Send"
                                 icon={<AiOutlineSend size={'16px'} />}
                                 onClick={() => {
-- 
cgit v1.2.3-70-g09d2

