From 72dad52c4fea5a2fccabacbb6a49ca1494093954 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 22 Jun 2023 10:14:26 -0400
Subject: cleaned up dragging - abort presItem drags properly, fix naming for
 drag/dropAction, small fix undo of drag removeproperties, dragging in/out of
 headerBar,  fixed isContentActive to avoid SnappingManager.GetIsDragging. 
 fixed resizing videos.

---
 src/client/views/nodes/ComparisonBox.tsx | 80 +++++++++++++++++++++-----------
 1 file changed, 53 insertions(+), 27 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 e6a4635c0..d747c4527 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -2,11 +2,10 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc, Opt } from '../../../fields/Doc';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { DocCast, NumCast, StrCast } from '../../../fields/Types';
 import { emptyFunction, returnFalse, returnNone, returnZero, setupMoveUpEvents } from '../../../Utils';
-import { Docs } from '../../documents/Documents';
+import { Docs, DocUtils } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
-import { SnappingManager } from '../../util/SnappingManager';
 import { undoBatch } from '../../util/UndoManager';
 import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
 import { StyleProp } from '../StyleProvider';
@@ -32,15 +31,12 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
     get clipWidthKey() {
         return '_' + this.props.fieldKey + '_clipWidth';
     }
-
     componentDidMount() {
         this.props.setContentView?.(this);
     }
-
     protected createDropTarget = (ele: HTMLDivElement | null, fieldKey: string, disposerId: number) => {
         this._disposers[disposerId]?.();
         if (ele) {
-            // create disposers identified by disposerId to remove drag & drop listeners
             this._disposers[disposerId] = DragManager.MakeDropTarget(ele, (e, dropEvent) => this.internalDrop(e, dropEvent, fieldKey), this.layoutDoc);
         }
     };
@@ -50,29 +46,40 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
         if (dropEvent.complete.docDragData) {
             event.stopPropagation(); // prevent parent Doc from registering new position so that it snaps back into place
             const droppedDocs = dropEvent.complete.docDragData?.droppedDocuments;
-            droppedDocs.lastElement().embedContainer = this.dataDoc;
-            this.dataDoc[fieldKey] = droppedDocs.lastElement();
+            const res = dropEvent.complete.docDragData.moveDocument?.(droppedDocs, this.rootDoc, (doc: Doc | Doc[]) => this.addDoc(doc instanceof Doc ? doc : doc.lastElement(), fieldKey));
+            res && (droppedDocs.lastElement().embedContainer = this.dataDoc);
+            return res;
         }
     };
 
     private registerSliding = (e: React.PointerEvent<HTMLDivElement>, targetWidth: number) => {
-        e.button !== 2 &&
+        if (e.button !== 2) {
             setupMoveUpEvents(
                 this,
                 e,
                 this.onPointerMove,
                 emptyFunction,
+                action((e, doubleTap) => {
+                    if (doubleTap) {
+                        this._isAnyChildContentActive = true;
+                        if (!this.dataDoc[this.fieldKey + '_1']) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
+                        if (!this.dataDoc[this.fieldKey + '_2']) this.dataDoc[this.fieldKey + '_2'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc);
+                    }
+                }),
+                false,
+                undefined,
                 action(() => {
-                    // on click, animate slider movement to the targetWidth
+                    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();
                     setTimeout(
                         action(() => (this._animating = '')),
                         200
                     );
-                }),
-                false
+                })
             );
+        }
     };
 
     @action
@@ -86,7 +93,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
 
     getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
         const anchor = Docs.Create.ConfigDocument({
-            title: 'ImgAnchor:' + this.rootDoc.title,
+            title: 'CompareAnchor:' + this.rootDoc.title,
             // set presentation timing properties for restoring view
             presTransition: 1000,
             annotationOn: this.rootDoc,
@@ -105,12 +112,29 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
         e.stopPropagation; // prevent click event action (slider movement) in registerSliding
         delete this.dataDoc[fieldKey];
     };
+    moveDoc = (doc: Doc, addDocument: (document: Doc | Doc[]) => boolean, which: string) => this.remDoc(doc, which) && addDocument(doc);
+    addDoc = (doc: Doc, which: string) => {
+        this.dataDoc[which] = doc;
+        return true;
+    };
+    remDoc = (doc: Doc, which: string) => {
+        if (this.dataDoc[which] === doc) {
+            this.dataDoc[which] = undefined;
+            return true;
+        }
+        return false;
+    };
+
+    whenChildContentsActiveChanged = action((isActive: boolean) => (this._isAnyChildContentActive = isActive));
 
     docStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
         if (property === StyleProp.PointerEvents) return 'none';
         return this.props.styleProvider?.(doc, props, property);
     };
-
+    moveDoc1 = (doc: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true);
+    moveDoc2 = (doc: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true);
+    remDoc1 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true);
+    remDoc2 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true);
     render() {
         const clearButton = (which: string) => {
             return (
@@ -118,33 +142,35 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
                     className={`clear-button ${which}`}
                     onPointerDown={e => e.stopPropagation()} // prevent triggering slider movement in registerSliding
                     onClick={e => this.clearDoc(e, which)}>
-                    <FontAwesomeIcon className={`clear-button ${which}`} icon={'times'} size="sm" />
+                    <FontAwesomeIcon className={`clear-button ${which}`} icon="times" size="sm" />
                 </div>
             );
         };
         const displayDoc = (which: string) => {
-            const whichDoc = Cast(this.dataDoc[which], Doc, null);
-            // if (whichDoc?.type === DocumentType.MARKER) whichDoc = Cast(whichDoc.annotationOn, Doc, null);
-            const targetDoc = Cast(whichDoc?.annotationOn, Doc, null) ?? whichDoc;
-            return whichDoc ? (
+            const whichDoc = DocCast(this.dataDoc[which]);
+            const targetDoc = DocCast(whichDoc?.annotationOn, whichDoc);
+            return targetDoc ? (
                 <>
                     <DocumentView
                         {...this.props}
+                        Document={targetDoc}
+                        DataDoc={undefined}
+                        moveDocument={which.endsWith('1') ? this.moveDoc1 : this.moveDoc2}
+                        removeDocument={which.endsWith('1') ? this.remDoc1 : this.remDoc2}
                         NativeWidth={returnZero}
                         NativeHeight={returnZero}
-                        isContentActive={returnFalse}
+                        isContentActive={emptyFunction}
                         isDocumentActive={returnFalse}
-                        styleProvider={this.docStyleProvider}
-                        Document={targetDoc}
-                        DataDoc={undefined}
+                        whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
+                        styleProvider={this._isAnyChildContentActive ? this.props.styleProvider : this.docStyleProvider}
                         hideLinkButton={true}
-                        pointerEvents={returnNone}
+                        pointerEvents={this._isAnyChildContentActive ? undefined : returnNone}
                     />
                     {clearButton(which)}
                 </> // placeholder image if doc is missing
             ) : (
                 <div className="placeholder">
-                    <FontAwesomeIcon className="upload-icon" icon={'cloud-upload-alt'} size="lg" />
+                    <FontAwesomeIcon className="upload-icon" icon="cloud-upload-alt" size="lg" />
                 </div>
             );
         };
@@ -157,7 +183,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
         };
 
         return (
-            <div className={`comparisonBox${this.props.isContentActive() || SnappingManager.GetIsDragging() ? '-interactive' : ''}` /* change className to easily disable/enable pointer events in CSS */}>
+            <div className={`comparisonBox${this.props.isContentActive() ? '-interactive' : ''}` /* change className to easily disable/enable pointer events in CSS */}>
                 {displayBox(`${this.fieldKey}_2`, 1, this.props.PanelWidth() - 3)}
                 <div className="clip-div" style={{ width: this.clipWidth + '%', transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, 'gray') }}>
                     {displayBox(`${this.fieldKey}_1`, 0, 0)}
@@ -169,7 +195,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
                         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.registerSliding(e, this.props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */
+                    onPointerDown={e => !this._isAnyChildContentActive && 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

