From 939e18624af4252551f38c43335ee8ef0acd144c Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 21 Apr 2024 19:03:49 -0400
Subject: more lint cleanup

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 295 +++++++++++++--------
 1 file changed, 184 insertions(+), 111 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index a70713429..d9c988d54 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/jsx-props-no-spreading */
 /* eslint-disable jsx-a11y/click-events-have-key-events */
 /* eslint-disable jsx-a11y/no-static-element-interactions */
 import { Bezier } from 'bezier-js';
@@ -22,7 +23,6 @@ import { TraceMobx } from '../../../../fields/util';
 import { Gestures, PointData } from '../../../../pen-gestures/GestureTypes';
 import { GestureUtils } from '../../../../pen-gestures/GestureUtils';
 import { aggregateBounds, emptyFunction, intersectRect, Utils } from '../../../../Utils';
-import { CognitiveServices } from '../../../cognitive_services/CognitiveServices';
 import { Docs, DocUtils } from '../../../documents/Documents';
 import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
 import { DocumentManager } from '../../../util/DocumentManager';
@@ -48,6 +48,7 @@ import { DocumentView, OpenWhere } from '../../nodes/DocumentView';
 import { FieldViewProps, FocusViewOptions } from '../../nodes/FieldView';
 import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
 import { PresBox } from '../../nodes/trails/PresBox';
+// eslint-disable-next-line import/extensions
 import { CreateImage } from '../../nodes/WebBoxRenderer';
 import { StyleProp } from '../../StyleProvider';
 import { CollectionSubView } from '../CollectionSubView';
@@ -76,7 +77,7 @@ export interface collectionFreeformViewProps {
 @observer
 export class CollectionFreeFormView extends CollectionSubView<Partial<collectionFreeformViewProps>>() {
     public get displayName() {
-        return 'CollectionFreeFormView(' + this.Document.title?.toString() + ')';
+        return 'CollectionFreeFormView(' + (this.Document.title?.toString() ?? '') + ')';
     } // this makes mobx trace() statements more descriptive
 
     @observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, '');
@@ -94,8 +95,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         super(props);
         makeObservable(this);
     }
-    @observable
-    public static ShowPresPaths = false;
 
     private _panZoomTransitionTimer: any;
     private _lastX: number = 0;
@@ -238,7 +237,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         }
     };
     @observable _keyframeEditing = false;
-    @action setKeyFrameEditing = (set: boolean) => (this._keyframeEditing = set);
+    @action setKeyFrameEditing = (set: boolean) => {
+        this._keyframeEditing = set;
+    };
     getKeyFrameEditing = () => this._keyframeEditing;
     onBrowseClickHandler = () => this._props.onBrowseClickScript?.() || ScriptCast(this.layoutDoc.onBrowseClick);
     onChildClickHandler = () => this._props.childClickScript || ScriptCast(this.Document.onChildClick);
@@ -256,7 +257,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     // this search order, for example, allows icons of cropped images to find the panx/pany/zoom on the cropped image's data doc instead of the usual layout doc because the zoom/panX/panY define the cropped image
     panX = () => this.freeformData()?.bounds.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1));
     panY = () => this.freeformData()?.bounds.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panY, 1));
-    zoomScaling = () => this.freeformData()?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); //, NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1));
+    zoomScaling = () => this.freeformData()?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); // , NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1));
     PanZoomCenterXf = () => (this._props.isAnnotationOverlay && this.zoomScaling() === 1 ? `` : `translate(${this.centeringShiftX}px, ${this.centeringShiftY}px) scale(${this.zoomScaling()}) translate(${-this.panX()}px, ${-this.panY()}px)`);
     ScreenToContentsXf = () => this.screenToFreeformContentsXf.copy();
     getActiveDocuments = () => this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout);
@@ -272,7 +273,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     addDocument = (newBox: Doc | Doc[]) => {
         let retVal = false;
         if (newBox instanceof Doc) {
-            if ((retVal = this._props.addDocument?.(newBox) || false)) {
+            retVal = this._props.addDocument?.(newBox) || false;
+            if (retVal) {
                 this.bringToFront(newBox);
                 this.updateCluster(newBox);
             }
@@ -282,15 +284,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         }
         if (retVal) {
             const newBoxes = newBox instanceof Doc ? [newBox] : newBox;
-            for (const newBox of newBoxes) {
-                if (newBox.activeFrame !== undefined) {
-                    const vals = CollectionFreeFormDocumentView.animFields.map(field => newBox[field.key]);
-                    CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[`${field.key}_indexed`]);
-                    CollectionFreeFormDocumentView.animFields.forEach(field => delete newBox[field.key]);
-                    delete newBox.activeFrame;
-                    CollectionFreeFormDocumentView.animFields.forEach((field, i) => field.key !== 'opacity' && (newBox[field.key] = vals[i]));
+            newBoxes.forEach(box => {
+                if (box.activeFrame !== undefined) {
+                    const vals = CollectionFreeFormDocumentView.animFields.map(field => box[field.key]);
+                    CollectionFreeFormDocumentView.animFields.forEach(field => delete box[`${field.key}_indexed`]);
+                    CollectionFreeFormDocumentView.animFields.forEach(field => delete box[field.key]);
+                    delete box.activeFrame;
+                    CollectionFreeFormDocumentView.animFields.forEach((field, i) => {
+                        field.key !== 'opacity' && (box[field.key] = vals[i]);
+                    });
                 }
-            }
+            });
             if (this.Document._currentFrame !== undefined && !this._props.isAnnotationOverlay) {
                 CollectionFreeFormDocumentView.setupKeyframes(newBoxes, NumCast(this.Document._currentFrame), true);
             }
@@ -313,14 +317,19 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     };
 
     focus = (anchor: Doc, options: FocusViewOptions) => {
-        if (this._lightboxDoc) return;
+        if (this._lightboxDoc) return undefined;
         if (anchor === this.Document) {
             // if (options.willZoomCentered && options.zoomScale) {
             //     this.fitContentOnce();
             //     options.didMove = true;
             // }
         }
-        if (anchor.type !== DocumentType.CONFIG && !DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor) && !this.childLayoutPairs.map(pair => pair.layout).includes(anchor)) return;
+        // prettier-ignore
+        if (anchor.type !== DocumentType.CONFIG && 
+            !DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor) && //
+            !this.childLayoutPairs.map(pair => pair.layout).includes(anchor)) { 
+            return undefined;
+        }
         const xfToCollection = options?.docTransform ?? Transform.Identity();
         const savedState = { panX: NumCast(this.Document[this.panXFieldKey]), panY: NumCast(this.Document[this.panYFieldKey]), scale: options?.willZoomCentered ? this.Document[this.scaleFieldKey] : undefined };
         const cantTransform = this.fitContentsToBox || ((this.Document.isGroup || this.layoutDoc._lockedTransform) && !LightboxView.LightboxDoc);
@@ -336,12 +345,16 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             this.setPan(panX, panY, focusTime, true); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
             return focusTime;
         }
+        return undefined;
     };
 
     getView = async (doc: Doc, options: FocusViewOptions): Promise<Opt<DocumentView>> =>
         new Promise<Opt<DocumentView>>(res => {
             if (doc.hidden && this._lightboxDoc !== doc) options.didMove = !(doc.hidden = false);
-            if (doc === this.Document) return res(this.DocumentView?.());
+            if (doc === this.Document) {
+                res(this.DocumentView?.());
+                return;
+            }
             const findDoc = (finish: (dv: DocumentView) => void) => DocumentManager.Instance.AddViewRenderedCb(doc, dv => finish(dv));
             findDoc(dv => res(dv));
         });
@@ -357,7 +370,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             .map(pair => pair.layout)
             .slice()
             .sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
-        zsorted.forEach((doc, index) => (doc.zIndex = doc.stroke_isInkMask ? 5000 : index + 1));
+        zsorted.forEach((doc, index) => {
+            doc.zIndex = doc.stroke_isInkMask ? 5000 : index + 1;
+        });
         const dvals = CollectionFreeFormDocumentView.getValues(refDoc, NumCast(refDoc.activeFrame, 1000));
         const dropPos = this.Document._currentFrame !== undefined ? [NumCast(dvals.x), NumCast(dvals.y)] : [NumCast(refDoc.x), NumCast(refDoc.y)];
 
@@ -410,7 +425,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             let added = false;
             //  do nothing if link is dropped into any freeform view parent of dragged document
             const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, x, y, title: 'dropped annotation' });
-            added = this._props.addDocument?.(source) ? true : false;
+            added = !!this._props.addDocument?.(source);
             de.complete.linkDocument = DocUtils.MakeLink(linkDragData.linkSourceGetAnchor(), source, { link_relationship: 'annotated by:annotation of' }); // TODODO this is where in text links get passed
             if (de.complete.linkDocument) {
                 de.complete.linkDocument.layout_isSvg = true;
@@ -425,8 +440,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
         if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de, de.complete.annoDragData);
-        else if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData);
-        else if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData);
+        if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData);
+        if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData);
         return false;
     };
 
@@ -487,8 +502,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     }
 
     @action
-    updateClusters(_freeform_useClusters: boolean) {
-        this.Document._freeform_useClusters = _freeform_useClusters;
+    updateClusters(useClusters: boolean) {
+        this.Document._freeform_useClusters = useClusters;
         this._clusterSets.length = 0;
         this.childLayoutPairs.map(pair => pair.layout).map(c => this.updateCluster(c));
     }
@@ -498,12 +513,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
         if (this.Document._freeform_useClusters) {
             const docFirst = docs[0];
-            docs.map(doc => this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)));
+            docs.forEach(doc => this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)));
             const preferredInd = NumCast(docFirst.layout_cluster);
-            docs.map(doc => (doc.layout_cluster = -1));
+            docs.forEach(doc => {
+                doc.layout_cluster = -1;
+            });
             docs.map(doc =>
                 this._clusterSets.map((set, i) =>
-                    set.map(member => {
+                    set.forEach(member => {
                         if (docFirst.layout_cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && CollectionFreeFormView.overlapping(doc, member, this._clusterDistance)) {
                             docFirst.layout_cluster = i;
                         }
@@ -518,19 +535,21 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             ) {
                 docFirst.layout_cluster = preferredInd;
             }
-            this._clusterSets.map((set, i) => {
+            this._clusterSets.forEach((set, i) => {
                 if (docFirst.layout_cluster === -1 && !set.filter(member => Doc.IndexOf(member, childLayouts) !== -1).length) {
                     docFirst.layout_cluster = i;
                 }
             });
             if (docFirst.layout_cluster === -1) {
-                docs.map(doc => {
+                docs.forEach(doc => {
                     doc.layout_cluster = this._clusterSets.length;
                     this._clusterSets.push([doc]);
                 });
             } else if (this._clusterSets.length) {
                 for (let i = this._clusterSets.length; i <= NumCast(docFirst.layout_cluster); i++) !this._clusterSets[i] && this._clusterSets.push([]);
-                docs.map(doc => this._clusterSets[(doc.layout_cluster = NumCast(docFirst.layout_cluster))].push(doc));
+                docs.forEach(doc => {
+                    this._clusterSets[(doc.layout_cluster = NumCast(docFirst.layout_cluster))].push(doc);
+                });
             }
             childLayouts.map(child => !this._clusterSets.some((set, i) => Doc.IndexOf(child, set) !== -1 && child.layout_cluster === i) && this.updateCluster(child));
         }
@@ -573,17 +592,21 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         if (doc && this.childDocList?.includes(doc))
             switch (property.split(':')[0]) {
                 case StyleProp.BackgroundColor:
-                    const cluster = NumCast(doc?.layout_cluster);
-                    if (this.Document._freeform_useClusters && doc?.type !== DocumentType.IMG) {
-                        if (this._clusterSets.length <= cluster) {
-                            setTimeout(() => doc && this.updateCluster(doc));
-                        } else {
-                            // choose a cluster color from a palette
-                            const colors = ['#da42429e', '#31ea318c', 'rgba(197, 87, 20, 0.55)', '#4a7ae2c4', 'rgba(216, 9, 255, 0.5)', '#ff7601', '#1dffff', 'yellow', 'rgba(27, 130, 49, 0.55)', 'rgba(0, 0, 0, 0.268)'];
-                            styleProp = colors[cluster % colors.length];
-                            const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor);
-                            // override the cluster color with an explicitly set color on a non-background document.  then override that with an explicitly set color on a background document
-                            set?.map(s => (styleProp = StrCast(s.backgroundColor)));
+                    {
+                        const cluster = NumCast(doc?.layout_cluster);
+                        if (this.Document._freeform_useClusters && doc?.type !== DocumentType.IMG) {
+                            if (this._clusterSets.length <= cluster) {
+                                setTimeout(() => doc && this.updateCluster(doc));
+                            } else {
+                                // choose a cluster color from a palette
+                                const colors = ['#da42429e', '#31ea318c', 'rgba(197, 87, 20, 0.55)', '#4a7ae2c4', 'rgba(216, 9, 255, 0.5)', '#ff7601', '#1dffff', 'yellow', 'rgba(27, 130, 49, 0.55)', 'rgba(0, 0, 0, 0.268)'];
+                                styleProp = colors[cluster % colors.length];
+                                const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor);
+                                // override the cluster color with an explicitly set color on a non-background document.  then override that with an explicitly set color on a background document
+                                set?.forEach(s => {
+                                    styleProp = StrCast(s.backgroundColor);
+                                });
+                            }
                         }
                     }
                     break;
@@ -591,6 +614,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     if (doc && this.Document._currentFrame !== undefined) {
                         return CollectionFreeFormDocumentView.getStringValues(doc, NumCast(this.Document._currentFrame))?.fillColor;
                     }
+                    break;
+                default:
             }
         return styleProp;
     };
@@ -626,9 +651,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     case InkTool.None:
                         if (!(this._props.layoutEngine?.() || StrCast(this.layoutDoc._layoutEngine))) {
                             this._hitCluster = this.pickCluster(this.screenToFreeformContentsXf.transformPoint(e.clientX, e.clientY));
-                            setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, this._hitCluster !== -1 ? true : false, false);
+                            setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, this._hitCluster !== -1, false);
                         }
                         break;
+                    default:
                 }
             }
         }
@@ -639,13 +665,34 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @undoBatch
     onGesture = (e: Event, ge: GestureUtils.GestureEvent) => {
         switch (ge.gesture) {
-            default:
+            // case Gestures.Rectangle:
+            //     {
+            //         const strokes = this.getActiveDocuments()
+            //             .filter(doc => doc.type === DocumentType.INK)
+            //             .map(i => {
+            //                 const d = Cast(i.stroke, InkField);
+            //                 const x = NumCast(i.x) - Math.min(...(d?.inkData.map(pd => pd.X) ?? [0]));
+            //                 const y = NumCast(i.y) - Math.min(...(d?.inkData.map(pd => pd.Y) ?? [0]));
+            //                 return !d ? [] : d.inkData.map(pd => ({ X: x + pd.X, Y: y + pd.Y }));
+            //             });
+
+            //         CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then(results => {});
+            //     }
+            //     break;
+            case Gestures.Text:
+                if (ge.text) {
+                    const B = this.screenToFreeformContentsXf.transformPoint(ge.points[0].X, ge.points[0].Y);
+                    this.addDocument(Docs.Create.TextDocument(ge.text, { title: ge.text, x: B[0], y: B[1] }));
+                    e.stopPropagation();
+                }
+                break;
             case Gestures.Line:
             case Gestures.Circle:
             case Gestures.Rectangle:
             case Gestures.Triangle:
             case Gestures.Stroke:
-                const points = ge.points;
+            default: {
+                const { points } = ge;
                 const B = this.screenToFreeformContentsXf.transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
                 const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale;
                 const inkDoc = Docs.Create.InkDocument(
@@ -664,29 +711,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 }
                 this.addDocument(inkDoc);
                 e.stopPropagation();
-                break;
-            case Gestures.Rectangle:
-                const strokes = this.getActiveDocuments()
-                    .filter(doc => doc.type === DocumentType.INK)
-                    .map(i => {
-                        const d = Cast(i.stroke, InkField);
-                        const x = NumCast(i.x) - Math.min(...(d?.inkData.map(pd => pd.X) ?? [0]));
-                        const y = NumCast(i.y) - Math.min(...(d?.inkData.map(pd => pd.Y) ?? [0]));
-                        return !d ? [] : d.inkData.map(pd => ({ X: x + pd.X, Y: y + pd.Y }));
-                    });
-
-                CognitiveServices.Inking.Appliers.InterpretStrokes(strokes).then(results => {});
-                break;
-            case Gestures.Text:
-                if (ge.text) {
-                    const B = this.screenToFreeformContentsXf.transformPoint(ge.points[0].X, ge.points[0].Y);
-                    this.addDocument(Docs.Create.TextDocument(ge.text, { title: ge.text, x: B[0], y: B[1] }));
-                    e.stopPropagation();
-                }
+            }
         }
     };
     @action
-    onEraserUp = (e: PointerEvent): void => {
+    onEraserUp = (): void => {
         this._deleteList.forEach(ink => ink._props.removeDocument?.(ink.Document));
         this._deleteList = [];
         this._batch?.end();
@@ -792,7 +821,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         return this.childDocs
             .map(doc => DocumentManager.Instance.getDocumentView(doc, this.DocumentView?.()))
             .filter(inkView => inkView?.ComponentView instanceof InkingStroke)
-            .map(inkView => ({ inkViewBounds: inkView!.getBounds, inkStroke: inkView!.ComponentView as InkingStroke, inkView: inkView! }))
+            .map(inkView => inkView!)
+            .map(inkView => ({ inkViewBounds: inkView.getBounds, inkStroke: inkView.ComponentView as InkingStroke, inkView }))
             .filter(
                 ({ inkViewBounds }) =>
                     inkViewBounds && // bounding box of eraser segment and ink stroke overlap
@@ -807,7 +837,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     // Convert from screen space to ink space for the intersection.
                     const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint);
                     const currPointInkSpace = inkStroke.ptFromScreen(currPoint);
-                    for (var i = 0; i < inkData.length - 3; i += 4) {
+                    for (let i = 0; i < inkData.length - 3; i += 4) {
                         const rawIntersects = InkField.Segment(inkData, i).intersects({
                             // compute all unique intersections
                             p1: { x: prevPointInkSpace.X, y: prevPointInkSpace.Y },
@@ -833,16 +863,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @action
     segmentInkStroke = (ink: DocumentView, excludeT: number): Segment[] => {
         const segments: Segment[] = [];
-        var segment: Segment = [];
-        var startSegmentT = 0;
+        let segment: Segment = [];
+        let startSegmentT = 0;
         const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData();
         // This iterates through all segments of the curve and splits them where they intersect another curve.
         // if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted)
-        for (var i = 0; i < inkData.length - 3; i += 4) {
+        for (let i = 0; i < inkData.length - 3; i += 4) {
             const inkSegment = InkField.Segment(inkData, i);
             // Getting all t-value intersections of the current curve with all other curves.
             const tVals = this.getInkIntersections(i, ink, inkSegment).sort();
             if (tVals.length) {
+                // eslint-disable-next-line no-loop-func
                 tVals.forEach((t, index) => {
                     const docCurveTVal = t + Math.floor(i / 4);
                     if (excludeT < startSegmentT || excludeT > docCurveTVal) {
@@ -895,9 +926,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 const { inkData: otherInkData } = otherInk?.inkScaledData() ?? { inkData: [] };
                 const otherScreenPts = otherInkData.map(point => otherInk.ptToScreen(point));
                 const otherCtrlPts = otherScreenPts.map(spt => (ink.ComponentView as InkingStroke).ptFromScreen(spt));
-                for (var j = 0; j < otherCtrlPts.length - 3; j += 4) {
+                for (let j = 0; j < otherCtrlPts.length - 3; j += 4) {
                     const neighboringSegment = i === j || i === j - 4 || i === j + 4;
                     // Ensuring that the curve intersected by the eraser is not checked for further ink intersections.
+                    // eslint-disable-next-line no-continue
                     if (ink?.Document === otherInk.Document && neighboringSegment) continue;
 
                     const otherCurve = new Bezier(otherCtrlPts.slice(j, j + 4).map(p => ({ x: p.X, y: p.Y })));
@@ -908,7 +940,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     if (apt.d !== undefined && apt.d < 1 && apt.t !== undefined && !tVals.includes(apt.t)) {
                         tVals.push(apt.t);
                     }
-                    this.bintersects(curve, otherCurve).forEach((val: string | number, i: number) => {
+                    this.bintersects(curve, otherCurve).forEach((val: string | number /* , i: number */) => {
                         // Converting the Bezier.js Split type to a t-value number.
                         const t = +val.toString().split('/')[0];
                         if (i % 2 === 0 && !tVals.includes(t)) tVals.push(t); // bcz: Hack!  don't know why but intersection points are doubled from bezier.js (but not identical).
@@ -971,8 +1003,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     this.scrollPan({ deltaX: -deltaX * this.screenToFreeformContentsXf.Scale, deltaY: e.shiftKey ? 0 : -deltaY * this.screenToFreeformContentsXf.Scale });
                     break;
                 }
-            default:
+            // eslint-disable-next-line no-fallthrough
             case freeformScrollMode.Zoom:
+            default:
                 if ((e.ctrlKey || !scrollable) && this._props.isContentActive()) {
                     this.zoom(e.clientX, e.clientY, Math.max(-1, Math.min(1, e.deltaY))); // if (!this._props.isAnnotationOverlay) // bcz: do we want to zoom in on images/videos/etc?
                     // e.preventDefault();
@@ -982,7 +1015,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     };
 
     @action
-    setPan(panX: number, panY: number, panTime: number = 0, clamp: boolean = false) {
+    setPan(panXIn: number, panYIn: number, panTime: number = 0, clamp: boolean = false) {
+        let panX = panXIn;
+        let panY = panYIn;
         // this is the easiest way to do this -> will talk with Bob about using mobx to do this to remove this line of code.
         if (Doc.UserDoc()?.presentationMode === 'watching') ReplayMovements.Instance.pauseFromInteraction();
 
@@ -1034,11 +1069,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 scale * NumCast(this.dataDoc._panY_max, nativeHeight) +
                 (!this._props.getScrollHeight?.() ? fitYscroll : 0); // when not zoomed, scrolling is handled via a scrollbar, not panning
             let newPanY = Math.max(minPanY, Math.min(maxPanY, panY));
-            if (false && NumCast(this.layoutDoc.layout_scrollTop) && NumCast(this.layoutDoc._freeform_scale, minScale) !== minScale) {
-            } else if (fitYscroll > 2 && this.layoutDoc.layout_scrollTop === undefined && NumCast(this.layoutDoc._freeform_scale, minScale) === minScale) {
-                const maxPanY = minPanY + fitYscroll;
-                const relTop = (panY - minPanY) / (maxPanY - minPanY);
-                setTimeout(() => (this.layoutDoc.layout_scrollTop = relTop * maxScrollTop), 10);
+            if (fitYscroll > 2 && this.layoutDoc.layout_scrollTop === undefined && NumCast(this.layoutDoc._freeform_scale, minScale) === minScale) {
+                const maxPanScrollY = minPanY + fitYscroll;
+                const relTop = (panY - minPanY) / (maxPanScrollY - minPanY);
+                setTimeout(() => {
+                    this.layoutDoc.layout_scrollTop = relTop * maxScrollTop;
+                }, 10);
                 newPanY = minPanY;
             }
             !this.Document._verticalScroll && (this.Document[this.panXFieldKey] = this.isAnnotationOverlay ? newPanX : panX);
@@ -1090,7 +1126,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         this._panZoomTransition = transitionTime;
         this._panZoomTransitionTimer && clearTimeout(this._panZoomTransitionTimer);
         this._panZoomTransitionTimer = setTimeout(
-            action(() => (this._panZoomTransition = 0)),
+            action(() => {
+                this._panZoomTransition = 0;
+            }),
             transitionTime
         );
     };
@@ -1173,6 +1211,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             e.stopPropagation?.();
             return this.createTextDocCopy(fieldProps, !e.altKey && e.key !== 'Tab');
         }
+        return undefined;
     };
     @computed get childPointerEvents() {
         const engine = this._props.layoutEngine?.() || StrCast(this.Document._layoutEngine);
@@ -1194,6 +1233,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const childData = entry.pair.data;
         return (
             <CollectionFreeFormDocumentView
+                // eslint-disable-next-line react/jsx-props-no-spreading
                 {...OmitKeys(entry, ['replica', 'pair']).omit}
                 key={childLayout[Id] + (entry.replica || '')}
                 Document={childLayout}
@@ -1205,7 +1245,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 isGroupActive={this._props.isGroupActive}
                 renderDepth={this._props.renderDepth + 1}
                 hideDecorations={BoolCast(childLayout._layout_isSvg && childLayout.type === DocumentType.LINK)}
-                suppressSetHeight={this.layoutEngine ? true : false}
+                suppressSetHeight={!!this.layoutEngine}
                 RenderCutoffProvider={this.renderCutoffProvider}
                 CollectionFreeFormView={this}
                 LayoutTemplate={childLayout.z ? undefined : this._props.childLayoutTemplate}
@@ -1239,37 +1279,42 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             />
         );
     }
-    addDocTab = action((doc: Doc, where: OpenWhere) => {
-        if (this._props.isAnnotationOverlay) return this._props.addDocTab(doc, where);
+    addDocTab = action((docsIn: Doc | Doc[], where: OpenWhere) => {
+        const docs = docsIn instanceof Doc ? [docsIn] : docsIn;
+        if (this._props.isAnnotationOverlay) return this._props.addDocTab(docs, where);
         switch (where) {
             case OpenWhere.inParent:
-                return this._props.addDocument?.(doc) || false;
-            case OpenWhere.inParentFromScreen:
-                const docContext = DocCast((doc instanceof Doc ? doc : doc?.[0])?.embedContainer);
+                return this._props.addDocument?.(docs) || false;
+            case OpenWhere.inParentFromScreen: {
+                const docContext = DocCast(docs[0]?.embedContainer);
                 return (
                     (this.addDocument?.(
-                        (doc instanceof Doc ? [doc] : doc).map(doc => {
-                            const pt = this.screenToFreeformContentsXf.transformPoint(NumCast(doc.x), NumCast(doc.y));
-                            doc.x = pt[0];
-                            doc.y = pt[1];
+                        (docs instanceof Doc ? [docs] : docs).map(doc => {
+                            [doc.x, doc.y] = this.screenToFreeformContentsXf.transformPoint(NumCast(doc.x), NumCast(doc.y));
                             return doc;
                         })
                     ) &&
                         (!docContext || this._props.removeDocument?.(docContext))) ||
                     false
                 );
+            }
             case undefined:
             case OpenWhere.lightbox:
-                if (this.layoutDoc._isLightbox) {
-                    this._lightboxDoc = doc;
-                    return true;
-                }
-                if (doc === this.Document || this.childDocList?.includes(doc) || this.childLayoutPairs.map(pair => pair.layout)?.includes(doc)) {
-                    if (doc.hidden) doc.hidden = false;
-                    return true;
+                {
+                    const firstDoc = docs[0];
+                    if (this.layoutDoc._isLightbox) {
+                        this._lightboxDoc = firstDoc;
+                        return true;
+                    }
+                    if (firstDoc === this.Document || this.childDocList?.includes(firstDoc) || this.childLayoutPairs.map(pair => pair.layout)?.includes(firstDoc)) {
+                        if (firstDoc.hidden) firstDoc.hidden = false;
+                        return true;
+                    }
                 }
+                break;
+            default:
         }
-        return this._props.addDocTab(doc, where);
+        return this._props.addDocTab(docs, where);
     });
     @observable _lightboxDoc: Opt<Doc> = undefined;
 
@@ -1314,9 +1359,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         e.stopPropagation();
     };
 
-    viewDefsToJSX = (views: ViewDefBounds[]) => {
-        return !Array.isArray(views) ? [] : views.filter(ele => this.viewDefToJSX(ele)).map(ele => this.viewDefToJSX(ele)!);
-    };
+    viewDefsToJSX = (views: ViewDefBounds[]) => (!Array.isArray(views) ? [] : views.filter(ele => this.viewDefToJSX(ele)).map(ele => this.viewDefToJSX(ele)!));
 
     viewDefToJSX(viewDef: ViewDefBounds): Opt<ViewDefResult> {
         const { x, y, z } = viewDef;
@@ -1337,7 +1380,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                       ),
                       bounds: viewDef,
                   };
-        } else if (viewDef.type === 'div') {
+        }
+        if (viewDef.type === 'div') {
             return [x, y].some(val => val === undefined)
                 ? undefined
                 : {
@@ -1353,9 +1397,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                       bounds: viewDef,
                   };
         }
+        return undefined;
     }
 
     renderCutoffProvider = computedFn(
+        // eslint-disable-next-line prefer-arrow-callback
         function renderCutoffProvider(this: any, doc: Doc) {
             return this.Document.isTemplateDoc ? false : !this._renderCutoffData.get(doc[Id] + '');
         }.bind(this)
@@ -1369,7 +1415,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     }
 
     doFreeformLayout(poolData: Map<string, PoolData>) {
-        this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => poolData.set(pair.layout[Id], this.getCalculatedPositions(pair)));
+        this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => poolData.set(pair.layout[Id], this.getCalculatedPositions(pair)));
         return [] as ViewDefResult[];
     }
 
@@ -1385,6 +1431,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             case computeTimelineLayout.name:  return { newPool, computedElementData: this.doEngineLayout(newPool, computeTimelineLayout) };
             case computePivotLayout.name:     return { newPool, computedElementData: this.doEngineLayout(newPool, computePivotLayout) };
             case computeStarburstLayout.name: return { newPool, computedElementData: this.doEngineLayout(newPool, computeStarburstLayout) };
+            default:
         }
         return { newPool, computedElementData: this.doFreeformLayout(newPool) };
     }
@@ -1469,7 +1516,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 
                 this._disposers.pointerevents = reaction(
                     () => this.childPointerEvents,
-                    pointerevents => (this._childPointerEvents = pointerevents as any),
+                    pointerevents => {
+                        this._childPointerEvents = pointerevents as any;
+                    },
                     { fireImmediately: true }
                 );
 
@@ -1643,7 +1692,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         }
     };
 
-    onContextMenu = (e: React.MouseEvent) => {
+    onContextMenu = () => {
         if (this._props.isAnnotationOverlay || !ContextMenu.Instance) return;
 
         const appearance = ContextMenu.Instance.findByDescription('Appearance...');
@@ -1654,7 +1703,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             !appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' });
             return;
         }
-        !Doc.noviceMode && Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: 'Reset default note style', event: () => (Doc.UserDoc().defaultTextLayout = undefined), icon: 'eye' });
+        !Doc.noviceMode &&
+            Doc.UserDoc().defaultTextLayout &&
+            appearanceItems.push({
+                description: 'Reset default note style',
+                event: () => {
+                    Doc.UserDoc().defaultTextLayout = undefined;
+                },
+                icon: 'eye',
+            });
         appearanceItems.push({ description: `Pin View`, event: () => this._props.pinToPres(this.Document, { pinViewport: MarqueeView.CurViewBounds(this.dataDoc, this._props.PanelWidth(), this._props.PanelHeight()) }), icon: 'map-pin' });
         !Doc.noviceMode && appearanceItems.push({ description: `update icon`, event: this.updateIcon, icon: 'compress-arrows-alt' });
         this._props.renderDepth && appearanceItems.push({ description: 'Ungroup collection', event: this.promoteCollection, icon: 'table' });
@@ -1669,8 +1726,21 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const optionItems = options && 'subitems' in options ? options.subitems : [];
         !this._props.isAnnotationOverlay &&
             !Doc.noviceMode &&
-            optionItems.push({ description: (this._showAnimTimeline ? 'Close' : 'Open') + ' Animation Timeline', event: action(() => (this._showAnimTimeline = !this._showAnimTimeline)), icon: 'eye' });
-        this._props.renderDepth && optionItems.push({ description: 'Use Background Color as Default', event: () => (Cast(Doc.UserDoc().emptyCollection, Doc, null).backgroundColor = StrCast(this.layoutDoc.backgroundColor)), icon: 'palette' });
+            optionItems.push({
+                description: (this._showAnimTimeline ? 'Close' : 'Open') + ' Animation Timeline',
+                event: action(() => {
+                    this._showAnimTimeline = !this._showAnimTimeline;
+                }),
+                icon: 'eye',
+            });
+        this._props.renderDepth &&
+            optionItems.push({
+                description: 'Use Background Color as Default',
+                event: () => {
+                    Cast(Doc.UserDoc().emptyCollection, Doc, null).backgroundColor = StrCast(this.layoutDoc.backgroundColor);
+                },
+                icon: 'palette',
+            });
         this._props.renderDepth && optionItems.push({ description: 'Fit Content Once', event: this.fitContentOnce, icon: 'object-group' });
         if (!Doc.noviceMode) {
             optionItems.push({ description: (!Doc.NativeWidth(this.layoutDoc) || !Doc.NativeHeight(this.layoutDoc) ? 'Freeze' : 'Unfreeze') + ' Aspect', event: this.toggleNativeDimensions, icon: 'snowflake' });
@@ -1750,7 +1820,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         );
     }
 
-    showPresPaths = () => CollectionFreeFormView.ShowPresPaths;
+    showPresPaths = () => SnappingManager.ShowPresPaths;
     brushedView = () => this._brushedView;
     gridColor = () =>
         DashColor(lightOrDark(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor)))
@@ -1908,7 +1978,10 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 ) : (
                     <>
                         {this._firstRender ? this.placeholder : this.marqueeView}
-                        {this._props.noOverlay ? null : <CollectionFreeFormOverlayView elements={this.elementFunc} />}
+                        {
+                            // eslint-disable-next-line no-use-before-define
+                            this._props.noOverlay ? null : <CollectionFreeFormOverlayView elements={this.elementFunc} />
+                        }
                         {!this.GroupChildDrag ? null : <div className="collectionFreeForm-groupDropper" />}
                     </>
                 )}
@@ -1920,7 +1993,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 @observer
 class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> {
     render() {
-        // eslint-disable-next-line react/destructuring-assignment
         return this.props.elements().filter(ele => ele.bounds?.z).map(ele => ele.ele); // prettier-ignore
     }
 }
@@ -1959,6 +2031,7 @@ ScriptingGlobals.add(function curKeyFrame(readOnly: boolean) {
     const selView = SelectionManager.Views;
     if (readOnly) return selView[0].ComponentView?.getKeyFrameEditing?.() ? Colors.MEDIUM_BLUE : 'transparent';
     runInAction(() => selView[0].ComponentView?.setKeyFrameEditing?.(!selView[0].ComponentView?.getKeyFrameEditing?.()));
+    return undefined;
 });
 // eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function pinWithView(pinContent: boolean) {
@@ -1989,7 +2062,7 @@ ScriptingGlobals.add(function datavizFromSchema() {
         if (!view.layoutDoc.schema_columnKeys) {
             view.layoutDoc.schema_columnKeys = new List<string>(['title', 'type', 'author', 'author_date']);
         }
-        const keys = Cast(view.layoutDoc.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text');
+        const keys = Cast(view.layoutDoc.schema_columnKeys, listSpec('string'))?.filter(key => key !== 'text');
         if (!keys) return;
 
         const children = DocListCast(view.Document[Doc.LayoutFieldKey(view.Document)]);
-- 
cgit v1.2.3-70-g09d2

