From dd95b5030ec2d66d5e02acf2140a2e48fd77f739 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 30 Sep 2024 14:46:50 -0400
Subject: from last.. fixed eslint

---
 src/client/views/nodes/ComparisonBox.tsx | 82 ++++++++++++++------------------
 1 file changed, 36 insertions(+), 46 deletions(-)

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

diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 9ac8d7c52..cc20f0c57 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -1,41 +1,34 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { MathJax, MathJaxContext } from 'better-react-mathjax';
 import { Tooltip } from '@mui/material';
+import axios from 'axios';
 import { action, computed, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { returnFalse, returnNone, returnTrue, returnZero, setupMoveUpEvents } from '../../../ClientUtils';
+import ReactLoading from 'react-loading';
+import { returnFalse, returnNone, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
 import { emptyFunction } from '../../../Utils';
 import { Doc, Opt } from '../../../fields/Doc';
 import { DocData } from '../../../fields/DocSymbols';
+import { Id } from '../../../fields/FieldSymbols';
 import { RichTextField } from '../../../fields/RichTextField';
 import { DocCast, NumCast, RTFCast, StrCast, toList } from '../../../fields/Types';
+import { nullAudio } from '../../../fields/URLField';
 import { GPTCallType, gptAPICall, gptImageLabel } from '../../apis/gpt/GPT';
-import '../pdf/GPTPopup/GPTPopup.scss';
-import { DocUtils } from '../../documents/DocUtils';
+import { DocUtils, FollowLinkScript } from '../../documents/DocUtils';
 import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
 import { Docs } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
 import { dropActionType } from '../../util/DropActionTypes';
 import { undoable } from '../../util/UndoManager';
+import { ContextMenu } from '../ContextMenu';
 import { ViewBoxAnnotatableComponent } from '../DocComponent';
 import { PinDocView, PinProps } from '../PinFuncs';
 import { StyleProp } from '../StyleProp';
+import '../pdf/GPTPopup/GPTPopup.scss';
 import './ComparisonBox.scss';
 import { DocumentView } from './DocumentView';
 import { FieldView, FieldViewProps } from './FieldView';
 import { FormattedTextBox } from './formattedText/FormattedTextBox';
-import ReactLoading from 'react-loading';
-import { ContextMenu } from '../ContextMenu';
-import { ContextMenuProps } from '../ContextMenuItem';
-import { tickStep } from 'd3';
-import { CollectionCarouselView } from '../collections/CollectionCarouselView';
-import { FollowLinkScript } from '../../documents/DocUtils';
-import { schema } from '../nodes/formattedText/schema_rts';
-import { Id } from '../../../fields/FieldSymbols';
-import axios from 'axios';
-import ReactMarkdown from 'react-markdown';
-import { WebField, nullAudio } from '../../../fields/URLField';
 
 const API_URL = 'https://api.unsplash.com/search/photos';
 
@@ -118,26 +111,26 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
             <div>
                 <Tooltip
                     title={this.frontSide ? <div className="dash-tooltip">Flip to front side to use GPT</div> : <div className="dash-tooltip">Ask GPT to create an answer on the back side of the flashcard based on your question on the front</div>}>
-                    <div style={{ position: 'absolute', bottom: '3px', right: '50px', cursor: 'pointer' }} onPointerDown={e => (!this.frontSide ? this.findImageTags() : null)}>
+                    <div style={{ position: 'absolute', bottom: '3px', right: '50px', cursor: 'pointer' }} onPointerDown={() => (!this.frontSide ? this.findImageTags() : null)}>
                         <FontAwesomeIcon icon="lightbulb" size="xl" />
                     </div>
                 </Tooltip>
                 {DocCast(this.Document.embedContainer)?.type_collection === CollectionViewType.Carousel ? null : (
                     <div>
                         <Tooltip title={<div>Create a flashcard pile</div>}>
-                            <div style={{ position: 'absolute', bottom: '3px', right: '74px', cursor: 'pointer' }} onPointerDown={e => this.createFlashcardPile([this.Document], false)}>
+                            <div style={{ position: 'absolute', bottom: '3px', right: '74px', cursor: 'pointer' }} onPointerDown={() => this.createFlashcardPile([this.Document], false)}>
                                 <FontAwesomeIcon icon="folder-plus" size="xl" />
                             </div>
                         </Tooltip>
                         <Tooltip title={<div className="dash-tooltip">Create new flashcard stack based on text</div>}>
-                            <div style={{ position: 'absolute', bottom: '3px', right: '104px', cursor: 'pointer' }} onClick={e => this.gptFlashcardPile()}>
+                            <div style={{ position: 'absolute', bottom: '3px', right: '104px', cursor: 'pointer' }} onClick={() => this.gptFlashcardPile()}>
                                 <FontAwesomeIcon icon="layer-group" size="xl" />
                             </div>
                         </Tooltip>
                     </div>
                 )}
                 <Tooltip title={<div className="dash-tooltip">Hover to reveal</div>}>
-                    <div style={{ position: 'absolute', bottom: '3px', right: '25px', cursor: 'pointer' }} onClick={e => this.handleHover()}>
+                    <div style={{ position: 'absolute', bottom: '3px', right: '25px', cursor: 'pointer' }} onClick={() => this.handleHover()}>
                         <FontAwesomeIcon color={this.revealOp === 'hover' ? 'blue' : 'black'} icon="hand-point-up" size="xl" />
                     </div>
                 </Tooltip>
@@ -354,13 +347,13 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     openContextMenu = (x: number, y: number, evalu: boolean) => {
         ContextMenu.Instance.clearItems();
-        ContextMenu.Instance.addItem({ description: 'English', event: e => this.setLanguage('en-US', 0), icon: 'question' }); //prettier-ignore
-        ContextMenu.Instance.addItem({ description: 'Spanish', event: e => this.setLanguage('es-ES', 1 ), icon: 'question'}); //prettier-ignore
-        ContextMenu.Instance.addItem({ description: 'French', event: e => this.setLanguage('fr-FR', 2), icon: 'question' }); //prettier-ignore
-        ContextMenu.Instance.addItem({ description: 'Italian', event: e => this.setLanguage('it-IT', 3), icon: 'question' }); //prettier-ignore
-        if (!evalu) ContextMenu.Instance.addItem({ description: 'Mandarin Chinese', event: e => this.setLanguage('zh-CH', 4), icon: 'question' }); //prettier-ignore
-        ContextMenu.Instance.addItem({ description: 'Japanese', event: e => this.setLanguage('ja', 5), icon: 'question' }); //prettier-ignore
-        ContextMenu.Instance.addItem({ description: 'Korean', event: e => this.setLanguage('ko', 6), icon: 'question' }); //prettier-ignore
+        ContextMenu.Instance.addItem({ description: 'English', event: () => this.setLanguage('en-US', 0), icon: 'question' }); //prettier-ignore
+        ContextMenu.Instance.addItem({ description: 'Spanish', event: () => this.setLanguage('es-ES', 1 ), icon: 'question'}); //prettier-ignore
+        ContextMenu.Instance.addItem({ description: 'French', event: () => this.setLanguage('fr-FR', 2), icon: 'question' }); //prettier-ignore
+        ContextMenu.Instance.addItem({ description: 'Italian', event: () => this.setLanguage('it-IT', 3), icon: 'question' }); //prettier-ignore
+        if (!evalu) ContextMenu.Instance.addItem({ description: 'Mandarin Chinese', event: () => this.setLanguage('zh-CH', 4), icon: 'question' }); //prettier-ignore
+        ContextMenu.Instance.addItem({ description: 'Japanese', event: () => this.setLanguage('ja', 5), icon: 'question' }); //prettier-ignore
+        ContextMenu.Instance.addItem({ description: 'Korean', event: () => this.setLanguage('ko', 6), icon: 'question' }); //prettier-ignore
         ContextMenu.Instance.displayMenu(x, y);
     };
 
@@ -387,7 +380,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     };
 
     getYouTubeVideoId = (url: string) => {
-        const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=|\?v=)([^#\&\?]*).*/;
+        const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=|\?v=)([^#&?]*).*/;
         const match = url.match(regExp);
         return match && match[2].length === 11 ? match[2] : null;
     };
@@ -418,7 +411,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         newCol['x'] = this.layoutDoc['x'];
         newCol['y'] = NumCast(this.layoutDoc['y']) + 50;
         newCol.type_collection = 'carousel';
-        for (var i = 0; i < collectionArr.length; i++) {
+        for (let i = 0; i < collectionArr.length; i++) {
             DocCast(collectionArr[i])[DocData].embedContainer = newCol;
         }
 
@@ -436,10 +429,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
      * Transfers the content of flashcards into a flashcard pile.
      */
     gptFlashcardPile = async () => {
-        var text = await this.askGPT(GPTCallType.STACK);
-        var senArr = text?.split('Question: ');
-        var collectionArr: Doc[] = [];
-        for (let i = 1; i < senArr?.length!; i++) {
+        const text = await this.askGPT(GPTCallType.STACK);
+        const senArr = text?.split('Question: ') ?? [];
+        const collectionArr: Doc[] = [];
+        for (let i = 1; i < senArr.length; i++) {
             const newDoc = Docs.Create.ComparisonDocument(senArr![i], { _layout_isFlashcard: true, _width: 300, _height: 300 });
 
             if (StrCast(senArr![i]).includes('Keyword: ')) {
@@ -481,11 +474,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
      * Calls GPT for each flashcard type.
      */
     askGPT = async (callType: GPTCallType): Promise<string | undefined> => {
-        let questionText = 'Question: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text);
+        const questionText = 'Question: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text);
         const rubricText = ' Rubric: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text);
         const queryText = questionText + ' UserAnswer: ' + this._inputValue + '. ' + rubricText;
         this._loading = true;
-        const doc = DocCast(this.dataDoc[this.props.fieldKey + '_0']);
 
         if (callType == GPTCallType.CHATCARD) {
             if (StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text) === '') {
@@ -511,11 +503,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 this._loading = false;
                 return res;
             } else if (callType === GPTCallType.STACK) {
+                /* empty */
             }
             this._loading = false;
             return res;
         } catch (err) {
-            console.error('GPT call failed');
+            console.error('GPT call failed', err);
         }
         this._loading = false;
     };
@@ -527,7 +520,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         if (c?.length === 0) await this.askGPT(GPTCallType.CHATCARD);
         if (c) {
             this._loading = true;
-            for (let i of c) {
+            for (const i of c) {
                 console.log(i);
                 if (i.className !== 'ProseMirror-separator') await this.getImageDesc(i.src);
             }
@@ -653,7 +646,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
             DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = response;
         } catch (error) {
-            console.log('Error');
+            console.log('Error', error);
         }
     };
 
@@ -692,6 +685,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         return layoutTemplateString;
     };
 
+    childActiveFunc = () => this.childActive;
+
     render() {
         const clearButton = (which: string) => (
             <Tooltip title={<div className="dash-tooltip">remove</div>}>
@@ -712,7 +707,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
             return targetDoc || layoutString ? (
                 <>
                     <DocumentView
-                        // eslint-disable-next-line react/jsx-props-no-spreading
                         {...this._props}
                         showTags={undefined}
                         fitWidth={undefined}
@@ -725,7 +719,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         removeDocument={whichSlot.endsWith('1') ? this.remDoc1 : this.remDoc2}
                         NativeWidth={this.layoutWidth}
                         NativeHeight={this.layoutHeight}
-                        isContentActive={() => this.childActive}
+                        isContentActive={this.childActiveFunc}
                         isDocumentActive={returnFalse}
                         dontSelect={returnTrue}
                         whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
@@ -837,13 +831,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
             return (
                 <div
                     className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`} /* change className to easily disable/enable pointer events in CSS */
-                    style={{ display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
-                    onMouseEnter={() => {
-                        this.hoverFlip(false);
-                    }}
-                    onMouseLeave={() => {
-                        this.hoverFlip(true);
-                    }}>
+                    style={{ display: 'flex', flexDirection: 'column' }}
+                    onMouseEnter={() => this.hoverFlip(true)}
+                    onMouseLeave={() => this.hoverFlip(false)}>
                     {displayBox(`${this.fieldKey}_${side === 0 ? 1 : 0}`, side, this._props.PanelWidth() - 3)}
                     {this._loading ? (
                         <div className="loading-spinner" style={{ position: 'absolute' }}>
-- 
cgit v1.2.3-70-g09d2


From 92d13a93ec871f3f3048b7344528e618845ad76f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 30 Sep 2024 16:20:43 -0400
Subject: a bunch of comparisonBox cleanup and restoring of original click to
 animate between before/after.

---
 src/client/views/nodes/ComparisonBox.tsx | 157 ++++++++++---------------------
 src/client/views/nodes/ImageBox.tsx      |   7 +-
 2 files changed, 54 insertions(+), 110 deletions(-)

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

diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index cc20f0c57..d2a032d79 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -1,11 +1,11 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import axios from 'axios';
-import { action, computed, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import ReactLoading from 'react-loading';
-import { returnFalse, returnNone, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
+import { returnFalse, returnNone, returnTrue, returnZero, setupMoveUpEvents } from '../../../ClientUtils';
 import { emptyFunction } from '../../../Utils';
 import { Doc, Opt } from '../../../fields/Doc';
 import { DocData } from '../../../fields/DocSymbols';
@@ -37,7 +37,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     public static LayoutString(fieldKey: string) {
         return FieldView.LayoutString(ComparisonBox, fieldKey);
     }
+    private SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
+    private _closeRef = React.createRef<HTMLDivElement>();
     private _disposers: (DragManager.DragDropDisposer | undefined)[] = [undefined, undefined];
+    private _reactDisposer: IReactionDisposer | undefined;
     constructor(props: FieldViewProps) {
         super(props);
         makeObservable(this);
@@ -48,38 +51,19 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     @observable private _outputValue = '';
     @observable private _loading = false;
     @observable private _isEmpty = false;
-    @observable private _audio: Doc = Docs.Create.TextDocument('');
-    @observable childActive = false;
-    @observable _yRelativeToTop: boolean = true;
-    @observable _animating = '';
-    @observable mathJaxConfig = {
-        loader: { load: ['input/asciimath'] },
-    };
+    @observable private _childActive = false;
+    @observable private _animating = '';
     @observable private _listening = false;
-    @observable transcriptElement = '';
-    @observable private frontSide = false;
-    SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
+    @observable private _frontSide = false;
     @observable recognition = new this.SpeechRecognition();
-    _closeRef = React.createRef<HTMLDivElement>();
-
-    get revealOp() {
-        return this.layoutDoc[`_${this._props.fieldKey}_revealOp`];
-    }
-    get clipHeightKey() {
-        return '_' + this._props.fieldKey + '_clipHeight';
-    }
-
-    get clipWidthKey() {
-        return '_' + this._props.fieldKey + '_clipWidth';
-    }
-
-    @computed get clipWidth() {
-        return NumCast(this.layoutDoc[this.clipWidthKey], 50);
-    }
 
-    @computed get clipHeight() {
-        return NumCast(this.layoutDoc[this.clipHeightKey], 200);
-    }
+    @computed get revealOpKey()   { return `_${this._props.fieldKey}_revealOp`; } // prettier-ignore
+    @computed get clipHeightKey() { return `_${this._props.fieldKey}_clipHeight`; } // prettier-ignore
+    @computed get clipWidthKey()  { return `_${this._props.fieldKey}_clipWidth`;  } // prettier-ignore
+    @computed get clipWidth()     { return NumCast(this.layoutDoc[this.clipWidthKey], 50); } // prettier-ignore
+    @computed get clipHeight()    { return NumCast(this.layoutDoc[this.clipHeightKey], 200);  } // prettier-ignore
+    @computed get revealOp()      { return StrCast(this.layoutDoc[this.revealOpKey]); } // prettier-ignore
+    set revealOp(value:string)    { this.layoutDoc[this.revealOpKey] = value; } // prettier-ignore
 
     @computed get overlayAlternateIcon() {
         return (
@@ -94,8 +78,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         })
                     }
                     style={{
-                        background: this.revealOp === 'hover' ? 'gray' : this.frontSide ? 'white' : 'black',
-                        color: this.revealOp === 'hover' ? 'black' : this.frontSide ? 'black' : 'white',
+                        background: this.revealOp === 'hover' ? 'gray' : this._frontSide ? 'white' : 'black',
+                        color: this.revealOp === 'hover' ? 'black' : this._frontSide ? 'black' : 'white',
                         display: 'inline-block',
                     }}>
                     <div key="alternate" className="formattedTextBox-flip">
@@ -110,8 +94,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         return (
             <div>
                 <Tooltip
-                    title={this.frontSide ? <div className="dash-tooltip">Flip to front side to use GPT</div> : <div className="dash-tooltip">Ask GPT to create an answer on the back side of the flashcard based on your question on the front</div>}>
-                    <div style={{ position: 'absolute', bottom: '3px', right: '50px', cursor: 'pointer' }} onPointerDown={() => (!this.frontSide ? this.findImageTags() : null)}>
+                    title={this._frontSide ? <div className="dash-tooltip">Flip to front side to use GPT</div> : <div className="dash-tooltip">Ask GPT to create an answer on the back side of the flashcard based on your question on the front</div>}>
+                    <div style={{ position: 'absolute', bottom: '3px', right: '50px', cursor: 'pointer' }} onPointerDown={() => (!this._frontSide ? this.findImageTags() : null)}>
                         <FontAwesomeIcon icon="lightbulb" size="xl" />
                     </div>
                 </Tooltip>
@@ -140,40 +124,37 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     @action handleHover = () => {
         if (this.revealOp === 'hover') {
-            this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'flip';
+            this.revealOp = 'flip';
             this.Document.forceActive = false;
         } else {
-            this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'hover';
+            this.revealOp = 'hover';
             this.Document.forceActive = true;
         }
     };
 
     @action handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
         this._inputValue = e.target.value;
-        console.log(this._inputValue);
     };
 
     @action activateContent = () => {
-        this.childActive = true;
+        this._childActive = true;
     };
 
     @action handleRenderClick = () => {
-        this.frontSide = !this.frontSide;
+        this._frontSide = !this._frontSide;
     };
 
     @action handleRenderGPTClick = async () => {
         const phonTrans = DocCast(this.Document.audio) ? DocCast(this.Document.audio).phoneticTranscription : undefined;
         if (phonTrans) {
             this._inputValue = StrCast(phonTrans);
-            console.log('INPUT:' + this._inputValue);
             this.askGPTPhonemes(this._inputValue);
         } else if (this._inputValue) this.askGPT(GPTCallType.QUIZ);
-        this.frontSide = false;
+        this._frontSide = false;
         this._outputValue = '';
     };
 
-    @action
-    private onPointerMove = ({ movementX }: PointerEvent) => {
+    onPointerMove = ({ movementX }: PointerEvent) => {
         const width = movementX * this.ScreenToLocalBoxXf().Scale + (this.clipWidth / 100) * this._props.PanelWidth();
         if (width && width > 5 && width < this._props.PanelWidth()) {
             this.layoutDoc[this.clipWidthKey] = (width * 100) / this._props.PanelWidth();
@@ -183,12 +164,16 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     componentDidMount() {
         this._props.setContentViewBox?.(this);
-        reaction(
+        this._reactDisposer = reaction(
             () => this._props.isSelected(), // when this reaction should update
-            selected => !selected && (this.childActive = false) // what it should update to
+            selected => !selected && (this._childActive = false) // what it should update to
         );
     }
 
+    componentWillUnmount() {
+        this._reactDisposer?.();
+    }
+
     protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => {
         this._disposers[disposerId]?.();
         if (ele) {
@@ -241,7 +226,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
             this.dataDoc[which] = undefined;
             return true;
         }
-        console.log('FALSE');
         return false;
     };
 
@@ -271,7 +255,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     remDoc1 = (docs: Doc | Doc[]) => toList(docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true);
     remDoc2 = (docs: Doc | Doc[]) => toList(docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true);
 
-    private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
+    registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
         if (e.button !== 2) {
             setupMoveUpEvents(
                 this,
@@ -280,7 +264,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 emptyFunction,
                 action((moveEv, doubleTap) => {
                     if (doubleTap) {
-                        this.childActive = true;
+                        this._childActive = true;
                         if (!this.dataDoc[this.fieldKey + '_1'] && !this.dataDoc[this.fieldKey]) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
                         if (!this.dataDoc[this.fieldKey + '_2'] && !this.dataDoc[this.fieldKey + '_alternate']) this.dataDoc[this.fieldKey + '_2'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
                     }
@@ -288,7 +272,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 false,
                 undefined,
                 action(() => {
-                    if (this.childActive) return;
+                    if (this._childActive) return;
                     this._animating = 'all 200ms';
                     // on click, animate slider movement to the targetWidth
                     this.layoutDoc[this.clipWidthKey] = (targetWidth * 100) / this._props.PanelWidth();
@@ -308,8 +292,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
      * Set up speech to text tool.
      */
     setListening = () => {
-        const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
-        if (SpeechRecognition) {
+        if (this.SpeechRecognition) {
             this.recognition.continuous = true;
             this.recognition.interimResults = true;
             this.recognition.lang = 'en-US';
@@ -340,8 +323,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
             case 'fr-FR': return 'French'; //prettier-ignore
             case 'it-IT': return 'Italian'; //prettier-ignore
             case 'zh-CH': return 'Mandarin Chinese'; //prettier-ignore
-            case 'ja': return 'Japanese'; //prettier-ignore
-            default: return 'Korean'; //prettier-ignore
+            case 'ja':    return 'Japanese'; //prettier-ignore
+            default:      return 'Korean'; //prettier-ignore
         }
     };
 
@@ -363,44 +346,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         this._props.DocumentView?.()._props.addDocument?.(newAudio);
     };
 
-    /**
-     * Gets the transcription of an audio recording by sending the
-     * recording to backend.
-     */
-    pushInfo = async () => {
-        const audio = {
-            file: this._audio.url,
-        };
-        const response = await axios.post('http://localhost:105/recognize/', audio, {
-            headers: {
-                'Content-Type': 'application/json',
-            },
-        });
-        this.Document.phoneticTranscription = response.data['transcription'];
-    };
-
-    getYouTubeVideoId = (url: string) => {
-        const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=|\?v=)([^#&?]*).*/;
-        const match = url.match(regExp);
-        return match && match[2].length === 11 ? match[2] : null;
-    };
-
-    /**
-     * Gets the transcript of a youtube video by sending the video url to the backend.
-     * @returns transcription of youtube recording
-     */
-    youtubeUpload = async () => {
-        const audio = {
-            file: this.getYouTubeVideoId(StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text)),
-        };
-        const response = await axios.post('http://localhost:105/youtube/', audio, {
-            headers: {
-                'Content-Type': 'application/json',
-            },
-        });
-        return response.data['transcription'];
-    };
-
     createFlashcardPile(collectionArr: Doc[], gpt: boolean) {
         const newCol = Docs.Create.CarouselDocument(collectionArr, {
             _width: NumCast(this.layoutDoc['_' + this._props.fieldKey + '_width'], 250) + 50,
@@ -497,7 +442,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 DocCast(this.dataDoc[this.props.fieldKey + '_0'])[DocData].text = res;
             } else if (callType == GPTCallType.QUIZ) {
                 console.log(this._inputValue);
-                this.frontSide = true;
+                this._frontSide = true;
                 this._outputValue = res.replace(/UserAnswer/g, "user's answer").replace(/Rubric/g, 'rubric');
             } else if (callType === GPTCallType.FLASHCARD) {
                 this._loading = false;
@@ -652,11 +597,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     @action
     flipFlashcard = () => {
-        this.frontSide = !this.frontSide;
+        this._frontSide = !this._frontSide;
     };
 
     hoverFlip = (side: boolean) => {
-        if (this.revealOp === 'hover') this.frontSide = side;
+        if (this.revealOp === 'hover') this._frontSide = side;
     };
 
     testForTextFields = (whichSlot: string) => {
@@ -685,7 +630,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         return layoutTemplateString;
     };
 
-    childActiveFunc = () => this.childActive;
+    childActiveFunc = () => this._childActive;
 
     render() {
         const clearButton = (which: string) => (
@@ -709,7 +654,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                     <DocumentView
                         {...this._props}
                         showTags={undefined}
-                        fitWidth={undefined}
+                        fitWidth={undefined} // set to returnTrue to make images fill the comparisonBox-- should be a user option
                         ignoreUsePath={layoutString ? true : undefined}
                         renderDepth={this.props.renderDepth + 1}
                         LayoutTemplateString={layoutString}
@@ -717,15 +662,15 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         containerViewPath={this._props.docViewPath}
                         moveDocument={whichSlot.endsWith('1') ? this.moveDoc1 : this.moveDoc2}
                         removeDocument={whichSlot.endsWith('1') ? this.remDoc1 : this.remDoc2}
-                        NativeWidth={this.layoutWidth}
-                        NativeHeight={this.layoutHeight}
+                        NativeWidth={returnZero}
+                        NativeHeight={returnZero}
                         isContentActive={this.childActiveFunc}
                         isDocumentActive={returnFalse}
                         dontSelect={returnTrue}
                         whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
-                        styleProvider={this.childActive ? this._props.styleProvider : this.docStyleProvider}
+                        styleProvider={this._childActive ? this._props.styleProvider : this.docStyleProvider}
                         hideLinkButton
-                        pointerEvents={this.childActive ? undefined : returnNone}
+                        pointerEvents={this._childActive ? undefined : returnNone}
                     />
                     {!this.Document._layout_isFlashcard ? clearButton(whichSlot) : null}
                 </>
@@ -742,7 +687,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 style={{ width: this._props.PanelWidth() }}
                 onPointerDown={e => {
                     this.registerSliding(e, cover);
-                    this.activateContent();
+                    this.Document._layout_isFlashcard && this.activateContent();
                 }}
                 ref={ele => this.createDropTarget(ele, which, index)}>
                 {!this._isEmpty ? displayDoc(which) : null}
@@ -750,7 +695,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         );
 
         if (this.Document._layout_isFlashcard) {
-            const side = this.frontSide ? 1 : 0;
+            const side = this._frontSide ? 1 : 0;
 
             // add text box to each side when comparison box is first created
             if (!this.dataDoc[this.fieldKey + '_0'] && !this._isEmpty) {
@@ -773,14 +718,14 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         <p style={{ display: text === '' ? 'flex' : 'none', color: 'white', marginLeft: '10px' }}>Return to all flashcards and add text to both sides. </p>
                         <div className="input-box">
                             <textarea
-                                value={this.frontSide ? this._outputValue : this._inputValue}
+                                value={this._frontSide ? this._outputValue : this._inputValue}
                                 onChange={this.handleInputChange}
                                 onScroll={e => {
                                     e.stopPropagation();
                                     e.preventDefault();
                                 }}
                                 placeholder={!this.layoutDoc[`_${this._props.fieldKey}_usePath`] ? 'Enter a response for GPT to evaluate.' : ''}
-                                readOnly={this.frontSide}></textarea>
+                                readOnly={this._frontSide}></textarea>
 
                             {this._loading ? (
                                 <div className="loading-spinner" style={{ position: 'absolute' }}>
@@ -812,7 +757,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                                     Evaluate Pronunciation
                                 </button>
 
-                                {!this.frontSide ? (
+                                {!this._frontSide ? (
                                     <button className="submit-buttonsubmit" type="button" onClick={this.handleRenderGPTClick} style={{ borderRadius: '2px', marginBottom: '3px', width: '100%' }}>
                                         Submit
                                     </button>
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index ae9e70e8d..509a0c8d7 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -25,7 +25,7 @@ import { Networking } from '../../Network';
 import { DragManager } from '../../util/DragManager';
 import { dropActionType } from '../../util/DropActionTypes';
 import { SnappingManager } from '../../util/SnappingManager';
-import { undoBatch } from '../../util/UndoManager';
+import { undoable, undoBatch } from '../../util/UndoManager';
 import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
@@ -195,8 +195,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         const images = await this.fetchImages();
     };
 
-    @undoBatch
-    drop = (e: Event, de: DragManager.DropEvent) => {
+    drop = undoable((e: Event, de: DragManager.DropEvent) => {
         if (de.complete.docDragData) {
             let added: boolean | undefined;
             const targetIsBullseye = (ele: HTMLElement): boolean => {
@@ -225,7 +224,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             return added;
         }
         return false;
-    };
+    }, 'image drop');
 
     @undoBatch
     resolution = () => {
-- 
cgit v1.2.3-70-g09d2

