From 25ea424ab2e6c32272e828b98822eb32f1fe2cab Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 15 Aug 2024 11:14:04 -0400
Subject: cleaned up server list add/rem.

---
 src/client/views/nodes/trails/PresBox.tsx | 98 ++++++++++++-------------------
 1 file changed, 39 insertions(+), 59 deletions(-)

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

diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 0c73400a9..c403f9415 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import Slider from '@mui/material/Slider';
@@ -32,7 +30,7 @@ import { dropActionType } from '../../../util/DropActionTypes';
 import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
 import { SerializationHelper } from '../../../util/SerializationHelper';
 import { SnappingManager } from '../../../util/SnappingManager';
-import { undoBatch, UndoManager } from '../../../util/UndoManager';
+import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager';
 import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
 import { CollectionFreeFormPannableContents } from '../../collections/collectionFreeForm/CollectionFreeFormPannableContents';
 import { CollectionView } from '../../collections/CollectionView';
@@ -191,7 +189,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
     @computed
     get isTreeOrStack() {
-        return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._type_collection) as any);
+        return [CollectionViewType.Tree, CollectionViewType.Stacking].includes(StrCast(this.layoutDoc._type_collection) as CollectionViewType);
     }
     @computed get isTree() {
         return this.layoutDoc._type_collection === CollectionViewType.Tree;
@@ -304,7 +302,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played
     startTempMedia = (targetDoc: Doc, activeItem: Doc) => {
         const duration: number = NumCast(activeItem.config_clipEnd) - NumCast(activeItem.config_clipStart);
-        if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as any)) {
+        if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as DocumentType)) {
             const targMedia = DocumentView.getDocumentView(targetDoc);
             targMedia?.ComponentView?.playFrom?.(NumCast(activeItem.config_clipStart), NumCast(activeItem.config_clipStart) + duration);
         }
@@ -312,7 +310,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
     stopTempMedia = (targetDocField: FieldResult) => {
         const targetDoc = DocCast(DocCast(targetDocField).annotationOn) ?? DocCast(targetDocField);
-        if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as any)) {
+        if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as DocumentType)) {
             const targMedia = DocumentView.getDocumentView(targetDoc);
             targMedia?.ComponentView?.Pause?.();
         }
@@ -364,7 +362,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         this.setIsRecording(false);
         this.setIsLoading(true);
 
-        const currSlideProperties: { [key: string]: any } = {};
+        const currSlideProperties: { [key: string]: FieldResult } = {};
         gptSlideProperties.forEach(key => {
             if (this.activeItem[key]) {
                 currSlideProperties[key] = this.activeItem[key];
@@ -554,7 +552,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         }
     });
     static pinDataTypes(target?: Doc): dataTypes {
-        const targetType = target?.type as any;
+        const targetType = target?.type as DocumentType;
         const inkable = [DocumentType.INK].includes(targetType);
         const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetType) || target?._type_collection === CollectionViewType.Stacking;
         const pannable = [DocumentType.IMG, DocumentType.PDF].includes(targetType) || (targetType === DocumentType.COL && target?._type_collection === CollectionViewType.Freeform);
@@ -759,8 +757,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     const doc = DocCast(DocServer.GetCachedRefField(data.id));
                     if (doc) {
                         transitioned.add(doc);
-                        const field = !data.data ? undefined : await SerializationHelper.Deserialize(data.data);
-                        const tfield = !data.text ? undefined : await SerializationHelper.Deserialize(data.text);
+                        const field = !data.data ? undefined : ((await SerializationHelper.Deserialize(data.data)) as FieldType);
+                        const tfield = !data.text ? undefined : ((await SerializationHelper.Deserialize(data.text)) as FieldType);
                         doc._dataTransition = `all ${transTime}ms`;
                         doc.x = data.x;
                         doc.y = data.y;
@@ -858,7 +856,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             effect: activeItem,
             noSelect: true,
             openLocation: targetDoc.type === DocumentType.PRES ? ((OpenWhere.replace + ':' + PresBox.PanelName) as OpenWhere) : OpenWhere.addLeft,
-            easeFunc: StrCast(activeItem.presentation_easeFunc, 'ease') as any,
+            easeFunc: StrCast(activeItem.presentation_easeFunc, 'ease') as 'linear' | 'ease',
             zoomTextSelections: BoolCast(activeItem.presentation_zoomText),
             playAudio: BoolCast(activeItem.presentation_playAudio),
             playMedia: activeItem.presentation_mediaStart === 'auto',
@@ -1101,7 +1099,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
      */
     @undoBatch
     viewChanged = action((e: React.ChangeEvent) => {
-        const typeCollection = (e.target as any).selectedOptions[0].value as CollectionViewType;
+        const typeCollection = (e.target as HTMLSelectElement).selectedOptions[0].value as CollectionViewType;
         this.layoutDoc.presFieldKey = this.fieldKey + (typeCollection === CollectionViewType.Tree ? '-linearized' : '');
         // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
         [CollectionViewType.Tree || CollectionViewType.Stacking].includes(typeCollection) && (this.Document._pivotField = undefined);
@@ -1111,30 +1109,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         }
     });
 
-    /**
-     * Called when the user changes the view type
-     * Either 'List' (stacking) or 'Slides' (carousel)
-     */
-    // @undoBatch
-    mediaStopChanged = action((e: React.ChangeEvent) => {
-        const { activeItem } = this;
-        const stopDoc = (e.target as any).selectedOptions[0].value as string;
-        const stopDocIndex = Number(stopDoc[0]);
-        activeItem.mediaStopDoc = stopDocIndex;
-        if (this.childDocs[stopDocIndex - 1].mediaStopTriggerList) {
-            const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList);
-            list.push(activeItem);
-            // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;\
-        } else {
-            this.childDocs[stopDocIndex - 1].mediaStopTriggerList = new List<Doc>();
-            const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList);
-            list.push(activeItem);
-            // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;
-        }
-    });
-
     movementName = action((activeItem: Doc) => {
-        if (![PresMovement.Zoom, PresMovement.Pan, PresMovement.Center, PresMovement.Jump, PresMovement.None].includes(StrCast(activeItem.presentation_movement) as any)) {
+        if (![PresMovement.Zoom, PresMovement.Pan, PresMovement.Center, PresMovement.Jump, PresMovement.None].includes(StrCast(activeItem.presentation_movement) as PresMovement)) {
             return PresMovement.Zoom;
         }
         return StrCast(activeItem.presentation_movement);
@@ -1185,7 +1161,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
      * Method to get the list of selected items in the order in which they have been selected
      */
     @computed get listOfSelected() {
-        return Array.from(this.selectedArray).map((doc: Doc, index: any) => {
+        return Array.from(this.selectedArray).map((doc, index) => {
             const curDoc = Cast(doc, Doc, null);
             const tagDoc = Cast(curDoc.presentation_targetDoc, Doc, null);
             if (curDoc && curDoc === this.activeItem)
@@ -1193,7 +1169,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     // eslint-disable-next-line react/no-array-index-key
                     <div key={index} className="selectedList-items">
                         <b>
-                            {index + 1}. {curDoc.title}
+                            {index + 1}. {StrCast(curDoc.title)})
                         </b>
                     </div>
                 );
@@ -1201,14 +1177,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 return (
                     // eslint-disable-next-line react/no-array-index-key
                     <div key={index} className="selectedList-items">
-                        {index + 1}. {curDoc.title}
+                        {index + 1}. {StrCast(curDoc.title)}
                     </div>
                 );
             if (curDoc)
                 return (
                     // eslint-disable-next-line react/no-array-index-key
                     <div key={index} className="selectedList-items">
-                        {index + 1}. {curDoc.title}
+                        {index + 1}. {StrCast(curDoc.title)}
                     </div>
                 );
             return null;
@@ -1301,13 +1277,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         switch (e.key) {
             case 'Backspace':
                 if (this.layoutDoc.presentation_status === 'edit') {
-                    undoBatch(
+                    undoable(
                         action(() => {
                             Array.from(this.selectedArray).forEach(doc => this.removeDocument(doc));
                             this.clearSelectedArray();
                             this._eleArray.length = 0;
                             this._dragArray.length = 0;
-                        })
+                        }),
+                        'delete slides'
                     )();
                     handled = true;
                 }
@@ -1488,7 +1465,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         );
     };
     // Converts seconds to ms and updates presentation_transition
-    public static SetTransitionTime = (number: String, setter: (timeInMS: number) => void, change?: number) => {
+    public static SetTransitionTime = (number: string, setter: (timeInMS: number) => void, change?: number) => {
         let timeInMS = Number(number) * 1000;
         if (change) timeInMS += change;
         if (timeInMS < 100) timeInMS = 100;
@@ -1497,7 +1474,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     };
 
     @undoBatch
-    updateTransitionTime = (number: String, change?: number) => {
+    updateTransitionTime = (number: string, change?: number) => {
         PresBox.SetTransitionTime(
             number,
             (timeInMS: number) =>
@@ -1510,7 +1487,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
     // Converts seconds to ms and updates presentation_transition
     @undoBatch
-    updateZoom = (number: String, change?: number) => {
+    updateZoom = (number: string, change?: number) => {
         let scale = Number(number) / 100;
         if (change) scale += change;
         if (scale < 0.01) scale = 0.01;
@@ -1524,7 +1501,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
      * Converts seconds to ms and updates presentation_duration
      */
     @undoBatch
-    updateDurationTime = (number: String, change?: number) => {
+    updateDurationTime = (number: string, change?: number) => {
         let timeInMS = Number(number) * 1000;
         if (change) timeInMS += change;
         if (timeInMS < 100) timeInMS = 100;
@@ -1608,9 +1585,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         });
     };
 
-    static _sliderBatch: any;
+    static _sliderBatch: UndoManager.Batch | undefined;
     static endBatch = () => {
-        PresBox._sliderBatch.end();
+        PresBox._sliderBatch?.end();
         document.removeEventListener('pointerup', PresBox.endBatch, true);
     };
     public static inputter = (min: string, step: string, max: string, value: number, active: boolean, change: (val: string) => void, hmargin?: number) => (
@@ -1704,7 +1681,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                 </div>
                             </Tooltip>
                         </div>
-                        {[DocumentType.AUDIO, DocumentType.VID].includes(targetType as any as DocumentType) ? null : (
+                        {[DocumentType.AUDIO, DocumentType.VID].includes(targetType as DocumentType) ? null : (
                             <>
                                 <div className="ribbon-doubleButton">
                                     <div className="presBox-subheading">Slide Duration</div>
@@ -1847,7 +1824,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (activeItem && this.targetDoc) {
             const transitionSpeed = activeItem.presentation_transition ? NumCast(activeItem.presentation_transition) / 1000 : 0.5;
             const zoom = NumCast(activeItem.config_zoom, 1) * 100;
-            const effect = StrCast(activeItem.presentation_effect) ? (StrCast(activeItem.presentation_effect) as any as PresEffect) : PresEffect.None;
+            const effect = StrCast(activeItem.presentation_effect) ? (StrCast(activeItem.presentation_effect) as PresEffect) : PresEffect.None;
             const direction = StrCast(activeItem.presentation_effectDirection) as PresEffectDirection;
 
             return (
@@ -2660,24 +2637,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             <div className={`dropdown-play ${this._presentTools ? 'active' : ''}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                 <div
                     className="dropdown-play-button"
-                    onClick={undoBatch(
+                    onClick={undoable(
                         action(() => {
                             this.enterMinimize();
                             this.turnOffEdit(true);
                             this.gotoDocument(this.itemIndex, this.activeItem);
-                        })
+                        }),
+                        'minimze presentation'
                     )}>
                     Mini-player
                 </div>
                 <div
                     className="dropdown-play-button"
-                    onClick={undoBatch(
+                    onClick={undoable(
                         action(() => {
                             this.layoutDoc.presentation_status = 'manual';
                             this.initializePresState(this.itemIndex);
                             this.turnOffEdit(true);
                             this.gotoDocument(this.itemIndex, this.activeItem);
-                        })
+                        }),
+                        'make presentation manual'
                     )}>
                     Sidebar player
                 </div>
@@ -2773,13 +2752,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     <span className={`presBox-button ${this.layoutDoc.presentation_status === PresStatus.Edit ? 'present' : ''}`}>
                         <div
                             className="presBox-button-left"
-                            onClick={undoBatch(() => {
+                            onClick={undoable(() => {
                                 if (this.childDocs.length) {
                                     this.layoutDoc.presentation_status = 'manual';
                                     this.initializePresState(this.itemIndex);
                                     this.gotoDocument(this.itemIndex, this.activeItem);
                                 }
-                            })}>
+                            }, 'start presentation')}>
                             <FontAwesomeIcon icon="play-circle" />
                             <div style={{ display: this._props.PanelWidth() > 200 ? 'inline-flex' : 'none' }}>&nbsp; Present</div>
                         </div>
@@ -2911,11 +2890,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 {this._props.PanelWidth() > 250 ? (
                     <div
                         className="presPanel-button-text"
-                        onClick={undoBatch(
+                        onClick={undoable(
                             action(() => {
                                 this.layoutDoc.presentation_status = PresStatus.Edit;
                                 clearTimeout(this._presTimer);
-                            })
+                            }),
+                            'edit presetnation'
                         )}>
                         EXIT
                     </div>
@@ -2988,7 +2968,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     };
 
     sort = (treeViewMap: Map<Doc, number>) => [...treeViewMap.entries()].sort((a: [Doc, number], b: [Doc, number]) => (a[1] > b[1] ? 1 : a[1] < b[1] ? -1 : 0)).map(kv => kv[0]);
-
+    emptyHierarchy = [];
     render() {
         // needed to ensure that the childDocs are loaded for looking up fields
         this.childDocs.slice();
@@ -3086,7 +3066,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                 ScreenToLocalTransform={this.getTransform}
                                 AddToMap={this.AddToMap}
                                 RemFromMap={this.RemFromMap}
-                                hierarchyIndex={emptyPath}
+                                hierarchyIndex={this.emptyHierarchy}
                             />
                         ) : null}
                     </div>
-- 
cgit v1.2.3-70-g09d2


From fed4bf0b7363b9d58828a7a51f037a26f287d874 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 15 Aug 2024 15:45:44 -0400
Subject: fixed emptyPath type

---
 src/ServerUtils.ts                              | 2 +-
 src/client/views/nodes/DocumentContentsView.tsx | 2 +-
 src/client/views/nodes/trails/PresBox.tsx       | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

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

diff --git a/src/ServerUtils.ts b/src/ServerUtils.ts
index 904541fc7..8b2d0b9f6 100644
--- a/src/ServerUtils.ts
+++ b/src/ServerUtils.ts
@@ -16,7 +16,7 @@ export namespace ServerUtils {
     export function AddServerHandlerCallback<T>(socket: Socket, message: Message<T>, handler: (args: [T, (res: unknown) => void]) => void) {
         socket.on(message.Message, (arg: T, fn: (res: unknown) => void) => {
             Utils.log('S receiving', message.Name, arg, true);
-            handler([arg, Utils.loggingCallback('S sending', fn, message.Name)]);
+            handler([arg, Utils.loggingCallback('Sending', fn, message.Name)]);
         });
     }
     export type RoomHandler = (socket: Socket, room: string) => void;
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 15baebae1..afc160297 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -4,7 +4,7 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as XRegExp from 'xregexp';
 import { OmitKeys } from '../../../ClientUtils';
-import { Without, emptyPath } from '../../../Utils';
+import { Without } from '../../../Utils';
 import { Doc, Opt } from '../../../fields/Doc';
 import { AclPrivate, DocData } from '../../../fields/DocSymbols';
 import { ScriptField } from '../../../fields/ScriptField';
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index c403f9415..cf32a0196 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -20,7 +20,7 @@ import { ObjectField } from '../../../../fields/ObjectField';
 import { listSpec } from '../../../../fields/Schema';
 import { ComputedField, ScriptField } from '../../../../fields/ScriptField';
 import { BoolCast, Cast, DocCast, NumCast, StrCast, toList } from '../../../../fields/Types';
-import { emptyFunction, emptyPath, stringHash } from '../../../../Utils';
+import { emptyFunction, stringHash } from '../../../../Utils';
 import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/PresCustomization';
 import { DocServer } from '../../../DocServer';
 import { Docs } from '../../../documents/Documents';
-- 
cgit v1.2.3-70-g09d2


From 325aa35c4bd5f57240ead2ec5f22ea9c4f19d522 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 15 Aug 2024 23:16:09 -0400
Subject: fixed dropping on multi col/row collections with margins

---
 .../CollectionMulticolumnView.scss                 | 69 +++++++++-------
 .../CollectionMulticolumnView.tsx                  | 94 +++++++++++-----------
 .../CollectionMultirowView.scss                    | 49 ++++++-----
 .../CollectionMultirowView.tsx                     | 31 +++----
 src/client/views/nodes/trails/PresBox.tsx          | 22 ++---
 5 files changed, 143 insertions(+), 122 deletions(-)

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

diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
index f983fd815..06d78c39e 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
@@ -1,43 +1,50 @@
-.collectionMulticolumnView_contents {
-    display: flex;
-    //overflow: hidden;  // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template)
-    width: 100%;
+.collectionMulticolumnView_drop {
     height: 100%;
+    top: 0;
+    left: 0;
+    position: absolute;
 
-    .document-wrapper {
+    .collectionMulticolumnView_contents {
         display: flex;
-        flex-direction: column;
+        //overflow: hidden;  // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template)
         width: 100%;
-        align-items: center;
-        position: relative;
-        > .iconButton-container {
-            top: 0;
-            left: 0;
-            position: absolute;
-        }
-
-        .contentFittingDocumentView {
-            margin: auto;
-        }
+        height: 100%;
 
-        .label-wrapper {
+        .document-wrapper {
             display: flex;
-            flex-direction: row;
-            justify-content: center;
-            height: 20px;
+            flex-direction: column;
+            width: 100%;
+            align-items: center;
+            position: relative;
+            > .iconButton-container {
+                top: 0;
+                left: 0;
+                position: absolute;
+            }
+
+            .contentFittingDocumentView {
+                margin: auto;
+            }
+
+            .label-wrapper {
+                display: flex;
+                flex-direction: row;
+                justify-content: center;
+                height: 20px;
+            }
         }
-    }
 
-    .multiColumnResizer {
-        cursor: ew-resize;
-        transition: 0.5s opacity ease;
-        display: flex;
-        flex-direction: column;
+        .multiColumnResizer {
+            cursor: ew-resize;
+            transition: 0.5s opacity ease;
+            display: flex;
+            flex-direction: column;
 
-        .multiColumnResizer-hdl {
-            width: 100%;
-            height: 100%;
-            transition: 0.5s background-color ease;
+            .multiColumnResizer-hdl {
+                width: 100%;
+                height: 100%;
+                transition: 0.5s background-color ease;
+            }
         }
     }
 }
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 5125bdb6c..c6884d866 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -17,6 +17,7 @@ import './CollectionMulticolumnView.scss';
 import ResizeBar from './MulticolumnResizer';
 import WidthLabel from './MulticolumnWidthLabel';
 import { dropActionType } from '../../../util/DropActionTypes';
+import { SnappingManager } from '../../../util/SnappingManager';
 
 interface WidthSpecifier {
     magnitude: number;
@@ -211,15 +212,14 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         return Transform.Identity();
     };
 
-    @undoBatch
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
         let dropInd = -1;
-        if (de.complete.docDragData && this._mainCont) {
+        if (de.complete.docDragData && this._contRef.current) {
             let curInd = -1;
             de.complete.docDragData?.droppedDocuments.forEach(d => {
                 curInd = this.childDocs.indexOf(d);
             });
-            Array.from(this._mainCont.children).forEach((child, index) => {
+            Array.from(this._contRef.current.children).forEach((child, index) => {
                 const brect = child.getBoundingClientRect();
                 if (brect.x < de.x && brect.x + brect.width > de.x) {
                     if (curInd !== -1 && curInd === Math.floor(index / 2)) {
@@ -317,11 +317,11 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         this.childLayouts.forEach((layout, i) => {
             collector.push(
                 // eslint-disable-next-line react/no-array-index-key
-                <Tooltip title={'Tab: ' + StrCast(layout.title)} key={'wrapper' + i}>
+                <Tooltip title={'Doc: ' + StrCast(layout.title)} key={'wrapper' + i}>
                     <div className="document-wrapper" style={{ flexDirection: 'column', width: this.lookupPixels(layout) }}>
                         {this.getDisplayDoc(layout)}
                         {this.layoutDoc._chromeHidden ? null : (
-                            <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(() => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} />
+                            <Button tooltip="Remove document" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(() => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} />
                         )}
                         <WidthLabel layout={layout} collectionDoc={this.Document} />
                     </div>
@@ -343,49 +343,53 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         return collector;
     }
 
+    _contRef = React.createRef<HTMLDivElement>();
     render() {
         return (
-            <div
-                className="collectionMulticolumnView_contents"
-                ref={this.createDashEventsTarget}
-                style={{
-                    width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`,
-                    height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`,
-                    marginLeft: NumCast(this.Document._xMargin),
-                    marginRight: NumCast(this.Document._xMargin),
-                    marginTop: NumCast(this.Document._yMargin),
-                    marginBottom: NumCast(this.Document._yMargin),
-                }}>
-                {this.contents}
-                {!this._startIndex ? null : (
-                    <Tooltip title="scroll back">
-                        <div
-                            style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }}
-                            onClick={action(() => {
-                                this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
-                            })}>
-                            <Button
-                                tooltip="Scroll back"
-                                icon={<FontAwesomeIcon icon="chevron-left" size="lg" />}
+            <div className="collectionMulticolumnView_drop" ref={this.createDashEventsTarget}>
+                <div
+                    className="collectionMulticolumnView_contents"
+                    ref={this._contRef}
+                    style={{
+                        pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : this._props.pointerEvents?.(),
+                        width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`,
+                        height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`,
+                        marginLeft: NumCast(this.Document._xMargin),
+                        marginRight: NumCast(this.Document._xMargin),
+                        marginTop: NumCast(this.Document._yMargin),
+                        marginBottom: NumCast(this.Document._yMargin),
+                    }}>
+                    {this.contents}
+                    {!this._startIndex ? null : (
+                        <Tooltip title="scroll back">
+                            <div
+                                style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }}
                                 onClick={action(() => {
-                                    this._startIndex = Math.max(0, this._startIndex - this.maxShown);
-                                })}
-                                color={SettingsManager.userColor}
-                            />
-                        </div>
-                    </Tooltip>
-                )}
-                {this._startIndex > this.childLayoutPairs.length - 1 || !this.maxShown ? null : (
-                    <Tooltip title="scroll forward">
-                        <div
-                            style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }}
-                            onClick={action(() => {
-                                this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
-                            })}>
-                            <IconButton icon={<FaChevronRight />} color={SettingsManager.userColor} />
-                        </div>
-                    </Tooltip>
-                )}
+                                    this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
+                                })}>
+                                <Button
+                                    tooltip="Scroll back"
+                                    icon={<FontAwesomeIcon icon="chevron-left" size="lg" />}
+                                    onClick={action(() => {
+                                        this._startIndex = Math.max(0, this._startIndex - this.maxShown);
+                                    })}
+                                    color={SettingsManager.userColor}
+                                />
+                            </div>
+                        </Tooltip>
+                    )}
+                    {this._startIndex > this.childLayoutPairs.length - 1 || !this.maxShown ? null : (
+                        <Tooltip title="scroll forward">
+                            <div
+                                style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }}
+                                onClick={action(() => {
+                                    this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
+                                })}>
+                                <IconButton icon={<FaChevronRight />} color={SettingsManager.userColor} />
+                            </div>
+                        </Tooltip>
+                    )}
+                </div>
             </div>
         );
     }
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
index f44eacb2a..0d49fabaa 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
@@ -1,34 +1,41 @@
-.collectionMultirowView_contents {
-    display: flex;
-    //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template)
-    width: 100%;
+.collectionMultirowView_drop {
     height: 100%;
-    flex-direction: column;
+    top: 0;
+    left: 0;
+    position: absolute;
 
-    .document-wrapper {
+    .collectionMultirowView_contents {
         display: flex;
-        flex-direction: row;
+        //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template)
+        width: 100%;
         height: 100%;
-        align-items: center;
+        flex-direction: column;
 
-        .label-wrapper {
+        .document-wrapper {
             display: flex;
             flex-direction: row;
-            justify-content: center;
-            height: 20px;
+            height: 100%;
+            align-items: center;
+
+            .label-wrapper {
+                display: flex;
+                flex-direction: row;
+                justify-content: center;
+                height: 20px;
+            }
         }
-    }
 
-    .multiRowResizer {
-        cursor: ns-resize;
-        transition: 0.5s opacity ease;
-        display: flex;
-        flex-direction: row;
+        .multiRowResizer {
+            cursor: ns-resize;
+            transition: 0.5s opacity ease;
+            display: flex;
+            flex-direction: row;
 
-        .multiRowResizer-hdl {
-            width: 100%;
-            height: 100%;
-            transition: 0.5s background-color ease;
+            .multiRowResizer-hdl {
+                width: 100%;
+                height: 100%;
+                transition: 0.5s background-color ease;
+            }
         }
     }
 }
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 2833ff2f8..04b85e182 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -196,12 +196,12 @@ export class CollectionMultirowView extends CollectionSubView() {
     @undoBatch
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
         let dropInd = -1;
-        if (de.complete.docDragData && this._mainCont) {
+        if (de.complete.docDragData && this._contRef.current) {
             let curInd = -1;
             de.complete.docDragData?.droppedDocuments.forEach(d => {
                 curInd = this.childDocs.indexOf(d);
             });
-            Array.from(this._mainCont.children).forEach((child, index) => {
+            Array.from(this._contRef.current.children).forEach((child, index) => {
                 const brect = child.getBoundingClientRect();
                 if (brect.y < de.y && brect.y + brect.height > de.y) {
                     if (curInd !== -1 && curInd === Math.floor(index / 2)) {
@@ -318,20 +318,23 @@ export class CollectionMultirowView extends CollectionSubView() {
         return collector;
     }
 
+    _contRef = React.createRef<HTMLDivElement>();
     render() {
         return (
-            <div
-                className="collectionMultirowView_contents"
-                style={{
-                    width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`,
-                    height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`,
-                    marginLeft: NumCast(this.Document._xMargin),
-                    marginRight: NumCast(this.Document._xMargin),
-                    marginTop: NumCast(this.Document._yMargin),
-                    marginBottom: NumCast(this.Document._yMargin),
-                }}
-                ref={this.createDashEventsTarget}>
-                {this.contents}
+            <div className="collectionMultirowView_drop" ref={this.createDashEventsTarget}>
+                <div
+                    ref={this._contRef}
+                    className="collectionMultirowView_contents"
+                    style={{
+                        width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`,
+                        height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`,
+                        marginLeft: NumCast(this.Document._xMargin),
+                        marginRight: NumCast(this.Document._xMargin),
+                        marginTop: NumCast(this.Document._yMargin),
+                        marginBottom: NumCast(this.Document._yMargin),
+                    }}>
+                    {this.contents}
+                </div>
             </div>
         );
     }
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index cf32a0196..7448fa898 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -2,7 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import Slider from '@mui/material/Slider';
 import { Button, Dropdown, DropdownType, IconButton, Toggle, ToggleType, Type } from 'browndash-components';
-import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx';
+import { IReactionDisposer, ObservableSet, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { AiOutlineSend } from 'react-icons/ai';
@@ -10,7 +10,8 @@ import { BiMicrophone } from 'react-icons/bi';
 import { FaArrowDown, FaArrowLeft, FaArrowRight, FaArrowUp } from 'react-icons/fa';
 import ReactLoading from 'react-loading';
 import ReactTextareaAutosize from 'react-textarea-autosize';
-import { lightOrDark, returnFalse, returnOne, setupMoveUpEvents, StopEvent } from '../../../../ClientUtils';
+import { StopEvent, lightOrDark, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils';
+import { emptyFunction, stringHash } from '../../../../Utils';
 import { Doc, DocListCast, Field, FieldResult, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
 import { Animation, DocData, TransitionTimer } from '../../../../fields/DocSymbols';
 import { Copy } from '../../../../fields/FieldSymbols';
@@ -20,24 +21,23 @@ import { ObjectField } from '../../../../fields/ObjectField';
 import { listSpec } from '../../../../fields/Schema';
 import { ComputedField, ScriptField } from '../../../../fields/ScriptField';
 import { BoolCast, Cast, DocCast, NumCast, StrCast, toList } from '../../../../fields/Types';
-import { emptyFunction, stringHash } from '../../../../Utils';
-import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/PresCustomization';
 import { DocServer } from '../../../DocServer';
-import { Docs } from '../../../documents/Documents';
+import { getSlideTransitionSuggestions, gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/PresCustomization';
 import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
 import { DictationManager } from '../../../util/DictationManager';
 import { dropActionType } from '../../../util/DropActionTypes';
 import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
 import { SerializationHelper } from '../../../util/SerializationHelper';
 import { SnappingManager } from '../../../util/SnappingManager';
-import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager';
-import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
-import { CollectionFreeFormPannableContents } from '../../collections/collectionFreeForm/CollectionFreeFormPannableContents';
+import { UndoManager, undoBatch, undoable } from '../../../util/UndoManager';
+import { ViewBoxBaseComponent } from '../../DocComponent';
+import { pinDataTypes as dataTypes } from '../../PinFuncs';
 import { CollectionView } from '../../collections/CollectionView';
 import { TreeView } from '../../collections/TreeView';
-import { ViewBoxBaseComponent } from '../../DocComponent';
+import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
+import { CollectionFreeFormPannableContents } from '../../collections/collectionFreeForm/CollectionFreeFormPannableContents';
 import { Colors } from '../../global/globalEnums';
-import { pinDataTypes as dataTypes } from '../../PinFuncs';
 import { DocumentView } from '../DocumentView';
 import { FieldView, FieldViewProps } from '../FieldView';
 import { FocusViewOptions } from '../FocusViewOptions';
@@ -47,7 +47,7 @@ import CubicBezierEditor, { EaseFuncToPoints, TIMING_DEFAULT_MAPPINGS } from './
 import './PresBox.scss';
 import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
 import SlideEffect from './SlideEffect';
-import { AnimationSettings, easeItems, effectItems, effectTimings, movementItems, presEffectDefaultTimings, springMappings, springPreviewColors, SpringSettings, SpringType } from './SpringUtils';
+import { AnimationSettings, SpringSettings, SpringType, easeItems, effectItems, effectTimings, movementItems, presEffectDefaultTimings, springMappings, springPreviewColors } from './SpringUtils';
 
 @observer
 export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
-- 
cgit v1.2.3-70-g09d2

