From 2e9ec2e32cdbe78df8cde0803335739964e88f9d Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 3 Jun 2024 23:31:29 -0400
Subject: comparisonbox cleanup.

---
 src/client/views/nodes/ComparisonBox.tsx | 119 +++++++++++++------------------
 1 file changed, 51 insertions(+), 68 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 adb380f12..fc4d7ab35 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -30,41 +30,23 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         return FieldView.LayoutString(ComparisonBox, fieldKey);
     }
     private _disposers: (DragManager.DragDropDisposer | undefined)[] = [undefined, undefined];
+    private _closeRef = React.createRef<HTMLDivElement>();
+    @observable _inputValue = '';
+    @observable _outputValue = '';
+    @observable _loading = false;
+    @observable _errorMessage = '';
+    @observable _outputMessage = '';
+    @observable _animating = '';
+
     constructor(props: FieldViewProps) {
         super(props);
         makeObservable(this);
     }
 
-    @observable inputValue = '';
-    @observable outputValue = '';
-    @observable loading = false;
-    @observable errorMessage = '';
-    @observable outputMessage = '';
-
-    @action handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
-        this.inputValue = e.target.value;
-        console.log(this.inputValue);
-    };
-
-    @observable _animating = '';
-
-    @computed get clipWidth() {
-        return NumCast(this.layoutDoc[this.clipWidthKey], 50);
-    }
-    get clipWidthKey() {
-        return '_' + this._props.fieldKey + '_clipWidth';
-    }
-
-    @computed get clipHeight() {
-        return NumCast(this.layoutDoc[this.clipHeightKey], 200);
-    }
-    get clipHeightKey() {
-        return '_' + this._props.fieldKey + '_clipHeight';
-    }
-
     componentDidMount() {
         this._props.setContentViewBox?.(this);
     }
+
     protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => {
         this._disposers[disposerId]?.();
         if (ele) {
@@ -72,7 +54,13 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         }
     };
 
-    private internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => {
+    @computed get revealOp()       { return this.layoutDoc[`_${this.fieldKey}_revealOp`] as ('flip'|'hover'|undefined); } // prettier-ignore
+    @computed get clipWidth()      { return NumCast(this.layoutDoc[`_${this.fieldKey}_clipWidth`], 50); } // prettier-ignore
+    set clipWidth(width: number)   { this.layoutDoc[`_${this.fieldKey}_clipWidth`] = width; } // prettier-ignore
+    @computed get useAlternate()   { return this.layoutDoc[`_${this.fieldKey}_usePath`] === 'alternate'; } // prettier-ignore
+    set useAlternate(alt: boolean) { this.layoutDoc[`_${this.fieldKey}_usePath`] = alt ? 'alternate' : undefined; } // prettier-ignore
+
+    internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => {
         if (dropEvent.complete.docDragData) {
             const { droppedDocuments } = dropEvent.complete.docDragData;
             const added = dropEvent.complete.docDragData.moveDocument?.(droppedDocuments, this.Document, (doc: Doc | Doc[]) => this.addDoc(toList(doc).lastElement(), fieldKey));
@@ -84,7 +72,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         return undefined;
     }, 'internal drop');
 
-    private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
+    registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
         if (e.button !== 2) {
             setupMoveUpEvents(
                 this,
@@ -96,16 +84,18 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         this._isAnyChildContentActive = 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);
+                        // DocumentView.addViewRenderedCb(DocCast(this.dataDoc[this.fieldKey + '_1']), dv => {
+                        //     dv?.select(false);
+                        // });
                     }
                 }),
-                false,
+                true,
                 undefined,
                 action(() => {
                     if (this._isAnyChildContentActive) return;
                     this._animating = 'all 200ms';
                     // on click, animate slider movement to the targetWidth
-                    this.layoutDoc[this.clipWidthKey] = (targetWidth * 100) / this._props.PanelWidth();
-                    // this.layoutDoc[this.clipHeightKey] = (targetWidth * 100) / this._props.PanelHeight();
+                    this.clipWidth = (targetWidth * 100) / this._props.PanelWidth();
 
                     setTimeout(
                         action(() => {
@@ -118,11 +108,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         }
     };
 
-    @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();
+            this.clipWidth = (width * 100) / this._props.PanelWidth();
         }
         return false;
     };
@@ -180,8 +169,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         );
     };
     docStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
-        if (property === StyleProp.PointerEvents) return 'none';
-        return this._props.styleProvider?.(doc, props, property);
+        switch (property) {
+            case StyleProp.PointerEvents: return 'none';
+            default:                      return this._props.styleProvider?.(doc, props, property);
+        } // prettier-ignore
     };
     moveDoc1 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true);
     moveDoc2 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true);
@@ -220,36 +211,31 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         return layoutTemplateString;
     };
 
-    _closeRef = React.createRef<HTMLDivElement>();
-
     /**
      * Flips a flashcard to the alternate side for the user to view.
      */
     flipFlashcard = () => {
-        const usePath = this.layoutDoc[`_${this._props.fieldKey}_usePath`];
-        this.layoutDoc[`_${this._props.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : undefined;
+        this.useAlternate = !this.useAlternate;
     };
 
     /**
      * Changes the view option to hover for a flashcard.
      */
-    hoverFlip = (side: string | undefined) => {
-        if (this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'hover') this.layoutDoc[`_${this._props.fieldKey}_usePath`] = side;
+    hoverFlip = (alternate: boolean) => {
+        if (this.revealOp === 'hover') this.useAlternate = alternate;
     };
 
     /**
      * Creates the button used to flip the flashcards.
      */
     @computed get overlayAlternateIcon() {
-        const usepath = this.layoutDoc[`_${this._props.fieldKey}_usePath`];
         return (
             <Tooltip title={<div className="dash-tooltip">flip</div>}>
                 <div
                     className="formattedTextBox-alternateButton"
                     onPointerDown={e =>
                         setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, () => {
-                            console.log(this.layoutDoc[`_${this._props.fieldKey}_revealOp`]);
-                            if (!this.layoutDoc[`_${this._props.fieldKey}_revealOp`] || this.layoutDoc[`_${this._props.fieldKey}_revealOp`] === 'flip') {
+                            if (!this.revealOp || this.revealOp === 'flip') {
                                 this.flipFlashcard();
                                 console.log('Print Front of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text ?? ''));
                                 console.log('Print Back of cards: ' + (RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text ?? ''));
@@ -257,8 +243,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         })
                     }
                     style={{
-                        background: usepath === 'alternate' ? 'white' : 'black',
-                        color: usepath === 'alternate' ? 'black' : 'white',
+                        background: this.useAlternate ? 'white' : 'black',
+                        color: this.useAlternate ? 'black' : 'white',
                     }}>
                     <FontAwesomeIcon icon="turn-up" size="sm" />
                 </div>
@@ -268,14 +254,14 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     @action handleRenderGPTClick = () => {
         // Call the GPT model and get the output
-        this.layoutDoc[`_${this._props.fieldKey}_usePath`] = 'alternate';
-        this.outputValue = '';
-        if (this.inputValue) this.askGPT();
+        this.useAlternate = true;
+        this._outputValue = '';
+        if (this._inputValue) this.askGPT();
     };
 
     @action handleRenderClick = () => {
         // Call the GPT model and get the output
-        this.layoutDoc[`_${this._props.fieldKey}_usePath`] = undefined;
+        this.useAlternate = false;
     };
 
     /**
@@ -285,7 +271,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     askGPT = async (): Promise<string | undefined> => {
         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;
+        const queryText = questionText + ' UserAnswer: ' + this._inputValue + '. ' + rubricText;
 
         try {
             const res = await gptAPICall(queryText, GPTCallType.QUIZ);
@@ -293,8 +279,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 console.error('GPT call failed');
                 return;
             }
-            this.outputValue = res;
-            console.log(res);
+            this._outputValue = res;
         } catch (err) {
             console.error('GPT call failed');
         }
@@ -355,7 +340,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         );
 
         if (this.Document._layout_isFlashcard) {
-            const side = this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 1 : 0;
+            const side = this.useAlternate ? 1 : 0;
 
             // add text box to each side when comparison box is first created
             if (!(this.dataDoc[this.fieldKey + '_0'] || this.dataDoc[this.fieldKey + '_0'] === 'empty')) {
@@ -383,17 +368,19 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         {/* {StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_1']).text)?.Text)} */}
                         <div className="input-box">
                             <textarea
-                                value={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? this.outputValue : this.inputValue}
-                                onChange={this.handleInputChange}
-                                readOnly={this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate'}
+                                value={this.useAlternate ? this._outputValue : this._inputValue}
+                                onChange={action(e => {
+                                    this._inputValue = e.target.value;
+                                })}
+                                readOnly={this.useAlternate}
                             />
                         </div>
-                        <div className="submit-button" style={{ display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'none' : 'flex' }}>
+                        <div className="submit-button" style={{ display: this.useAlternate ? 'none' : 'flex' }}>
                             <button type="button" onClick={this.handleRenderGPTClick}>
                                 Submit
                             </button>
                         </div>
-                        <div className="submit-button" style={{ display: this.layoutDoc[`_${this._props.fieldKey}_usePath`] === 'alternate' ? 'flex' : 'none' }}>
+                        <div className="submit-button" style={{ display: this.useAlternate ? 'flex' : 'none' }}>
                             <button type="button" onClick={this.handleRenderClick}>
                                 Edit Your Response
                             </button>
@@ -407,12 +394,8 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 <div
                     className={`comparisonBox${this._props.isContentActive() ? '-interactive' : ''}`} /* change className to easily disable/enable pointer events in CSS */
                     style={{ display: 'flex', flexDirection: 'column' }}
-                    onMouseEnter={() => {
-                        this.hoverFlip('alternate');
-                    }}
-                    onMouseLeave={() => {
-                        this.hoverFlip(undefined);
-                    }}>
+                    onMouseEnter={() => this.hoverFlip(true)}
+                    onMouseLeave={() => this.hoverFlip(false)}>
                     {displayBox(`${this.fieldKey}_${side === 0 ? 1 : 0}`, side, this._props.PanelWidth() - 3)}
                     {this.overlayAlternateIcon}
                 </div>
@@ -432,7 +415,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         left: `calc(${this.clipWidth + '%'} - 0.5px)`,
                         cursor: this.clipWidth < 5 ? 'e-resize' : this.clipWidth / 100 > (this._props.PanelWidth() - 5) / this._props.PanelWidth() ? 'w-resize' : undefined,
                     }}
-                    onPointerDown={e => !this._isAnyChildContentActive && this.registerSliding(e, this._props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */
+                    onPointerDown={e => this.registerSliding(e, this._props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */
                 >
                     <div className="slide-handle" />
                 </div>
-- 
cgit v1.2.3-70-g09d2


From abcb61ccf695f1cd76ca6a633b1f5f962b638053 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 4 Jun 2024 09:03:34 -0400
Subject: comparisonbox cleanup

---
 src/client/views/nodes/ComparisonBox.tsx | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 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 fc4d7ab35..72dd8a6a8 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -60,6 +60,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     @computed get useAlternate()   { return this.layoutDoc[`_${this.fieldKey}_usePath`] === 'alternate'; } // prettier-ignore
     set useAlternate(alt: boolean) { this.layoutDoc[`_${this.fieldKey}_usePath`] = alt ? 'alternate' : undefined; } // prettier-ignore
 
+    animateClipWidth = action((clipWidth: number, duration = 200 /* ms */) => {
+        this._animating = `all ${duration}ms`; // turn on clip animation transition, then turn it off at end of animation
+        setTimeout(action(() => { this._animating = ''; }), duration); // prettier-ignore
+        this.clipWidth = clipWidth;
+    });
+
     internalDrop = undoable((e: Event, dropEvent: DragManager.DropEvent, fieldKey: string) => {
         if (dropEvent.complete.docDragData) {
             const { droppedDocuments } = dropEvent.complete.docDragData;
@@ -91,26 +97,14 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 }),
                 true,
                 undefined,
-                action(() => {
-                    if (this._isAnyChildContentActive) return;
-                    this._animating = 'all 200ms';
-                    // on click, animate slider movement to the targetWidth
-                    this.clipWidth = (targetWidth * 100) / this._props.PanelWidth();
-
-                    setTimeout(
-                        action(() => {
-                            this._animating = '';
-                        }),
-                        200
-                    );
-                })
+                () => !this._isAnyChildContentActive && this.animateClipWidth((targetWidth * 100) / this._props.PanelWidth())
             );
         }
     };
 
     onPointerMove = ({ movementX }: PointerEvent) => {
         const width = movementX * this.ScreenToLocalBoxXf().Scale + (this.clipWidth / 100) * this._props.PanelWidth();
-        if (width && width > 5 && width < this._props.PanelWidth()) {
+        if (width > 5 && width < this._props.PanelWidth()) {
             this.clipWidth = (width * 100) / this._props.PanelWidth();
         }
         return false;
-- 
cgit v1.2.3-70-g09d2


From 56de54fea88891b621d6298541bd0a26334b8db5 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 4 Jun 2024 09:15:35 -0400
Subject: fixed animation of comparisonBox clip sliding

---
 src/client/views/nodes/ComparisonBox.scss | 2 --
 src/client/views/nodes/ComparisonBox.tsx  | 3 ++-
 2 files changed, 2 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss
index 093b9c004..08d9e6010 100644
--- a/src/client/views/nodes/ComparisonBox.scss
+++ b/src/client/views/nodes/ComparisonBox.scss
@@ -49,7 +49,6 @@
         left: 0;
         height: 100%;
         overflow: hidden;
-        transition: 200ms;
 
         .beforeBox-cont {
             height: 100%;
@@ -63,7 +62,6 @@
         width: 3px;
         display: inline-block;
         background: white;
-        transition: 200ms;
 
         .slide-handle {
             position: absolute;
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 72dd8a6a8..efaf6807a 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -85,7 +85,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 e,
                 this.onPointerMove,
                 emptyFunction,
-                action((moveEv, doubleTap) => {
+                action((clickEv, doubleTap) => {
                     if (doubleTap) {
                         this._isAnyChildContentActive = true;
                         if (!this.dataDoc[this.fieldKey + '_1'] && !this.dataDoc[this.fieldKey]) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
@@ -407,6 +407,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                     className="slide-bar"
                     style={{
                         left: `calc(${this.clipWidth + '%'} - 0.5px)`,
+                        transition: this._animating,
                         cursor: this.clipWidth < 5 ? 'e-resize' : this.clipWidth / 100 > (this._props.PanelWidth() - 5) / this._props.PanelWidth() ? 'w-resize' : undefined,
                     }}
                     onPointerDown={e => this.registerSliding(e, this._props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */
-- 
cgit v1.2.3-70-g09d2

