From 081632757af3c2ec2e4482c1e5fe710c8ee6cad8 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 11 Aug 2022 19:01:37 -0400
Subject: added better ui and backend support for mask ink strokes. added frame
 #'s ui for seeing current animation frame.

---
 src/client/views/collections/TabDocView.tsx | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

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

diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index f30faab79..ff4b1e2ce 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -292,11 +292,11 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     pinDoc.presActiveFrame = pinProps?.activeFrame;
                     pinDoc.title = doc.title + ' (move)';
                     pinDoc.presMovement = PresMovement.Pan;
-                    if (pinDoc.isInkMask) {
-                        pinDoc.presHideAfter = true;
-                        pinDoc.presHideBefore = true;
-                        pinDoc.presMovement = PresMovement.None;
-                    }
+                }
+                if (pinDoc.isInkMask) {
+                    pinDoc.presHideAfter = true;
+                    pinDoc.presHideBefore = true;
+                    pinDoc.presMovement = PresMovement.None;
                 }
                 if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
                 PresBox.Instance?._selectedArray.clear();
-- 
cgit v1.2.3-70-g09d2


From 5a425e5cf18115921ecb4e7cf931e65f45dab8e2 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 18 Aug 2022 11:18:14 -0400
Subject: fixed up presboxelement to not reference presbox.instance.  fixing
 layout of presboxelement in treeview.  fixing "removing" an inkMask without
 removing it from the collection so that it can be turned on and off.

---
 src/client/util/CurrentUserUtils.ts                |   9 +-
 src/client/views/DocumentDecorations.tsx           |   6 +-
 src/client/views/PropertiesView.tsx                |   5 +-
 .../views/collections/CollectionTreeView.scss      |  11 +-
 src/client/views/collections/TabDocView.tsx        |   4 +-
 src/client/views/collections/TreeView.scss         |  17 +--
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   1 +
 src/client/views/nodes/trails/PresBox.tsx          | 137 +++++++++------------
 src/client/views/nodes/trails/PresElementBox.tsx   |  73 ++++++-----
 9 files changed, 132 insertions(+), 131 deletions(-)

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

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index dcf4a71c8..f7d072d80 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -289,11 +289,12 @@ export class CurrentUserUtils {
             { toolTip: "Tap or drag to create a map",             title: "Map", icon: "map-marker-alt", dragFactory: doc.emptyMap as Doc, },
             { toolTip: "Tap or drag to create a screen grabber",  title: "Grab", icon: "photo-video",   dragFactory: doc.emptyScreengrab as Doc,  scripts: { onClick: 'openInOverlay(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'},funcs: { hidden: 'IsNoviceMode()'} },
             { toolTip: "Tap or drag to create a WebCam recorder", title: "WebCam", icon: "photo-video", dragFactory: doc.emptyWebCam as Doc,      scripts: { onClick: 'openInOverlay(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'},funcs: { hidden: 'IsNoviceMode()'}},
-            { toolTip: "Tap or drag to create a button",          title: "Button", icon: "bolt",        dragFactory: doc.emptyButton as Doc,      funcs: { hidden: 'IsNoviceMode()'} },
-            { toolTip: "Tap or drag to create a scripting box",   title: "Script", icon: "terminal",    dragFactory: doc.emptyScript as Doc,      funcs: { hidden: 'IsNoviceMode()'}},
+            { toolTip: "Tap or drag to create a button",          title: "Button", icon: "bolt",        dragFactory: doc.emptyButton as Doc,      funcs:   { hidden: 'IsNoviceMode()'} },
+            { toolTip: "Tap or drag to create a scripting box",   title: "Script", icon: "terminal",    dragFactory: doc.emptyScript as Doc,      funcs:   { hidden: 'IsNoviceMode()'}},
             { toolTip: "Tap or drag to create a data viz node",   title: "DataViz", icon: "file",       dragFactory: doc.emptyDataViz as Doc, },
-            { toolTip: "Tap or drag to create a data note",       title: "DataNote", icon: "window-maximize", dragFactory: doc.emptyHeader as Doc,  scripts: {onClick: 'openOnRight(delegateDragFactory(this.dragFactory))', onDragStart: '{ return delegateDragFactory(this.dragFactory);}'},  },
-            { toolTip: "Toggle a Calculator REPL",                title: "repl", icon: "calculator",                                              scripts: {onClick: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' } },
+            { toolTip: "Tap or drag to create a bullet slide",    title: "PPT Slide", icon: "file",     dragFactory: doc.emptySlide as Doc,       funcs:   { hidden: 'IsNoviceMode()'}},
+            { toolTip: "Tap or drag to create a data note",       title: "DataNote", icon: "window-maximize", dragFactory: doc.emptyHeader as Doc,scripts: { onClick: 'openOnRight(delegateDragFactory(this.dragFactory))', onDragStart: '{ return delegateDragFactory(this.dragFactory);}'},  },
+            { toolTip: "Toggle a Calculator REPL",                title: "repl", icon: "calculator",                                              scripts: { onClick: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' } },
           ].map(tuple => ({scripts: {onClick: 'openOnRight(copyDragFactory(this.dragFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, ...tuple, }))
     }
 
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 3544f74b4..6d1397395 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -203,7 +203,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                 if (this._deleteAfterIconify) {
                     views.forEach(iconView => {
                         Doc.setNativeView(iconView.props.Document);
-                        iconView.props.removeDocument?.(iconView.props.Document);
+                        if (iconView.props.Document.isInkMask && iconView.props.Document.activeFrame !== undefined) {
+                            iconView.props.Document.opacity = 0; // bcz: hacky ... allows inkMaks to be "turned off" without removing them from the collection which allows them to function properly in a presenation.
+                        } else {
+                            iconView.props.removeDocument?.(iconView.props.Document);
+                        }
                     });
                     SelectionManager.DeselectAll();
                 }
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index ef0e057dc..33f17047b 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -15,7 +15,7 @@ import { ComputedField } from '../../fields/ScriptField';
 import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
 import { denormalizeEmail, GetEffectiveAcl, SharingPermissions } from '../../fields/util';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
-import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
+import { DocumentType } from '../documents/DocumentTypes';
 import { DocumentManager } from '../util/DocumentManager';
 import { LinkManager } from '../util/LinkManager';
 import { SelectionManager } from '../util/SelectionManager';
@@ -1614,9 +1614,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
             if (this.isPres) {
                 const selectedItem: boolean = PresBox.Instance?._selectedArray.size > 0;
                 const type = PresBox.Instance.activeItem?.type;
-                const viewType = PresBox.Instance.activeItem?._viewType;
-                const pannable: boolean = (type === DocumentType.COL && viewType === CollectionViewType.Freeform) || type === DocumentType.IMG;
-                const scrollable: boolean = type === DocumentType.PDF || type === DocumentType.WEB || type === DocumentType.RTF || viewType === CollectionViewType.Stacking || viewType === CollectionViewType.NoteTaking;
                 return (
                     <div className="propertiesView" style={{ width: this.props.width }}>
                         <div className="propertiesView-title" style={{ width: this.props.width }}>
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 93523a6cf..c0561e42c 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -1,6 +1,5 @@
-@import "../global/globalCssVariables";
+@import '../global/globalCssVariables';
 
-  
 .collectionTreeView-container {
     transform-origin: top left;
     height: 100%;
@@ -28,7 +27,7 @@
         list-style: none;
         padding-left: $TREE_BULLET_WIDTH;
         margin-bottom: 1px; // otherwise vertical scrollbars may pop up for no apparent reason....
-        > .contentFittingDocumentView  {
+        > .contentFittingDocumentView {
             width: unset;
             height: unset;
         }
@@ -39,7 +38,7 @@
 
     .no-indent {
         padding-left: 0;
-        width: max-content;
+        //width: max-content;
     }
 
     .no-indent-outline {
@@ -85,7 +84,7 @@
     width: 100%;
     height: max-content;
     .contentFittingDocumentView {
-        display: block;  // makes titleBar take up full width of the treeView (flex doesn't for some reason)
+        display: block; // makes titleBar take up full width of the treeView (flex doesn't for some reason)
     }
 }
 
@@ -114,4 +113,4 @@
     padding-left: 3px;
     padding-right: 3px;
     padding-bottom: 2px;
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index ff4b1e2ce..e147f34d2 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -299,8 +299,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     pinDoc.presMovement = PresMovement.None;
                 }
                 if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
-                PresBox.Instance?._selectedArray.clear();
-                pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array
+                PresBox.Instance?.clearSelectedArray();
+                pinDoc && PresBox.Instance?.addToSelectedArray(pinDoc); //Update selected array
             });
             if (
                 CollectionDockingView.Instance &&
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index f587dbbf6..ce87e6f89 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -1,4 +1,4 @@
-@import "../global/globalCssVariables";
+@import '../global/globalCssVariables';
 
 .treeView-label {
     max-height: 1.5em;
@@ -21,7 +21,7 @@
     }
 
     .treeView-bulletIcons {
-        // width: $TREE_BULLET_WIDTH; 
+        // width: $TREE_BULLET_WIDTH;
         width: 100%;
         height: 100%;
 
@@ -101,6 +101,9 @@
 .treeView-border {
     display: flex;
     overflow: hidden;
+    > ul {
+        width: 100%;
+    }
 }
 
 .treeView-border {
@@ -118,7 +121,6 @@
     }
 
     .formattedTextBox-cont {
-
         .formattedTextbox-sidebar,
         .formattedTextbox-sidebar-inking {
             overflow: visible !important;
@@ -144,12 +146,12 @@
         pointer-events: all;
         cursor: pointer;
 
-        >svg {
+        > svg {
             margin-left: 0.25rem;
             margin-right: 0.25rem;
         }
 
-        >svg {
+        > svg {
             //display: none;
             opacity: 0;
             pointer-events: none;
@@ -176,8 +178,7 @@
     }
 
     .treeView-rightButtons {
-
-        >svg,
+        > svg,
         .styleProvider-treeView-icon {
             display: inherit;
             opacity: unset;
@@ -196,4 +197,4 @@
 
 .treeView-header-inside {
     border: black 1px solid;
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 45a5e30ff..0fd326091 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -251,6 +251,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     };
 
     isCurrent(doc: Doc) {
+        if (doc.isInkMask && doc.opacity === 0) return false; // bcz: hacky --- allows inkMasks to be "turned off" in a presentation without removing them from the collection.  otherwise, they still render a gray background.. need to come back to this and fix.
         const dispTime = NumCast(doc._timecodeToShow, -1);
         const endTime = NumCast(doc._timecodeToHide, dispTime + 1.5);
         const curTime = NumCast(this.Document._currentTimecode, -1);
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 627f35e71..05e09361b 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1,7 +1,7 @@
 import React = require('react');
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { ColorState, SketchPicker } from 'react-color';
 import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
@@ -20,6 +20,7 @@ import { SettingsManager } from '../../../util/SettingsManager';
 import { undoBatch, UndoManager } from '../../../util/UndoManager';
 import { CollectionDockingView } from '../../collections/CollectionDockingView';
 import { MarqueeViewBounds } from '../../collections/collectionFreeForm';
+import { CollectionFreeFormViewChrome } from '../../collections/CollectionMenu';
 import { CollectionView } from '../../collections/CollectionView';
 import { TabDocView } from '../../collections/TabDocView';
 import { ViewBoxBaseComponent } from '../../DocComponent';
@@ -29,7 +30,6 @@ import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentVie
 import { FieldView, FieldViewProps } from '../FieldView';
 import './PresBox.scss';
 import { PresEffect, PresMovement, PresStatus } from './PresEnums';
-import { CollectionFreeFormViewChrome } from '../../collections/CollectionMenu';
 
 export interface PinProps {
     audioRange?: boolean;
@@ -67,30 +67,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             delay: presDoc.presTransition,
             // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc,
         };
+        //prettier-ignore
         switch (presDoc.presEffect) {
-            case PresEffect.Zoom:
-                return <Zoom {...effectProps}>{renderDoc}</Zoom>;
-            case PresEffect.Fade:
-                return <Fade {...effectProps}>{renderDoc}</Fade>;
-            case PresEffect.Flip:
-                return <Flip {...effectProps}>{renderDoc}</Flip>;
-            case PresEffect.Rotate:
-                return <Rotate {...effectProps}>{renderDoc}</Rotate>;
-            case PresEffect.Bounce:
-                return <Bounce {...effectProps}>{renderDoc}</Bounce>;
-            case PresEffect.Roll:
-                return <Roll {...effectProps}>{renderDoc}</Roll>;
-            case PresEffect.Lightspeed:
-                return <LightSpeed {...effectProps}>{renderDoc}</LightSpeed>;
-            case PresEffect.None:
-            default:
-                return renderDoc;
+            default: 
+            case PresEffect.None:       return renderDoc;
+            case PresEffect.Zoom:       return <Zoom {...effectProps}>{renderDoc}</Zoom>;
+            case PresEffect.Fade:       return <Fade {...effectProps}>{renderDoc}</Fade>;
+            case PresEffect.Flip:       return <Flip {...effectProps}>{renderDoc}</Flip>;
+            case PresEffect.Rotate:     return <Rotate {...effectProps}>{renderDoc}</Rotate>;
+            case PresEffect.Bounce:     return <Bounce {...effectProps}>{renderDoc}</Bounce>;
+            case PresEffect.Roll:       return <Roll {...effectProps}>{renderDoc}</Roll>;
+            case PresEffect.Lightspeed: return <LightSpeed {...effectProps}>{renderDoc}</LightSpeed>;
         }
     }
     public static EffectsProvider(layoutDoc: Doc, renderDoc: any) {
         return PresBox.Instance && layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ? PresBox.renderEffectsDoc(renderDoc, layoutDoc, PresBox.Instance.childDocs[PresBox.Instance.itemIndex]) : renderDoc;
     }
 
+    private _disposers: { [name: string]: IReactionDisposer } = {};
+
+    constructor(props: any) {
+        super(props);
+        if ((Doc.ActivePresentation = this.rootDoc)) runInAction(() => (PresBox.Instance = this));
+        this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox
+    }
+
     @observable public static Instance: PresBox;
 
     @observable _isChildActive = false;
@@ -98,14 +99,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @observable _presTimer!: NodeJS.Timeout;
     @observable _presKeyEventsActive: boolean = false;
 
-    @observable _selectedArray: ObservableMap = new ObservableMap<Doc, any>();
     @observable _eleArray: HTMLElement[] = [];
     @observable _dragArray: HTMLElement[] = [];
     @observable _pathBoolean: boolean = false;
     @observable _expandBoolean: boolean = false;
 
-    private _disposers: { [name: string]: IReactionDisposer } = {};
-
     @observable static startMarquee: boolean = false; // onclick "+ new slide" in presentation mode, set as true, then when marquee selection finish, onPointerUp automatically triggers PinWithView
     @observable private transitionTools: boolean = false;
     @observable private newDocumentTools: boolean = false;
@@ -152,11 +150,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if ((this.targetDoc.type === DocumentType.COL && this.targetDoc._viewType === CollectionViewType.Freeform) || this.targetDoc.type === DocumentType.IMG) return true;
         else return false;
     }
-    constructor(props: any) {
-        super(props);
-        if ((Doc.ActivePresentation = this.rootDoc)) runInAction(() => (PresBox.Instance = this));
-        this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox
-    }
     @computed get selectedDocumentView() {
         if (SelectionManager.Views().length) return SelectionManager.Views()[0];
         if (this._selectedArray.size) return DocumentManager.Instance.getDocumentView(this.rootDoc);
@@ -173,6 +166,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @computed get selectedDoc() {
         return this.selectedDocumentView?.rootDoc;
     }
+    _selectedArray = new ObservableSet<Doc>();
+    clearSelectedArray = () => this._selectedArray.clear();
+    addToSelectedArray = (doc: Doc) => this._selectedArray.add(doc);
+    removeFromSelectedArray = (doc: Doc) => this._selectedArray.delete(doc);
 
     _unmounting = false;
     @action
@@ -188,6 +185,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
     @action
     componentDidMount() {
+        this.props.setContentView?.(this);
         this._unmounting = false;
         this.rootDoc._forceRenderEngine = 'timeline';
         this.layoutDoc.presStatus = PresStatus.Edit;
@@ -344,8 +342,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             if (targetDoc?.lastFrame !== undefined) {
                 targetDoc._currentFrame = 0;
             }
-            if (!group) this._selectedArray.clear();
-            this.childDocs[index] && this._selectedArray.set(this.childDocs[index], undefined); //Update selected array
+            if (!group) this.clearSelectedArray();
+            this.childDocs[index] && this.addToSelectedArray(this.childDocs[index]); //Update selected array
             this.navigateToElement(this.childDocs[index]); //Handles movement to element only when presTrail is list
             this.onHideDocument(); //Handles hide after/before
         }
@@ -415,7 +413,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             this.layoutDoc.presCollection = srcContext;
         }
         const presStatus = this.rootDoc.presStatus;
-        const selViewCache = Array.from(this._selectedArray.keys());
+        const selViewCache = Array.from(this._selectedArray);
         const dragViewCache = Array.from(this._dragArray);
         const eleViewCache = Array.from(this._eleArray);
         const self = this;
@@ -423,8 +421,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             const presDocView = DocumentManager.Instance.getDocumentView(self.rootDoc);
             if (presDocView) SelectionManager.SelectView(presDocView, false);
             self.rootDoc.presStatus = presStatus;
-            self._selectedArray.clear();
-            selViewCache.forEach(doc => self._selectedArray.set(doc, undefined));
+            self.clearSelectedArray();
+            selViewCache.forEach(doc => self.addToSelectedArray(doc));
             self._dragArray.splice(0, self._dragArray.length, ...dragViewCache);
             self._eleArray.splice(0, self._eleArray.length, ...eleViewCache);
         });
@@ -792,7 +790,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() {
-        const list = Array.from(this._selectedArray.keys()).map((doc: Doc, index: any) => {
+        return Array.from(this._selectedArray).map((doc: Doc, index: any) => {
             const curDoc = Cast(doc, Doc, null);
             const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
             if (curDoc && curDoc === this.activeItem)
@@ -816,7 +814,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     </div>
                 );
         });
-        return list;
     }
 
     @action
@@ -838,11 +835,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @action
     multiSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
         if (!this._selectedArray.has(doc)) {
-            this._selectedArray.set(doc, undefined);
+            this.addToSelectedArray(doc);
             this._eleArray.push(ref);
             this._dragArray.push(drag);
         } else {
-            this._selectedArray.delete(doc);
+            this.removeFromSelectedArray(doc);
             this.removeFromArray(this._eleArray, doc);
             this.removeFromArray(this._dragArray, doc);
         }
@@ -858,11 +855,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     //Shift click
     @action
     shiftSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
-        this._selectedArray.clear();
+        this.clearSelectedArray();
         // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         if (this.activeItem) {
             for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) {
-                this._selectedArray.set(this.childDocs[i], undefined);
+                this.addToSelectedArray(this.childDocs[i]);
                 this._eleArray.push(ref);
                 this._dragArray.push(drag);
             }
@@ -873,8 +870,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     //regular click
     @action
     regularSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, selectPres = true) => {
-        this._selectedArray.clear();
-        this._selectedArray.set(doc, undefined);
+        this.clearSelectedArray();
+        this.addToSelectedArray(doc);
         this._eleArray.splice(0, this._eleArray.length, ref);
         this._dragArray.splice(0, this._dragArray.length, drag);
         focus && this.selectElement(doc);
@@ -903,10 +900,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 if (this.layoutDoc.presStatus === 'edit') {
                     undoBatch(
                         action(() => {
-                            for (const doc of Array.from(this._selectedArray.keys())) {
+                            for (const doc of this._selectedArray) {
                                 this.removeDocument(doc);
                             }
-                            this._selectedArray.clear();
+                            this.clearSelectedArray();
                             this._eleArray.length = 0;
                             this._dragArray.length = 0;
                         })
@@ -918,7 +915,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 if (DocListCast(Doc.MyOverlayDocs?.data).includes(this.layoutDoc)) {
                     this.updateMinimize();
                 } else if (this.layoutDoc.presStatus === 'edit') {
-                    this._selectedArray.clear();
+                    this.clearSelectedArray();
                     this._eleArray.length = this._dragArray.length = 0;
                 } else this.layoutDoc.presStatus = 'edit';
                 if (this._presTimer) clearTimeout(this._presTimer);
@@ -931,7 +928,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 if (e.shiftKey && this.itemIndex < this.childDocs.length - 1) {
                     // TODO: update to work properly
                     this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) + 1;
-                    this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
+                    this.addToSelectedArray(this.childDocs[this.rootDoc._itemIndex]);
                 } else {
                     this.next();
                     if (this._presTimer) {
@@ -948,7 +945,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 if (e.shiftKey && this.itemIndex !== 0) {
                     // TODO: update to work properly
                     this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1;
-                    this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
+                    this.addToSelectedArray(this.childDocs[this.rootDoc._itemIndex]);
                 } else {
                     this.back();
                     if (this._presTimer) {
@@ -966,8 +963,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 break;
             case 'a':
                 if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === 'edit') {
-                    this._selectedArray.clear();
-                    this.childDocs.forEach(doc => this._selectedArray.set(doc, undefined));
+                    this.clearSelectedArray();
+                    this.childDocs.forEach(doc => this.addToSelectedArray(doc));
                     handled = true;
                 }
             default:
@@ -1115,7 +1112,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (change) timeInMS += change;
         if (timeInMS < 100) timeInMS = 100;
         if (timeInMS > 10000) timeInMS = 10000;
-        Array.from(this._selectedArray.keys()).forEach(doc => (doc.presTransition = timeInMS));
+        this._selectedArray.forEach(doc => (doc.presTransition = timeInMS));
     };
 
     // Converts seconds to ms and updates presTransition
@@ -1124,7 +1121,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (change) scale += change;
         if (scale < 0.01) scale = 0.01;
         if (scale > 1.5) scale = 1.5;
-        Array.from(this._selectedArray.keys()).forEach(doc => (doc.presZoom = scale));
+        this._selectedArray.forEach(doc => (doc.presZoom = scale));
     };
 
     // Converts seconds to ms and updates presDuration
@@ -1133,7 +1130,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (change) timeInMS += change;
         if (timeInMS < 100) timeInMS = 100;
         if (timeInMS > 20000) timeInMS = 20000;
-        Array.from(this._selectedArray.keys()).forEach(doc => (doc.presDuration = timeInMS));
+        this._selectedArray.forEach(doc => (doc.presDuration = timeInMS));
     };
 
     /**
@@ -1141,8 +1138,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
      */
     @undoBatch
     updateMovement = action((movement: any, all?: boolean) => {
-        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
-        array.forEach(doc => {
+        (all ? this.childDocs : this._selectedArray).forEach(doc => {
             switch (movement) {
                 case PresMovement.Zoom: //Pan and zoom
                     doc.presMovement = PresMovement.Zoom;
@@ -1166,21 +1162,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @action
     updateHideBefore = (activeItem: Doc) => {
         activeItem.presHideBefore = !activeItem.presHideBefore;
-        Array.from(this._selectedArray.keys()).forEach(doc => (doc.presHideBefore = activeItem.presHideBefore));
+        this._selectedArray.forEach(doc => (doc.presHideBefore = activeItem.presHideBefore));
     };
 
     @undoBatch
     @action
     updateHideAfter = (activeItem: Doc) => {
         activeItem.presHideAfter = !activeItem.presHideAfter;
-        Array.from(this._selectedArray.keys()).forEach(doc => (doc.presHideAfter = activeItem.presHideAfter));
+        this._selectedArray.forEach(doc => (doc.presHideAfter = activeItem.presHideAfter));
     };
 
     @undoBatch
     @action
     updateOpenDoc = (activeItem: Doc) => {
         activeItem.openDocument = !activeItem.openDocument;
-        Array.from(this._selectedArray.keys()).forEach(doc => {
+        this._selectedArray.forEach(doc => {
             doc.openDocument = activeItem.openDocument;
         });
     };
@@ -1188,8 +1184,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @undoBatch
     @action
     updateEffectDirection = (effect: any, all?: boolean) => {
-        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
-        array.forEach(doc => {
+        (all ? this.childDocs : this._selectedArray).forEach(doc => {
             const tagDoc = doc; // Cast(doc.presentationTargetDoc, Doc, null);
             switch (effect) {
                 case PresEffect.Left:
@@ -1215,29 +1210,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @undoBatch
     @action
     updateEffect = (effect: any, all?: boolean) => {
-        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
-        array.forEach(doc => {
+        (all ? this.childDocs : this._selectedArray).forEach(doc => {
             const tagDoc = doc; //Cast(doc.presentationTargetDoc, Doc, null);
+            //prettier-ignore
             switch (effect) {
-                case PresEffect.Bounce:
-                    tagDoc.presEffect = PresEffect.Bounce;
-                    break;
-                case PresEffect.Fade:
-                    tagDoc.presEffect = PresEffect.Fade;
-                    break;
-                case PresEffect.Flip:
-                    tagDoc.presEffect = PresEffect.Flip;
-                    break;
-                case PresEffect.Roll:
-                    tagDoc.presEffect = PresEffect.Roll;
-                    break;
-                case PresEffect.Rotate:
-                    tagDoc.presEffect = PresEffect.Rotate;
-                    break;
-                case PresEffect.None:
                 default:
-                    tagDoc.presEffect = PresEffect.None;
-                    break;
+                case PresEffect.None:   tagDoc.presEffect = PresEffect.None; break;
+                case PresEffect.Bounce: tagDoc.presEffect = PresEffect.Bounce; break;
+                case PresEffect.Fade:   tagDoc.presEffect = PresEffect.Fade; break;
+                case PresEffect.Flip:   tagDoc.presEffect = PresEffect.Flip; break;
+                case PresEffect.Roll:   tagDoc.presEffect = PresEffect.Roll; break;
+                case PresEffect.Rotate: tagDoc.presEffect = PresEffect.Rotate; break;
             }
         });
     };
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 0cf15d297..3af8cad9a 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -47,6 +47,13 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @computed get presStatus() {
         return this.presBox.presStatus;
     }
+    @computed get selectedArray() {
+        return this.presBoxView?._selectedArray;
+    }
+    @computed get presBoxView() {
+        const vpath = this.props.docViewPath();
+        return vpath.length > 1 ? (vpath[vpath.length - 2].ComponentView as PresBox) : undefined;
+    }
     @computed get presBox() {
         return (this.props.DocumentView?.().props.treeViewDoc ?? this.props.ContainingCollectionDoc)!;
     }
@@ -129,10 +136,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
             <div
                 className="presItem-groupSlide"
                 onClick={e => {
-                    console.log('Clicked on slide with index: ', ind);
                     e.stopPropagation();
                     e.preventDefault();
-                    PresBox.Instance.modifierSelect(doc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey);
+                    this.presBoxView?.modifierSelect(doc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey);
                     this.presExpandDocumentClick();
                 }}>
                 <div className="presItem-groupNum">{`${ind + 1}.`}</div>
@@ -181,15 +187,15 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
         e.stopPropagation();
         e.preventDefault();
         if (element && !(e.ctrlKey || e.metaKey)) {
-            if (PresBox.Instance._selectedArray.has(this.rootDoc)) {
-                PresBox.Instance._selectedArray.size === 1 && PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false, false);
+            if (this.selectedArray?.has(this.rootDoc)) {
+                this.selectedArray.size === 1 && this.presBoxView?.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false, false);
                 setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
             } else {
                 setupMoveUpEvents(
                     this,
                     e,
                     (e: PointerEvent) => {
-                        PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false, false);
+                        this.presBoxView?.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false, false);
                         return this.startDrag(e);
                     },
                     emptyFunction,
@@ -205,8 +211,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
     startDrag = (e: PointerEvent) => {
         const miniView: boolean = this.toolbarWidth <= 100;
         const activeItem = this.rootDoc;
-        const dragArray = PresBox.Instance._dragArray;
-        const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray());
+        const dragArray = this.presBoxView?._dragArray ?? [];
+        const dragData = new DragManager.DocumentDragData(this.presBoxView?.sortArray() ?? []);
         if (!dragData.draggedDocuments.length) dragData.draggedDocuments.push(this.rootDoc);
         dragData.dropAction = 'move';
         dragData.treeViewDoc = this.props.docViewPath().lastElement()?.props.treeViewDoc;
@@ -221,7 +227,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
         } else if (dragArray.length >= 1) {
             const doc = document.createElement('div');
             doc.className = 'presItem-multiDrag';
-            doc.innerText = 'Move ' + PresBox.Instance._selectedArray.size + ' slides';
+            doc.innerText = 'Move ' + this.selectedArray?.size + ' slides';
             doc.style.position = 'absolute';
             doc.style.top = e.clientY + 'px';
             doc.style.left = e.clientX - 50 + 'px';
@@ -286,10 +292,11 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
     @undoBatch
     removeItem = action((e: React.MouseEvent) => {
         e.stopPropagation();
-        this.props.removeDocument?.(this.rootDoc);
-        if (PresBox.Instance._selectedArray.has(this.rootDoc)) {
-            PresBox.Instance._selectedArray.delete(this.rootDoc);
+        if (this.indexInPres < (this.presBoxView?.itemIndex || 0)) {
+            this.presBox.itemIndex = (this.presBoxView?.itemIndex || 0) - 1;
         }
+        this.props.removeDocument?.(this.rootDoc);
+        this.presBoxView?.removeFromSelectedArray(this.rootDoc);
         this.removeAllRecordingInOverlay();
     });
 
@@ -441,7 +448,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
     }
 
     @computed get mainItem() {
-        const isSelected: boolean = PresBox.Instance?._selectedArray.has(this.rootDoc);
+        const isSelected: boolean = this.selectedArray?.has(this.rootDoc) ? true : false;
         const toolbarWidth: number = this.toolbarWidth;
         const showMore: boolean = this.toolbarWidth >= 300;
         const miniView: boolean = this.toolbarWidth <= 110;
@@ -463,12 +470,12 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 onClick={e => {
                     e.stopPropagation();
                     e.preventDefault();
-                    PresBox.Instance.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey);
+                    this.presBoxView?.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey);
                     this.showRecording(activeItem);
                 }}
                 onDoubleClick={action(e => {
                     this.toggleProperties();
-                    PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true);
+                    this.presBoxView?.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true);
                 })}
                 onPointerOver={this.onPointerOver}
                 onPointerLeave={this.onPointerLeave}
@@ -542,21 +549,29 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                 </Tooltip>
                             )}
 
-                            {/* {this.indexInPres === 0 ? (null) : <Tooltip title={<><div className="dash-tooltip">{activeItem.groupWithUp ? "Ungroup" : "Group with up"}</div></>}>
-                                          <div className="slideButton"
-                                                onClick={() => activeItem.groupWithUp = !activeItem.groupWithUp}
-                                                style={{
-                                                      zIndex: 1000 - this.indexInPres,
-                                                      fontWeight: 700,
-                                                      backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : Colors.MEDIUM_BLUE : undefined,
-                                                      height: activeItem.groupWithUp ? 53 : 18,
-                                                      transform: activeItem.groupWithUp ? "translate(0, -17px)" : undefined
-                                                }}>
-                                                <div style={{ transform: activeItem.groupWithUp ? "rotate(180deg) translate(0, -17.5px)" : "rotate(0deg)" }}>
-                                                      <FontAwesomeIcon icon={"arrow-up"} onPointerDown={e => e.stopPropagation()} />
-                                                </div>
-                                          </div>
-                                    </Tooltip>} */}
+                            {this.indexInPres === 0 ? null : (
+                                <Tooltip
+                                    title={
+                                        <>
+                                            <div className="dash-tooltip">{activeItem.groupWithUp ? 'Ungroup' : 'Group with up'}</div>
+                                        </>
+                                    }>
+                                    <div
+                                        className="slideButton"
+                                        onClick={() => (activeItem.groupWithUp = !activeItem.groupWithUp)}
+                                        style={{
+                                            zIndex: 1000 - this.indexInPres,
+                                            fontWeight: 700,
+                                            backgroundColor: activeItem.groupWithUp ? (presColorBool ? presBoxColor : Colors.MEDIUM_BLUE) : undefined,
+                                            height: activeItem.groupWithUp ? 53 : 18,
+                                            transform: activeItem.groupWithUp ? 'translate(0, -17px)' : undefined,
+                                        }}>
+                                        <div style={{ transform: activeItem.groupWithUp ? 'rotate(180deg) translate(0, -17.5px)' : 'rotate(0deg)' }}>
+                                            <FontAwesomeIcon icon={'arrow-up'} onPointerDown={e => e.stopPropagation()} />
+                                        </div>
+                                    </div>
+                                </Tooltip>
+                            )}
                             <Tooltip
                                 title={
                                     <>
-- 
cgit v1.2.3-70-g09d2

