From 981f1f164d816e60312d50912acb8de89fbcd912 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 3 Jul 2020 13:10:44 +0800
Subject: highlight active presentation + UI Changes

---
 src/client/views/nodes/PresBox.tsx | 114 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 111 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 8818d375e..30b1e0058 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -20,6 +20,7 @@ import { PrefetchProxy } from "../../../fields/Proxy";
 import { ScriptField } from "../../../fields/ScriptField";
 import { Scripting } from "../../util/Scripting";
 import { InkingStroke } from "../InkingStroke";
+import { HighlightSpanKind } from "typescript";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -35,7 +36,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         super(props);
         if (!this.presElement) { // create exactly one presElmentBox template to use by any and all presentations.
             Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
-                title: "pres element template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data"
+                title: "pres element template", backgroundColor: "transparent", _xMargin: 0, _height: 20, isTemplateDoc: true, isTemplateForField: "data"
             }));
             // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement
             // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent
@@ -209,7 +210,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 this.layoutDoc.presStatus = true;
                 this.startPresentation(index);
             }
-
+            const heights: number[] = [];
+            this.childDocs.forEach(doc => {
+                if (doc.presExpandInlineButton) heights.push(155);
+                else heights.push(58);
+            });
+            let sum: number = 65;
+            for (let i = 0; i < this.itemIndex; i++) {
+                sum += heights[i];
+            }
+            const highlight = document.getElementById("presBox-hightlight");
+            if (this.itemIndex === 0 && highlight) highlight.style.top = "65";
+            else if (highlight) highlight.style.top = sum.toString();
+            if (this.childDocs[this.itemIndex].presExpandInlineButton && highlight) highlight.style.height = "156";
+            else if (highlight) highlight.style.height = "58";
+            console.log(highlight?.style.top);
+            console.log(highlight?.className);
+            console.log(sum);
             this.navigateToElement(this.childDocs[index], fromDoc);
             this.hideIfNotPresented(index);
             this.showAfterPresented(index);
@@ -296,9 +313,76 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) &&
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
 
+
+    @observable private transitionTools: boolean = false;
+    // For toggling transition toolbar
+    @action
+    toggleTransitionTools = () => this.transitionTools = !this.transitionTools
+
+    @undoBatch
+    @action
+    toolbarTest = () => {
+        const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
+        console.log("title: " + presTargetDoc.title);
+        console.log("index: " + this.itemIndex);
+    }
+
+    @observable private activeItem = this.itemIndex ? this.childDocs[this.itemIndex] : null;
+
+
+    /**
+    * The function that is called on click to turn zoom option of docs on/off.
+    */
+    @action
+    onZoomDocumentClick = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        activeItem.presZoomButton = !activeItem.presZoomButton;
+        if (activeItem.presZoomButton) {
+            activeItem.presNavButton = false;
+        }
+    }
+
+    /**
+     * The function that is called on click to turn navigation option of docs on/off.
+     */
+    @action
+    onNavigateDocumentClick = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        activeItem.presNavButton = !activeItem.presNavButton;
+        if (activeItem.presNavButton) {
+            activeItem.presZoomButton = false;
+        }
+    }
+
+    /**
+     * The function that is called on click to turn fading document after presented option on/off.
+     * It also makes sure that the option swithches from hide-after to this one, since both
+     * can't coexist.
+     */
+    @action
+    onFadeDocumentAfterPresentedClick = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        activeItem.presFadeButton = !activeItem.presFadeButton;
+        if (!activeItem.presFadeButton) {
+            if (targetDoc) {
+                targetDoc.opacity = 1;
+            }
+        } else {
+            activeItem.presHideAfterButton = false;
+            if (this.rootDoc.presStatus && targetDoc) {
+                targetDoc.opacity = 0.5;
+            }
+        }
+    }
+
+
     render() {
         // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
-        // const presOrderedDocs = DocListCast(this.rootDoc.presOrderedDocs);
+        // const presOrderedDocs = DocListCast(activeItem.presOrderedDocs);
         // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
         //     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
         // }
@@ -325,6 +409,30 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <FontAwesomeIcon icon={"arrow-right"} />
                 </div>
             </div>
+            <div className="presBox-highlight" id="presBox-hightlight" />
+            <div className="presBox-toolbar">
+                <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.toolbarTest} /></div>
+                <div className="toolbar-divider" />
+                <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.toolbarTest} /></div>
+                <div className="toolbar-button"><FontAwesomeIcon icon={"object-group"} onClick={this.toolbarTest} /></div>
+                <div className="toolbar-button"><FontAwesomeIcon icon={"eye"} onClick={this.toolbarTest} /></div>
+                <div className="toolbar-divider" />
+                <div className="toolbar-button" onClick={this.toggleTransitionTools}>
+                    Transitions <FontAwesomeIcon className="toolbar-dropdown" icon={"angle-down"} />
+                    <div className={`toolbar-transitionTools ${this.transitionTools ? "active" : ""}`} onPointerDown={e => e.stopPropagation()}>
+                        <div className="toolbar-transitionButtons">
+                            <button title="Zoom" className={`toolbar-transition ${this.activeItem?.presZoomButton ? "active" : ""}`} onClick={this.onZoomDocumentClick}><FontAwesomeIcon className="toolbar-icon" icon={"search-plus"} onPointerDown={e => e.stopPropagation()} />Zoom</button>
+                            <button title="Navigate" className={`toolbar-transition ${this.activeItem?.presNavButton ? "active" : ""}`} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon className="toolbar-icon" icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} />Navigate</button>
+                            <button title="Fade After" className={`toolbar-transition ${this.activeItem?.presFadeButton ? "active" : ""}`} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon className="toolbar-icon" icon={"file-download"} onPointerDown={e => e.stopPropagation()} /> Fade After</button>
+                            {/* <button title="Hide After" className={pbi + (this.rootDoc.presHideAfterButton ? "-selected" : "")} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button> */}
+                            {/* <button title="Hide Before" className={pbi + (this.rootDoc.presHideTillShownButton ? "-selected" : "")} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={"file"} onPointerDown={e => e.stopPropagation()} /></button>
+                            <button title="Group With Up" className={pbi + (this.rootDoc.presGroupButton ? "-selected" : "")} onClick={e => { e.stopPropagation(); this.rootDoc.presGroupButton = !this.rootDoc.presGroupButton; }}><FontAwesomeIcon icon={"arrow-up"} onPointerDown={e => e.stopPropagation()} /></button>
+                            <button title="Progressivize" className={pbi + (this.rootDoc.pres ? "-selected" : "")} onClick={this.progressivize}><FontAwesomeIcon icon={"tasks"} onPointerDown={e => e.stopPropagation()} /></button> */}
+                        </div>
+                    </div>
+                </div>
+                <div className="toolbar-divider" />
+            </div>
             <div className="presBox-listCont" >
                 {mode !== CollectionViewType.Invalid ?
                     <CollectionView {...this.props}
-- 
cgit v1.2.3-70-g09d2


From 2c04b0ae3689d931675151acbec24c88ea00daa1 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Sat, 4 Jul 2020 02:01:32 +0800
Subject: transition speed + viewLinks

---
 src/client/documents/Documents.ts                  |  1 +
 .../views/collections/CollectionStackingView.tsx   |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  3 +-
 src/client/views/nodes/PresBox.tsx                 | 36 ++++++++++++++++++++--
 4 files changed, 38 insertions(+), 4 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 9feee0d47..b6c453847 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -128,6 +128,7 @@ export interface DocumentOptions {
     currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide)
     lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide)
     activeFrame?: number; // the active frame of a document in a frame base collection
+    presTransition?: number; //the time taken for the transition TO a document
     borderRounding?: string;
     boxShadow?: string;
     dontRegisterChildViews?: boolean;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 7bdf5e7df..8bd32b81f 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -184,7 +184,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
         if (found) {
             const top = found.getBoundingClientRect().top;
             const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top);
-            smoothScroll(500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
+            smoothScroll(doc.presTransition ? Number(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
         }
         afterFocus && setTimeout(() => {
             if (afterFocus?.()) { }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 546a4307c..e2d4d4459 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -910,7 +910,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             //     !doc.z && NumCast(this.layoutDoc.scale) < 1 && this.scaleAtPt(DocumentView._focusHack, 1); // [NumCast(doc.x), NumCast(doc.y)], 1);
             // } else {
             if (DocListCast(this.dataDoc[this.props.fieldKey]).includes(doc)) {
-                if (!doc.z) this.setPan(newPanX, newPanY, "transform 500ms", 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
+                // glr: freeform transform speed can be set through user by adjusting for presentation transform
+                if (!doc.z) this.setPan(newPanX, newPanY, doc.presTransition ? `transform ${doc.presTransition}ms` : "transform 500ms", 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
             }
             Doc.BrushDoc(this.props.Document);
             this.props.focus(this.props.Document);
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 30b1e0058..736551443 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -9,7 +9,7 @@ import { returnFalse, returnOne } from "../../../Utils";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
+import { CollectionDockingView, DockedFrameRenderer } from "../collections/CollectionDockingView";
 import { CollectionView, CollectionViewType } from "../collections/CollectionView";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./PresBox.scss";
@@ -21,6 +21,7 @@ import { ScriptField } from "../../../fields/ScriptField";
 import { Scripting } from "../../util/Scripting";
 import { InkingStroke } from "../InkingStroke";
 import { HighlightSpanKind } from "typescript";
+import { SearchUtil } from "../../util/SearchUtil";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -327,6 +328,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         console.log("index: " + this.itemIndex);
     }
 
+    @undoBatch
+    @action
+    viewLinks = () => {
+        const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
+        console.log(SearchUtil.GetContextsOfDocument(presTargetDoc));
+        console.log(DocListCast(presTargetDoc.context));
+        console.log(DocumentManager.Instance.getAllDocumentViews(presTargetDoc));
+
+        // if (!DocumentManager.Instance.getDocumentView(curPres)) {
+        //     CollectionDockingView.AddRightSplit(curPres);
+        // }
+    }
+
     @observable private activeItem = this.itemIndex ? this.childDocs[this.itemIndex] : null;
 
 
@@ -379,6 +393,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    // @computed
+    // transitionTimer = (doc: Doc) => {
+    //     const slider: HTMLInputElement = document.getElementById("toolbar-slider");
+    //     // let output = document.getElementById("demo");
+    //     // if (output && slider) output.innerHTML = slider.value; // Display the default slider value
+    //     const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+    //     const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+    //     targetDoc.presTransition = slider ? (Number(slider.value) * 1000) : 0.5;
+    // }
+
+    setTransitionTime = (number: String) => {
+        const timeInMS = Number(number) * 1000;
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        if (targetDoc) targetDoc.presTransition = timeInMS;
+    }
+
 
     render() {
         // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
@@ -413,7 +444,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             <div className="presBox-toolbar">
                 <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.toolbarTest} /></div>
                 <div className="toolbar-divider" />
-                <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.toolbarTest} /></div>
+                <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.viewLinks} /></div>
                 <div className="toolbar-button"><FontAwesomeIcon icon={"object-group"} onClick={this.toolbarTest} /></div>
                 <div className="toolbar-button"><FontAwesomeIcon icon={"eye"} onClick={this.toolbarTest} /></div>
                 <div className="toolbar-divider" />
@@ -424,6 +455,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <button title="Zoom" className={`toolbar-transition ${this.activeItem?.presZoomButton ? "active" : ""}`} onClick={this.onZoomDocumentClick}><FontAwesomeIcon className="toolbar-icon" icon={"search-plus"} onPointerDown={e => e.stopPropagation()} />Zoom</button>
                             <button title="Navigate" className={`toolbar-transition ${this.activeItem?.presNavButton ? "active" : ""}`} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon className="toolbar-icon" icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} />Navigate</button>
                             <button title="Fade After" className={`toolbar-transition ${this.activeItem?.presFadeButton ? "active" : ""}`} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon className="toolbar-icon" icon={"file-download"} onPointerDown={e => e.stopPropagation()} /> Fade After</button>
+                            <input type="range" min="0.1" max="10" defaultValue="0.5" className="toolbar-slider" id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.setTransitionTime(e.target.value)} />
                             {/* <button title="Hide After" className={pbi + (this.rootDoc.presHideAfterButton ? "-selected" : "")} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button> */}
                             {/* <button title="Hide Before" className={pbi + (this.rootDoc.presHideTillShownButton ? "-selected" : "")} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={"file"} onPointerDown={e => e.stopPropagation()} /></button>
                             <button title="Group With Up" className={pbi + (this.rootDoc.presGroupButton ? "-selected" : "")} onClick={e => { e.stopPropagation(); this.rootDoc.presGroupButton = !this.rootDoc.presGroupButton; }}><FontAwesomeIcon icon={"arrow-up"} onPointerDown={e => e.stopPropagation()} /></button>
-- 
cgit v1.2.3-70-g09d2


From ec1f159d60695a3cc89327561f7c60c00a06366d Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Mon, 13 Jul 2020 16:18:46 +0800
Subject: highlights, readjusted view, keyboard events

---
 src/client/documents/Documents.ts                  |   1 +
 src/client/views/MainView.tsx                      |   5 +-
 src/client/views/nodes/FieldView.tsx               |   1 +
 src/client/views/nodes/PresBox.scss                | 477 +++++++++++++---
 src/client/views/nodes/PresBox.tsx                 | 611 +++++++++++++++++----
 .../views/presentationview/PresElementBox.scss     |  29 +-
 .../views/presentationview/PresElementBox.tsx      |  47 +-
 7 files changed, 949 insertions(+), 222 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 0e44a46d9..1aa3aef3e 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -131,6 +131,7 @@ export interface DocumentOptions {
     lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide)
     activeFrame?: number; // the active frame of a document in a frame base collection
     presTransition?: number; //the time taken for the transition TO a document
+    presDuration?: number; //the duration of the slide in presentation view
     borderRounding?: string;
     boxShadow?: string;
     dontRegisterChildViews?: boolean;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index e961e2e5c..440368a32 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -6,7 +6,7 @@ import {
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
     faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTimesCircle,
     faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight,
-    faAngleDown, faAngleUp, faSearchPlus
+    faAngleDown, faAngleUp, faSearchPlus, faPlayCircle, faClock, faRocket
 } from '@fortawesome/free-solid-svg-icons';
 import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -144,7 +144,8 @@ export class MainView extends React.Component {
             faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
             faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
             faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell,
-            faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight, faAngleDown, faAngleUp, faSearchPlus);
+            faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight,
+            faAngleDown, faAngleUp, faSearchPlus, faPlayCircle, faClock, faRocket);
         this.initEventListeners();
         this.initAuthenticationRouters();
     }
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index c57738361..b1132ce33 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -45,6 +45,7 @@ export interface FieldViewProps {
     whenActiveChanged: (isActive: boolean) => void;
     dontRegisterView?: boolean;
     focus: (doc: Doc) => void;
+    presMultiSelect?: (doc: Doc) => void; //added for selecting multiple documents in a presentation
     ignoreAutoHeight?: boolean;
     PanelWidth: () => number;
     PanelHeight: () => number;
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 9c2daf5d3..07e53fa94 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -19,16 +19,11 @@
         margin-top: 10px;
     }
 
-    .presBox-highlight {
-        position: absolute;
-        top: 0;
-        height: 0;
-        width: 100%;
-        margin-top: 10px;
-        background-color: #ffe4b3;
+    .presBox-toolbar {
+        display: none;
     }
 
-    .presBox-toolbar {
+    .presBox-toolbar.active {
         position: relative;
         display: inline-flex;
         align-items: center;
@@ -43,115 +38,437 @@
             letter-spacing: 0;
             display: flex;
             align-items: center;
+            transition: 0.5s;
 
-            .toolbar-dropdown {
-                margin-left: 5px;
+            @media only screen and (max-width: 400) {
+                .toolbar-buttonText {
+                    display: none;
+                }
             }
+        }
 
-            .toolbar-transitionTools {
-                display: none;
-            }
+        .toolbar-button.active {
+            color: #AEDDF8;
+        }
 
-            .toolbar-transitionTools.active {
-                position: absolute;
-                display: block;
-                top: 30px;
-                transform: translate(-10px, 0px);
-                border-top: solid 3px grey;
-                background-color: #323232;
-                width: 105px;
-                height: max-content;
-                z-index: 100;
-
-                .toolbar-transitionButtons {
-                    display: block;
-
-                    .toolbar-transition {
-                        display: flex;
-                        font-size: 10;
-                        width: 100;
-                        background-color: rgba(0, 0, 0, 0);
-                        min-width: max-content;
-
-                        .toolbar-icon {
-                            margin-right: 5px;
-                        }
-                    }
+        .toolbar-transitionButtons {
+            display: block;
+
+            .toolbar-transition {
+                display: flex;
+                font-size: 10;
+                width: 100;
+                background-color: rgba(0, 0, 0, 0);
+                min-width: max-content;
+
+                .toolbar-icon {
+                    margin-right: 5px;
                 }
             }
         }
+    }
+
+    .toolbar-moreInfo {
+        position: absolute;
+        right: 5px;
+        display: flex;
+        width: max-content;
+        height: 25px;
+        /* background-color: pink; */
+        justify-content: center;
+        transform: rotate(90deg);
+        align-items: center;
+        transition: 0.7s ease;
 
-        .toolbar-divider {
-            border-left: 1px solid white;
-            height: 80%;
+        .toolbar-moreInfoBall {
+            width: 4px;
+            height: 4px;
+            border-radius: 100%;
+            background-color: white;
+            margin: 1px;
+            position: relative;
         }
     }
 
-    .presBox-buttons {
+    .toolbar-moreInfo.active {
+        transform: rotate(0deg);
+    }
+
+    .toolbar-divider {
+        border-left: solid #ffffff70 0.5px;
+        height: 20px;
+    }
+}
+
+.dropdown {
+    font-size: 10;
+    margin-left: 5px;
+    color: darkgrey;
+    transition: 0.5s ease;
+}
+
+.dropdown.active {
+    transform: rotate(180deg);
+    color: #AEDDF8;
+    opacity: 0.8;
+}
+
+.presBox-ribbon {
+    position: relative;
+    display: none;
+    background-color: white;
+    color: black;
+    width: 100%;
+    height: 0;
+    z-index: 100;
+    transition: 0.7s;
+
+    .toolbar-slider {
         position: relative;
+        -webkit-appearance: none;
+        transform: rotateY(180deg);
+        background-color: #40B3D8;
+        margin-top: 1px;
         width: 100%;
-        background: gray;
-        padding-top: 5px;
-        padding-bottom: 5px;
+        max-width: 100px;
+        height: 2.5px;
+        left: 0px;
+    }
+
+    .toolbar-slider:focus {
+        outline: none;
+    }
+
+    .toolbar-slider::-webkit-slider-thumb {
+        -webkit-appearance: none;
+        background-color: #40B3D8;
+        border: 1px white solid;
+        border-radius: 100%;
+        width: 9px;
+        height: 9px;
+    }
+
+    .slider-headers {
+        position: relative;
         display: grid;
-        grid-column-end: 4;
-        grid-column-start: 1;
+        justify-content: space-between;
+        width: 100%;
+        grid-template-columns: auto auto auto;
+        grid-template-rows: auto;
+        font-weight: 100;
+        margin-top: 5px;
+        font-size: 8px;
+    }
 
-        .presBox-viewPicker {
-            height: 25;
-            position: relative;
-            display: inline-block;
-            grid-column: 1/2;
-            min-width: 15px;
+    .slider-value {
+        font-size: 10;
+        position: relative;
+    }
+
+    .slider-value.none,
+    .slider-headers.none,
+    .toolbar-slider.none {
+        display: none;
+    }
+
+    .dropdown-header {
+        padding-bottom: 10px;
+        font-weight: 800;
+        text-align: center;
+        font-size: 16;
+        width: 90%;
+        color: black;
+        transform: translate(5%, 0px);
+        border-bottom: solid 2px darkgrey;
+    }
+
+
+    .ribbon-textInput {
+        border-radius: 2px;
+        height: 25px;
+        font-size: 10;
+        font-weight: 100;
+        align-self: center;
+        justify-self: center;
+        padding-left: 10px;
+        border: solid 1px black;
+        width: 100%;
+    }
+
+    .ribbon-final-box {
+        align-self: flex-start;
+        display: grid;
+        grid-template-rows: auto auto;
+        padding-left: 10px;
+        padding-right: 10px;
+        letter-spacing: normal;
+        width: max-content;
+        font-size: 13;
+        font-weight: 600;
+        position: relative;
+
+        .selectedList {
+            display: block;
+            min-width: 50;
+            max-width: 120;
+            height: 70;
+            overflow-y: scroll;
+
+            .selectedList-items {
+                font-size: 7;
+                font-weight: normal;
+            }
         }
 
-        select {
-            background: #323232;
+
+        .ribbon-final-button {
+            position: relative;
+            font-size: 10;
+            font-weight: normal;
+            letter-spacing: normal;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-bottom: 5px;
+            height: 25px;
             color: white;
+            width: 100%;
+            max-width: 120;
+            padding-left: 10;
+            padding-right: 10;
+            border-radius: 10px;
+            background-color: #979797;
         }
+    }
 
-        .presBox-button {
-            margin-right: 2.5%;
-            margin-left: 2.5%;
-            height: 25px;
-            border-radius: 5px;
+    .ribbon-box {
+        display: grid;
+        grid-template-rows: max-content auto;
+        padding-left: 10px;
+        padding-right: 10px;
+        letter-spacing: normal;
+        width: max-content;
+        font-weight: 600;
+        position: relative;
+        font-size: 13;
+        border-right: solid 2px darkgrey;
+
+        .ribbon-button {
+            font-size: 10;
+            font-weight: 200;
+            height: 25;
+            border: solid 1px black;
             display: flex;
+            border-radius: 10px;
+            margin-right: 5px;
+            width: max-content;
+            justify-content: center;
             align-items: center;
-            background: #323232;
-            color: white;
+            padding-right: 10px;
+            padding-left: 10px;
+        }
+
+        .ribbon-button.active {
+            background-color: #5B9FDD;
+        }
+
+        .ribbon-button:hover {
+            background-color: lightgrey;
+        }
+
+        .presBox-dropdown:hover {
+            border: solid 1px #378AD8;
+
+            .presBox-dropdownOption {
+                font-size: 10;
+                display: block;
+                padding-left: 5px;
+                margin-top: 3;
+                margin-bottom: 3;
+            }
+
+            .presBox-dropdownOption:hover {
+                position: relative;
+                background-color: lightgrey;
+            }
+
+            .presBox-dropdownOption.active {
+                position: relative;
+                background-color: #9CE2F8;
+            }
+
+            .presBox-dropdownOptions {
+                position: absolute;
+                top: 19px;
+                left: -1px;
+                z-index: 200;
+                width: 85%;
+                display: block;
+                background: #FFFFFF;
+                border: 0.5px solid #979797;
+                box-sizing: border-box;
+                box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
+            }
 
-            svg {
-                margin: auto;
+            .presBox-dropdownIcon {
+                color: #378AD8;
             }
         }
 
-        .collectionViewBaseChrome-viewPicker {
-            min-width: 50;
-            width: 5%;
-            height: 25;
+        .presBox-dropdown {
+            display: grid;
+            grid-template-columns: auto 20%;
             position: relative;
-            display: inline-block;
+            border: solid 1px black;
+            font-size: 10;
+            height: 20;
+            padding-left: 5px;
+            align-items: center;
+            margin-top: 5px;
+            margin-bottom: 5px;
+            font-weight: 200;
+            width: 100%;
+            min-width: max-content;
+            max-width: 120;
+            overflow: visible;
+
+            .presBox-dropdownOptions {
+                display: none;
+            }
+
+            .presBox-dropdownIcon {
+                position: relative;
+                color: black;
+                align-self: center;
+                justify-self: center;
+            }
         }
     }
+}
 
-    .presBox-backward,
-    .presBox-forward {
-        width: 25px;
-        border-radius: 5px;
-        top: 50%;
-        position: absolute;
+.presBox-ribbon.active {
+    display: inline-flex;
+    height: 100px;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    border: solid 1px black;
+}
+
+
+
+.dropdown-play {
+    top: 32px;
+    transform: translate(-28%, 0px);
+    /* left: 0; */
+    display: none;
+    border-radius: 5px;
+    width: 100px;
+    height: 100px;
+    z-index: 200;
+    background-color: black;
+    position: absolute;
+}
+
+.dropdown-play.active {
+    display: flex;
+}
+
+.presBox-buttons {
+    position: relative;
+    width: 100%;
+    background: gray;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    display: grid;
+    grid-template-columns: auto auto;
+
+    .presBox-viewPicker {
+        height: 25;
+        position: relative;
         display: inline-block;
+        grid-column: 1;
+        border-radius: 5px;
+        min-width: 15px;
+        max-width: 100px;
     }
 
-    .presBox-backward {
-        left: 5;
+    .presBox-presentPanel {
+        display: flex;
+        justify-self: end;
+        width: 100%;
+
     }
 
-    .presBox-forward {
-        right: 5;
+    select {
+        background: #323232;
+        color: white;
+    }
+
+    .presBox-button {
+        margin-right: 2.5px;
+        margin-left: 2.5px;
+        height: 25px;
+        border-radius: 5px;
+        display: none;
+        justify-content: center;
+        align-content: center;
+        align-items: center;
+        text-align: center;
+        letter-spacing: normal;
+        width: inherit;
+        background: #323232;
+        color: white;
+    }
+
+    .presBox-button.active {
+        display: flex;
+    }
+
+    .presBox-button.edit {
+        display: flex;
+        max-width: 25px;
+    }
+
+    .presBox-button.present {
+        display: flex;
+        min-width: 100px;
+        width: 100px;
+        position: absolute;
+        right: 0px;
+
+        .present-icon {
+            margin-right: 7px;
+        }
+    }
+
+
+
+    .collectionViewBaseChrome-viewPicker {
+        min-width: 50;
+        width: 5%;
+        height: 25;
+        position: relative;
+        display: inline-block;
     }
 }
 
+.presBox-backward,
+.presBox-forward {
+    width: 25px;
+    border-radius: 5px;
+    top: 50%;
+    position: absolute;
+    display: inline-block;
+}
+
+.presBox-backward {
+    left: 5;
+}
+
+.presBox-forward {
+    right: 5;
+}
+
 // CSS adjusted for mobile devices
 @media only screen and (max-device-width: 480px) {
     .presBox-cont .presBox-buttons {
@@ -197,4 +514,4 @@
     .select {
         font-size: 100%;
     }
-}
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 736551443..abf97142e 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -14,7 +14,7 @@ import { CollectionView, CollectionViewType } from "../collections/CollectionVie
 import { FieldView, FieldViewProps } from './FieldView';
 import "./PresBox.scss";
 import { ViewBoxBaseComponent } from "../DocComponent";
-import { makeInterface } from "../../../fields/Schema";
+import { makeInterface, listSpec } from "../../../fields/Schema";
 import { Docs } from "../../documents/Documents";
 import { PrefetchProxy } from "../../../fields/Proxy";
 import { ScriptField } from "../../../fields/ScriptField";
@@ -22,6 +22,8 @@ import { Scripting } from "../../util/Scripting";
 import { InkingStroke } from "../InkingStroke";
 import { HighlightSpanKind } from "typescript";
 import { SearchUtil } from "../../util/SearchUtil";
+import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
+import { child } from "serializr";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -29,15 +31,17 @@ const PresBoxDocument = makeInterface(documentSchema);
 @observer
 export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>(PresBoxDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
+    static Instance: PresBox;
     @observable _isChildActive = false;
     @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); }
     @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); }
     @computed get presElement() { return Cast(Doc.UserDoc().presElement, Doc, null); }
     constructor(props: any) {
         super(props);
+        PresBox.Instance = this;
         if (!this.presElement) { // create exactly one presElmentBox template to use by any and all presentations.
             Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
-                title: "pres element template", backgroundColor: "transparent", _xMargin: 0, _height: 20, isTemplateDoc: true, isTemplateForField: "data"
+                title: "pres element template", backgroundColor: "transparent", _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data"
             }));
             // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement
             // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent
@@ -53,7 +57,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.rootDoc.presBox = this.rootDoc;
         this.rootDoc._forceRenderEngine = "timeline";
         this.rootDoc._replacedChrome = "replaced";
+        this.layoutDoc.presStatus = "edit";
+        document.addEventListener("keydown", this.keyEvents, false);
     }
+
+    componentWillUnmount() {
+        document.removeEventListener("keydown", this.keyEvents, false);
+    }
+
     updateCurrentPresentation = () => Doc.UserDoc().activePresentation = this.rootDoc;
 
     @undoBatch
@@ -148,7 +159,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     /**
      * This method makes sure that cursor navigates to the element that
      * has the option open and last in the group. If not in the group, and it has
-     * te option open, navigates to that element.
+     * the option open, navigates to that element.
      */
     navigateToElement = async (curDoc: Doc, fromDocIndex: number) => {
         this.updateCurrentPresentation();
@@ -203,47 +214,57 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (index >= 0 && index < this.childDocs.length) {
             this.rootDoc._itemIndex = index;
             const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
-            if (presTargetDoc.lastFrame !== undefined) {
+            if (presTargetDoc?.lastFrame !== undefined) {
                 presTargetDoc.currentFrame = 0;
             }
-
-            if (!this.layoutDoc.presStatus) {
-                this.layoutDoc.presStatus = true;
-                this.startPresentation(index);
-            }
-            const heights: number[] = [];
-            this.childDocs.forEach(doc => {
-                if (doc.presExpandInlineButton) heights.push(155);
-                else heights.push(58);
-            });
-            let sum: number = 65;
-            for (let i = 0; i < this.itemIndex; i++) {
-                sum += heights[i];
-            }
-            const highlight = document.getElementById("presBox-hightlight");
-            if (this.itemIndex === 0 && highlight) highlight.style.top = "65";
-            else if (highlight) highlight.style.top = sum.toString();
-            if (this.childDocs[this.itemIndex].presExpandInlineButton && highlight) highlight.style.height = "156";
-            else if (highlight) highlight.style.height = "58";
-            console.log(highlight?.style.top);
-            console.log(highlight?.className);
-            console.log(sum);
+            // if (this.layoutDoc.presStatus === "edit") {
+            //     this.layoutDoc.presStatus = true;
+            //     this.startPresentation(index);
+            // }
             this.navigateToElement(this.childDocs[index], fromDoc);
             this.hideIfNotPresented(index);
             this.showAfterPresented(index);
         }
     });
 
+
+    @observable _presTimer!: NodeJS.Timeout;
+
     //The function that starts or resets presentaton functionally, depending on status flag.
+    @action
     startOrResetPres = () => {
         this.updateCurrentPresentation();
-        if (this.layoutDoc.presStatus) {
-            this.resetPresentation();
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        if (this._presTimer && this.layoutDoc.presStatus === "auto") {
+            clearInterval(this._presTimer);
+            this.layoutDoc.presStatus = "manual";
         } else {
-            this.layoutDoc.presStatus = true;
-            this.startPresentation(0);
-            this.gotoDocument(0, this.itemIndex);
+            this.layoutDoc.presStatus = "auto";
+            // this.startPresentation(0);
+            // this.gotoDocument(0, this.itemIndex);
+            this._presTimer = setInterval(() => {
+                if (this.itemIndex + 1 < this.childDocs.length) this.next();
+                else {
+                    clearInterval(this._presTimer);
+                    this.layoutDoc.presStatus = "manual";
+                }
+            }, activeItem.presDuration ? NumCast(activeItem.presDuration) : 2000);
+            // for (let i = this.itemIndex + 1; i <= this.childDocs.length; i++) {
+            //     if (this.itemIndex + 1 === this.childDocs.length) {
+            //         clearTimeout(this._presTimer);
+            //         this.layoutDoc.presStatus = "manual";
+            //     } else timer = setTimeout(() => { console.log(i); this.next(); }, i * 2000);
+            // }
+
         }
+
+        // if (this.layoutDoc.presStatus) {
+        //     this.resetPresentation();
+        // } else {
+        //     this.layoutDoc.presStatus = true;
+        //     this.startPresentation(0);
+        //     this.gotoDocument(0, this.itemIndex);
+        // }
     }
 
     //The function that resets the presentation by removing every action done by it. It also
@@ -252,7 +273,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.updateCurrentPresentation();
         this.childDocs.forEach(doc => (doc.presentationTargetDoc as Doc).opacity = 1);
         this.rootDoc._itemIndex = 0;
-        this.layoutDoc.presStatus = false;
+        // this.layoutDoc.presStatus = false;
     }
 
     //The function that starts the presentation, also checking if actions should be applied
@@ -297,6 +318,39 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.updateMinimize(e, this.rootDoc._viewType = viewType);
     });
 
+    @undoBatch
+    movementChanged = action((movement: string) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        if (movement === 'zoom') {
+            activeItem.presZoomButton = !activeItem.presZoomButton;
+            activeItem.presNavButton = false;
+        } else if (movement === 'nav') {
+            activeItem.presZoomButton = false;
+            activeItem.presNavButton = !activeItem.presNavButton;
+        } else {
+            activeItem.presZoomButton = false;
+            activeItem.presNavButton = false;
+        }
+    });
+
+    @undoBatch
+    visibilityChanged = action((visibility: string) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        if (visibility === 'fade') {
+            activeItem.presFadeButton = !activeItem.presFadeButton;
+        } else if (visibility === 'hideBefore') {
+            activeItem.presHideTillShownButton = !activeItem.presHideTillShownButton;
+            activeItem.presHideAfterButton = false;
+        } else if (visibility === 'hideAfter') {
+            activeItem.presHideAfterButton = !activeItem.presHideAfterButton;
+            activeItem.presHideAfterButton = false;
+        } else {
+            activeItem.presHideAfterButton = false;
+            activeItem.presHideTillShownButton = false;
+            activeItem.presFadeButton = false;
+        }
+    });
+
     whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
     addDocumentFilter = (doc: Doc | Doc[]) => {
         const docs = doc instanceof Doc ? [doc] : doc;
@@ -308,17 +362,124 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
     childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement;
     removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc);
-    selectElement = (doc: Doc) => this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex));
     getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
     panelHeight = () => this.props.PanelHeight() - 20;
     active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) &&
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
 
 
+    // KEYS
+    @observable _selectedArray: Doc[] = [];
+
+    @computed get listOfSelected() {
+        const list = this._selectedArray.map((doc: Doc, index: any) => {
+            return (
+                <div className="selectedList-items">{index + 1}.  {doc.title}</div>
+            );
+        });
+        return list;
+    }
+
+    //Regular click
+    @action
+    selectElement = (doc: Doc) => {
+        this._selectedArray = [];
+        this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex));
+        this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
+        console.log(this._selectedArray);
+    }
+
+    //Command click
+    @action
+    multiSelect = (doc: Doc) => {
+        this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
+        console.log(this._selectedArray);
+    }
+
+    //Shift click
+    @action
+    shiftSelect = (doc: Doc) => {
+        this._selectedArray = [];
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        if (activeItem) {
+            for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) {
+                this._selectedArray.push(this.childDocs[i]);
+            }
+        }
+        console.log(this._selectedArray);
+    }
+
+
+
+    //Esc click
+    @action
+    keyEvents = (e: KeyboardEvent) => {
+        e.stopPropagation;
+        // Escape key
+        if (e.keyCode === 27) {
+            if (this.layoutDoc.presStatus === "edit") this._selectedArray = [];
+            else this.layoutDoc.presStatus = "edit";
+            // Ctrl-A to select all
+        } else if ((e.metaKey || e.altKey) && e.keyCode === 65) {
+            this._selectedArray = this.childDocs;
+        }
+    }
+
+
     @observable private transitionTools: boolean = false;
+    @observable private newDocumentTools: boolean = false;
+    @observable private progressivizeTools: boolean = false;
+    @observable private moreInfoTools: boolean = false;
+    @observable private playTools: boolean = false;
+
     // For toggling transition toolbar
-    @action
-    toggleTransitionTools = () => this.transitionTools = !this.transitionTools
+    @action toggleTransitionTools = () => {
+        this.transitionTools = !this.transitionTools;
+        this.newDocumentTools = false;
+        this.progressivizeTools = false;
+        this.moreInfoTools = false;
+        this.playTools = false;
+    }
+    // For toggling the add new document dropdown
+    @action toggleNewDocument = () => {
+        this.newDocumentTools = !this.newDocumentTools;
+        this.transitionTools = false;
+        this.progressivizeTools = false;
+        this.moreInfoTools = false;
+        this.playTools = false;
+    }
+    // For toggling the tools for progressivize
+    @action toggleProgressivize = () => {
+        this.progressivizeTools = !this.progressivizeTools;
+        this.transitionTools = false;
+        this.newDocumentTools = false;
+        this.moreInfoTools = false;
+        this.playTools = false;
+    }
+    // For toggling the tools for more info
+    @action toggleMoreInfo = () => {
+        this.moreInfoTools = !this.moreInfoTools;
+        this.transitionTools = false;
+        this.newDocumentTools = false;
+        this.progressivizeTools = false;
+        this.playTools = false;
+    }
+    // For toggling the options when the user wants to select play
+    @action togglePlay = () => {
+        this.playTools = !this.playTools;
+        this.transitionTools = false;
+        this.newDocumentTools = false;
+        this.progressivizeTools = false;
+        this.moreInfoTools = false;
+    }
+
+    @action toggleAllDropdowns() {
+        this.transitionTools = false;
+        this.newDocumentTools = false;
+        this.progressivizeTools = false;
+        this.moreInfoTools = false;
+        this.playTools = false;
+    }
 
     @undoBatch
     @action
@@ -330,46 +491,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     @undoBatch
     @action
-    viewLinks = () => {
-        const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
-        console.log(SearchUtil.GetContextsOfDocument(presTargetDoc));
-        console.log(DocListCast(presTargetDoc.context));
-        console.log(DocumentManager.Instance.getAllDocumentViews(presTargetDoc));
+    viewLinks = async () => {
+        let docToJump = this.childDocs[0];
+        // console.log(SearchUtil.GetContextsOfDocument(presTargetDoc));
+        // console.log(DocListCast(presTargetDoc.context));
+        // console.log(DocumentManager.Instance.getAllDocumentViews(presTargetDoc));
+        const aliasOf = await DocCastAsync(docToJump.aliasOf);
+        const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
+        console.log(srcContext?.title);
+        const viewType = srcContext?._viewType;
+        const fit = srcContext?._fitToBox;
+        if (srcContext) {
+            srcContext._fitToBox = true;
+            srcContext._viewType = "freeform";
+        }
 
         // if (!DocumentManager.Instance.getDocumentView(curPres)) {
         //     CollectionDockingView.AddRightSplit(curPres);
         // }
     }
 
-    @observable private activeItem = this.itemIndex ? this.childDocs[this.itemIndex] : null;
-
-
-    /**
-    * The function that is called on click to turn zoom option of docs on/off.
-    */
-    @action
-    onZoomDocumentClick = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        activeItem.presZoomButton = !activeItem.presZoomButton;
-        if (activeItem.presZoomButton) {
-            activeItem.presNavButton = false;
-        }
-    }
-
-    /**
-     * The function that is called on click to turn navigation option of docs on/off.
-     */
-    @action
-    onNavigateDocumentClick = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        activeItem.presNavButton = !activeItem.presNavButton;
-        if (activeItem.presNavButton) {
-            activeItem.presZoomButton = false;
-        }
-    }
-
     /**
      * The function that is called on click to turn fading document after presented option on/off.
      * It also makes sure that the option swithches from hide-after to this one, since both
@@ -387,21 +528,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             }
         } else {
             activeItem.presHideAfterButton = false;
-            if (this.rootDoc.presStatus && targetDoc) {
+            if (this.rootDoc.presStatus !== "edit" && targetDoc) {
                 targetDoc.opacity = 0.5;
             }
         }
     }
 
-    // @computed
-    // transitionTimer = (doc: Doc) => {
-    //     const slider: HTMLInputElement = document.getElementById("toolbar-slider");
-    //     // let output = document.getElementById("demo");
-    //     // if (output && slider) output.innerHTML = slider.value; // Display the default slider value
-    //     const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-    //     const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-    //     targetDoc.presTransition = slider ? (Number(slider.value) * 1000) : 0.5;
-    // }
+    @action
+    dropdownToggle = (menu: string) => {
+        console.log('presBox' + menu + 'Dropdown');
+        const dropMenu = document.getElementById('presBox' + menu + 'Dropdown');
+        console.log(dropMenu);
+        console.log(dropMenu?.style.display);
+        if (dropMenu) dropMenu.style.display === 'none' ? dropMenu.style.display = 'block' : dropMenu.style.display = 'none';
+    }
 
     setTransitionTime = (number: String) => {
         const timeInMS = Number(number) * 1000;
@@ -410,13 +550,249 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (targetDoc) targetDoc.presTransition = timeInMS;
     }
 
+    @computed get transitionDropdown() {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+
+        if (activeItem) {
+            const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+            const transitionSpeed = targetDoc ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
+            const visibilityTime = targetDoc ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
+            const thumbLocation = String(-9.48 * Number(transitionSpeed) + 93);
+            const movement = activeItem.presZoomButton ? 'Zoom' : activeItem.presNavbutton ? 'Navigate' : 'None';
+            const visibility = activeItem.presFadeButton ? 'Fade' : activeItem.presHideTillShownButton ? 'Hide till shown' : activeItem.presHideAfter ? 'Hide on exit' : 'None';
+            return (
+                <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+                    <div className="ribbon-box">
+                        Movement
+                        <div className="presBox-dropdown"
+                            onPointerDown={e => e.stopPropagation()}
+                        // onClick={() => this.dropdownToggle('Movement')}
+                        >
+                            {movement}
+                            <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
+                            <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
+                                <div className={`presBox-dropdownOption ${!activeItem.presZoomButton && !activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presZoomButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Zoom</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Navigate</div>
+                            </div>
+                        </div>
+                        <div className={`slider-value ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} style={{ left: thumbLocation + '%' }}>{transitionSpeed}s</div>
+                        <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed} className={`toolbar-slider ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
+                        <div className={`slider-headers ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`}>
+                            <div className="slider-text">Slow</div>
+                            <div className="slider-text">Medium</div>
+                            <div className="slider-text">Fast</div>
+                        </div>
+                    </div>
+                    <div className="ribbon-box">
+                        Visibility
+                        <div className="presBox-dropdown"
+                            onPointerDown={e => e.stopPropagation()}
+                        // onClick={() => this.dropdownToggle('Movement')}
+                        >
+                            {visibility}
+                            <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
+                            <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
+                                <div className={`presBox-dropdownOption ${!activeItem.presFadeButton && !activeItem.presHideAfterButton && !activeItem.presHideTillShownButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.visibilityChanged('none')}>None</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presFadeButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.visibilityChanged('fade')}>Fade on exit</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presHideAfterButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.visibilityChanged('hideAfter')}>Hide on exit</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presHideTillShownButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.visibilityChanged('hideBefore')}>Hidden til presented</div>
+                            </div>
+                        </div>
+                        <div className={`slider-value ${activeItem.presFadeButton ? "" : "none"}`} style={{ left: thumbLocation + '%' }}>{transitionSpeed}s</div>
+                        <input type="range" step="0.1" min="0.1" max="10" value={visibilityTime} className={`toolbar-slider ${activeItem.presFadeButton ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
+                        <div className={`slider-headers ${activeItem.presFadeButton ? "" : "none"}`}>
+                            <div className="slider-text">Slow</div>
+                            <div className="slider-text">Medium</div>
+                            <div className="slider-text">Fast</div>
+                        </div>
+                        {/* <div title="Fade After" className={`ribbon-button ${activeItem.presFadeButton ? "active" : ""}`} onClick={this.onFadeDocumentAfterPresentedClick}>Fade After</div> */}
+                        {/* <div title="Hide After" className={`ribbon-button ${activeItem.presHideTillShownButton ? "active" : ""}`} onClick={() => console.log("hide before")}>Hide Before</div> */}
+                        {/* <div title="Hide Before" className={`ribbon-button ${activeItem.presHideAfterButton ? "active" : ""}`} onClick={() => console.log("hide after")}>Hide After</div> */}
+                    </div>
+                    <div className="ribbon-box">
+                        Effects
+                        <div className="presBox-dropdown"
+                            onPointerDown={e => e.stopPropagation()}
+                        // onClick={() => this.dropdownToggle('Movement')}
+                        >
+                            None
+                            <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
+                            <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
+                                <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()}>None</div>
+                            </div>
+                        </div>
+                    </div>
+                    <div className="ribbon-final-box">
+                        {this._selectedArray.length} selected
+                        <div className="selectedList">
+                            {this.listOfSelected}
+                        </div>
+                    </div>
+                    <div className="ribbon-final-box">
+                        <div className="ribbon-final-button">
+                            Apply to selected
+                        </div>
+                        <div className="ribbon-final-button">
+                            Apply to all
+                        </div>
+                    </div>
+                </div>
+            );
+        }
+    }
+
+    public inputRef = React.createRef<HTMLInputElement>();
+
+
+    createNewSlide = (title: string, type: string) => {
+        let doc = null;
+        if (type === "text") {
+            doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 400, title: title });
+            const data = Cast(this.rootDoc.data, listSpec(Doc));
+            if (data) data.push(doc);
+        } else {
+            doc = Docs.Create.FreeformDocument([], { _nativeWidth: 400, _width: 400, title: title });
+            const data = Cast(this.rootDoc.data, listSpec(Doc));
+            if (data) data.push(doc);
+        }
+    }
+
+    @computed get newDocumentDropdown() {
+        let type = "";
+        let title = "";
+        return (
+            <div>
+                <div className={`presBox-ribbon ${this.newDocumentTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+                    <div className="ribbon-box">
+                        Slide Title: <br></br>
+                        {/* <div className="dropdown-textInput"> */}
+                        <input className="ribbon-textInput" placeholder="..." type="text" name="fname" ref={this.inputRef} onChange={(e) => {
+                            e.stopPropagation();
+                            title = e.target.value;
+                        }}></input>
+                        {/* </div> */}
+                    </div>
+                    <div className="ribbon-box">
+                        Choose type:
+                        <div style={{ display: "flex", alignSelf: "center" }}>
+                            <div title="Text" className={`ribbon-button ${type === "text" ? "active" : ""}`} onClick={() => { type = "text"; }}>Text</div>
+                            <div title="Freeform" className={`ribbon-button ${type === "freeform" ? "active" : ""}`} onClick={() => { type = "freeform"; }}>Freeform</div>
+                        </div>
+                    </div>
+                    <div className="ribbon-final-box">
+                        <div className="ribbon-final-button" onClick={() => this.createNewSlide(title, type)}>
+                            Create New Slide
+                        </div>
+                    </div>
+                </div>
+            </div >
+        );
+    }
+
+    @computed get playDropdown() {
+        return (
+            <div className={`dropdown-play ${this.playTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+
+            </div>
+        );
+    }
+
+    @computed get progressivizeDropdown() {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        if (activeItem) {
+            return (
+                <div>
+                    <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+                        <div className="ribbon-box">
+                            <div title="Progressivize" className={`ribbon-button ${activeItem.presProgressivize ? "active" : ""}`} onClick={this.progressivize}>Progressivize Child Documents</div>
+                        </div>
+                        <div className="ribbon-box">
+                            Other progressivize features:
+                            <div title="Progressivize" className={"ribbon-button"}>Progressivize Text Bullet Points</div>
+                            <div title="Progressivize" className={"ribbon-button"}>Internal Navigation</div>
+                        </div>
+                    </div>
+                </div>
+            );
+        }
+    }
+
+    @action
+    progressivize = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        activeItem.presProgressivize = !activeItem.presProgressivize;
+        const rootTarget = Cast(activeItem.presentationTargetDoc, Doc, null);
+        const docs = DocListCast(rootTarget[Doc.LayoutFieldKey(rootTarget)]);
+        if (this.rootDoc.presProgressivize) {
+            rootTarget.currentFrame = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
+            rootTarget.lastFrame = docs.length - 1;
+        }
+    }
+
+    @computed get moreInfoDropdown() {
+        return (<div></div>);
+
+    }
+
+    @computed get toolbar() {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+
+        if (activeItem) {
+            return (
+                <>
+                    <div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={this.toggleNewDocument}><FontAwesomeIcon icon={"plus"} />
+                        <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
+                    </div>
+                    <div className="toolbar-divider" />
+                    <div className="toolbar-button"><FontAwesomeIcon title={"View Links"} icon={"object-group"} onClick={this.toolbarTest} /></div>
+                    <div className="toolbar-button"><FontAwesomeIcon title={"Portal"} icon={"eye"} onClick={this.viewLinks} /></div>
+                    <div className="toolbar-divider" />
+                    <div className={`toolbar-button ${this.transitionTools ? "active" : ""}`} onClick={this.toggleTransitionTools}>
+                        <FontAwesomeIcon icon={"rocket"} />
+                        <div className="toolbar-buttonText">&nbsp; Transitions</div>
+                        <FontAwesomeIcon className={`dropdown ${this.transitionTools ? "active" : ""}`} icon={"angle-down"} />
+                    </div>
+                    <div className="toolbar-divider" />
+                    <div className={`toolbar-button ${this.progressivizeTools ? "active" : ""}`} onClick={this.toggleProgressivize}>
+                        <FontAwesomeIcon icon={"tasks"} />
+                        <div className="toolbar-buttonText">&nbsp; Progressivize</div>
+                        <FontAwesomeIcon className={`dropdown ${this.progressivizeTools ? "active" : ""}`} icon={"angle-down"} />
+                    </div>
+                    <div className="toolbar-divider" />
+                    <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
+                        <div className={`toolbar-moreInfo ${this.moreInfoTools ? "active" : ""}`}>
+                            <div className="toolbar-moreInfoBall" />
+                            <div className="toolbar-moreInfoBall" />
+                            <div className="toolbar-moreInfoBall" />
+                        </div>
+                    </div>
+                </>
+            );
+        } else {
+            return (
+                <>
+                    <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.toggleNewDocument} />
+                        <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
+                    </div>
+                    <div className="toolbar-button">
+                        <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"thumbtack"} />
+                    </div>
+                    <div className="toolbar-button" onClick={this.toggleMoreInfo}>
+                        <div className="toolbar-moreInfo">
+                            <div className="toolbar-moreInfoBall" />
+                            <div className="toolbar-moreInfoBall" />
+                            <div className="toolbar-moreInfoBall" />
+                        </div>
+                    </div>
+                </>
+            );
+        }
+    }
 
     render() {
-        // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
-        // const presOrderedDocs = DocListCast(activeItem.presOrderedDocs);
-        // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
-        //     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
-        // }
         this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields 
         const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
         return <div className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
@@ -430,41 +806,33 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Time}>Time</option>
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel}>Slides</option>
                 </select>
-                <div className="presBox-button" title="Back" style={{ gridColumn: 2 }} onClick={this.back}>
-                    <FontAwesomeIcon icon={"arrow-left"} />
-                </div>
-                <div className="presBox-button" title={"Reset Presentation" + this.layoutDoc.presStatus ? "" : " From Start"} style={{ gridColumn: 3 }} onClick={this.startOrResetPres}>
-                    <FontAwesomeIcon icon={this.layoutDoc.presStatus ? "stop" : "play"} />
-                </div>
-                <div className="presBox-button" title="Next" style={{ gridColumn: 4 }} onClick={this.next}>
-                    <FontAwesomeIcon icon={"arrow-right"} />
-                </div>
-            </div>
-            <div className="presBox-highlight" id="presBox-hightlight" />
-            <div className="presBox-toolbar">
-                <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.toolbarTest} /></div>
-                <div className="toolbar-divider" />
-                <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.viewLinks} /></div>
-                <div className="toolbar-button"><FontAwesomeIcon icon={"object-group"} onClick={this.toolbarTest} /></div>
-                <div className="toolbar-button"><FontAwesomeIcon icon={"eye"} onClick={this.toolbarTest} /></div>
-                <div className="toolbar-divider" />
-                <div className="toolbar-button" onClick={this.toggleTransitionTools}>
-                    Transitions <FontAwesomeIcon className="toolbar-dropdown" icon={"angle-down"} />
-                    <div className={`toolbar-transitionTools ${this.transitionTools ? "active" : ""}`} onPointerDown={e => e.stopPropagation()}>
-                        <div className="toolbar-transitionButtons">
-                            <button title="Zoom" className={`toolbar-transition ${this.activeItem?.presZoomButton ? "active" : ""}`} onClick={this.onZoomDocumentClick}><FontAwesomeIcon className="toolbar-icon" icon={"search-plus"} onPointerDown={e => e.stopPropagation()} />Zoom</button>
-                            <button title="Navigate" className={`toolbar-transition ${this.activeItem?.presNavButton ? "active" : ""}`} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon className="toolbar-icon" icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} />Navigate</button>
-                            <button title="Fade After" className={`toolbar-transition ${this.activeItem?.presFadeButton ? "active" : ""}`} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon className="toolbar-icon" icon={"file-download"} onPointerDown={e => e.stopPropagation()} /> Fade After</button>
-                            <input type="range" min="0.1" max="10" defaultValue="0.5" className="toolbar-slider" id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => this.setTransitionTime(e.target.value)} />
-                            {/* <button title="Hide After" className={pbi + (this.rootDoc.presHideAfterButton ? "-selected" : "")} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button> */}
-                            {/* <button title="Hide Before" className={pbi + (this.rootDoc.presHideTillShownButton ? "-selected" : "")} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={"file"} onPointerDown={e => e.stopPropagation()} /></button>
-                            <button title="Group With Up" className={pbi + (this.rootDoc.presGroupButton ? "-selected" : "")} onClick={e => { e.stopPropagation(); this.rootDoc.presGroupButton = !this.rootDoc.presGroupButton; }}><FontAwesomeIcon icon={"arrow-up"} onPointerDown={e => e.stopPropagation()} /></button>
-                            <button title="Progressivize" className={pbi + (this.rootDoc.pres ? "-selected" : "")} onClick={this.progressivize}><FontAwesomeIcon icon={"tasks"} onPointerDown={e => e.stopPropagation()} /></button> */}
-                        </div>
+                <div className="presBox-presentPanel">
+                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title={"Reset Presentation" + this.layoutDoc.presStatus ? "" : " From Start"} style={{ gridColumn: 2 }} onClick={this.startOrResetPres}>
+                        <FontAwesomeIcon icon={"clock"} /> &nbsp;
+                        <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
+                        <div className="toolbar-divider" />
+                        <FontAwesomeIcon onClick={e => { e.stopPropagation; this.togglePlay(); }} className="dropdown" icon={"angle-down"} />
+                        {this.playDropdown}
+                    </div>
+                    <div className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`} title="Present" onClick={() => this.layoutDoc.presStatus = "manual"}>
+                        <FontAwesomeIcon className="present-icon" icon={"play-circle"} /> Present
+                    </div>
+                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title="Back" onClick={this.back}>
+                        <FontAwesomeIcon icon={"arrow-left"} />
+                    </div>
+                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title="Next" onClick={this.next}>
+                        <FontAwesomeIcon icon={"arrow-right"} />
+                    </div>
+                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "edit" : ""}`} title="Next" onClick={() => this.layoutDoc.presStatus = "edit"}>
+                        <FontAwesomeIcon icon={"times"} />
                     </div>
                 </div>
-                <div className="toolbar-divider" />
             </div>
+            <div className={`presBox-toolbar ${this.layoutDoc.presStatus === "edit" ? "active" : ""}`}> {this.toolbar} </div>
+            {this.newDocumentDropdown}
+            {this.moreInfoDropdown}
+            {this.transitionDropdown}
+            {this.progressivizeDropdown}
             <div className="presBox-listCont" >
                 {mode !== CollectionViewType.Invalid ?
                     <CollectionView {...this.props}
@@ -474,10 +842,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         moveDocument={returnFalse}
                         childOpacity={returnOne}
                         childLayoutTemplate={this.childLayoutTemplate}
-                        filterAddDocument={this.addDocumentFilter}
+                        filterAddDocument={returnFalse}
                         removeDocument={returnFalse}
                         dontRegisterView={true}
                         focus={this.selectElement}
+                        presMultiSelect={this.multiSelect}
                         ScreenToLocalTransform={this.getTransform} />
                     : (null)
                 }
@@ -493,3 +862,11 @@ Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, d
     if (field === 'presBox') return container;
     return undefined;
 });
+
+
+
+        // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
+        // const presOrderedDocs = DocListCast(activeItem.presOrderedDocs);
+        // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
+        //     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
+        // }
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 6d37ede8a..0e58d77a0 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -1,6 +1,9 @@
 .presElementBox-item {
-    display: inline-block;
-    background-color: #eeeeee;
+    display: grid;
+    grid-template-rows: max-content max-content max-content;
+    background-color: #d0d0d0;
+    box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
+    position: relative;
     pointer-events: all;
     width: 100%;
     height: 100%;
@@ -17,6 +20,15 @@
     padding: 0px;
     padding-bottom: 3px;
 
+    .presElementBox-highlight {
+        position: absolute;
+        transform: translate(-100px, -6px);
+        z-index: -1;
+        width: calc(100% + 200px);
+        height: calc(100% + 12px);
+        background-color: #AEDDF8;
+    }
+
     .documentView-node {
         position: absolute;
         z-index: 1;
@@ -38,10 +50,9 @@
 }
 
 .presElementBox-active {
-    background: gray;
     color: black;
     border-radius: 6px;
-    box-shadow: black 2px 2px 5px;
+    border: solid 2px #5B9FDD;
 }
 
 .presElementBox-buttons {
@@ -88,6 +99,14 @@
     white-space: pre;
 }
 
+.presElementBox-time {
+    position: relative;
+    font-size: 8;
+    font-style: italic;
+    letter-spacing: normal;
+    left: 10px;
+}
+
 .presElementBox-embedded {
     position: relative;
     display: flex;
@@ -143,4 +162,4 @@
     display: flex;
     justify-content: center;
     align-items: center;
-}
+}
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index bca63e94d..f30ee2a5c 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -5,7 +5,7 @@ import { Doc, DataSym, DocListCast } from "../../../fields/Doc";
 import { documentSchema } from '../../../fields/documentSchemas';
 import { Id } from "../../../fields/FieldSymbols";
 import { createSchema, makeInterface, listSpec } from '../../../fields/Schema';
-import { Cast, NumCast, BoolCast, ScriptCast } from "../../../fields/Types";
+import { Cast, NumCast, BoolCast, ScriptCast, StrCast } from "../../../fields/Types";
 import { emptyFunction, emptyPath, returnFalse, returnTrue, returnOne, returnZero, numberRange } from "../../../Utils";
 import { Transform } from "../../util/Transform";
 import { CollectionViewType } from '../collections/CollectionView';
@@ -15,6 +15,7 @@ import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import "./PresElementBox.scss";
 import React = require("react");
 import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
+import { PresBox } from "../nodes/PresBox";
 
 export const presSchema = createSchema({
     presentationTargetDoc: Doc,
@@ -37,19 +38,18 @@ const PresDocument = makeInterface(presSchema, documentSchema);
 @observer
 export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDocument>(PresDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); }
-
     _heightDisposer: IReactionDisposer | undefined;
     // these fields are conditionally computed fields on the layout document that take this document as a parameter
     @computed get indexInPres() { return Number(this.lookupField("indexInPres")); }  // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
-    @computed get collapsedHeight() { return Number(this.lookupField("presCollapsedHeight")); } // the collapsed height changes depending on the state of the presBox.  We could store this on the presentation elemnt template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
-    @computed get presStatus() { return BoolCast(this.lookupField("presStatus")); }
+    @computed get collapsedHeight() { return Number(this.lookupField("presCollapsedHeight")); } // the collapsed height changes depending on the state of the presBox.  We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
+    @computed get presStatus() { return StrCast(this.lookupField("presStatus")); }
     @computed get itemIndex() { return NumCast(this.lookupField("_itemIndex")); }
     @computed get presBox() { return Cast(this.lookupField("presBox"), Doc, null); }
     @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; }
 
     componentDidMount() {
         this._heightDisposer = reaction(() => [this.rootDoc.presExpandInlineButton, this.collapsedHeight],
-            params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 200 : 0), { fireImmediately: true });
+            params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0), { fireImmediately: true });
     }
     componentWillUnmount() {
         this._heightDisposer?.();
@@ -68,7 +68,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                 this.targetDoc.opacity = 1;
             }
         } else {
-            if (this.presStatus && this.indexInPres > this.itemIndex && this.targetDoc) {
+            if (this.presStatus !== "edit" && this.indexInPres > this.itemIndex && this.targetDoc) {
                 this.targetDoc.opacity = 0;
             }
         }
@@ -89,7 +89,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
             }
         } else {
             if (this.rootDoc.presFadeButton) this.rootDoc.presFadeButton = false;
-            if (this.presStatus && this.indexInPres < this.itemIndex && this.targetDoc) {
+            if (this.presStatus !== "edit" && this.indexInPres < this.itemIndex && this.targetDoc) {
                 this.targetDoc.opacity = 0;
             }
         }
@@ -123,7 +123,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
             }
         } else {
             this.rootDoc.presHideAfterButton = false;
-            if (this.presStatus && (this.indexInPres < this.itemIndex) && this.targetDoc) {
+            if (this.presStatus !== "edit" && (this.indexInPres < this.itemIndex) && this.targetDoc) {
                 this.targetDoc.opacity = 0.5;
             }
         }
@@ -166,14 +166,13 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
 
     @action
     presExpandDocumentClick = () => {
-        const highlight = document.getElementById("presBox-hightlight");
         this.rootDoc.presExpandInlineButton = !this.rootDoc.presExpandInlineButton;
-        if (highlight && this.rootDoc.presExpandInlineButton) highlight.style.height = "156";
-        else if (highlight && !this.rootDoc.presExpandInlineButton) highlight.style.height = "58";
     }
 
-    embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight);
+    embedHeight = () => 100;
     embedWidth = () => this.props.PanelWidth() - 20;
+    // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight);
+    // embedWidth = () => this.props.PanelWidth() - 20;
     /**
      * The function that is responsible for rendering a preview or not for this
      * presentation element.
@@ -220,7 +219,18 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : (
             <div className={className} key={this.props.Document[Id] + this.indexInPres}
                 style={{ outlineWidth: Doc.IsBrushed(this.targetDoc) ? `1px` : "0px", }}
-                onClick={e => { this.props.focus(this.rootDoc); e.stopPropagation(); }}>
+                onClick={e => {
+                    if (e.ctrlKey || e.metaKey) {
+                        PresBox.Instance.multiSelect(this.rootDoc);
+                        console.log("cmmd click");
+                    } else if (e.shiftKey) {
+                        PresBox.Instance.shiftSelect(this.rootDoc);
+                    } else {
+                        this.props.focus(this.rootDoc); e.stopPropagation();
+                        console.log("normal click");
+                    }
+                }}
+                onPointerDown={e => e.stopPropagation()}>
                 {treecontainer ? (null) : <>
                     <div className="presElementBox-number">
                         {`${this.indexInPres + 1}.`}
@@ -228,6 +238,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     <div className="presElementBox-name">
                         {`${this.targetDoc?.title}`}
                     </div>
+                    <div className="presElementBox-time">{"Transition speed: " + (this.targetDoc?.presTransition) + "ms"}</div>
+                    <div className="presElementBox-time" style={{ display: this.targetDoc.presDuration ? "block" : "none" }}>{"Duration: " + (this.targetDoc?.presDuration) + "ms"}</div>
                     <button
                         title="Close"
                         className="presElementBox-closeIcon"
@@ -236,21 +248,20 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                             this.props.removeDocument?.(this.rootDoc);
                             e.stopPropagation();
                         }}>
-                        <FontAwesomeIcon icon={"times"} onPointerDown={e => e.stopPropagation()} />
+                        <FontAwesomeIcon icon={"trash"} onPointerDown={e => e.stopPropagation()} />
                     </button>
                     <button title="Expand Inline" className={"presElementBox-expand" + (this.rootDoc.presExpandInlineButton ? "-selected" : "")} onClick={e => { e.stopPropagation(); this.presExpandDocumentClick(); }}>
                         <FontAwesomeIcon icon={(this.rootDoc.presExpandInlineButton ? "angle-up" : "angle-down")} onPointerDown={e => e.stopPropagation()} />
                     </button>
-                    <br />
                 </>}
+                <div className="presElementBox-highlight" style={{ display: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "block" : "none" }} />
                 <div className="presElementBox-buttons">
-                    <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} onPointerDown={e => e.stopPropagation()} /></button>
+                    <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search-plus"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Navigate" className={pbi + (this.rootDoc.presNavButton ? "-selected" : "")} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Hide Before" className={pbi + (this.rootDoc.presHideTillShownButton ? "-selected" : "")} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={"file"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Fade After" className={pbi + (this.rootDoc.presFadeButton ? "-selected" : "")} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Hide After" className={pbi + (this.rootDoc.presHideAfterButton ? "-selected" : "")} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button>
-                    {/* <button title="Group With Up" className={pbi + (this.rootDoc.presGroupButton ? "-selected" : "")} onClick={e => { e.stopPropagation(); this.rootDoc.presGroupButton = !this.rootDoc.presGroupButton; }}><FontAwesomeIcon icon={"arrow-up"} onPointerDown={e => e.stopPropagation()} /></button> */}
-                    <button title="Progressivize" className={pbi + (this.rootDoc.pres ? "-selected" : "")} onClick={this.progressivize}><FontAwesomeIcon icon={"tasks"} onPointerDown={e => e.stopPropagation()} /></button>
+                    <button title="Progressivize" className={pbi + (this.rootDoc.presProgressivize ? "-selected" : "")} onClick={this.progressivize}><FontAwesomeIcon icon={"tasks"} onPointerDown={e => e.stopPropagation()} /></button>
                 </div>
                 {this.renderEmbeddedInline}
             </div>
-- 
cgit v1.2.3-70-g09d2


From 11ca5a85ff8ecf7c1709331c12d75213fdfa1589 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Wed, 15 Jul 2020 22:04:59 +0800
Subject: added progressivize features

---
 package-lock.json                                  |  13 ++
 package.json                                       |   4 +-
 .../collectionFreeForm/CollectionFreeFormView.scss |  40 ++++-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  40 ++++-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |   9 +-
 src/client/views/nodes/PresBox.scss                | 142 ++++++++++------
 src/client/views/nodes/PresBox.tsx                 | 185 +++++++++++++++++----
 .../views/presentationview/PresElementBox.tsx      |   3 +-
 8 files changed, 344 insertions(+), 92 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index ad181758c..1e8359fbf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14335,6 +14335,14 @@
                 "react-draggable": "^4.0.3"
             }
         },
+        "react-reveal": {
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/react-reveal/-/react-reveal-1.2.2.tgz",
+            "integrity": "sha512-JCv3fAoU6Z+Lcd8U48bwzm4pMZ79qsedSXYwpwt6lJNtj/v5nKJYZZbw3yhaQPPgYePo3Y0NOCoYOq/jcsisuw==",
+            "requires": {
+                "prop-types": "^15.5.10"
+            }
+        },
         "react-select": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.1.0.tgz",
@@ -14800,6 +14808,11 @@
             "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
             "dev": true
         },
+        "reveal.js": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-4.0.2.tgz",
+            "integrity": "sha512-LWZSUenufF1gpD7npxJ7KfoQQFKgc1D6XrLTFgKlwWNP1BQ74hT48KONFWMAw+8R/QUeaScCLCLrBVHDfFIEiw=="
+        },
         "right-align": {
             "version": "0.1.3",
             "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
diff --git a/package.json b/package.json
index 89af3b0b5..745f7d947 100644
--- a/package.json
+++ b/package.json
@@ -222,11 +222,13 @@
         "react-jsx-parser": "^1.25.1",
         "react-measure": "^2.2.4",
         "react-resizable": "^1.10.1",
+        "react-reveal": "^1.2.2",
         "react-select": "^3.1.0",
         "react-table": "^6.11.5",
         "readline": "^1.3.0",
         "request": "^2.88.0",
         "request-promise": "^4.2.5",
+        "reveal.js": "^4.0.2",
         "rimraf": "^3.0.0",
         "serializr": "^1.5.4",
         "sharp": "^0.23.4",
@@ -248,4 +250,4 @@
         "xoauth2": "^1.2.0",
         "xregexp": "^4.3.0"
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index 92aee3776..fad90ca32 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -13,16 +13,54 @@
 }
 
 .collectionfreeformview-viewdef {
-    > .collectionFreeFormDocumentView-container {
+    >.collectionFreeFormDocumentView-container {
         pointer-events: none;
+
         .contentFittingDocumentDocumentView-previewDoc {
             pointer-events: all;
         }
     }
+
+    svg.presPaths {
+        position: absolute;
+        z-index: 100000;
+        overflow: visible;
+    }
+
+    svg.presPaths-hidden {
+        display: none;
+    }
 }
 
 .collectionfreeformview-none {
     touch-action: none;
+
+    svg.presPaths {
+        position: absolute;
+        z-index: 100000;
+        overflow: visible;
+    }
+
+    svg.presPaths-hidden {
+        display: none;
+    }
+}
+
+.progressivizeButton {
+    position: absolute;
+    display: flex;
+    transform: translate(-105%, 0);
+    align-items: center;
+    border: black solid 1px;
+    border-radius: 3px;
+    justify-content: center;
+    width: 30;
+    height: 20;
+    background-color: #c8c8c8;
+}
+
+.progressivizeButton:hover {
+    background-color: #aedef8;
 }
 
 .collectionFreeform-customText {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 98be2dc03..ded410a9c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,7 +1,7 @@
 import { library } from "@fortawesome/fontawesome-svg-core";
 import { faEye } from "@fortawesome/free-regular-svg-icons";
 import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faFileUpload, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons";
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx";
 import { observer } from "mobx-react";
 import { computedFn } from "mobx-utils";
 import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../fields/Doc";
@@ -46,6 +46,7 @@ import "./CollectionFreeFormView.scss";
 import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
 import { MarqueeView } from "./MarqueeView";
 import React = require("react");
+import { PresBox } from "../../nodes/PresBox";
 
 library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
 
@@ -1350,6 +1351,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             <CollectionFreeFormViewPannableContents
                 centeringShiftX={this.centeringShiftX}
                 centeringShiftY={this.centeringShiftY}
+                presPaths={BoolCast(this.Document.presPathView)}
+                progressivize={BoolCast(this.Document.editProgressivize)}
                 transition={Cast(this.layoutDoc._viewTransition, "string", null)}
                 viewDefDivClick={this.props.viewDefDivClick}
                 zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
@@ -1432,11 +1435,44 @@ interface CollectionFreeFormViewPannableContentsProps {
     viewDefDivClick?: ScriptField;
     children: () => JSX.Element[];
     transition?: string;
+    presPaths?: boolean;
+    progressivize?: boolean;
 }
 
 @observer
 class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
+    @computed get progressivize() {
+        if (this.props.progressivize) {
+            console.log("should render");
+            return (
+                <>
+                    {PresBox.Instance.progressivizeChildDocs}
+                </>
+            );
+        }
+    }
+
+    @computed get presPaths() {
+        const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden");
+        if (this.props.presPaths) {
+            return (
+                <svg className={presPaths}>
+                    <defs>
+                        <marker id="arrow" markerWidth="10" overflow="visible" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
+                            <path d="M0,0 L0,6 L9,3 z" fill="#69a6db" />
+                        </marker>
+                        <marker id={`dot`} orient="auto" overflow="visible">
+                            <circle r={3} fill="#69a6db" />
+                        </marker>
+                    </defs>;
+                    {PresBox.Instance.paths}
+                </svg>
+            );
+        }
+    }
+
     render() {
+        trace();
         const freeformclass = "collectionfreeformview" + (this.props.viewDefDivClick ? "-viewDef" : "-none");
         const cenx = this.props.centeringShiftX();
         const ceny = this.props.centeringShiftY();
@@ -1449,6 +1485,8 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
                 transition: this.props.transition
             }}>
             {this.props.children()}
+            {this.presPaths}
+            {this.progressivize}
         </div>;
     }
 }
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index a3020f912..52a7d4ebf 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -15,6 +15,8 @@ import { numberRange } from "../../../Utils";
 import { ComputedField } from "../../../fields/ScriptField";
 import { listSpec } from "../../../fields/Schema";
 import { DocumentType } from "../../documents/DocumentTypes";
+// @ts-ignore
+import Zoom from 'react-reveal/Zoom';
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -112,10 +114,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) {
         docs.forEach((doc, i) => {
+            if (!doc.appearFrame) doc.appearFrame = i;
             const curTimecode = progressivize ? i : timecode;
             const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
-            const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1));
+            const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && (t < NumCast(doc.appearFrame)) ? 0 : 1));
+            const oarray = new List<number>();
+            oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
+            oarray.fill(1, NumCast(doc.appearFrame), timecode);
+            console.log(oarray);
             xlist[curTimecode] = NumCast(doc.x);
             ylist[curTimecode] = NumCast(doc.y);
             doc["x-indexed"] = xlist;
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 07e53fa94..4d1518b61 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -125,12 +125,14 @@
 
     .toolbar-slider {
         position: relative;
+        align-self: center;
+        justify-self: left;
         -webkit-appearance: none;
         transform: rotateY(180deg);
         background-color: #40B3D8;
-        margin-top: 1px;
+        margin-top: 5px;
         width: 100%;
-        max-width: 100px;
+        max-width: 120px;
         height: 2.5px;
         left: 0px;
     }
@@ -153,16 +155,19 @@
         display: grid;
         justify-content: space-between;
         width: 100%;
+        height: max-content;
+        max-width: 120px;
         grid-template-columns: auto auto auto;
-        grid-template-rows: auto;
+        grid-template-rows: max-content;
         font-weight: 100;
-        margin-top: 5px;
+        /* margin-top: 5px; */
         font-size: 8px;
     }
 
     .slider-value {
-        font-size: 10;
-        position: relative;
+        top: -20;
+        color: #2f86a2;
+        position: absolute;
     }
 
     .slider-value.none,
@@ -197,29 +202,18 @@
 
     .ribbon-final-box {
         align-self: flex-start;
+        justify-self: center;
         display: grid;
         grid-template-rows: auto auto;
         padding-left: 10px;
         padding-right: 10px;
         letter-spacing: normal;
-        width: max-content;
+        min-width: max-content;
+        width: 100%;
         font-size: 13;
         font-weight: 600;
         position: relative;
 
-        .selectedList {
-            display: block;
-            min-width: 50;
-            max-width: 120;
-            height: 70;
-            overflow-y: scroll;
-
-            .selectedList-items {
-                font-size: 7;
-                font-weight: normal;
-            }
-        }
-
 
         .ribbon-final-button {
             position: relative;
@@ -241,41 +235,61 @@
         }
     }
 
+    .selectedList {
+        display: block;
+        min-width: 50;
+        max-width: 120;
+        height: 70;
+        overflow-y: scroll;
+
+        .selectedList-items {
+            font-size: 7;
+            font-weight: normal;
+        }
+    }
+
+    .ribbon-button {
+        font-size: 10;
+        font-weight: 200;
+        height: 25;
+        border: solid 1px black;
+        display: flex;
+        border-radius: 10px;
+        margin-right: 5px;
+        width: max-content;
+        justify-content: center;
+        align-items: center;
+        padding-right: 10px;
+        padding-left: 10px;
+    }
+
+    .ribbon-button.active {
+        background-color: #5B9FDD;
+    }
+
+    .ribbon-button:hover {
+        background-color: lightgrey;
+    }
+
+    svg.svg-inline--fa.fa-thumbtack.fa-w-12.toolbar-thumbtack {
+        right: 40;
+        position: absolute;
+        transform: rotate(45deg);
+    }
+
     .ribbon-box {
         display: grid;
         grid-template-rows: max-content auto;
+        justify-self: center;
         padding-left: 10px;
         padding-right: 10px;
         letter-spacing: normal;
-        width: max-content;
+        width: 100%;
         font-weight: 600;
         position: relative;
         font-size: 13;
         border-right: solid 2px darkgrey;
 
-        .ribbon-button {
-            font-size: 10;
-            font-weight: 200;
-            height: 25;
-            border: solid 1px black;
-            display: flex;
-            border-radius: 10px;
-            margin-right: 5px;
-            width: max-content;
-            justify-content: center;
-            align-items: center;
-            padding-right: 10px;
-            padding-left: 10px;
-        }
-
-        .ribbon-button.active {
-            background-color: #5B9FDD;
-        }
-
-        .ribbon-button:hover {
-            background-color: lightgrey;
-        }
-
         .presBox-dropdown:hover {
             border: solid 1px #378AD8;
 
@@ -283,6 +297,7 @@
                 font-size: 10;
                 display: block;
                 padding-left: 5px;
+                padding-right: 5px;
                 margin-top: 3;
                 margin-bottom: 3;
             }
@@ -303,6 +318,7 @@
                 left: -1px;
                 z-index: 200;
                 width: 85%;
+                min-width: max-content;
                 display: block;
                 background: #FFFFFF;
                 border: 0.5px solid #979797;
@@ -341,36 +357,58 @@
                 color: black;
                 align-self: center;
                 justify-self: center;
+                margin-right: 2px;
             }
         }
     }
 }
 
 .presBox-ribbon.active {
-    display: inline-flex;
+    display: grid;
+    grid-template-columns: auto auto auto auto auto;
+    grid-template-rows: 100%;
     height: 100px;
     padding-top: 5px;
     padding-bottom: 5px;
     border: solid 1px black;
-}
 
+    ::-webkit-scrollbar {
+        -webkit-appearance: none;
+        height: 3px;
+        width: 8px;
+    }
 
+    ::-webkit-scrollbar-thumb {
+        border-radius: 2px;
+        background-color: rgb(101, 164, 220);
+    }
+}
+
+.dropdown-play-button {
+    font-size: 10;
+    margin-left: 10;
+    margin-right: 10;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    text-align: left;
+    justify-content: left;
+    border-bottom: solid 1px lightgrey;
+}
 
 .dropdown-play {
     top: 32px;
-    transform: translate(-28%, 0px);
-    /* left: 0; */
     display: none;
     border-radius: 5px;
-    width: 100px;
-    height: 100px;
+    width: max-content;
+    min-height: 20px;
+    height: max-content;
     z-index: 200;
-    background-color: black;
+    background-color: #323232;
     position: absolute;
 }
 
 .dropdown-play.active {
-    display: flex;
+    display: block;
 }
 
 .presBox-buttons {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index abf97142e..5c21f6656 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -25,6 +25,8 @@ import { SearchUtil } from "../../util/SearchUtil";
 import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
 import { child } from "serializr";
 
+
+
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
 
@@ -232,7 +234,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     //The function that starts or resets presentaton functionally, depending on status flag.
     @action
-    startOrResetPres = () => {
+    startOrResetPres = (startSlide: number) => {
         this.updateCurrentPresentation();
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         if (this._presTimer && this.layoutDoc.presStatus === "auto") {
@@ -240,8 +242,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             this.layoutDoc.presStatus = "manual";
         } else {
             this.layoutDoc.presStatus = "auto";
-            // this.startPresentation(0);
-            // this.gotoDocument(0, this.itemIndex);
+            this.startPresentation(startSlide);
+            this.gotoDocument(startSlide, this.itemIndex);
             this._presTimer = setInterval(() => {
                 if (this.itemIndex + 1 < this.childDocs.length) this.next();
                 else {
@@ -373,8 +375,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     @computed get listOfSelected() {
         const list = this._selectedArray.map((doc: Doc, index: any) => {
+            const activeItem = Cast(doc, Doc, null);
+            const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
             return (
-                <div className="selectedList-items">{index + 1}.  {doc.title}</div>
+                <div className="selectedList-items">{index + 1}.  {targetDoc.title}</div>
             );
         });
         return list;
@@ -415,13 +419,27 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @action
     keyEvents = (e: KeyboardEvent) => {
         e.stopPropagation;
+        // switch(e.keyCode) {
+        //     case 27: console.log("escape");
+        //     case 65 && (e.metaKey || e.altKey): 
+        // }
         // Escape key
         if (e.keyCode === 27) {
             if (this.layoutDoc.presStatus === "edit") this._selectedArray = [];
             else this.layoutDoc.presStatus = "edit";
             // Ctrl-A to select all
         } else if ((e.metaKey || e.altKey) && e.keyCode === 65) {
-            this._selectedArray = this.childDocs;
+            if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs;
+            // left / a / up to go back
+        } else if (e.keyCode === 37 || 65 || 38) {
+            if (this.layoutDoc.presStatus !== "edit") this.back();
+            // right / d / down to go to next
+        } else if (e.keyCode === 39 || 68 || 40) {
+            if (this.layoutDoc.presStatus !== "edit") this.next();
+            // spacebar to 'present' or go to next slide
+        } else if (e.keyCode === 32) {
+            if (this.layoutDoc.presStatus !== "edit") this.next();
+            else this.layoutDoc.presStatus = "manual";
         }
     }
 
@@ -432,6 +450,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @observable private moreInfoTools: boolean = false;
     @observable private playTools: boolean = false;
 
+    @observable private pathBoolean: boolean = false;
+
     // For toggling transition toolbar
     @action toggleTransitionTools = () => {
         this.transitionTools = !this.transitionTools;
@@ -491,26 +511,64 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     @undoBatch
     @action
-    viewLinks = async () => {
-        let docToJump = this.childDocs[0];
-        // console.log(SearchUtil.GetContextsOfDocument(presTargetDoc));
-        // console.log(DocListCast(presTargetDoc.context));
-        // console.log(DocumentManager.Instance.getAllDocumentViews(presTargetDoc));
+    viewPaths = async () => {
+        const docToJump = this.childDocs[0];
         const aliasOf = await DocCastAsync(docToJump.aliasOf);
         const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
-        console.log(srcContext?.title);
+        if (this.pathBoolean) {
+            console.log("true");
+            if (srcContext) {
+                this.togglePath();
+                srcContext._fitToBox = false;
+                srcContext._viewType = "freeform";
+                srcContext.presPathView = false;
+            }
+        } else {
+            console.log("false");
+            if (srcContext) {
+                this.togglePath();
+                srcContext._fitToBox = true;
+                srcContext._viewType = "freeform";
+                srcContext.presPathView = true;
+            }
+        }
+        console.log("view paths");
         const viewType = srcContext?._viewType;
         const fit = srcContext?._fitToBox;
-        if (srcContext) {
-            srcContext._fitToBox = true;
-            srcContext._viewType = "freeform";
-        }
 
         // if (!DocumentManager.Instance.getDocumentView(curPres)) {
         //     CollectionDockingView.AddRightSplit(curPres);
         // }
     }
 
+    @computed get paths() {
+        const paths = []; //List of all of the paths that need to be added
+        console.log(this.childDocs.length - 1);
+        for (let i = 0; i <= this.childDocs.length - 1; i++) {
+            const targetDoc = Cast(this.childDocs[i].presentationTargetDoc, Doc, null);
+            if (this.childDocs[i + 1] && targetDoc) {
+                const nextTargetDoc = Cast(this.childDocs[i + 1].presentationTargetDoc, Doc, null);
+                const n1x = NumCast(targetDoc.x) + (NumCast(targetDoc._width) / 2);
+                const n1y = NumCast(targetDoc.y) + (NumCast(targetDoc._height) / 2);
+                const n2x = NumCast(nextTargetDoc.x) + (NumCast(targetDoc._width) / 2);
+                const n2y = NumCast(nextTargetDoc.y) + (NumCast(targetDoc._height) / 2);
+                const pathPoints = n1x + "," + n1y + " " + n2x + "," + n2y;
+                paths.push(<polyline
+                    points={pathPoints}
+                    style={{
+                        opacity: 1,
+                        stroke: "#69a6db",
+                        strokeWidth: 5,
+                    }}
+                    markerStart="url(#dot)"
+                    markerEnd="url(#arrow)" />);
+            }
+        }
+        return paths;
+    }
+
+    @action togglePath = () => this.pathBoolean = !this.pathBoolean;
+
     /**
      * The function that is called on click to turn fading document after presented option on/off.
      * It also makes sure that the option swithches from hide-after to this one, since both
@@ -572,13 +630,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
                             <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
                                 <div className={`presBox-dropdownOption ${!activeItem.presZoomButton && !activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presZoomButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Zoom</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Navigate</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presZoomButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan</div>
                             </div>
                         </div>
-                        <div className={`slider-value ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} style={{ left: thumbLocation + '%' }}>{transitionSpeed}s</div>
                         <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed} className={`toolbar-slider ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
                         <div className={`slider-headers ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`}>
+                            <div className={`slider-value ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} style={{ left: thumbLocation + '%' }}>{transitionSpeed}s</div>
                             <div className="slider-text">Slow</div>
                             <div className="slider-text">Medium</div>
                             <div className="slider-text">Fast</div>
@@ -693,24 +751,48 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @computed get playDropdown() {
         return (
             <div className={`dropdown-play ${this.playTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-
+                <div className="dropdown-play-button" onClick={() => this.startOrResetPres(this.itemIndex)}>
+                    Start from current slide
+                </div>
+                <div className="dropdown-play-button" onClick={() => this.startOrResetPres(0)}>
+                    Start from first slide
+                </div>
             </div>
         );
     }
 
+    progressivizeOptions = (viewType: string) => {
+        const buttons = [];
+        buttons.push(<div className="ribbon-button" title="Progressivize child documents" onClick={this.progressivize}>Progressivize child documents</div>);
+        buttons.push(<div className="ribbon-button" title="Internal navigation" onClick={() => console.log("hide after")}>Internal navigation</div>);
+        if (viewType === "rtf") {
+            buttons.push(<div className="ribbon-button" title="Progressivize bullet points" onClick={() => console.log("hide after")}>Bullet points</div>);
+        }
+        return buttons;
+    }
+
+
+
     @computed get progressivizeDropdown() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        if (activeItem) {
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+
+        if (activeItem && targetDoc) {
             return (
                 <div>
                     <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                         <div className="ribbon-box">
-                            <div title="Progressivize" className={`ribbon-button ${activeItem.presProgressivize ? "active" : ""}`} onClick={this.progressivize}>Progressivize Child Documents</div>
+                            {targetDoc.type} selected
+                            <div className="selectedList">
+                                <div className="selectedList-items">1. {targetDoc.title}</div>
+                            </div>
                         </div>
-                        <div className="ribbon-box">
-                            Other progressivize features:
-                            <div title="Progressivize" className={"ribbon-button"}>Progressivize Text Bullet Points</div>
-                            <div title="Progressivize" className={"ribbon-button"}>Internal Navigation</div>
+                        <div className="ribbon-final-box">
+                            <div className="progressivizeEdit">
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} title="Progressivize child documents" onClick={this.progressivize}>Progressivize child documents</div>
+                                <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "block" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} title="Edit progresivize" onClick={this.editProgressivize}>Edit</div>
+                            </div>
+                            <div className="ribbon-button" title="Internal navigation" onClick={() => console.log("hide after")}>Internal navigation</div>
                         </div>
                     </div>
                 </div>
@@ -718,20 +800,50 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    @action
+    editProgressivize = (e: React.MouseEvent) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        targetDoc.currentFrame = targetDoc.lastFrame;
+        if (targetDoc?.editProgressivize) {
+            targetDoc.editProgressivize = false;
+        } else {
+            targetDoc.editProgressivize = true;
+        }
+    }
+
     @action
     progressivize = (e: React.MouseEvent) => {
         e.stopPropagation();
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         activeItem.presProgressivize = !activeItem.presProgressivize;
-        const rootTarget = Cast(activeItem.presentationTargetDoc, Doc, null);
-        const docs = DocListCast(rootTarget[Doc.LayoutFieldKey(rootTarget)]);
-        if (this.rootDoc.presProgressivize) {
-            rootTarget.currentFrame = 0;
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
+        targetDoc.presProgressivize = !targetDoc.presProgressivize;
+        console.log(targetDoc.presProgressivize);
+        if (activeItem.presProgressivize) {
+            console.log("progressivize");
+            targetDoc.currentFrame = 0;
             CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
-            rootTarget.lastFrame = docs.length - 1;
+            targetDoc.lastFrame = docs.length - 1;
         }
     }
 
+    @computed get progressivizeChildDocs() {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
+        const tags: JSX.Element[] = [];
+        docs.forEach((doc, index) => {
+            tags.push(
+                <div className="progressivizeButton" style={{ top: NumCast(doc.y), left: NumCast(doc.x) }}>{doc.appearFrame}</div>
+            );
+        });
+        return tags;
+    }
+
+
+
     @computed get moreInfoDropdown() {
         return (<div></div>);
 
@@ -747,8 +859,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div>
                     <div className="toolbar-divider" />
-                    <div className="toolbar-button"><FontAwesomeIcon title={"View Links"} icon={"object-group"} onClick={this.toolbarTest} /></div>
-                    <div className="toolbar-button"><FontAwesomeIcon title={"Portal"} icon={"eye"} onClick={this.viewLinks} /></div>
+                    <div className={`toolbar-button ${this.pathBoolean ? "active" : ""}`}><FontAwesomeIcon title={"View Paths"} icon={"object-group"} onClick={this.viewPaths} /></div>
+                    {/* <div className="toolbar-button"><FontAwesomeIcon title={"Portal"} icon={"eye"} onClick={this.toolbarTest} /></div> */}
                     <div className="toolbar-divider" />
                     <div className={`toolbar-button ${this.transitionTools ? "active" : ""}`} onClick={this.toggleTransitionTools}>
                         <FontAwesomeIcon icon={"rocket"} />
@@ -762,6 +874,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         <FontAwesomeIcon className={`dropdown ${this.progressivizeTools ? "active" : ""}`} icon={"angle-down"} />
                     </div>
                     <div className="toolbar-divider" />
+                    <div className="toolbar-button">
+                        <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
+                    </div>
                     <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
                         <div className={`toolbar-moreInfo ${this.moreInfoTools ? "active" : ""}`}>
                             <div className="toolbar-moreInfoBall" />
@@ -778,7 +893,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div>
                     <div className="toolbar-button">
-                        <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"thumbtack"} />
+                        <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
                     </div>
                     <div className="toolbar-button" onClick={this.toggleMoreInfo}>
                         <div className="toolbar-moreInfo">
@@ -807,10 +922,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel}>Slides</option>
                 </select>
                 <div className="presBox-presentPanel">
-                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title={"Reset Presentation" + this.layoutDoc.presStatus ? "" : " From Start"} style={{ gridColumn: 2 }} onClick={this.startOrResetPres}>
+                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title={"Reset Presentation" + this.layoutDoc.presStatus ? "" : " From Start"} style={{ gridColumn: 2 }} onClick={() => this.startOrResetPres(0)}>
                         <FontAwesomeIcon icon={"clock"} /> &nbsp;
                         <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
-                        <div className="toolbar-divider" />
+                        <div className="toolbar-divider" style={{ marginLeft: 5 }} />
                         <FontAwesomeIcon onClick={e => { e.stopPropagation; this.togglePlay(); }} className="dropdown" icon={"angle-down"} />
                         {this.playDropdown}
                     </div>
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index f30ee2a5c..fc040f67b 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -230,7 +230,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                         console.log("normal click");
                     }
                 }}
-                onPointerDown={e => e.stopPropagation()}>
+            // onPointerDown={e => e.stopPropagation()}
+            >
                 {treecontainer ? (null) : <>
                     <div className="presElementBox-number">
                         {`${this.indexInPres + 1}.`}
-- 
cgit v1.2.3-70-g09d2


From ae47181bab9bdaa104dc417c4493bc1a0e52eea1 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 17 Jul 2020 14:38:02 +0800
Subject: pres changes

---
 package-lock.json                                  |   5 +
 package.json                                       |   1 +
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  36 +++---
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  53 ++++++---
 src/client/views/nodes/PresBox.scss                |  28 +++++
 src/client/views/nodes/PresBox.tsx                 | 129 ++++++++++++++++-----
 src/typings/index.d.ts                             |   5 +-
 tsconfig.json                                      |   3 +-
 8 files changed, 195 insertions(+), 65 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 1e8359fbf..f0f40d4dd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1205,6 +1205,11 @@
                 "@types/request": "*"
             }
         },
+        "@types/reveal": {
+            "version": "3.3.33",
+            "resolved": "https://registry.npmjs.org/@types/reveal/-/reveal-3.3.33.tgz",
+            "integrity": "sha512-lKbezA9Oa5LfdSRwFDc/FHEGH4+FjiXh/a/PCSZAmN+KCeQJL/3ClOdAQwOxt3zdHc8XyioT+cNvIOletwRI7A=="
+        },
         "@types/rimraf": {
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz",
diff --git a/package.json b/package.json
index 745f7d947..eef6aae03 100644
--- a/package.json
+++ b/package.json
@@ -123,6 +123,7 @@
         "@hig/theme-data": "^2.16.1",
         "@material-ui/core": "^4.11.0",
         "@types/google-maps": "^3.2.2",
+        "@types/reveal": "^3.3.33",
         "@types/webscopeio__react-textarea-autocomplete": "^4.6.1",
         "@webscopeio/react-textarea-autocomplete": "^4.7.0",
         "adm-zip": "^0.4.16",
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ded410a9c..2b55008f4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -48,6 +48,7 @@ import { MarqueeView } from "./MarqueeView";
 import React = require("react");
 import { PresBox } from "../../nodes/PresBox";
 
+
 library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
 
 export const panZoomSchema = createSchema({
@@ -1352,7 +1353,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 centeringShiftX={this.centeringShiftX}
                 centeringShiftY={this.centeringShiftY}
                 presPaths={BoolCast(this.Document.presPathView)}
-                progressivize={BoolCast(this.Document.editProgressivize)}
+                // progressivize={BoolCast(this.Document.editProgressivize)}
                 transition={Cast(this.layoutDoc._viewTransition, "string", null)}
                 viewDefDivClick={this.props.viewDefDivClick}
                 zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
@@ -1436,21 +1437,21 @@ interface CollectionFreeFormViewPannableContentsProps {
     children: () => JSX.Element[];
     transition?: string;
     presPaths?: boolean;
-    progressivize?: boolean;
+    // progressivize?: boolean;
 }
 
 @observer
 class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
-    @computed get progressivize() {
-        if (this.props.progressivize) {
-            console.log("should render");
-            return (
-                <>
-                    {PresBox.Instance.progressivizeChildDocs}
-                </>
-            );
-        }
-    }
+    // @computed get progressivize() {
+    //     if (this.props.progressivize) {
+    //         console.log("should render");
+    //         return (
+    //             <>
+    //                 {PresBox.Instance.progressivizeChildDocs}
+    //             </>
+    //         );
+    //     }
+    // }
 
     @computed get presPaths() {
         const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden");
@@ -1458,11 +1459,12 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
             return (
                 <svg className={presPaths}>
                     <defs>
-                        <marker id="arrow" markerWidth="10" overflow="visible" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
-                            <path d="M0,0 L0,6 L9,3 z" fill="#69a6db" />
+                        <marker id="arrow" markerWidth="5" overflow="visible" markerHeight="3" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
+                            <path d="M0,0 L0,6 L9,3 z" fill="#40B3D8" />
                         </marker>
-                        <marker id={`dot`} orient="auto" overflow="visible">
-                            <circle r={3} fill="#69a6db" />
+                        <marker id="square" markerWidth="3" markerHeight="3"
+                            refX="5" refY="5" orient="auto">
+                            <path d="M 5,1 L 9,5 5,9 1,5 z" fill="#40B3D8" />
                         </marker>
                     </defs>;
                     {PresBox.Instance.paths}
@@ -1486,7 +1488,7 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
             }}>
             {this.props.children()}
             {this.presPaths}
-            {this.progressivize}
+            {/* {this.progressivize} */}
         </div>;
     }
 }
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 52a7d4ebf..f797ffe8a 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -15,8 +15,9 @@ import { numberRange } from "../../../Utils";
 import { ComputedField } from "../../../fields/ScriptField";
 import { listSpec } from "../../../fields/Schema";
 import { DocumentType } from "../../documents/DocumentTypes";
-// @ts-ignore
-import Zoom from 'react-reveal/Zoom';
+import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal';
+import { PresBox } from "./PresBox";
+
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -118,8 +119,10 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             const curTimecode = progressivize ? i : timecode;
             const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
-            const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && (t < NumCast(doc.appearFrame)) ? 0 : 1));
-            const oarray = new List<number>();
+            const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1));
+            const oarray: number[] = [];
+            console.log(doc.title + "AF: " + doc.appearFrame);
+            console.log("timecode: " + timecode);
             oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
             oarray.fill(1, NumCast(doc.appearFrame), timecode);
             console.log(oarray);
@@ -141,6 +144,35 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         this.props.Document.y = NumCast(this.props.Document.y) + y;
     }
 
+    @computed get freeformNodeDiv() {
+        const node = <DocumentView {...this.props}
+            nudge={this.nudge}
+            dragDivName={"collectionFreeFormDocumentView-container"}
+            ContentScaling={this.contentScaling}
+            ScreenToLocalTransform={this.getTransform}
+            backgroundColor={this.props.backgroundColor}
+            opacity={this.opacity}
+            NativeHeight={this.NativeHeight}
+            NativeWidth={this.NativeWidth}
+            PanelWidth={this.panelWidth}
+            PanelHeight={this.panelHeight} />;
+        if (this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc) {
+            switch (this.layoutDoc.presEffect) {
+                case "Zoom": return (<Zoom>{node}</Zoom>); break;
+                case "Fade": return (<Fade>{node}</Fade>); break;
+                case "Flip": return (<Flip>{node}</Flip>); break;
+                case "Rotate": return (<Rotate>{node}</Rotate>); break;
+                case "Bounce": return (<Bounce>{node}</Bounce>); break;
+                case "Roll": return (<Roll>{node}</Roll>); break;
+                case "LightSpeed": return (<LightSpeed>{node}</LightSpeed>); break;
+                case "None": return node; break;
+                default: return node; break;
+            }
+        } else {
+            return node;
+        }
+    }
+
     contentScaling = () => this.nativeWidth > 0 && !this.props.fitToBox && !this.freezeDimensions ? this.width / this.nativeWidth : 1;
     panelWidth = () => (this.sizeProvider?.width || this.props.PanelWidth?.());
     panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.());
@@ -171,6 +203,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 display: this.ZInd === -99 ? "none" : undefined,
                 pointerEvents: this.props.Document.isBackground || this.Opacity === 0 || this.props.Document.type === DocumentType.INK || this.props.Document.isInkMask ? "none" : this.props.pointerEvents ? "all" : undefined
             }} >
+
             {Doc.UserDoc().renderStyle !== "comic" ? (null) :
                 <div style={{ width: "100%", height: "100%", position: "absolute" }}>
                     <svg style={{ transform: `scale(1,${this.props.PanelHeight() / this.props.PanelWidth()})`, transformOrigin: "top left", overflow: "visible" }} viewBox="0 0 12 14">
@@ -180,17 +213,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 </div>}
 
             {!this.props.fitToBox ?
-                <DocumentView {...this.props}
-                    nudge={this.nudge}
-                    dragDivName={"collectionFreeFormDocumentView-container"}
-                    ContentScaling={this.contentScaling}
-                    ScreenToLocalTransform={this.getTransform}
-                    backgroundColor={this.props.backgroundColor}
-                    opacity={this.opacity}
-                    NativeHeight={this.NativeHeight}
-                    NativeWidth={this.NativeWidth}
-                    PanelWidth={this.panelWidth}
-                    PanelHeight={this.panelHeight} />
+                <>{this.freeformNodeDiv}</>
                 : <ContentFittingDocumentView {...this.props}
                     ContainingCollectionDoc={this.props.ContainingCollectionDoc}
                     DataDoc={this.props.DataDoc}
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 4d1518b61..bf31f71d2 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -141,6 +141,15 @@
         outline: none;
     }
 
+    .effectDirection {
+        justify-self: center;
+        align-self: center;
+        align-items: center;
+        justify-content: center;
+        grid-template-columns: 13px 13px 13px;
+        display: grid;
+    }
+
     .toolbar-slider::-webkit-slider-thumb {
         -webkit-appearance: none;
         background-color: #40B3D8;
@@ -233,6 +242,25 @@
             border-radius: 10px;
             background-color: #979797;
         }
+
+        .ribbon-final-button-hidden {
+            position: relative;
+            font-size: 10;
+            font-weight: normal;
+            letter-spacing: normal;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-bottom: 5px;
+            height: 25px;
+            color: lightgrey;
+            width: 100%;
+            max-width: 120;
+            padding-left: 10;
+            padding-right: 10;
+            border-radius: 10px;
+            background-color: black;
+        }
     }
 
     .selectedList {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 5c21f6656..fc5e73c81 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -24,7 +24,7 @@ import { HighlightSpanKind } from "typescript";
 import { SearchUtil } from "../../util/SearchUtil";
 import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
 import { child } from "serializr";
-
+import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal';
 
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
@@ -226,6 +226,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             this.navigateToElement(this.childDocs[index], fromDoc);
             this.hideIfNotPresented(index);
             this.showAfterPresented(index);
+            this.onHideDocumentUntilPressClick();
         }
     });
 
@@ -237,6 +238,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     startOrResetPres = (startSlide: number) => {
         this.updateCurrentPresentation();
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         if (this._presTimer && this.layoutDoc.presStatus === "auto") {
             clearInterval(this._presTimer);
             this.layoutDoc.presStatus = "manual";
@@ -250,7 +252,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     clearInterval(this._presTimer);
                     this.layoutDoc.presStatus = "manual";
                 }
-            }, activeItem.presDuration ? NumCast(activeItem.presDuration) : 2000);
+            }, targetDoc.presDuration ? NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition) : 2000);
             // for (let i = this.itemIndex + 1; i <= this.childDocs.length; i++) {
             //     if (this.itemIndex + 1 === this.childDocs.length) {
             //         clearTimeout(this._presTimer);
@@ -323,12 +325,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @undoBatch
     movementChanged = action((movement: string) => {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         if (movement === 'zoom') {
             activeItem.presZoomButton = !activeItem.presZoomButton;
             activeItem.presNavButton = false;
         } else if (movement === 'nav') {
             activeItem.presZoomButton = false;
             activeItem.presNavButton = !activeItem.presNavButton;
+        } else if (movement === 'swap') {
+            targetDoc.presTransition = 0;
         } else {
             activeItem.presZoomButton = false;
             activeItem.presNavButton = false;
@@ -443,13 +448,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    @action
+    onHideDocumentUntilPressClick = () => {
+        this.childDocs.forEach((doc, index) => {
+            const curDoc = Cast(doc, Doc, null);
+            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
+            if (tagDoc.presEffect === 'None' || !tagDoc.presEffect) {
+                tagDoc.opacity = 1;
+            } else {
+                if (index <= this.itemIndex) {
+                    tagDoc.opacity = 1;
+                } else {
+                    tagDoc.opacity = 0;
+                }
+            }
+        });
+    }
+
 
     @observable private transitionTools: boolean = false;
     @observable private newDocumentTools: boolean = false;
     @observable private progressivizeTools: boolean = false;
     @observable private moreInfoTools: boolean = false;
     @observable private playTools: boolean = false;
-
     @observable private pathBoolean: boolean = false;
 
     // For toggling transition toolbar
@@ -556,11 +577,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 paths.push(<polyline
                     points={pathPoints}
                     style={{
-                        opacity: 1,
+                        opacity: 0.7,
                         stroke: "#69a6db",
                         strokeWidth: 5,
                     }}
-                    markerStart="url(#dot)"
+                    markerStart="url(#square)"
                     markerEnd="url(#arrow)" />);
             }
         }
@@ -608,15 +629,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (targetDoc) targetDoc.presTransition = timeInMS;
     }
 
+    setDurationTime = (number: String) => {
+        const timeInMS = Number(number) * 1000;
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        if (targetDoc) targetDoc.presDuration = timeInMS;
+    }
+
     @computed get transitionDropdown() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
 
         if (activeItem) {
             const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-            const transitionSpeed = targetDoc ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
-            const visibilityTime = targetDoc ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
-            const thumbLocation = String(-9.48 * Number(transitionSpeed) + 93);
+            const transitionSpeed = targetDoc.presTransition ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
+            const duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2;
+            const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93);
+            const durationThumbLocation = String(9.48 * Number(duration));
             const movement = activeItem.presZoomButton ? 'Zoom' : activeItem.presNavbutton ? 'Navigate' : 'None';
+            const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
             const visibility = activeItem.presFadeButton ? 'Fade' : activeItem.presHideTillShownButton ? 'Hide till shown' : activeItem.presHideAfter ? 'Hide on exit' : 'None';
             return (
                 <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
@@ -632,37 +662,30 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 <div className={`presBox-dropdownOption ${!activeItem.presZoomButton && !activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div>
                                 <div className={`presBox-dropdownOption ${activeItem.presZoomButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom</div>
                                 <div className={`presBox-dropdownOption ${activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('swap')}>Swap</div>
                             </div>
                         </div>
                         <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed} className={`toolbar-slider ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
                         <div className={`slider-headers ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`}>
-                            <div className={`slider-value ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} style={{ left: thumbLocation + '%' }}>{transitionSpeed}s</div>
+                            <div className={`slider-value ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} style={{ left: transitionThumbLocation + '%' }}>{transitionSpeed}s</div>
                             <div className="slider-text">Slow</div>
                             <div className="slider-text">Medium</div>
                             <div className="slider-text">Fast</div>
                         </div>
                     </div>
                     <div className="ribbon-box">
-                        Visibility
+                        Duration
                         <div className="presBox-dropdown"
                             onPointerDown={e => e.stopPropagation()}
-                        // onClick={() => this.dropdownToggle('Movement')}
                         >
-                            {visibility}
-                            <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
-                            <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
-                                <div className={`presBox-dropdownOption ${!activeItem.presFadeButton && !activeItem.presHideAfterButton && !activeItem.presHideTillShownButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.visibilityChanged('none')}>None</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presFadeButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.visibilityChanged('fade')}>Fade on exit</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presHideAfterButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.visibilityChanged('hideAfter')}>Hide on exit</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presHideTillShownButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.visibilityChanged('hideBefore')}>Hidden til presented</div>
-                            </div>
+                            {duration} seconds
                         </div>
-                        <div className={`slider-value ${activeItem.presFadeButton ? "" : "none"}`} style={{ left: thumbLocation + '%' }}>{transitionSpeed}s</div>
-                        <input type="range" step="0.1" min="0.1" max="10" value={visibilityTime} className={`toolbar-slider ${activeItem.presFadeButton ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
-                        <div className={`slider-headers ${activeItem.presFadeButton ? "" : "none"}`}>
-                            <div className="slider-text">Slow</div>
-                            <div className="slider-text">Medium</div>
-                            <div className="slider-text">Fast</div>
+                        <input type="range" step="0.1" min="0.1" max="10" value={duration} style={{ transform: 'rotate(0deg)' }} className={"toolbar-slider"} id="duration-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
+                        <div className={"slider-headers"}>
+                            <div className={"slider-value"} style={{ left: durationThumbLocation + '%' }}>{duration}s</div>
+                            <div className="slider-text">Short</div>
+                            <div className="slider-text"></div>
+                            <div className="slider-text">Long</div>
                         </div>
                         {/* <div title="Fade After" className={`ribbon-button ${activeItem.presFadeButton ? "active" : ""}`} onClick={this.onFadeDocumentAfterPresentedClick}>Fade After</div> */}
                         {/* <div title="Hide After" className={`ribbon-button ${activeItem.presHideTillShownButton ? "active" : ""}`} onClick={() => console.log("hide before")}>Hide Before</div> */}
@@ -674,12 +697,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             onPointerDown={e => e.stopPropagation()}
                         // onClick={() => this.dropdownToggle('Movement')}
                         >
-                            None
+                            {effect}
                             <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
                             <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
-                                <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()}>None</div>
+                                <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'None'}>None</div>
+                                <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Fade'}>Fade In</div>
+                                <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Flip'}>Flip</div>
+                                <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Rotate'}>Rotate</div>
+                                <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Bounce'}>Bounce</div>
+                                <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Roll'}>Roll</div>
                             </div>
                         </div>
+                        <div className="effectDirection">
+                            <div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "left" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'left'}><FontAwesomeIcon icon={"angle-right"} /></div>
+                            <div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "right" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'right'}><FontAwesomeIcon icon={"angle-left"} /></div>
+                            <div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === "top" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'top'}><FontAwesomeIcon icon={"angle-down"} /></div>
+                            <div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: targetDoc.presEffectDirection === "bottom" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'bottom'}><FontAwesomeIcon icon={"angle-up"} /></div>
+                            <div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: targetDoc.presEffectDirection ? "solid 2px black" : "solid 2px #5a9edd", borderRadius: "100%" }} onClick={() => targetDoc.presEffectDirection = false}></div>
+                        </div>
                     </div>
                     <div className="ribbon-final-box">
                         {this._selectedArray.length} selected
@@ -688,10 +723,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         </div>
                     </div>
                     <div className="ribbon-final-box">
-                        <div className="ribbon-final-button">
+                        <div className={this._selectedArray.length === 0 ? "ribbon-final-button" : "ribbon-final-button-hidden"} onClick={() => this.applyTo(this._selectedArray)}>
                             Apply to selected
                         </div>
-                        <div className="ribbon-final-button">
+                        <div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>
                             Apply to all
                         </div>
                     </div>
@@ -700,6 +735,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    applyTo = (array: Doc[]) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        array.forEach((doc, index) => {
+            const curDoc = Cast(doc, Doc, null);
+            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
+            if (tagDoc && targetDoc) {
+                tagDoc.presTransition = targetDoc.presTransition;
+                tagDoc.presDuration = targetDoc.presDuration;
+                tagDoc.presEffect = targetDoc.presEffect;
+            }
+        });
+    }
+
     public inputRef = React.createRef<HTMLInputElement>();
 
 
@@ -846,7 +895,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     @computed get moreInfoDropdown() {
         return (<div></div>);
+    }
+
+    @computed get effectOpenBracket() {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        if (targetDoc.presEffect && this.itemIndex) {
+            return ("<" + targetDoc.presEffect + "when=" + this.layoutDoc === PresBox.Instance.childDocs[this.itemIndex].presentationTargetDoc + ">");
+        } else return;
+    }
 
+    @computed get effectCloseBracket() {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        if (targetDoc.presEffect && this.itemIndex) {
+            return ("</" + targetDoc.presEffect + ">");
+        } else return;
     }
 
     @computed get toolbar() {
@@ -895,8 +959,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <div className="toolbar-button">
                         <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
                     </div>
-                    <div className="toolbar-button" onClick={this.toggleMoreInfo}>
-                        <div className="toolbar-moreInfo">
+                    <Fade left when={this.moreInfoTools}>
+                        <h1>uppercase</h1>
+                    </Fade>
+                    <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
+                        <div className={`toolbar-moreInfo ${this.moreInfoTools ? "active" : ""}`}>
                             <div className="toolbar-moreInfoBall" />
                             <div className="toolbar-moreInfoBall" />
                             <div className="toolbar-moreInfoBall" />
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts
index 452882e09..799a3ee6f 100644
--- a/src/typings/index.d.ts
+++ b/src/typings/index.d.ts
@@ -6,7 +6,10 @@ declare module 'cors';
 
 declare module 'webrtc-adapter';
 declare module 'bezier-curve';
-declare module 'fit-curve'
+declare module 'fit-curve';
+declare module 'reveal';
+declare module 'react-reveal';
+declare module 'react-reveal/makeCarousel';
 
 
 declare module '@react-pdf/renderer' {
diff --git a/tsconfig.json b/tsconfig.json
index 803245ca6..b06cec79f 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -15,7 +15,8 @@
             "es2015"
         ],
         "typeRoots": [
-            "node_modules/@types"
+            "node_modules/@types",
+            "./src/typings"
         ],
         "types": [
             "youtube"
-- 
cgit v1.2.3-70-g09d2


From ad6762c369fd0933326579707ecbc34fda42ab6c Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Mon, 20 Jul 2020 22:53:08 +0800
Subject: ui updates + progressivize features

---
 deploy/index.html                                  |   1 +
 src/client/documents/Documents.ts                  |   3 +
 src/client/views/collections/CollectionMenu.scss   |  60 +--
 .../collectionFreeForm/CollectionFreeFormView.scss |  56 ++-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  62 ++-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  34 +-
 src/client/views/nodes/PresBox.scss                |  68 ++-
 src/client/views/nodes/PresBox.tsx                 | 504 +++++++++++++++------
 .../views/presentationview/PresElementBox.scss     |  40 +-
 .../views/presentationview/PresElementBox.tsx      |  25 +-
 10 files changed, 602 insertions(+), 251 deletions(-)

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

diff --git a/deploy/index.html b/deploy/index.html
index 82e8c53a3..990ca510d 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -3,6 +3,7 @@
 <head>
     <title>Dash Web</title>
     <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
+    <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500' rel='stylesheet'>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
         integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
     <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/3.3.1/typescript.min.js"></script>
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 080369afe..89a7c0f18 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -133,8 +133,11 @@ export interface DocumentOptions {
     currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide)
     lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide)
     activeFrame?: number; // the active frame of a document in a frame base collection
+    appearFrame?: number; // the frame in which the document appears
     presTransition?: number; //the time taken for the transition TO a document
     presDuration?: number; //the duration of the slide in presentation view
+    // xArray?: number[];
+    // yArray?: number[];
     borderRounding?: string;
     boxShadow?: string;
     dontRegisterChildViews?: boolean;
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 348b9e6ea..929c22c35 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -312,44 +312,44 @@
     align-items: center;
 
     .fwdKeyframe,
-    .numKeyframe,
-    .backKeyframe {
-        cursor: pointer;
-        position: absolute;
-        width: 20;
-        height: 30;
-        bottom: 0;
-        background: #121721;
-        display: flex;
-        align-items: center;
-        color: white;
-    }
+.numKeyframe,
+.backKeyframe {
+    cursor: pointer;
+    position: absolute;
+    width: 20;
+    height: 30;
+    bottom: 0;
+    background: #121721;
+    display: flex;
+    align-items: center;
+    color: white;
+}
 
-    .backKeyframe {
-        left: 0;
+.backKeyframe {
+    left: 0;
 
-        svg {
-            display: block;
-            margin: auto;
-        }
+    svg {
+        display: block;
+        margin: auto;
     }
+}
 
-    .numKeyframe {
-        left: 20;
-        display: flex;
-        flex-direction: column;
-        padding: 5px;
-    }
+.numKeyframe {
+    left: 20;
+    display: flex;
+    flex-direction: column;
+    padding: 5px;
+}
 
-    .fwdKeyframe {
-        left: 40;
+.fwdKeyframe {
+    left: 40;
 
-        svg {
-            display: block;
-            margin: auto;
-        }
+    svg {
+        display: block;
+        margin: auto;
     }
 }
+}
 
 .collectionSchemaViewChrome-cont {
     display: flex;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index fad90ca32..b50a93775 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -46,21 +46,69 @@
     }
 }
 
+.pathOrder {
+    position: absolute;
+    z-index: 200000;
+
+    .pathOrder-frame {
+        position: absolute;
+        width: 40;
+        text-align: center;
+        font-size: 30;
+        background-color: #69a6db;
+        font-family: Roboto;
+        font-weight: 300;
+    }
+}
+
 .progressivizeButton {
     position: absolute;
-    display: flex;
+    display: grid;
+    grid-template-columns: auto 20px auto;
     transform: translate(-105%, 0);
     align-items: center;
     border: black solid 1px;
     border-radius: 3px;
     justify-content: center;
-    width: 30;
+    width: 40;
+    z-index: 30000;
     height: 20;
-    background-color: #c8c8c8;
+    overflow: hidden;
+    background-color: #d5dce2;
+    transition: all 1s;
+
+    .progressivizeButton-prev:hover {
+        color: #5a9edd;
+    }
+
+    .progressivizeButton-frame {
+        justify-self: center;
+        text-align: center;
+        width: 15px;
+    }
+
+    .progressivizeButton-next:hover {
+        color: #5a9edd;
+    }
+}
+
+.progressivizeMove-frame {
+    width: 40px;
+    border-radius: 2px;
+    z-index: 100000;
+    color: white;
+    text-align: center;
+    background-color: #5a9edd;
+    transform: translate(-105%, -110%);
 }
 
 .progressivizeButton:hover {
-    background-color: #aedef8;
+    box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.5);
+
+    .progressivizeButton-frame {
+        background-color: #5a9edd;
+        color: white;
+    }
 }
 
 .collectionFreeform-customText {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 45c5c6a40..953b218b2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1408,7 +1408,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                     centeringShiftX={this.centeringShiftX}
                     centeringShiftY={this.centeringShiftY}
                     presPaths={BoolCast(this.Document.presPathView)}
-                    // progressivize={BoolCast(this.Document.editProgressivize)}
+                    progressivize={BoolCast(this.Document.editProgressivize)}
                     transition={Cast(this.layoutDoc._viewTransition, "string", null)}
                     viewDefDivClick={this.props.viewDefDivClick}
                     zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
@@ -1493,44 +1493,56 @@ interface CollectionFreeFormViewPannableContentsProps {
     children: () => JSX.Element[];
     transition?: string;
     presPaths?: boolean;
-    // progressivize?: boolean;
+    progressivize?: boolean;
 }
 
 @observer
 class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
-    // @computed get progressivize() {
-    //     if (this.props.progressivize) {
-    //         console.log("should render");
-    //         return (
-    //             <>
-    //                 {PresBox.Instance.progressivizeChildDocs}
-    //             </>
-    //         );
-    //     }
-    // }
+    @computed get progressivize() {
+        if (this.props.progressivize) {
+            console.log("should render");
+            return (
+                <>
+                    {PresBox.Instance.progressivizeChildDocs}
+                </>
+            );
+        }
+    }
 
     @computed get presPaths() {
         const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden");
         if (this.props.presPaths) {
             return (
-                <svg className={presPaths}>
-                    <defs>
-                        <marker id="arrow" markerWidth="5" overflow="visible" markerHeight="3" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
-                            <path d="M0,0 L0,6 L9,3 z" fill="#40B3D8" />
-                        </marker>
-                        <marker id="square" markerWidth="3" markerHeight="3"
-                            refX="5" refY="5" orient="auto">
-                            <path d="M 5,1 L 9,5 5,9 1,5 z" fill="#40B3D8" />
-                        </marker>
-                    </defs>;
+                <>
+                    <div>{PresBox.Instance.order}</div>
+                    <svg className={presPaths}>
+                        <defs>
+                            <marker id="arrow" markerWidth="3" overflow="visible" markerHeight="3" refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
+                                <path d="M0,0 L0,6 L9,3 z" fill="#69a6db" />
+                            </marker>
+                            <marker id="square" markerWidth="3" markerHeight="3" overflow="visible"
+                                refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
+                                <path d="M 5,1 L 9,5 5,9 1,5 z" fill="#69a6db" />
+                            </marker>
+                            <marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4"
+                                orient="auto" overflow="visible">
+                                <rect width="3" height="3" fill="#69a6db" />
+                            </marker>
+
+                            <marker id="markerArrow" markerWidth="5" markerHeight="5" refX="2" refY="3"
+                                orient="auto" overflow="visible">
+                                <path d="M2,2 L2,13 L8,7 L2,2" fill="#69a6db" />
+                            </marker>
+                        </defs>;
                     {PresBox.Instance.paths}
-                </svg>
+                    </svg>
+                </>
             );
         }
     }
 
     render() {
-        trace();
+        // trace();
         const freeformclass = "collectionfreeformview" + (this.props.viewDefDivClick ? "-viewDef" : "-none");
         const cenx = this.props.centeringShiftX();
         const ceny = this.props.centeringShiftY();
@@ -1544,7 +1556,7 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
             }}>
             {this.props.children()}
             {this.presPaths}
-            {/* {this.progressivize} */}
+            {this.progressivize}
         </div>;
     }
 }
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index b975e24e2..2cf2ab35d 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -119,18 +119,23 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             const curTimecode = progressivize ? i : timecode;
             const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
-            const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1));
-            const oarray: number[] = [];
+            const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1));
+            let oarray: List<number>;
             console.log(doc.title + "AF: " + doc.appearFrame);
             console.log("timecode: " + timecode);
+            oarray = olist;
             oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
             oarray.fill(1, NumCast(doc.appearFrame), timecode);
+            // oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
+            // oarray.fill(1, NumCast(doc.appearFrame), timecode);
             console.log(oarray);
             xlist[curTimecode] = NumCast(doc.x);
             ylist[curTimecode] = NumCast(doc.y);
+            doc.xArray = xlist;
+            doc.yArray = ylist;
             doc["x-indexed"] = xlist;
             doc["y-indexed"] = ylist;
-            doc["opacity-indexed"] = olist;
+            doc["opacity-indexed"] = oarray;
             doc.activeFrame = ComputedField.MakeFunction("self.context?.currentFrame||0");
             doc.x = ComputedField.MakeInterpolated("x", "activeFrame");
             doc.y = ComputedField.MakeInterpolated("y", "activeFrame");
@@ -157,14 +162,23 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             PanelWidth={this.panelWidth}
             PanelHeight={this.panelHeight} />;
         if (this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc) {
+            const effectProps = {
+                left: this.layoutDoc.presEffectDirection === 'left',
+                right: this.layoutDoc.presEffectDirection === 'right',
+                top: this.layoutDoc.presEffectDirection === 'top',
+                bottom: this.layoutDoc.presEffectDirection === 'bottom',
+                opposite: true,
+                delay: this.layoutDoc.presTransition,
+                // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc,
+            };
             switch (this.layoutDoc.presEffect) {
-                case "Zoom": return (<Zoom>{node}</Zoom>); break;
-                case "Fade": return (<Fade>{node}</Fade>); break;
-                case "Flip": return (<Flip>{node}</Flip>); break;
-                case "Rotate": return (<Rotate>{node}</Rotate>); break;
-                case "Bounce": return (<Bounce>{node}</Bounce>); break;
-                case "Roll": return (<Roll>{node}</Roll>); break;
-                case "LightSpeed": return (<LightSpeed>{node}</LightSpeed>); break;
+                case "Zoom": return (<Zoom {...effectProps}>{node}</Zoom>); break;
+                case "Fade": return (<Fade {...effectProps}>{node}</Fade>); break;
+                case "Flip": return (<Flip {...effectProps}>{node}</Flip>); break;
+                case "Rotate": return (<Rotate {...effectProps}>{node}</Rotate>); break;
+                case "Bounce": return (<Bounce {...effectProps}>{node}</Bounce>); break;
+                case "Roll": return (<Roll {...effectProps}>{node}</Roll>); break;
+                case "LightSpeed": return (<LightSpeed {...effectProps}>{node}</LightSpeed>); break;
                 case "None": return node; break;
                 default: return node; break;
             }
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index bf31f71d2..45bb4293b 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -3,6 +3,7 @@
     display: block;
     pointer-events: inherit;
     z-index: 2;
+    font-family: Roboto;
     box-shadow: #AAAAAA .2vw .2vw .4vw;
     width: 100%;
     min-width: 20px;
@@ -16,7 +17,7 @@
         position: relative;
         height: calc(100% - 25px);
         width: 100%;
-        margin-top: 10px;
+        margin-top: 3px;
     }
 
     .presBox-toolbar {
@@ -39,12 +40,6 @@
             display: flex;
             align-items: center;
             transition: 0.5s;
-
-            @media only screen and (max-width: 400) {
-                .toolbar-buttonText {
-                    display: none;
-                }
-            }
         }
 
         .toolbar-button.active {
@@ -116,6 +111,7 @@
 .presBox-ribbon {
     position: relative;
     display: none;
+    font-family: Roboto;
     background-color: white;
     color: black;
     width: 100%;
@@ -123,6 +119,10 @@
     z-index: 100;
     transition: 0.7s;
 
+    .ribbon-doubleButton {
+        display: inline-flex;
+    }
+
     .toolbar-slider {
         position: relative;
         align-self: center;
@@ -199,16 +199,56 @@
 
     .ribbon-textInput {
         border-radius: 2px;
-        height: 25px;
+        height: 20px;
         font-size: 10;
         font-weight: 100;
         align-self: center;
         justify-self: center;
         padding-left: 10px;
         border: solid 1px black;
+        min-width: 80px;
         width: 100%;
     }
 
+    .ribbon-frameSelector {
+        border: black solid 1px;
+        width: 60px;
+        height: 20px;
+        display: grid;
+        grid-template-columns: auto 27px auto;
+        position: relative;
+        border-radius: 5px;
+        overflow: hidden;
+        align-items: center;
+        justify-self: left;
+
+        .fwdKeyframe,
+        .backKeyframe {
+            cursor: pointer;
+            position: relative;
+            height: 100%;
+            background: #d5dce2;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            text-align: center;
+            color: black;
+        }
+
+        .numKeyframe {
+            font-size: 10;
+            font-weight: 600;
+            position: relative;
+            color: black;
+            display: flex;
+            width: 100%;
+            height: 100%;
+            text-align: center;
+            align-items: center;
+            justify-content: center;
+        }
+    }
+
     .ribbon-final-box {
         align-self: flex-start;
         justify-self: center;
@@ -279,10 +319,12 @@
     .ribbon-button {
         font-size: 10;
         font-weight: 200;
-        height: 25;
+        height: 20;
         border: solid 1px black;
         display: flex;
-        border-radius: 10px;
+        margin-top: 5px;
+        margin-bottom: 5px;
+        border-radius: 5px;
         margin-right: 5px;
         width: max-content;
         justify-content: center;
@@ -326,8 +368,8 @@
                 display: block;
                 padding-left: 5px;
                 padding-right: 5px;
-                margin-top: 3;
-                margin-bottom: 3;
+                padding-top: 3;
+                padding-bottom: 3;
             }
 
             .presBox-dropdownOption:hover {
@@ -337,7 +379,7 @@
 
             .presBox-dropdownOption.active {
                 position: relative;
-                background-color: #9CE2F8;
+                background-color: #aedef8;
             }
 
             .presBox-dropdownOptions {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index fc5e73c81..9b942c065 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -2,10 +2,10 @@ import React = require("react");
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, DocCastAsync } from "../../../fields/Doc";
+import { Doc, DocListCast, DocCastAsync, WidthSym } from "../../../fields/Doc";
 import { InkTool } from "../../../fields/InkField";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { returnFalse, returnOne } from "../../../Utils";
+import { returnFalse, returnOne, numberRange } from "../../../Utils";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
@@ -25,6 +25,9 @@ import { SearchUtil } from "../../util/SearchUtil";
 import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
 import { child } from "serializr";
 import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal';
+import { List } from "../../../fields/List";
+import { Tooltip } from "@material-ui/core";
+import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
 
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
@@ -60,11 +63,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.rootDoc._forceRenderEngine = "timeline";
         this.rootDoc._replacedChrome = "replaced";
         this.layoutDoc.presStatus = "edit";
-        document.addEventListener("keydown", this.keyEvents, false);
+        // document.addEventListener("keydown", this.keyEvents, false);
     }
 
-    componentWillUnmount() {
-        document.removeEventListener("keydown", this.keyEvents, false);
+    // componentWillUnmount() {
+    //     document.removeEventListener("keydown", this.keyEvents, false);
+    // }
+
+    onPointerOver = () => {
+        document.addEventListener("keydown", this.keyEvents, true);
+        // document.addEventListener("keydown", this.keyEvents, false);
+    }
+
+    onPointerLeave = () => {
+        // document.removeEventListener("keydown", this.keyEvents, false);
+        document.removeEventListener("keydown", this.keyEvents, true);
     }
 
     updateCurrentPresentation = () => Doc.UserDoc().activePresentation = this.rootDoc;
@@ -114,50 +127,77 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+
+    @action
+    onHideDocumentUntilPressClick = () => {
+        this.childDocs.forEach((doc, index) => {
+            const curDoc = Cast(doc, Doc, null);
+            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
+            if (tagDoc.presEffect === 'None' || !tagDoc.presEffect) {
+                tagDoc.opacity = 1;
+            } else {
+                if (index <= this.itemIndex) {
+                    tagDoc.opacity = 1;
+                } else {
+                    tagDoc.opacity = 0;
+                }
+            }
+        });
+    }
+
     /**
      * This is the method that checks for the actions that need to be performed
-     * after the document has been presented, which involves 3 button options:
+     * before the document has been presented, which involves 3 button options:
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
-    showAfterPresented = (index: number) => {
+    @action
+    hideDocumentInPres = () => {
         this.updateCurrentPresentation();
-        this.childDocs.forEach((doc, ind) => {
-            const presTargetDoc = doc.presentationTargetDoc as Doc;
-            //the order of cases is aligned based on priority
-            if (doc.presHideTillShownButton && ind <= index) {
-                presTargetDoc.opacity = 1;
-            }
-            if (doc.presHideAfterButton && ind < index) {
-                presTargetDoc.opacity = 0;
+        this.childDocs.forEach((doc, i) => {
+            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            console.log("HB: " + doc.presHideTillShownButton);
+            console.log("HA: " + doc.presHideAfterButton);
+            if (doc.presHideTillShownButton) {
+                if (i < this.itemIndex) {
+                    console.log(i + 1 + "hide before");
+                    tagDoc.opacity = 0;
+                    console.log(tagDoc.opacity);
+                } else {
+                    tagDoc.opacity = 1;
+                }
             }
-            if (doc.presFadeButton && ind < index) {
-                presTargetDoc.opacity = 0.5;
+            if (doc.presHideAfterButton) {
+                if (i > this.itemIndex) {
+                    console.log(i + 1 + "hide after");
+                    tagDoc.opacity = 0;
+                    console.log(tagDoc.opacity);
+                } else {
+                    tagDoc.opacity = 1;
+                }
             }
         });
     }
 
     /**
      * This is the method that checks for the actions that need to be performed
-     * before the document has been presented, which involves 3 button options:
+     * after the document has been presented, which involves 3 button options:
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
-    hideIfNotPresented = (index: number) => {
+    showAfterPresented = (index: number) => {
         this.updateCurrentPresentation();
-        this.childDocs.forEach((key, ind) => {
+        this.childDocs.forEach((doc, ind) => {
+            const presTargetDoc = doc.presentationTargetDoc as Doc;
             //the order of cases is aligned based on priority
-            const presTargetDoc = key.presentationTargetDoc as Doc;
-            if (key.hideAfterButton && ind >= index) {
-                presTargetDoc.opacity = 1;
-            }
-            if (key.fadeButton && ind >= index) {
+            if (doc.presHideTillShownButton && ind <= index) {
                 presTargetDoc.opacity = 1;
             }
-            if (key.hideTillShownButton && ind > index) {
+            if (doc.presHideAfterButton && ind < index) {
                 presTargetDoc.opacity = 0;
             }
         });
     }
 
+
     /**
      * This method makes sure that cursor navigates to the element that
      * has the option open and last in the group. If not in the group, and it has
@@ -224,9 +264,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             //     this.startPresentation(index);
             // }
             this.navigateToElement(this.childDocs[index], fromDoc);
-            this.hideIfNotPresented(index);
-            this.showAfterPresented(index);
-            this.onHideDocumentUntilPressClick();
+            // this.hideIfNotPresented(index);
+            // this.showAfterPresented(index);
+            this.hideDocumentInPres();
+            // this.onHideDocumentUntilPressClick();
         }
     });
 
@@ -340,24 +381,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     });
 
-    @undoBatch
-    visibilityChanged = action((visibility: string) => {
-        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        if (visibility === 'fade') {
-            activeItem.presFadeButton = !activeItem.presFadeButton;
-        } else if (visibility === 'hideBefore') {
-            activeItem.presHideTillShownButton = !activeItem.presHideTillShownButton;
-            activeItem.presHideAfterButton = false;
-        } else if (visibility === 'hideAfter') {
-            activeItem.presHideAfterButton = !activeItem.presHideAfterButton;
-            activeItem.presHideAfterButton = false;
-        } else {
-            activeItem.presHideAfterButton = false;
-            activeItem.presHideTillShownButton = false;
-            activeItem.presFadeButton = false;
-        }
-    });
-
     whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
     addDocumentFilter = (doc: Doc | Doc[]) => {
         const docs = doc instanceof Doc ? [doc] : doc;
@@ -433,39 +456,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             if (this.layoutDoc.presStatus === "edit") this._selectedArray = [];
             else this.layoutDoc.presStatus = "edit";
             // Ctrl-A to select all
-        } else if ((e.metaKey || e.altKey) && e.keyCode === 65) {
+        } if ((e.metaKey || e.altKey) && e.keyCode === 65) {
             if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs;
             // left / a / up to go back
-        } else if (e.keyCode === 37 || 65 || 38) {
+        } if (e.keyCode === 37 || 65 || 38) {
             if (this.layoutDoc.presStatus !== "edit") this.back();
             // right / d / down to go to next
-        } else if (e.keyCode === 39 || 68 || 40) {
+        } if (e.keyCode === 39 || 68 || 40) {
             if (this.layoutDoc.presStatus !== "edit") this.next();
             // spacebar to 'present' or go to next slide
-        } else if (e.keyCode === 32) {
+        } if (e.keyCode === 32) {
             if (this.layoutDoc.presStatus !== "edit") this.next();
             else this.layoutDoc.presStatus = "manual";
         }
     }
 
-    @action
-    onHideDocumentUntilPressClick = () => {
-        this.childDocs.forEach((doc, index) => {
-            const curDoc = Cast(doc, Doc, null);
-            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
-            if (tagDoc.presEffect === 'None' || !tagDoc.presEffect) {
-                tagDoc.opacity = 1;
-            } else {
-                if (index <= this.itemIndex) {
-                    tagDoc.opacity = 1;
-                } else {
-                    tagDoc.opacity = 0;
-                }
-            }
-        });
-    }
-
-
     @observable private transitionTools: boolean = false;
     @observable private newDocumentTools: boolean = false;
     @observable private progressivizeTools: boolean = false;
@@ -562,30 +567,60 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         // }
     }
 
+    @computed get order() {
+        const order: JSX.Element[] = [];
+        this.childDocs.forEach((doc, index) => {
+            const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            order.push(
+                <div className="pathOrder" style={{ top: NumCast(targetDoc.y), left: NumCast(targetDoc.x) }}>
+                    <div className="pathOrder-frame">{index + 1}</div>
+                </div>);
+        });
+        return order;
+    }
+
     @computed get paths() {
-        const paths = []; //List of all of the paths that need to be added
+        // const paths = []; //List of all of the paths that need to be added
+        let pathPoints = "";
         console.log(this.childDocs.length - 1);
-        for (let i = 0; i <= this.childDocs.length - 1; i++) {
-            const targetDoc = Cast(this.childDocs[i].presentationTargetDoc, Doc, null);
-            if (this.childDocs[i + 1] && targetDoc) {
-                const nextTargetDoc = Cast(this.childDocs[i + 1].presentationTargetDoc, Doc, null);
+        this.childDocs.forEach((doc, index) => {
+            const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            if (targetDoc) {
                 const n1x = NumCast(targetDoc.x) + (NumCast(targetDoc._width) / 2);
                 const n1y = NumCast(targetDoc.y) + (NumCast(targetDoc._height) / 2);
-                const n2x = NumCast(nextTargetDoc.x) + (NumCast(targetDoc._width) / 2);
-                const n2y = NumCast(nextTargetDoc.y) + (NumCast(targetDoc._height) / 2);
-                const pathPoints = n1x + "," + n1y + " " + n2x + "," + n2y;
-                paths.push(<polyline
-                    points={pathPoints}
-                    style={{
-                        opacity: 0.7,
-                        stroke: "#69a6db",
-                        strokeWidth: 5,
-                    }}
-                    markerStart="url(#square)"
-                    markerEnd="url(#arrow)" />);
+                // const n2x = NumCast(nextTargetDoc.x) + (NumCast(targetDoc._width) / 2);
+                // const n2y = NumCast(nextTargetDoc.y) + (NumCast(targetDoc._height) / 2);
+                if (index = 0) pathPoints = n1x + "," + n1y;
+                else pathPoints = pathPoints + " " + n1x + "," + n1y;
+                // const pathPoints = n1x + "," + n1y + " " + n2x + "," + n2y;
+                // else pathPoints = pathPoints + " " + n1x + "," + n1y;
+                // paths.push(<polyline
+                //     points={pathPoints}
+                //     style={{
+                //         opacity: 1,
+                //         stroke: "#69a6db",
+                //         strokeWidth: 5,
+                //     }}
+                //     markerStart="url(#square)"
+                //     markerEnd="url(#arrow)" />);
             }
-        }
-        return paths;
+        });
+        console.log(pathPoints);
+        // return paths;
+        return (<polyline
+            points={pathPoints}
+            style={{
+                opacity: 1,
+                stroke: "#69a6db",
+                strokeWidth: 5,
+            }}
+            fill="none"
+            // markerStart="url(#square)"
+            // markerEnd="url(#arrow)" 
+            marker-start="url(#markerSquare)"
+            marker-mid="url(#markerSquare)"
+            marker-end="url(#markerArrow)"
+        />);
     }
 
     @action togglePath = () => this.pathBoolean = !this.pathBoolean;
@@ -638,16 +673,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     @computed get transitionDropdown() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-
-        if (activeItem) {
-            const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        if (activeItem && targetDoc) {
             const transitionSpeed = targetDoc.presTransition ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
             const duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2;
             const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93);
             const durationThumbLocation = String(9.48 * Number(duration));
             const movement = activeItem.presZoomButton ? 'Zoom' : activeItem.presNavbutton ? 'Navigate' : 'None';
             const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
-            const visibility = activeItem.presFadeButton ? 'Fade' : activeItem.presHideTillShownButton ? 'Hide till shown' : activeItem.presHideAfter ? 'Hide on exit' : 'None';
             return (
                 <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                     <div className="ribbon-box">
@@ -669,16 +702,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         <div className={`slider-headers ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`}>
                             <div className={`slider-value ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} style={{ left: transitionThumbLocation + '%' }}>{transitionSpeed}s</div>
                             <div className="slider-text">Slow</div>
-                            <div className="slider-text">Medium</div>
+                            <div className="slider-text"></div>
                             <div className="slider-text">Fast</div>
                         </div>
                     </div>
                     <div className="ribbon-box">
-                        Duration
-                        <div className="presBox-dropdown"
-                            onPointerDown={e => e.stopPropagation()}
-                        >
-                            {duration} seconds
+                        Visibility
+                        <div className="ribbon-doubleButton">
+                            <Tooltip title={<><div className="dash-tooltip">{"Hide before presented"}</div></>}><div className={`ribbon-button ${activeItem.presHideTillShownButton ? "active" : ""}`} onClick={() => activeItem.presHideTillShownButton = !activeItem.presHideTillShownButton}>HB</div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Hide after presented"}</div></>}><div className={`ribbon-button ${activeItem.presHideAfterButton ? "active" : ""}`} onClick={() => activeItem.presHideAfterButton = !activeItem.presHideAfterButton}>HA</div></Tooltip>
                         </div>
                         <input type="range" step="0.1" min="0.1" max="10" value={duration} style={{ transform: 'rotate(0deg)' }} className={"toolbar-slider"} id="duration-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
                         <div className={"slider-headers"}>
@@ -709,11 +741,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             </div>
                         </div>
                         <div className="effectDirection">
-                            <div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "left" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'left'}><FontAwesomeIcon icon={"angle-right"} /></div>
-                            <div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "right" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'right'}><FontAwesomeIcon icon={"angle-left"} /></div>
-                            <div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === "top" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'top'}><FontAwesomeIcon icon={"angle-down"} /></div>
-                            <div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: targetDoc.presEffectDirection === "bottom" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'bottom'}><FontAwesomeIcon icon={"angle-up"} /></div>
-                            <div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: targetDoc.presEffectDirection ? "solid 2px black" : "solid 2px #5a9edd", borderRadius: "100%" }} onClick={() => targetDoc.presEffectDirection = false}></div>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "left" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'left'}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "right" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'right'}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === "top" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'top'}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: targetDoc.presEffectDirection === "bottom" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'bottom'}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: targetDoc.presEffectDirection ? "solid 2px black" : "solid 2px #5a9edd", borderRadius: "100%" }} onClick={() => targetDoc.presEffectDirection = false}></div></Tooltip>
                         </div>
                     </div>
                     <div className="ribbon-final-box">
@@ -782,9 +814,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     </div>
                     <div className="ribbon-box">
                         Choose type:
-                        <div style={{ display: "flex", alignSelf: "center" }}>
-                            <div title="Text" className={`ribbon-button ${type === "text" ? "active" : ""}`} onClick={() => { type = "text"; }}>Text</div>
-                            <div title="Freeform" className={`ribbon-button ${type === "freeform" ? "active" : ""}`} onClick={() => { type = "freeform"; }}>Freeform</div>
+                        <div style={{ display: 'block', alignSelf: 'center' }}>
+                            <div title="Text" className={'ribbon-button'} style={{ background: type === 'text' ? "#000000" : "#f6f6f6" }} onClick={action(() => { type = "text"; })}>Text</div>
+                            <div title="Freeform" className={'ribbon-button'} style={{ background: type === 'freeform' ? "#000000" : "#f6f6f6" }} onClick={action(() => { type = "freeform"; })}>Freeform</div>
                         </div>
                     </div>
                     <div className="ribbon-final-box">
@@ -810,17 +842,43 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         );
     }
 
-    progressivizeOptions = (viewType: string) => {
-        const buttons = [];
-        buttons.push(<div className="ribbon-button" title="Progressivize child documents" onClick={this.progressivize}>Progressivize child documents</div>);
-        buttons.push(<div className="ribbon-button" title="Internal navigation" onClick={() => console.log("hide after")}>Internal navigation</div>);
-        if (viewType === "rtf") {
-            buttons.push(<div className="ribbon-button" title="Progressivize bullet points" onClick={() => console.log("hide after")}>Bullet points</div>);
+    // progressivizeOptions = (viewType: string) => {
+    //     const buttons = [];
+    //     buttons.push(<div className="ribbon-button" onClick={this.progressivize}>Child documents</div>);
+    //     buttons.push(<div className="ribbon-button" onClick={() => console.log("hide after")}>Internal zoom</div>);
+    //     buttons.push(<div className="ribbon-button" onClick={() => console.log("hide after")}>Bullet points</div>);
+    //     if (viewType === "rtf") {
+    //         buttons.push(<div className="ribbon-button" title="Progressivize bullet points" onClick={() => console.log("hide after")}>Bullet points</div>);
+    //     }
+    //     return buttons;
+    // }
+
+    @undoBatch
+    @action
+    nextKeyframe = (tagDoc: Doc): void => {
+        const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
+        const currentFrame = Cast(tagDoc.currentFrame, "number", null);
+        if (currentFrame === undefined) {
+            tagDoc.currentFrame = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
         }
-        return buttons;
+        CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
+        tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1);
+        tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), NumCast(tagDoc.lastFrame));
     }
 
-
+    @undoBatch
+    @action
+    prevKeyframe = (tagDoc: Doc): void => {
+        const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
+        const currentFrame = Cast(tagDoc.currentFrame, "number", null);
+        if (currentFrame === undefined) {
+            tagDoc.currentFrame = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
+        }
+        CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice());
+        tagDoc.currentFrame = Math.max(0, (currentFrame || 0) - 1);
+    }
 
     @computed get progressivizeDropdown() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
@@ -832,16 +890,38 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                         <div className="ribbon-box">
                             {targetDoc.type} selected
-                            <div className="selectedList">
-                                <div className="selectedList-items">1. {targetDoc.title}</div>
+                            <div className="selectedList" style={{ height: 'max-content' }}>
+                                <div className="selectedList-items">{targetDoc.title}</div>
+                            </div>
+                            <div className="ribbon-doubleButton">
+                                <div className="ribbon-frameSelector">
+                                    <div key="back" title="back frame" className="backKeyframe" onClick={e => { e.stopPropagation(); this.prevKeyframe(targetDoc); }}>
+                                        <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
+                                    </div>
+                                    <div key="num" title="toggle view all" className="numKeyframe" style={{ backgroundColor: targetDoc.editing ? "#5a9edd" : "#5a9edd" }}
+                                        onClick={action(() => targetDoc.editing = !targetDoc.editing)} >
+                                        {NumCast(targetDoc.currentFrame)}
+                                    </div>
+                                    <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={e => { e.stopPropagation(); this.nextKeyframe(targetDoc); }}>
+                                        <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
+                                    </div>
+                                </div>
+                                <Tooltip title={<><div className="dash-tooltip">{"Last frame"}</div></>}><div style={{ fontWeight: 600, marginTop: 0, marginLeft: 3 }} className="ribbon-button">{NumCast(targetDoc.lastFrame)}</div></Tooltip>
                             </div>
                         </div>
                         <div className="ribbon-final-box">
-                            <div className="progressivizeEdit">
-                                <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} title="Progressivize child documents" onClick={this.progressivize}>Progressivize child documents</div>
-                                <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "block" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} title="Edit progresivize" onClick={this.editProgressivize}>Edit</div>
+                            <div className="ribbon-doubleButton">
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Child documents</div>
+                                <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "flex" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Edit</div>
+                            </div>
+                            <div className="ribbon-doubleButton">
+                                <div className="ribbon-button" onClick={this.progressivizeZoom}>Internal zoom</div>
+                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.zoomProgressivize ? "#aedef8" : "" }} onClick={this.zoomProgressivize}>Edit</div>
+                            </div>
+                            <div className="ribbon-doubleButton">
+                                <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
+                                <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.textProgressivize ? "#aedef8" : "" }} onClick={this.textProgressivize}>Edit</div>
                             </div>
-                            <div className="ribbon-button" title="Internal navigation" onClick={() => console.log("hide after")}>Internal navigation</div>
                         </div>
                     </div>
                 </div>
@@ -849,8 +929,38 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    //Progressivize Zoom
     @action
-    editProgressivize = (e: React.MouseEvent) => {
+    zoomProgressivize = (e: React.MouseEvent) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        targetDoc.currentFrame = targetDoc.lastFrame;
+        if (targetDoc?.zoomProgressivize) {
+            targetDoc.zoomProgressivize = false;
+        } else {
+            targetDoc.zoomProgressivize = true;
+        }
+    }
+
+    @action
+    progressivizeZoom = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        activeItem.zoomProgressivize = !activeItem.zoomProgressivize;
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
+        targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize;
+        console.log(targetDoc.zoomProgressivize);
+        if (activeItem.zoomProgressivize) {
+            console.log("progressivize");
+            targetDoc.currentFrame = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
+        }
+    }
+
+    //Progressivize Text nodes
+    @action
+    textProgressivize = (e: React.MouseEvent) => {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         targetDoc.currentFrame = targetDoc.lastFrame;
@@ -862,7 +972,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
     @action
-    progressivize = (e: React.MouseEvent) => {
+    progressivizeText = (e: React.MouseEvent) => {
         e.stopPropagation();
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         activeItem.presProgressivize = !activeItem.presProgressivize;
@@ -878,67 +988,163 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    //Progressivize Child Docs
+    @action
+    editProgressivize = (e: React.MouseEvent) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        targetDoc.currentFrame = targetDoc.lastFrame;
+        if (targetDoc?.editProgressivize) {
+            targetDoc.editProgressivize = false;
+        } else {
+            targetDoc.editProgressivize = true;
+        }
+    }
+
+    @action
+    progressivizeChild = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
+        if (!activeItem.presProgressivize) {
+            activeItem.presProgressivize = true;
+            targetDoc.presProgressivize = true;
+            targetDoc.currentFrame = 0;
+            CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
+            targetDoc.lastFrame = docs.length - 1;
+        } else {
+            activeItem.presProgressivize = false;
+            targetDoc.presProgressivize = false;
+            docs.forEach((doc, index) => {
+                doc.appearFrame = 0;
+            });
+            targetDoc.currentFrame = 0;
+            targetDoc.lastFrame = 0;
+        }
+    }
+
+    @action
+    checkMovementLists = (doc: Doc, xlist: any, ylist: any) => {
+        const x: List<number> = xlist;
+        const y: List<number> = ylist;
+        const tags: JSX.Element[] = [];
+        let pathPoints = ""; //List of all of the paths that need to be added
+        // console.log(x);
+        // console.log(x.length);
+        // console.log(x[0]);
+        for (let i = 0; i < x.length - 1; i++) {
+            if (y[i] || x[i]) {
+                if (i === 0) pathPoints = (x[i] - 11) + "," + (y[i] + 33);
+                else pathPoints = pathPoints + " " + (x[i] - 11) + "," + (y[i] + 33);
+                tags.push(<div className="progressivizeMove-frame" style={{ position: 'absolute', top: y[i], left: x[i] }}>{i}</div>);
+            }
+        }
+        tags.push(<svg style={{ overflow: 'visible', position: 'absolute' }}><polyline
+            points={pathPoints}
+            style={{
+                position: 'absolute',
+                opacity: 1,
+                stroke: "#000000",
+                strokeWidth: 2,
+            }}
+            fill="none"
+        /></svg>);
+        return tags;
+    }
+
+    @observable
+    toggleDisplayMovement = (doc: Doc) => {
+        if (doc.displayMovement) doc.displayMovement = false;
+        else doc.displayMovement = true;
+    }
+
     @computed get progressivizeChildDocs() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
         const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
         const tags: JSX.Element[] = [];
         docs.forEach((doc, index) => {
+            if (doc["x-indexed"] && doc["y-indexed"]) {
+                tags.push(<div style={{ position: 'absolute', display: doc.displayMovement ? "block" : "none" }}>{this.checkMovementLists(doc, doc["x-indexed"], doc["y-indexed"])}</div>);
+            }
             tags.push(
-                <div className="progressivizeButton" style={{ top: NumCast(doc.y), left: NumCast(doc.x) }}>{doc.appearFrame}</div>
-            );
+                <div className="progressivizeButton" onPointerLeave={() => { if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? "#aedff8" : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}>
+                    <div className="progressivizeButton-prev"><FontAwesomeIcon icon={"caret-left"} size={"lg"} onClick={e => { e.stopPropagation(); this.prevAppearFrame(doc, index); }} /></div>
+                    <div className="progressivizeButton-frame">{doc.appearFrame}</div>
+                    <div className="progressivizeButton-next"><FontAwesomeIcon icon={"caret-right"} size={"lg"} onClick={e => { e.stopPropagation(); this.nextAppearFrame(doc, index); }} /></div>
+                </div>);
         });
         return tags;
     }
 
-
-
-    @computed get moreInfoDropdown() {
-        return (<div></div>);
+    @undoBatch
+    @action
+    nextAppearFrame = (doc: Doc, i: number): void => {
+        console.log("next");
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        const appearFrame = Cast(doc.appearFrame, "number", null);
+        if (appearFrame === undefined) {
+            doc.appearFrame = 0;
+        }
+        doc.appearFrame = appearFrame + 1;
+        const olist = new List<number>(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1));
+        doc["opacity-indexed"] = olist;
+        console.log(doc.appearFrame);
     }
 
-    @computed get effectOpenBracket() {
+    @undoBatch
+    @action
+    prevAppearFrame = (doc: Doc, i: number): void => {
+        console.log("prev");
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        if (targetDoc.presEffect && this.itemIndex) {
-            return ("<" + targetDoc.presEffect + "when=" + this.layoutDoc === PresBox.Instance.childDocs[this.itemIndex].presentationTargetDoc + ">");
-        } else return;
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        const appearFrame = Cast(doc.appearFrame, "number", null);
+        if (appearFrame === undefined) {
+            doc.appearFrame = 0;
+        }
+        doc.appearFrame = Math.max(0, appearFrame - 1);
+        const olist = new List<number>(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1));
+        doc["opacity-indexed"] = olist;
+        console.log(doc.appearFrame);
     }
 
-    @computed get effectCloseBracket() {
-        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        if (targetDoc.presEffect && this.itemIndex) {
-            return ("</" + targetDoc.presEffect + ">");
-        } else return;
+    @computed get moreInfoDropdown() {
+        return (<div></div>);
     }
 
     @computed get toolbar() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-
+        const parent = document.getElementById('toolbarContainer');
+        let width = 0;
+        if (parent) width = parent.offsetWidth;
+        console.log(width);
         if (activeItem) {
             return (
                 <>
-                    <div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={this.toggleNewDocument}><FontAwesomeIcon icon={"plus"} />
+                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={this.toggleNewDocument}><FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
-                    </div>
+                    </div></Tooltip>
                     <div className="toolbar-divider" />
-                    <div className={`toolbar-button ${this.pathBoolean ? "active" : ""}`}><FontAwesomeIcon title={"View Paths"} icon={"object-group"} onClick={this.viewPaths} /></div>
+                    <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}><div className={`toolbar-button ${this.pathBoolean ? "active" : ""}`}>
+                        <FontAwesomeIcon icon={"object-group"} onClick={this.viewPaths} />
+                    </div></Tooltip>
                     {/* <div className="toolbar-button"><FontAwesomeIcon title={"Portal"} icon={"eye"} onClick={this.toolbarTest} /></div> */}
                     <div className="toolbar-divider" />
                     <div className={`toolbar-button ${this.transitionTools ? "active" : ""}`} onClick={this.toggleTransitionTools}>
                         <FontAwesomeIcon icon={"rocket"} />
-                        <div className="toolbar-buttonText">&nbsp; Transitions</div>
+                        <div style={{ display: width > 400 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Transitions</div>
                         <FontAwesomeIcon className={`dropdown ${this.transitionTools ? "active" : ""}`} icon={"angle-down"} />
                     </div>
                     <div className="toolbar-divider" />
                     <div className={`toolbar-button ${this.progressivizeTools ? "active" : ""}`} onClick={this.toggleProgressivize}>
                         <FontAwesomeIcon icon={"tasks"} />
-                        <div className="toolbar-buttonText">&nbsp; Progressivize</div>
+                        <div style={{ display: width > 400 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Progressivize</div>
                         <FontAwesomeIcon className={`dropdown ${this.progressivizeTools ? "active" : ""}`} icon={"angle-down"} />
                     </div>
                     <div className="toolbar-divider" />
-                    <div className="toolbar-button">
+                    <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
                         <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
                     </div>
                     <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
@@ -977,7 +1183,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     render() {
         this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields 
         const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
-        return <div className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
+        return <div onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
             <div className="presBox-buttons" style={{ display: this.rootDoc._chromeStatus === "disabled" ? "none" : undefined }}>
                 <select className="presBox-viewPicker"
                     onPointerDown={e => e.stopPropagation()}
@@ -1010,7 +1216,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     </div>
                 </div>
             </div>
-            <div className={`presBox-toolbar ${this.layoutDoc.presStatus === "edit" ? "active" : ""}`}> {this.toolbar} </div>
+            <div id="toolbarContainer" className={`presBox-toolbar ${this.layoutDoc.presStatus === "edit" ? "active" : ""}`}> {this.toolbar} </div>
             {this.newDocumentDropdown}
             {this.moreInfoDropdown}
             {this.transitionDropdown}
@@ -1038,7 +1244,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 }
 Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, data: Doc) {
     if (field === 'indexInPres') return DocListCast(container[StrCast(container.presentationFieldKey)]).indexOf(data);
-    if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 50 : 46;
+    if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 30 : 26;
     if (field === 'presStatus') return container.presStatus;
     if (field === '_itemIndex') return container._itemIndex;
     if (field === 'presBox') return container;
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 0e58d77a0..51ad6839c 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -1,14 +1,13 @@
 .presElementBox-item {
     display: grid;
-    grid-template-rows: max-content max-content max-content;
-    background-color: #d0d0d0;
-    box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
+    grid-template-columns: max-content max-content max-content;
+    background-color: #d5dce2;
+    box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.25);
     position: relative;
     pointer-events: all;
     width: 100%;
     height: 100%;
-    outline-color: maroon;
-    outline-style: dashed;
+    font-weight: 400;
     border-radius: 6px;
     -webkit-touch-callout: none;
     -webkit-user-select: none;
@@ -16,7 +15,7 @@
     -moz-user-select: none;
     -ms-user-select: none;
     user-select: none;
-    transition: all .1s;
+    transition: all .3s;
     padding: 0px;
     padding-bottom: 3px;
 
@@ -88,26 +87,36 @@
 }
 
 .presElementBox-name {
+    align-self: center;
     font-size: 13px;
+    font-family: Roboto;
+    font-weight: 500;
     position: relative;
-    left: 10px;
-    top: 4px;
+    top: 1px;
+    padding-left: 10px;
+    padding-right: 10px;
     letter-spacing: normal;
-    width: calc(100% - 60px);
+    max-width: max-content;
     text-overflow: ellipsis;
     overflow: hidden;
     white-space: pre;
 }
 
 .presElementBox-time {
+    align-self: center;
     position: relative;
-    font-size: 8;
-    font-style: italic;
+    top: 2px;
+    padding-right: 10px;
+    font-size: 10;
+    font-weight: 300;
+    font-family: Roboto;
+    /* font-style: italic; */
     letter-spacing: normal;
-    left: 10px;
+    /* left: 10px; */
 }
 
 .presElementBox-embedded {
+    grid-column: 1/8;
     position: relative;
     display: flex;
     width: auto;
@@ -119,10 +128,11 @@
     width: 100%;
     height: 100%;
     position: absolute;
-    left: 0;
+    border-radius: 3px;
     top: 0;
-    background: transparent;
-    z-index: 2;
+    left: 0;
+    z-index: 1;
+    overflow: hidden;
 }
 
 .presElementBox-closeIcon {
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index c503b0678..ab27443d2 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -17,6 +17,7 @@ import React = require("react");
 import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
 import { PresBox } from "../nodes/PresBox";
 import { DocumentType } from "../../documents/DocumentTypes";
+import { Tooltip } from "@material-ui/core";
 
 export const presSchema = createSchema({
     presentationTargetDoc: Doc,
@@ -214,6 +215,20 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
             </div>;
     }
 
+    @computed get duration() {
+        let durationInS: number;
+        if (this.targetDoc.presDuration) durationInS = NumCast(this.targetDoc.presDuration) / 1000;
+        else durationInS = 2;
+        return "D: " + durationInS + "s";
+    }
+
+    @computed get transition() {
+        let transitionInS: number;
+        if (this.targetDoc.presTransition) transitionInS = NumCast(this.targetDoc.presTransition) / 1000;
+        else transitionInS = 0.5;
+        return "T: " + transitionInS + "s";
+    }
+
     render() {
         const treecontainer = this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Tree;
         const className = "presElementBox-item" + (this.itemIndex === this.indexInPres ? " presElementBox-active" : "");
@@ -232,7 +247,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                         console.log("normal click");
                     }
                 }}
-            // onPointerDown={e => e.stopPropagation()}
+                onPointerDown={e => e.stopPropagation()}
             >
                 {treecontainer ? (null) : <>
                     <div className="presElementBox-number">
@@ -241,8 +256,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     <div className="presElementBox-name">
                         {`${this.targetDoc?.title}`}
                     </div>
-                    <div className="presElementBox-time">{"Transition speed: " + (this.targetDoc?.presTransition) + "ms"}</div>
-                    <div className="presElementBox-time" style={{ display: this.targetDoc.presDuration ? "block" : "none" }}>{"Duration: " + (this.targetDoc?.presDuration) + "ms"}</div>
+                    <Tooltip title={<><div className="dash-tooltip">{"Transition speed"}</div></>}><div className="presElementBox-time">{this.transition}</div></Tooltip>
+                    <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presElementBox-time">{this.duration}</div></Tooltip>
                     <button
                         title="Close"
                         className="presElementBox-closeIcon"
@@ -258,13 +273,13 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     </button>
                 </>}
                 <div className="presElementBox-highlight" style={{ display: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "block" : "none" }} />
-                <div className="presElementBox-buttons">
+                <div className="presElementBox-buttons" style={{ display: this.rootDoc.presExpandInlineButton ? "grid" : "none" }}>
                     <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search-plus"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Navigate" className={pbi + (this.rootDoc.presNavButton ? "-selected" : "")} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Hide Before" className={pbi + (this.rootDoc.presHideTillShownButton ? "-selected" : "")} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={"file"} onPointerDown={e => e.stopPropagation()} /></button>
-                    <button title="Fade After" className={pbi + (this.rootDoc.presFadeButton ? "-selected" : "")} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Hide After" className={pbi + (this.rootDoc.presHideAfterButton ? "-selected" : "")} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Progressivize" className={pbi + (this.rootDoc.presProgressivize ? "-selected" : "")} onClick={this.progressivize}><FontAwesomeIcon icon={"tasks"} onPointerDown={e => e.stopPropagation()} /></button>
+                    <button title="Effect" className={pbi + (this.rootDoc.presEffect ? "-selected" : "")}>E</button>
                 </div>
                 {this.renderEmbeddedInline}
             </div>
-- 
cgit v1.2.3-70-g09d2


From 0bdbf8bfbd4c2c2e8e7c1f4e7d530c628ad5e398 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 24 Jul 2020 14:00:58 +0800
Subject: internal nav

---
 package-lock.json                                  | 170 ++++++++++-
 package.json                                       |   3 +
 .../collectionFreeForm/CollectionFreeFormView.scss |  55 +++-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  14 +
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  15 +
 src/client/views/nodes/PresBox.tsx                 | 328 +++++++++++++++++----
 .../views/presentationview/PresElementBox.scss     |   8 +
 .../views/presentationview/PresElementBox.tsx      |  15 +-
 src/typings/index.d.ts                             |   2 +-
 9 files changed, 547 insertions(+), 63 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 3f596aa66..daa2ab967 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35,6 +35,36 @@
                 }
             }
         },
+        "@babel/helper-annotate-as-pure": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz",
+            "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==",
+            "requires": {
+                "@babel/types": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-validator-identifier": {
+                    "version": "7.10.4",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+                    "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw=="
+                },
+                "@babel/types": {
+                    "version": "7.10.5",
+                    "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz",
+                    "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==",
+                    "requires": {
+                        "@babel/helper-validator-identifier": "^7.10.4",
+                        "lodash": "^4.17.19",
+                        "to-fast-properties": "^2.0.0"
+                    }
+                },
+                "lodash": {
+                    "version": "4.17.19",
+                    "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
+                    "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
+                }
+            }
+        },
         "@babel/helper-function-name": {
             "version": "7.9.5",
             "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
@@ -2283,6 +2313,17 @@
                 "resolve": "^1.12.0"
             }
         },
+        "babel-plugin-styled-components": {
+            "version": "1.10.7",
+            "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz",
+            "integrity": "sha512-MBMHGcIA22996n9hZRf/UJLVVgkEOITuR2SvjHLb5dSTUyR4ZRGn+ngITapes36FI3WLxZHfRhkA1ffHxihOrg==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.0.0",
+                "@babel/helper-module-imports": "^7.0.0",
+                "babel-plugin-syntax-jsx": "^6.18.0",
+                "lodash": "^4.17.11"
+            }
+        },
         "babel-plugin-syntax-jsx": {
             "version": "6.18.0",
             "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
@@ -2913,6 +2954,11 @@
                 }
             }
         },
+        "camelize": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
+            "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
+        },
         "canvas": {
             "version": "2.6.1",
             "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.6.1.tgz",
@@ -4382,6 +4428,19 @@
             "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
             "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
         },
+        "css-box-model": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
+            "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
+            "requires": {
+                "tiny-invariant": "^1.0.6"
+            }
+        },
+        "css-color-keywords": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+            "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
+        },
         "css-in-js-utils": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz",
@@ -4445,6 +4504,16 @@
                 }
             }
         },
+        "css-to-react-native": {
+            "version": "2.3.2",
+            "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz",
+            "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==",
+            "requires": {
+                "camelize": "^1.0.0",
+                "css-color-keywords": "^1.0.0",
+                "postcss-value-parser": "^3.3.0"
+            }
+        },
         "css-vendor": {
             "version": "2.0.8",
             "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
@@ -7841,6 +7910,11 @@
             "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
             "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
         },
+        "is-what": {
+            "version": "3.10.0",
+            "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.10.0.tgz",
+            "integrity": "sha512-U4RYCXNOmATQHlOPlOCHCfXyKEFIPqvyaKDqYRuLbD6EYKcTTfc3YXkAYjzOVxO3zt34L+Wh2feIyWrYiZ7kng=="
+        },
         "is-windows": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -8723,6 +8797,14 @@
                 "trim-newlines": "^1.0.0"
             }
         },
+        "merge-anything": {
+            "version": "2.4.4",
+            "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz",
+            "integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==",
+            "requires": {
+                "is-what": "^3.3.1"
+            }
+        },
         "merge-descriptors": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -13489,8 +13571,7 @@
         "postcss-value-parser": {
             "version": "3.3.1",
             "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
-            "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
-            "dev": true
+            "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ=="
         },
         "prebuild-install": {
             "version": "5.3.3",
@@ -13981,6 +14062,11 @@
             "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
             "dev": true
         },
+        "raf-schd": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.2.tgz",
+            "integrity": "sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ=="
+        },
         "random-bytes": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
@@ -14104,6 +14190,20 @@
                 "pure-color": "^1.2.0"
             }
         },
+        "react-beautiful-dnd": {
+            "version": "13.0.0",
+            "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.0.0.tgz",
+            "integrity": "sha512-87It8sN0ineoC3nBW0SbQuTFXM6bUqM62uJGY4BtTf0yzPl8/3+bHMWkgIe0Z6m8e+gJgjWxefGRVfpE3VcdEg==",
+            "requires": {
+                "@babel/runtime": "^7.8.4",
+                "css-box-model": "^1.2.0",
+                "memoize-one": "^5.1.1",
+                "raf-schd": "^4.0.2",
+                "react-redux": "^7.1.1",
+                "redux": "^4.0.4",
+                "use-memo-one": "^1.1.1"
+            }
+        },
         "react-color": {
             "version": "2.18.1",
             "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.18.1.tgz",
@@ -14336,6 +14436,18 @@
                 }
             }
         },
+        "react-redux": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz",
+            "integrity": "sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==",
+            "requires": {
+                "@babel/runtime": "^7.5.5",
+                "hoist-non-react-statics": "^3.3.0",
+                "loose-envify": "^1.4.0",
+                "prop-types": "^15.7.2",
+                "react-is": "^16.9.0"
+            }
+        },
         "react-resizable": {
             "version": "1.10.1",
             "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-1.10.1.tgz",
@@ -14345,6 +14457,11 @@
                 "react-draggable": "^4.0.3"
             }
         },
+        "react-resizable-rotatable-draggable": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/react-resizable-rotatable-draggable/-/react-resizable-rotatable-draggable-0.2.0.tgz",
+            "integrity": "sha512-F8TPx3z7/AcmRViySbYV3LpUWXFpHlGAmKmNcYMgPlS+h1eYFazRG3xYS8Z6e48hWY1EcCny/YNrwRNUrap8CQ=="
+        },
         "react-reveal": {
             "version": "1.2.2",
             "resolved": "https://registry.npmjs.org/react-reveal/-/react-reveal-1.2.2.tgz",
@@ -14570,6 +14687,15 @@
             "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
             "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc="
         },
+        "redux": {
+            "version": "4.0.5",
+            "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
+            "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
+            "requires": {
+                "loose-envify": "^1.4.0",
+                "symbol-observable": "^1.2.0"
+            }
+        },
         "regenerator-runtime": {
             "version": "0.13.5",
             "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
@@ -16161,6 +16287,36 @@
                 }
             }
         },
+        "styled-components": {
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz",
+            "integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==",
+            "requires": {
+                "@babel/helper-module-imports": "^7.0.0",
+                "@babel/traverse": "^7.0.0",
+                "@emotion/is-prop-valid": "^0.8.1",
+                "@emotion/unitless": "^0.7.0",
+                "babel-plugin-styled-components": ">= 1",
+                "css-to-react-native": "^2.2.2",
+                "memoize-one": "^5.0.0",
+                "merge-anything": "^2.2.4",
+                "prop-types": "^15.5.4",
+                "react-is": "^16.6.0",
+                "stylis": "^3.5.0",
+                "stylis-rule-sheet": "^0.0.10",
+                "supports-color": "^5.5.0"
+            }
+        },
+        "stylis": {
+            "version": "3.5.4",
+            "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz",
+            "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q=="
+        },
+        "stylis-rule-sheet": {
+            "version": "0.0.10",
+            "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz",
+            "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw=="
+        },
         "supports-color": {
             "version": "5.5.0",
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -16469,6 +16625,11 @@
             "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
             "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
         },
+        "tiny-invariant": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
+            "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
+        },
         "tiny-warning": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
@@ -17354,6 +17515,11 @@
             "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
             "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
         },
+        "use-memo-one": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.1.tgz",
+            "integrity": "sha512-oFfsyun+bP7RX8X2AskHNTxu+R3QdE/RC5IefMbqptmACAA/gfol1KDD5KRzPsGMa62sWxGZw+Ui43u6x4ddoQ=="
+        },
         "util": {
             "version": "0.11.1",
             "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
diff --git a/package.json b/package.json
index b031387fc..182f47004 100644
--- a/package.json
+++ b/package.json
@@ -215,6 +215,7 @@
         "rc-switch": "^1.9.0",
         "react": "^16.12.0",
         "react-autosuggest": "^9.4.3",
+        "react-beautiful-dnd": "^13.0.0",
         "react-color": "^2.18.1",
         "react-compound-slider": "^2.5.0",
         "react-datepicker": "^3.0.0",
@@ -225,6 +226,7 @@
         "react-loading": "^2.0.3",
         "react-measure": "^2.2.4",
         "react-resizable": "^1.10.1",
+        "react-resizable-rotatable-draggable": "^0.2.0",
         "react-reveal": "^1.2.2",
         "react-select": "^3.1.0",
         "react-table": "^6.11.5",
@@ -240,6 +242,7 @@
         "socket.io-client": "^2.3.0",
         "solr-node": "^1.2.1",
         "standard-http-error": "^2.0.1",
+        "styled-components": "^4.4.1",
         "textarea-caret": "^3.1.0",
         "typescript-collections": "^1.3.3",
         "typescript-language-server": "^0.4.0",
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index b50a93775..2b07c4efb 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -92,14 +92,65 @@
     }
 }
 
+.resizable {
+    background: rgba(0, 0, 0, 0.2);
+    width: 100px;
+    height: 100px;
+    position: absolute;
+    top: 100px;
+    left: 100px;
+
+    .resizers {
+        width: 100%;
+        height: 100%;
+        border: 3px solid #69a6db;
+        box-sizing: border-box;
+
+        .resizer {
+            position: absolute;
+            width: 10px;
+            height: 10px;
+            border-radius: 50%;
+            /*magic to turn square into circle*/
+            background: white;
+            border: 3px solid #69a6db;
+        }
+
+        .resizer.top-left {
+            left: -3px;
+            top: -3px;
+            cursor: nwse-resize;
+            /*resizer cursor*/
+        }
+
+        .resizer.top-right {
+            right: -3px;
+            top: -3px;
+            cursor: nesw-resize;
+        }
+
+        .resizer.bottom-left {
+            left: -3px;
+            bottom: -3px;
+            cursor: nesw-resize;
+        }
+
+        .resizer.bottom-right {
+            right: -3px;
+            bottom: -3px;
+            cursor: nwse-resize;
+        }
+    }
+}
+
 .progressivizeMove-frame {
-    width: 40px;
+    width: 20px;
     border-radius: 2px;
     z-index: 100000;
     color: white;
     text-align: center;
     background-color: #5a9edd;
-    transform: translate(-105%, -110%);
+    transform: translate(-110%, 110%);
 }
 
 .progressivizeButton:hover {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index fe9c99e32..186fd710b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1388,6 +1388,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                     centeringShiftY={this.centeringShiftY}
                     presPaths={BoolCast(this.Document.presPathView)}
                     progressivize={BoolCast(this.Document.editProgressivize)}
+                    zoomProgressivize={BoolCast(this.Document.zoomProgressivize)}
                     transition={Cast(this.layoutDoc._viewTransition, "string", null)}
                     viewDefDivClick={this.props.viewDefDivClick}
                     zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
@@ -1473,10 +1474,22 @@ interface CollectionFreeFormViewPannableContentsProps {
     transition?: string;
     presPaths?: boolean;
     progressivize?: boolean;
+    zoomProgressivize?: boolean;
 }
 
 @observer
 class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
+    @computed get zoomProgressivize() {
+        if (this.props.zoomProgressivize) {
+            console.log("should render");
+            return (
+                <>
+                    {PresBox.Instance.zoomProgressivizeContainer}
+                </>
+            );
+        }
+    }
+
     @computed get progressivize() {
         if (this.props.progressivize) {
             console.log("should render");
@@ -1536,6 +1549,7 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
             {this.props.children()}
             {this.presPaths}
             {this.progressivize}
+            {this.zoomProgressivize}
         </div>;
     }
 }
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 2cf2ab35d..3bbe3e5dd 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -113,6 +113,21 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         setTimeout(() => docs.forEach(doc => doc.dataTransition = "inherit"), 1010);
     }
 
+    public static setupZoom(doc: Doc, zoomProgressivize: boolean = false) {
+        let width = new List<number>();
+        let height = new List<number>();
+        let top = new List<number>();
+        let left = new List<number>();
+        width.push(NumCast(doc.width));
+        height.push(NumCast(doc.height));
+        top.push(NumCast(doc.height) / -2);
+        left.push(NumCast(doc.width) / -2);
+        doc["width-indexed"] = width;
+        doc["height-indexed"] = height;
+        doc["top-indexed"] = top;
+        doc["left-indexed"] = left;
+    }
+
     public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) {
         docs.forEach((doc, i) => {
             if (!doc.appearFrame) doc.appearFrame = i;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 5c130e20e..7ac2dc317 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -28,7 +28,7 @@ import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal
 import { List } from "../../../fields/List";
 import { Tooltip } from "@material-ui/core";
 import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
-
+import { conformsTo } from "lodash";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -89,12 +89,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
         const lastFrame = Cast(presTargetDoc.lastFrame, "number", null);
         const curFrame = NumCast(presTargetDoc.currentFrame);
+        // Case 1: There are still other frames and should go through all frames before going to next slide
         if (lastFrame !== undefined && curFrame < lastFrame) {
             presTargetDoc._viewTransition = "all 1s";
             setTimeout(() => presTargetDoc._viewTransition = undefined, 1010);
             presTargetDoc.currentFrame = curFrame + 1;
-        }
-        else if (this.childDocs[this.itemIndex + 1] !== undefined) {
+            if (presTargetDoc.zoomProgressivize) {
+                const srcContext = Cast(presTargetDoc.context, Doc, null);
+                if (srcContext) {
+                    srcContext._panX = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]);
+                    srcContext._panY = this.checkList(presTargetDoc, presTargetDoc["top-indexed"]);
+                    srcContext._viewScale = this.checkList(presTargetDoc, presTargetDoc["width-indexed"]);
+                }
+                presTargetDoc._panY = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]);
+                const resize = document.getElementById('resizable');
+                if (resize) {
+                    resize.style.width = this.checkList(presTargetDoc, presTargetDoc["width-indexed"]) + 'px';
+                    resize.style.height = this.checkList(presTargetDoc, presTargetDoc["height-indexed"]) + 'px';
+                    resize.style.top = this.checkList(presTargetDoc, presTargetDoc["top-indexed"]) + 'px';
+                    resize.style.left = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]) + 'px';
+                }
+            }
+            // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
+        } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
             let nextSelected = this.itemIndex + 1;
             this.gotoDocument(nextSelected, this.itemIndex);
 
@@ -197,7 +214,28 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         });
     }
 
+    checkCollection = async (curTarget: Doc, nextTarget: Doc) => {
+        const aliasOf = await DocCastAsync(curTarget.aliasOf);
+        const curContext = aliasOf && await DocCastAsync(aliasOf.context);
+        const aliasOfNext = await DocCastAsync(nextTarget.aliasOf);
+        const nextContext = aliasOfNext && await DocCastAsync(aliasOfNext.context);
+        if (curContext && nextContext) {
+            // Case: Documents are not in the same collection
+            if (curContext !== nextContext) {
+                // Current document is contained in the next collection (zoom out)
+                if (curContext.context === nextContext) {
+                    console.log("current in next");
+                    // Next document is contained in the current collection (zoom in)
+                } else if (nextContext.context === curContext) {
+                    console.log("next in current");
+                }
+                // No change in parent collection
+            } else {
+                console.log("same collection");
+            }
 
+        }
+    }
     /**
      * This method makes sure that cursor navigates to the element that
      * has the option open and last in the group. If not in the group, and it has
@@ -208,26 +246,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         let docToJump = curDoc;
         let willZoom = false;
 
-        const presDocs = DocListCast(this.dataDoc[this.props.fieldKey]);
-        let nextSelected = presDocs.indexOf(curDoc);
-        const currentDocGroups: Doc[] = [];
-        for (; nextSelected < presDocs.length - 1; nextSelected++) {
-            if (!presDocs[nextSelected + 1].groupButton) {
-                break;
-            }
-            currentDocGroups.push(presDocs[nextSelected]);
-        }
+        const nextTarget = curDoc;
+        const curTarget = this.childDocs[fromDocIndex];
+        this.checkCollection(curTarget, nextTarget);
+        // const presDocs = DocListCast(this.dataDoc[this.props.fieldKey]);
+        // let nextSelected = presDocs.indexOf(curDoc);
+        // const currentDocGroups: Doc[] = [];
+        // for (; nextSelected < presDocs.length - 1; nextSelected++) {
+        //     if (!presDocs[nextSelected + 1].groupButton) {
+        //         break;
+        //     }
+        //     currentDocGroups.push(presDocs[nextSelected]);
+        // }
 
-        currentDocGroups.forEach((doc: Doc, index: number) => {
-            if (doc.presNavButton) {
-                docToJump = doc;
-                willZoom = false;
-            }
-            if (doc.presZoomButton) {
-                docToJump = doc;
-                willZoom = true;
-            }
-        });
+        // currentDocGroups.forEach((doc: Doc, index: number) => {
+        //     if (doc.presNavButton) {
+        //         docToJump = doc;
+        //         willZoom = false;
+        //     }
+        //     if (doc.presZoomButton) {
+        //         docToJump = doc;
+        //         willZoom = true;
+        //     }
+        // });
 
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
         const aliasOf = await DocCastAsync(docToJump.aliasOf);
@@ -264,6 +305,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             //     this.startPresentation(index);
             // }
             this.navigateToElement(this.childDocs[index], fromDoc);
+            this._selectedArray = [this.childDocs[index]];
             // this.hideIfNotPresented(index);
             // this.showAfterPresented(index);
             // this.hideDocumentInPres();
@@ -369,13 +411,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         if (movement === 'zoom') {
             activeItem.presZoomButton = !activeItem.presZoomButton;
+            activeItem.presMovement = 'Zoom';
             activeItem.presNavButton = false;
         } else if (movement === 'nav') {
             activeItem.presZoomButton = false;
+            activeItem.presMovement = 'Pan';
             activeItem.presNavButton = !activeItem.presNavButton;
-        } else if (movement === 'swap') {
+        } else if (movement === 'switch') {
+            activeItem.presMovement = 'Switch';
             targetDoc.presTransition = 0;
         } else {
+            activeItem.presMovement = 'None';
             activeItem.presZoomButton = false;
             activeItem.presNavButton = false;
         }
@@ -528,14 +574,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.playTools = false;
     }
 
-    @undoBatch
-    @action
-    toolbarTest = () => {
-        const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
-        console.log("title: " + presTargetDoc.title);
-        console.log("index: " + this.itemIndex);
-    }
-
     @undoBatch
     @action
     viewPaths = async () => {
@@ -614,6 +652,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 opacity: 1,
                 stroke: "#69a6db",
                 strokeWidth: 5,
+                strokeDasharray: '10 5',
             }}
             fill="none"
             // markerStart="url(#square)"
@@ -681,7 +720,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             const duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2;
             const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93);
             const durationThumbLocation = String(9.48 * Number(duration));
-            const movement = activeItem.presZoomButton ? 'Zoom' : activeItem.presNavbutton ? 'Navigate' : 'None';
             const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
             return (
                 <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
@@ -691,13 +729,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             onPointerDown={e => e.stopPropagation()}
                         // onClick={() => this.dropdownToggle('Movement')}
                         >
-                            {movement}
+                            {activeItem.presMovement}
                             <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
                             <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
-                                <div className={`presBox-dropdownOption ${!activeItem.presZoomButton && !activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presZoomButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presNavButton ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('swap')}>Swap</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'None' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Zoom' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Pan' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Switch' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Switch</div>
                             </div>
                         </div>
                         <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed} className={`toolbar-slider ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
@@ -864,9 +902,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             tagDoc.currentFrame = 0;
             CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
         }
+        let lastFrame: number = 0;
+        childDocs.forEach((doc) => {
+            if (NumCast(doc.appearFrame) > lastFrame) lastFrame = NumCast(doc.appearFrame);
+        });
         CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
         tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1);
-        tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), NumCast(tagDoc.lastFrame));
+        tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), lastFrame);
+        if (tagDoc.zoomProgressivize) {
+            const resize = document.getElementById('resizable');
+            if (resize) {
+                resize.style.width = this.checkList(tagDoc, tagDoc["width-indexed"]) + 'px';
+                resize.style.height = this.checkList(tagDoc, tagDoc["height-indexed"]) + 'px';
+                resize.style.top = this.checkList(tagDoc, tagDoc["top-indexed"]) + 'px';
+                resize.style.left = this.checkList(tagDoc, tagDoc["left-indexed"]) + 'px';
+            }
+        }
     }
 
     @undoBatch
@@ -880,6 +931,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
         CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice());
         tagDoc.currentFrame = Math.max(0, (currentFrame || 0) - 1);
+        if (tagDoc.zoomProgressivize) {
+            const resize = document.getElementById('resizable');
+            if (resize) {
+                resize.style.width = this.checkList(tagDoc, tagDoc["width-indexed"]) + 'px';
+                resize.style.height = this.checkList(tagDoc, tagDoc["height-indexed"]) + 'px';
+                resize.style.top = this.checkList(tagDoc, tagDoc["top-indexed"]) + 'px';
+                resize.style.left = this.checkList(tagDoc, tagDoc["left-indexed"]) + 'px';
+            }
+        }
     }
 
     @computed get progressivizeDropdown() {
@@ -936,7 +996,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     zoomProgressivize = (e: React.MouseEvent) => {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        targetDoc.currentFrame = targetDoc.lastFrame;
         if (targetDoc?.zoomProgressivize) {
             targetDoc.zoomProgressivize = false;
         } else {
@@ -956,7 +1015,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (activeItem.zoomProgressivize) {
             console.log("progressivize");
             targetDoc.currentFrame = 0;
-            CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
         }
     }
 
@@ -1050,6 +1108,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 opacity: 1,
                 stroke: "#000000",
                 strokeWidth: 2,
+                strokeDasharray: '10 5',
             }}
             fill="none"
         /></svg>);
@@ -1062,6 +1121,167 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         else doc.displayMovement = true;
     }
 
+    private _isDraggingTL = false;
+    private _isDraggingTR = false;
+    private _isDraggingBR = false;
+    private _isDraggingBL = false;
+    private _isDragging = false;
+
+    //Adds event listener so knows pointer is down and moving
+    onPointerMid = (e: React.PointerEvent): void => {
+        e.stopPropagation();
+        e.preventDefault();
+        this._isDragging = true;
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.addEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+        document.addEventListener("pointerup", this.onPointerUp);
+    }
+
+    //Adds event listener so knows pointer is down and moving
+    onPointerBR = (e: React.PointerEvent): void => {
+        e.stopPropagation();
+        e.preventDefault();
+        this._isDraggingBR = true;
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.addEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+        document.addEventListener("pointerup", this.onPointerUp);
+    }
+
+    //Adds event listener so knows pointer is down and moving
+    onPointerBL = (e: React.PointerEvent): void => {
+        e.stopPropagation();
+        e.preventDefault();
+        this._isDraggingBL = true;
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.addEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+        document.addEventListener("pointerup", this.onPointerUp);
+    }
+
+    //Adds event listener so knows pointer is down and moving
+    onPointerTR = (e: React.PointerEvent): void => {
+        e.stopPropagation();
+        e.preventDefault();
+        this._isDraggingTR = true;
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.addEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+        document.addEventListener("pointerup", this.onPointerUp);
+    }
+
+    //Adds event listener so knows pointer is down and moving
+    onPointerTL = (e: React.PointerEvent): void => {
+        e.stopPropagation();
+        e.preventDefault();
+        this._isDraggingTL = true;
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.addEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+        document.addEventListener("pointerup", this.onPointerUp);
+    }
+
+    //Removes all event listeners
+    onPointerUp = (e: PointerEvent): void => {
+        e.stopPropagation();
+        e.preventDefault();
+        this._isDraggingTL = false;
+        this._isDraggingTR = false;
+        this._isDraggingBL = false;
+        this._isDraggingBR = false;
+        this._isDragging = false;
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+    }
+
+    //Adjusts the value in NodeStore
+    onPointerMove = (e: PointerEvent): void => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        e.stopPropagation();
+        e.preventDefault();
+        const doc = document.getElementById('resizable');
+        if (doc) {
+            let height = doc.offsetHeight;
+            let width = doc.offsetWidth;
+            let top = doc.offsetTop;
+            let left = doc.offsetLeft;
+            //Bottom right
+            if (this._isDraggingBR) {
+                let newHeight = height += e.movementY;
+                doc.style.height = newHeight + 'px';
+                let newWidth = width += e.movementX;
+                doc.style.width = newWidth + 'px';
+                // Bottom left
+            } else if (this._isDraggingBL) {
+                let newHeight = height += e.movementY;
+                doc.style.height = newHeight + 'px';
+                let newWidth = width -= e.movementX;
+                doc.style.width = newWidth + 'px';
+                let newLeft = left += e.movementX;
+                doc.style.left = newLeft + 'px';
+                // Top right
+            } else if (this._isDraggingTR) {
+                let newWidth = width += e.movementX;
+                doc.style.width = newWidth + 'px';
+                let newHeight = height -= e.movementY;
+                doc.style.height = newHeight + 'px';
+                let newTop = top += e.movementY;
+                doc.style.top = newTop + 'px';
+                // Top left
+            } else if (this._isDraggingTL) {
+                const newWidth = width -= e.movementX;
+                doc.style.width = newWidth + 'px';
+                const newHeight = height -= e.movementY;
+                doc.style.height = newHeight + 'px';
+                const newTop = top += e.movementY;
+                doc.style.top = newTop + 'px';
+                const newLeft = left += e.movementX;
+                doc.style.left = newLeft + 'px';
+            } else if (this._isDragging) {
+                let newTop = top += e.movementY;
+                doc.style.top = newTop + 'px';
+                let newLeft = left += e.movementX;
+                doc.style.left = newLeft + 'px';
+            }
+            this.updateList(targetDoc, targetDoc["width-indexed"], width);
+            this.updateList(targetDoc, targetDoc["height-indexed"], height);
+            this.updateList(targetDoc, targetDoc["top-indexed"], top);
+            this.updateList(targetDoc, targetDoc["left-indexed"], left);
+        }
+    }
+
+    @action
+    checkList = (doc: Doc, list: any): number => {
+        const x: List<number> = list;
+        return x[NumCast(doc.currentFrame)];
+    }
+
+    @action
+    updateList = (doc: Doc, list: any, val: number) => {
+        const x: List<number> = list;
+        x[NumCast(doc.currentFrame)] = val;
+        list = x;
+    }
+
+    @computed get zoomProgressivizeContainer() {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        CollectionFreeFormDocumentView.setupZoom(targetDoc, true);
+
+        return (
+            <div id="resizable" className="resizable" onPointerDown={this.onPointerMid} style={{ width: this.checkList(targetDoc, targetDoc["width-indexed"]), height: this.checkList(targetDoc, targetDoc["height-indexed"]), top: this.checkList(targetDoc, targetDoc["top-indexed"]), left: this.checkList(targetDoc, targetDoc["left-indexed"]), position: 'absolute' }}>
+                <div className='resizers'>
+                    <div className='resizer top-left' onPointerDown={this.onPointerTL}></div>
+                    <div className='resizer top-right' onPointerDown={this.onPointerTR}></div>
+                    <div className='resizer bottom-left' onPointerDown={this.onPointerBL}></div>
+                    <div className='resizer bottom-right' onPointerDown={this.onPointerBR}></div>
+                </div>
+            </div>
+        );
+    }
+
     @computed get progressivizeChildDocs() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
@@ -1117,12 +1337,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return (<div></div>);
     }
 
+    @observable
+    toolbarWidth = (): number => {
+        console.log(this.props.PanelWidth());
+        const width = this.props.PanelWidth();
+        return width;
+    }
+
+
     @computed get toolbar() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        const parent = document.getElementById('toolbarContainer');
-        let width = 0;
-        if (parent) width = parent.offsetWidth;
-        console.log(width);
         if (activeItem) {
             return (
                 <>
@@ -1133,22 +1357,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}><div className={`toolbar-button ${this.pathBoolean ? "active" : ""}`}>
                         <FontAwesomeIcon icon={"exchange-alt"} onClick={this.viewPaths} />
                     </div></Tooltip>
-                    <Tooltip title={<><div className="dash-tooltip">{this.expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
-                        <div className={`toolbar-button ${this.expandBoolean ? "active" : ""}`} onClick={() => { this.toggleExpand(); this.childDocs.forEach((doc, ind) => { doc.presExpandInlineButton = !doc.presExpandInlineButton; }); }}>
-                            <FontAwesomeIcon icon={"image"} />
+                    <Tooltip title={<><div className="dash-tooltip">{this.expandBoolean ? "Expand all" : "Minimize all"}</div></>}>
+                        <div className={`toolbar-button ${this.expandBoolean ? "" : "active"}`} onClick={() => { this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = false; else doc.presExpandInlineButton = true; }); }}>
+                            <FontAwesomeIcon icon={"eye"} />
                         </div>
                     </Tooltip>
                     {/* <div className="toolbar-button"><FontAwesomeIcon title={"Portal"} icon={"eye"} onClick={this.toolbarTest} /></div> */}
                     <div className="toolbar-divider" />
                     <Tooltip title={<><div className="dash-tooltip">{"Transitions"}</div></>}><div className={`toolbar-button ${this.transitionTools ? "active" : ""}`} onClick={this.toggleTransitionTools}>
                         <FontAwesomeIcon icon={"rocket"} />
-                        <div style={{ display: width > 400 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Transitions</div>
+                        <div style={{ display: this.toolbarWidth() > 380 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Transitions</div>
                         <FontAwesomeIcon className={`dropdown ${this.transitionTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
                     <div className="toolbar-divider" />
                     <Tooltip title={<><div className="dash-tooltip">{"Progressivize"}</div></>}><div className={`toolbar-button ${this.progressivizeTools ? "active" : ""}`} onClick={this.toggleProgressivize}>
                         <FontAwesomeIcon icon={"tasks"} />
-                        <div style={{ display: width > 400 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Progressivize</div>
+                        <div style={{ display: this.toolbarWidth() > 380 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Progressivize</div>
                         <FontAwesomeIcon className={`dropdown ${this.progressivizeTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
                     <div className="toolbar-divider" />
@@ -1167,10 +1391,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         } else {
             return (
                 <>
-                    <div className="toolbar-button"><FontAwesomeIcon icon={"plus"} onClick={this.toggleNewDocument} />
+                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={this.toggleNewDocument}><FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
-                    </div>
-                    <div className="toolbar-button">
+                    </div></Tooltip>
+                    <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
                         <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
                     </div>
                     <Fade left when={this.moreInfoTools}>
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 51ad6839c..c87a1583a 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -144,6 +144,9 @@
     width: 20px;
     height: 20px;
     display: flex;
+    font-size: 75%;
+    background-color: black;
+    color: white;
     justify-content: center;
     align-items: center;
 }
@@ -157,6 +160,9 @@
     width: 20px;
     height: 20px;
     display: flex;
+    font-size: 75%;
+    background-color: black;
+    color: white;
     justify-content: center;
     align-items: center;
 }
@@ -170,6 +176,8 @@
     height: 20px;
     z-index: 200;
     display: flex;
+    background-color: black;
+    color: white;
     justify-content: center;
     align-items: center;
 }
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 53d922cee..6c6bad06a 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -186,6 +186,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                 <ContentFittingDocumentView
                     Document={this.targetDoc}
                     DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
+                    dragDivName={"collectionFreeFormDocumentView-container"}
                     LibraryPath={emptyPath}
                     fitToBox={true}
                     backgroundColor={this.props.backgroundColor}
@@ -247,7 +248,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                         console.log("normal click");
                     }
                 }}
-                onPointerDown={e => e.stopPropagation()}
+                onPointerDown={e => {
+                    this.props.dropAction;
+                    e.stopPropagation();
+                }}
             >
                 {treecontainer ? (null) : <>
                     <div className="presElementBox-number">
@@ -258,8 +262,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     </div>
                     <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presElementBox-time">{this.transition}</div></Tooltip>
                     <Tooltip title={<><div className="dash-tooltip">{"Duration of visibility"}</div></>}><div className="presElementBox-time">{this.duration}</div></Tooltip>
-                    <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><button
-                        title="Close"
+                    <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><div
                         className="presElementBox-closeIcon"
                         onPointerDown={e => e.stopPropagation()}
                         onClick={e => {
@@ -267,10 +270,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                             e.stopPropagation();
                         }}>
                         <FontAwesomeIcon icon={"trash"} onPointerDown={e => e.stopPropagation()} />
-                    </button></Tooltip>
-                    <Tooltip title={<><div className="dash-tooltip">{this.rootDoc.presExpandInlineButton ? "Expand" : "Minimize"}</div></>}><button title="Expand Inline" className={"presElementBox-expand" + (this.rootDoc.presExpandInlineButton ? "-selected" : "")} onClick={e => { e.stopPropagation(); this.presExpandDocumentClick(); }}>
+                    </div></Tooltip>
+                    <Tooltip title={<><div className="dash-tooltip">{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}</div></>}><div className={"presElementBox-expand" + (this.rootDoc.presExpandInlineButton ? "-selected" : "")} onClick={e => { e.stopPropagation(); this.presExpandDocumentClick(); }}>
                         <FontAwesomeIcon icon={(this.rootDoc.presExpandInlineButton ? "angle-up" : "angle-down")} onPointerDown={e => e.stopPropagation()} />
-                    </button></Tooltip>
+                    </div></Tooltip>
                 </>}
                 <div className="presElementBox-highlight" style={{ display: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "block" : "none" }} />
                 <div className="presElementBox-buttons" style={{ display: this.rootDoc.presExpandInlineButton ? "grid" : "none" }}>
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts
index 799a3ee6f..24b70057a 100644
--- a/src/typings/index.d.ts
+++ b/src/typings/index.d.ts
@@ -10,7 +10,7 @@ declare module 'fit-curve';
 declare module 'reveal';
 declare module 'react-reveal';
 declare module 'react-reveal/makeCarousel';
-
+declare module 'react-resizable-rotatable-draggable';
 
 declare module '@react-pdf/renderer' {
     import * as React from 'react';
-- 
cgit v1.2.3-70-g09d2


From b9f77b5f539e7b5f44f11e28bd72fefde34fff97 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 24 Jul 2020 15:26:29 +0800
Subject: let -> const

---
 src/client/views/nodes/PresBox.tsx | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

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

diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index e8e788bc5..ac2288944 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -243,8 +243,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
      */
     navigateToElement = async (curDoc: Doc, fromDocIndex: number) => {
         this.updateCurrentPresentation();
-        let docToJump = curDoc;
-        let willZoom = false;
+        const docToJump = curDoc;
+        const willZoom = false;
 
         const nextTarget = curDoc;
         const curTarget = this.childDocs[fromDocIndex];
@@ -444,9 +444,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
 
     // render() {
-        // const presOrderedDocs = DocListCast(this.rootDoc.presOrderedDocs);
-        // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
-        //     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
+    // const presOrderedDocs = DocListCast(this.rootDoc.presOrderedDocs);
+    // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
+    //     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
 
     // KEYS
     @observable _selectedArray: Doc[] = [];
@@ -1213,25 +1213,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             let left = doc.offsetLeft;
             //Bottom right
             if (this._isDraggingBR) {
-                let newHeight = height += e.movementY;
+                const newHeight = height += e.movementY;
                 doc.style.height = newHeight + 'px';
-                let newWidth = width += e.movementX;
+                const newWidth = width += e.movementX;
                 doc.style.width = newWidth + 'px';
                 // Bottom left
             } else if (this._isDraggingBL) {
-                let newHeight = height += e.movementY;
+                const newHeight = height += e.movementY;
                 doc.style.height = newHeight + 'px';
-                let newWidth = width -= e.movementX;
+                const newWidth = width -= e.movementX;
                 doc.style.width = newWidth + 'px';
-                let newLeft = left += e.movementX;
+                const newLeft = left += e.movementX;
                 doc.style.left = newLeft + 'px';
                 // Top right
             } else if (this._isDraggingTR) {
-                let newWidth = width += e.movementX;
+                const newWidth = width += e.movementX;
                 doc.style.width = newWidth + 'px';
-                let newHeight = height -= e.movementY;
+                const newHeight = height -= e.movementY;
                 doc.style.height = newHeight + 'px';
-                let newTop = top += e.movementY;
+                const newTop = top += e.movementY;
                 doc.style.top = newTop + 'px';
                 // Top left
             } else if (this._isDraggingTL) {
@@ -1244,9 +1244,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 const newLeft = left += e.movementX;
                 doc.style.left = newLeft + 'px';
             } else if (this._isDragging) {
-                let newTop = top += e.movementY;
+                const newTop = top += e.movementY;
                 doc.style.top = newTop + 'px';
-                let newLeft = left += e.movementX;
+                const newLeft = left += e.movementX;
                 doc.style.left = newLeft + 'px';
             }
             this.updateList(targetDoc, targetDoc["width-indexed"], width);
-- 
cgit v1.2.3-70-g09d2


From bdb52eb3090cae3f146a6777f18d53f54d1e1d0f Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Tue, 28 Jul 2020 23:48:12 +0800
Subject: scrollProgressivize + viewfinder

---
 src/client/util/DocumentManager.ts                 |   4 +
 src/client/views/.DS_Store                         | Bin 6148 -> 6148 bytes
 .../views/collections/CollectionDockingView.scss   |  62 +++
 .../views/collections/CollectionDockingView.tsx    |  24 ++
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   4 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  42 +-
 src/client/views/nodes/PresBox.scss                | 118 +++++-
 src/client/views/nodes/PresBox.tsx                 | 436 +++++++++++++++------
 .../views/presentationview/PresElementBox.tsx      |   6 +-
 9 files changed, 550 insertions(+), 146 deletions(-)

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

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 237ea7675..d18eac374 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -127,6 +127,10 @@ export class DocumentManager {
         CollectionDockingView.AddRightSplit(doc);
         finished?.();
     }
+    // static openInPlace = (doc: Doc, finished?: () => void) => {
+    //     CollectionDockingView.AddTab(doc);
+    //     finished?.();
+    // }
     public jumpToDocument = async (
         targetDoc: Doc,        // document to display
         willZoom: boolean,     // whether to zoom doc to take up most of screen
diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store
index 3717a2923..3ce88292c 100644
Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index 1895c06a1..9b14df760 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -18,6 +18,68 @@
         }
     }
 }
+
+.miniPres:hover {
+    opacity: 1;
+}
+
+.miniPres {
+    position: absolute;
+    overflow: hidden;
+    right: 10;
+    top: 10;
+    opacity: 0.1;
+    transition: all 0.4s;
+    /* border: solid 1px; */
+    color: white;
+    /* box-shadow: black 0.4vw 0.4vw 0.8vw; */
+    
+    .miniPresOverlay {
+        display: grid;
+        grid-template-columns: auto auto auto auto auto auto auto auto;
+        grid-template-rows: 100%;
+        height: 100%;
+        justify-items: center;
+        align-items: center;
+
+        .miniPres-button-text {
+            display: flex;
+            height: 30;
+            font-weight: 400;
+            min-width: 100%;
+            border-radius: 5px;
+            align-items: center;
+            justify-content: center;
+            transition: all 0.3s;
+        }
+
+        .miniPres-divider {
+            width: 1px;
+            height: 80%;
+            border-right: solid 2px #5a5a5a;
+        }
+
+        .miniPres-button {
+            display: flex;
+            height: 30;
+            min-width: 30;
+            border-radius: 100%;
+            align-items: center;
+            justify-content: center;
+            transition: all 0.3s;
+        }
+
+        .miniPres-button:hover {
+            background-color: #5a5a5a;
+        }
+
+        .miniPres-button-text:hover {
+            background-color: #5a5a5a;
+        }
+    }
+}
+
+
 .lm_title {
     margin-top: 3px;
     border-radius: 5px;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 53b2d5254..b82a33bd8 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -31,6 +31,8 @@ import { SnappingManager } from '../../util/SnappingManager';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import { listSpec } from '../../../fields/Schema';
 import { clamp } from 'lodash';
+import { PresBox } from '../nodes/PresBox';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
@@ -838,6 +840,27 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
             return false;
         }), emptyFunction, emptyFunction);
     }
+    getCurrentFrame = (): number => {
+        const presTargetDoc = Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex].presentationTargetDoc, Doc, null);
+        const currentFrame = Cast(presTargetDoc.currentFrame, "number", null);
+        return currentFrame;
+    }
+    renderMiniPres() {
+        return <div className="miniPres" style={{
+            width: 400, height: 50, background: '#323232'
+        }}>
+            <div className="miniPresOverlay" >
+                <div className="miniPres-button" onClick={PresBox.Instance.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
+                <div className="miniPres-button" onClick={() => PresBox.Instance.startOrResetPres(PresBox.Instance.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
+                <div className="miniPres-button" onClick={PresBox.Instance.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
+                <div className="miniPres-divider"></div>
+                <div className="miniPres-button-text">Slide {PresBox.Instance.itemIndex + 1} / {PresBox.Instance.childDocs.length}</div>
+                {/* <div className="miniPres-button-text">{this.getCurrentFrame}</div> */}
+                <div className="miniPres-divider"></div>
+                <div className="miniPres-button-text" onClick={PresBox.Instance.updateMinimize}>EXIT</div>
+            </div>
+        </div>;
+    }
     renderMiniMap() {
         return <div className="miniMap" style={{
             width: this.returnMiniSize(), height: this.returnMiniSize(), background: StrCast(this._document!._backgroundColor,
@@ -920,6 +943,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
                 ContainingCollectionView={undefined}
                 ContainingCollectionDoc={undefined} />
             {document._viewType === CollectionViewType.Freeform && !this._document?.hideMinimap ? this.renderMiniMap() : (null)}
+            {document._viewType === CollectionViewType.Freeform && this._document?.miniPres ? this.renderMiniPres() : (null)}
         </>;
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e22b400c0..79540d19e 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -214,7 +214,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             const layoutDoc = Doc.Layout(d);
             if (this.Document.currentFrame !== undefined) {
                 const vals = CollectionFreeFormDocumentView.getValues(d, NumCast(d.activeFrame, 1000));
-                CollectionFreeFormDocumentView.setValues(this.Document.currentFrame, d, x + vals.x - dropPos[0], y + vals.y - dropPos[1], vals.opacity);
+                CollectionFreeFormDocumentView.setValues(this.Document.currentFrame, d, x + vals.x - dropPos[0], y + vals.y - dropPos[1], vals.h, vals.w, vals.opacity);
             } else {
                 d.x = x + NumCast(d.x) - dropPos[0];
                 d.y = y + NumCast(d.y) - dropPos[1];
@@ -1405,7 +1405,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                     centeringShiftY={this.centeringShiftY}
                     presPaths={BoolCast(this.Document.presPathView)}
                     progressivize={BoolCast(this.Document.editProgressivize)}
-                    zoomProgressivize={BoolCast(this.Document.zoomProgressivize)}
+                    zoomProgressivize={BoolCast(this.Document.editZoomProgressivize)}
                     transition={Cast(this.layoutDoc._viewTransition, "string", null)}
                     viewDefDivClick={this.props.viewDefDivClick}
                     zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 480abdaed..5d1db6de2 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -76,22 +76,30 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     public static getValues(doc: Doc, time: number) {
         const timecode = Math.round(time);
         return ({
+            h: Cast(doc["h-indexed"], listSpec("number"), [NumCast(doc._height)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number),
+            w: Cast(doc["w-indexed"], listSpec("number"), [NumCast(doc._width)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number),
             x: Cast(doc["x-indexed"], listSpec("number"), [NumCast(doc.x)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number),
             y: Cast(doc["y-indexed"], listSpec("number"), [NumCast(doc.y)]).reduce((p, y, i) => (i <= timecode && y !== undefined) || p === undefined ? y : p, undefined as any as number),
             opacity: Cast(doc["opacity-indexed"], listSpec("number"), [NumCast(doc.opacity, 1)]).reduce((p, o, i) => i <= timecode || p === undefined ? o : p, undefined as any as number),
         });
     }
 
-    public static setValues(time: number, d: Doc, x?: number, y?: number, opacity?: number) {
+    public static setValues(time: number, d: Doc, x?: number, y?: number, h?: number, w?: number, opacity?: number) {
         const timecode = Math.round(time);
+        const hindexed = Cast(d["h-indexed"], listSpec("number"), []).slice();
+        const windexed = Cast(d["w-indexed"], listSpec("number"), []).slice();
         const xindexed = Cast(d["x-indexed"], listSpec("number"), []).slice();
         const yindexed = Cast(d["y-indexed"], listSpec("number"), []).slice();
         const oindexed = Cast(d["opacity-indexed"], listSpec("number"), []).slice();
         xindexed[timecode] = x as any as number;
         yindexed[timecode] = y as any as number;
+        hindexed[timecode] = h as any as number;
+        windexed[timecode] = w as any as number;
         oindexed[timecode] = opacity as any as number;
         d["x-indexed"] = new List<number>(xindexed);
         d["y-indexed"] = new List<number>(yindexed);
+        d["h-indexed"] = new List<number>(hindexed);
+        d["w-indexed"] = new List<number>(windexed);
         d["opacity-indexed"] = new List<number>(oindexed);
     }
     public static updateKeyframe(docs: Doc[], time: number) {
@@ -99,7 +107,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         docs.forEach(doc => {
             const xindexed = Cast(doc['x-indexed'], listSpec("number"), null);
             const yindexed = Cast(doc['y-indexed'], listSpec("number"), null);
+            const hindexed = Cast(doc['h-indexed'], listSpec("number"), null);
+            const windexed = Cast(doc['w-indexed'], listSpec("number"), null);
             const opacityindexed = Cast(doc['opacity-indexed'], listSpec("number"), null);
+            hindexed?.length <= timecode + 1 && hindexed.push(undefined as any as number);
+            windexed?.length <= timecode + 1 && windexed.push(undefined as any as number);
             xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number);
             yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number);
             opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
@@ -118,14 +130,24 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         const height = new List<number>();
         const top = new List<number>();
         const left = new List<number>();
+        // width.push(100);
+        // height.push(100);
+        // top.push(0);
+        // left.push(0);
         width.push(NumCast(doc.width));
         height.push(NumCast(doc.height));
         top.push(NumCast(doc.height) / -2);
         left.push(NumCast(doc.width) / -2);
-        doc["width-indexed"] = width;
-        doc["height-indexed"] = height;
-        doc["top-indexed"] = top;
-        doc["left-indexed"] = left;
+        doc["viewfinder-width-indexed"] = width;
+        doc["viewfinder-height-indexed"] = height;
+        doc["viewfinder-top-indexed"] = top;
+        doc["viewfinder-left-indexed"] = left;
+    }
+
+    public static setupScroll(doc: Doc, scrollProgressivize: boolean = false) {
+        const scrollList = new List<number>();
+        scrollList.push(NumCast(doc._scrollTop));
+        doc["scroll-indexed"] = scrollList;
     }
 
     public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) {
@@ -134,6 +156,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             const curTimecode = progressivize ? i : timecode;
             const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
+            const wlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
+            const hlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1));
             let oarray: List<number>;
             console.log(doc.title + "AF: " + doc.appearFrame);
@@ -143,15 +167,21 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             oarray.fill(1, NumCast(doc.appearFrame), timecode);
             // oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
             // oarray.fill(1, NumCast(doc.appearFrame), timecode);
-            console.log(oarray);
+            // console.log(oarray);
+            wlist[curTimecode] = NumCast(doc._width);
+            hlist[curTimecode] = NumCast(doc._height);
             xlist[curTimecode] = NumCast(doc.x);
             ylist[curTimecode] = NumCast(doc.y);
             doc.xArray = xlist;
             doc.yArray = ylist;
             doc["x-indexed"] = xlist;
             doc["y-indexed"] = ylist;
+            doc["w-indexed"] = wlist;
+            doc["h-indexed"] = hlist;
             doc["opacity-indexed"] = oarray;
             doc.activeFrame = ComputedField.MakeFunction("self.context?.currentFrame||0");
+            doc._height = ComputedField.MakeInterpolated("h", "activeFrame");
+            doc._width = ComputedField.MakeInterpolated("w", "activeFrame");
             doc.x = ComputedField.MakeInterpolated("x", "activeFrame");
             doc.y = ComputedField.MakeInterpolated("y", "activeFrame");
             doc.opacity = ComputedField.MakeInterpolated("opacity", "activeFrame");
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 45bb4293b..b06503472 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -441,6 +441,7 @@
     padding-top: 5px;
     padding-bottom: 5px;
     border: solid 1px black;
+    // overflow: auto; 
 
     ::-webkit-scrollbar {
         -webkit-appearance: none;
@@ -450,37 +451,127 @@
 
     ::-webkit-scrollbar-thumb {
         border-radius: 2px;
-        background-color: rgb(101, 164, 220);
     }
 }
 
 .dropdown-play-button {
-    font-size: 10;
-    margin-left: 10;
-    margin-right: 10;
+    font-size: 12;
+    padding-left: 5px;
+    padding-right: 5px;
     padding-top: 5px;
     padding-bottom: 5px;
     text-align: left;
     justify-content: left;
-    border-bottom: solid 1px lightgrey;
+}
+
+.dropdown-play-button:hover {
+    background-color: lightgrey;
+}
+
+.presBox-button-left {
+    position: relative;
+    align-self: flex-start;
+    justify-self: flex-start;
+    width: 80%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 4px;
+    border-bottom-right-radius: 0;
+    border-top-right-radius: 0;
+}
+
+.presBox-button-right {
+    position: relative;
+    text-align: center;
+    border-left: solid 1px darkgrey;
+    width: 20%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 4px;
+    border-bottom-left-radius: 0;
+    border-top-left-radius: 0;
+}
+
+.presBox-button-right.active {
+    background-color: #223063;
+    border: #aedcf6 solid 1px;
+    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.8);
 }
 
 .dropdown-play {
-    top: 32px;
+    right: 0px;
+    top: calc(100% + 2px);
     display: none;
     border-radius: 5px;
     width: max-content;
     min-height: 20px;
     height: max-content;
+    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.8);
     z-index: 200;
-    background-color: #323232;
+    background-color: white;
+    color: black;
     position: absolute;
+    overflow: hidden;
 }
 
 .dropdown-play.active {
     display: block;
 }
 
+.layout-container {
+    overflow-x: scroll;
+    display: flex;
+    width: 100%;
+    /* max-width: 200px; */
+    min-width: 100px;
+    height: 100%;
+    // border: solid 1px;
+    /* display: block; */
+    align-self: center;
+
+    .layout:hover {
+        border: solid 2px #5c9edd;
+    }
+
+    .layout {
+        position: relative;
+        top: 10%;
+        height: 80%;
+        margin-right: 10;
+        min-width: 90px;
+        width: 90px;
+        border: solid black 1px;
+        display: grid;
+        grid-template-rows: 20px 30px;
+        align-items: center;
+        text-align: center;
+
+        .header {
+            font-size: 10;
+            font-weight: 600;
+            width: 70%;
+            height: max-content;
+            align-self: center;
+            justify-self: center;
+            border: solid 0.8px black;
+        }
+
+        .subheader {
+            font-size: 8;
+            font-weight: 400;
+            width: 70%;
+            height: 90%;
+            align-self: center;
+            justify-self: center;
+            border: solid 0.4px black;
+        }
+    }
+}
+
 .presBox-buttons {
     position: relative;
     width: 100%;
@@ -498,15 +589,19 @@
         border-radius: 5px;
         min-width: 15px;
         max-width: 100px;
+        left: 8px;
     }
 
     .presBox-presentPanel {
         display: flex;
         justify-self: end;
         width: 100%;
-
+        max-width: 300px;
+        min-width: 150px;
     }
 
+    
+
     select {
         background: #323232;
         color: white;
@@ -532,6 +627,10 @@
         display: flex;
     }
 
+    .presBox-button.active:hover {
+        background-color: #233163;
+    }
+
     .presBox-button.edit {
         display: flex;
         max-width: 25px;
@@ -542,7 +641,7 @@
         min-width: 100px;
         width: 100px;
         position: absolute;
-        right: 0px;
+        right: 8px;
 
         .present-icon {
             margin-right: 7px;
@@ -557,6 +656,7 @@
         height: 25;
         position: relative;
         display: inline-block;
+        left: 8px;
     }
 }
 
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index ac2288944..221f1e6a0 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -24,11 +24,11 @@ import { HighlightSpanKind } from "typescript";
 import { SearchUtil } from "../../util/SearchUtil";
 import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
 import { child } from "serializr";
-import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal';
 import { List } from "../../../fields/List";
 import { Tooltip } from "@material-ui/core";
 import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
 import { conformsTo } from "lodash";
+import { translate } from "googleapis/build/src/apis/translate";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -72,11 +72,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     onPointerOver = () => {
         document.addEventListener("keydown", this.keyEvents, true);
-        // document.addEventListener("keydown", this.keyEvents, false);
     }
 
     onPointerLeave = () => {
-        // document.removeEventListener("keydown", this.keyEvents, false);
         document.removeEventListener("keydown", this.keyEvents, true);
     }
 
@@ -96,18 +94,34 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             presTargetDoc.currentFrame = curFrame + 1;
             if (presTargetDoc.zoomProgressivize) {
                 const srcContext = Cast(presTargetDoc.context, Doc, null);
-                if (srcContext) {
-                    srcContext._panX = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]);
-                    srcContext._panY = this.checkList(presTargetDoc, presTargetDoc["top-indexed"]);
-                    srcContext._viewScale = this.checkList(presTargetDoc, presTargetDoc["width-indexed"]);
-                }
-                presTargetDoc._panY = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]);
-                const resize = document.getElementById('resizable');
-                if (resize) {
-                    resize.style.width = this.checkList(presTargetDoc, presTargetDoc["width-indexed"]) + 'px';
-                    resize.style.height = this.checkList(presTargetDoc, presTargetDoc["height-indexed"]) + 'px';
-                    resize.style.top = this.checkList(presTargetDoc, presTargetDoc["top-indexed"]) + 'px';
-                    resize.style.left = this.checkList(presTargetDoc, presTargetDoc["left-indexed"]) + 'px';
+                const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
+                if (srcContext && srcDocView) {
+                    const layoutdoc = Doc.Layout(presTargetDoc);
+                    const panelWidth: number = srcDocView.props.PanelWidth();
+                    const panelHeight: number = srcDocView.props.PanelHeight();
+                    console.log("srcDocView: " + srcDocView.props.PanelWidth());
+                    // console.log("layoutdoc._width: " + layoutdoc._width);
+                    // console.log("srcContext._width: " + srcContext._width);
+                    const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2;
+                    const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2;
+                    // const newPanX = NumCast(presTargetDoc.x) + panelWidth / 2;
+                    // const newPanY = NumCast(presTargetDoc.y) + panelHeight / 2;
+                    let newScale = 0.9 * Math.min(Number(panelWidth) / this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]), Number(panelHeight) / this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]));
+                    // srcContext._panX = newPanX + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
+                    // srcContext._panY = newPanY + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
+                    srcContext._panX = newPanX + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
+                    srcContext._panY = newPanY + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
+                    // srcContext._panX = newPanX
+                    // srcContext._panY = newPanY
+                    srcContext._viewScale = newScale;
+                    console.log("X: " + srcContext._panX + ", Y: " + srcContext._panY + ", Scale: " + srcContext._viewScale);
+                    const resize = document.getElementById('resizable');
+                    if (resize) {
+                        resize.style.width = this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) + 'px';
+                        resize.style.height = this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) + 'px';
+                        resize.style.top = this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + 'px';
+                        resize.style.left = this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + 'px';
+                    }
                 }
             }
             // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
@@ -322,8 +336,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.updateCurrentPresentation();
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        if (this._presTimer && this.layoutDoc.presStatus === "auto") {
-            clearInterval(this._presTimer);
+        if (this.layoutDoc.presStatus === "auto") {
+            if (this._presTimer) clearInterval(this._presTimer);
             this.layoutDoc.presStatus = "manual";
         } else {
             this.layoutDoc.presStatus = "auto";
@@ -381,28 +395,48 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         });
     }
 
-    updateMinimize = action((e: React.ChangeEvent, mode: CollectionViewType) => {
-        if (BoolCast(this.layoutDoc.inOverlay) !== (mode === CollectionViewType.Invalid)) {
-            if (this.layoutDoc.inOverlay) {
+    updateMinimize = async () => {
+        const docToJump = this.childDocs[0];
+        const aliasOf = await DocCastAsync(docToJump.aliasOf);
+        const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
+        if (srcContext) {
+            if (srcContext.miniPres) {
+                document.removeEventListener("keydown", this.keyEvents, true);
+                srcContext.miniPres = false;
                 Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
                 CollectionDockingView.AddRightSplit(this.rootDoc);
                 this.layoutDoc.inOverlay = false;
             } else {
-                const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
-                this.rootDoc.x = pt[0];// 500;//e.clientX + 25;
-                this.rootDoc.y = pt[1];////e.clientY - 25;
+                document.addEventListener("keydown", this.keyEvents, true);
+                srcContext.miniPres = true;
                 this.props.addDocTab?.(this.rootDoc, "close");
                 Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
             }
+
+
         }
-    });
+        // if (srcContext) {
+        //     Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
+        //     CollectionDockingView.AddRightSplit(this.rootDoc);
+        //     this.layoutDoc.inOverlay = false;
+        // }
+        // else {
+        //         const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+        //         this.rootDoc.x = pt[0];// 500;//e.clientX + 25;
+        //         this.rootDoc.y = pt[1];////e.clientY - 25;
+        //         this.props.addDocTab?.(this.rootDoc, "close");
+        //         Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
+        //     }
+        // }
+    };
 
     @undoBatch
     viewChanged = action((e: React.ChangeEvent) => {
         //@ts-ignore
         const viewType = e.target.selectedOptions[0].value as CollectionViewType;
         viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
-        this.updateMinimize(e, this.rootDoc._viewType = viewType);
+        // this.updateMinimize(this.rootDoc._viewType = viewType);
+        if (viewType === CollectionViewType.Stacking) this.rootDoc._gridGap = 5;
     });
 
     @undoBatch
@@ -411,19 +445,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         if (movement === 'zoom') {
             activeItem.presZoomButton = !activeItem.presZoomButton;
-            activeItem.presMovement = 'Zoom';
+            if (activeItem.presZoomButton) activeItem.presMovement = 'Zoom';
+            else activeItem.presMovement = 'None';
             activeItem.presNavButton = false;
         } else if (movement === 'nav') {
             activeItem.presZoomButton = false;
-            activeItem.presMovement = 'Pan';
             activeItem.presNavButton = !activeItem.presNavButton;
+            if (activeItem.presNavButton) activeItem.presMovement = 'Pan';
+            else activeItem.presMovement = 'None';
         } else if (movement === 'switch') {
-            activeItem.presMovement = 'Switch';
             targetDoc.presTransition = 0;
+            activeItem.presSwitchButton = !activeItem.presSwitchButton;
+            if (activeItem.presSwitchButton) activeItem.presMovement = 'Switch';
+            else activeItem.presMovement = 'None';
         } else {
             activeItem.presMovement = 'None';
             activeItem.presZoomButton = false;
             activeItem.presNavButton = false;
+            activeItem.presSwitchButton = false;
         }
     });
 
@@ -439,7 +478,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement;
     removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc);
     getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
-    panelHeight = () => this.props.PanelHeight() - 20;
+    panelHeight = () => this.props.PanelHeight() - 40;
     active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) &&
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
 
@@ -465,9 +504,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     //Regular click
     @action
     selectElement = (doc: Doc) => {
-        this._selectedArray = [];
+        // this._selectedArray = [];
         this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex));
-        this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
+        // this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
         console.log(this._selectedArray);
     }
 
@@ -508,11 +547,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             // Ctrl-A to select all
         } if ((e.metaKey || e.altKey) && e.keyCode === 65) {
             if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs;
-            // left / a / up to go back
-        } if (e.keyCode === 37 || 65 || 38) {
+            // left(37) / a(65) / up(38) to go back
+        } if (e.keyCode === 37) {
             if (this.layoutDoc.presStatus !== "edit") this.back();
-            // right / d / down to go to next
-        } if (e.keyCode === 39 || 68 || 40) {
+            // right (39) / d(68) / down(40) to go to next
+        } if (e.keyCode === 39) {
             if (this.layoutDoc.presStatus !== "edit") this.next();
             // spacebar to 'present' or go to next slide
         } if (e.keyCode === 32) {
@@ -526,6 +565,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @observable private progressivizeTools: boolean = false;
     @observable private moreInfoTools: boolean = false;
     @observable private playTools: boolean = false;
+    @observable private presentTools: boolean = false;
     @observable private pathBoolean: boolean = false;
     @observable private expandBoolean: boolean = false;
 
@@ -548,6 +588,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     // For toggling the tools for progressivize
     @action toggleProgressivize = () => {
         this.progressivizeTools = !this.progressivizeTools;
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        targetDoc.editZoomProgressivize = false;
+        targetDoc.editProgressivize = false;
         this.transitionTools = false;
         this.newDocumentTools = false;
         this.moreInfoTools = false;
@@ -570,6 +614,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.moreInfoTools = false;
     }
 
+    // For toggling the options when the user wants to select play
+    @action togglePresent = () => {
+        this.presentTools = !this.presentTools;
+        this.playTools = false;
+        this.transitionTools = false;
+        this.newDocumentTools = false;
+        this.progressivizeTools = false;
+        this.moreInfoTools = false;
+    }
+
     @action toggleAllDropdowns() {
         this.transitionTools = false;
         this.newDocumentTools = false;
@@ -659,11 +713,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 strokeDasharray: '10 5',
             }}
             fill="none"
-            // markerStart="url(#square)"
-            // markerEnd="url(#arrow)"
-            marker-start="url(#markerSquare)"
-            marker-mid="url(#markerSquare)"
-            marker-end="url(#markerArrow)"
+            markerStart="url(#markerSquare)"
+            markerMid="url(#markerSquare)"
+            markerEnd="url(#markerArrow)"
         />);
     }
 
@@ -725,6 +777,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93);
             const durationThumbLocation = String(9.48 * Number(duration));
             const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
+            activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
             return (
                 <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                     <div className="ribbon-box">
@@ -742,8 +795,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Switch' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Switch</div>
                             </div>
                         </div>
-                        <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed} className={`toolbar-slider ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
-                        <div className={`slider-headers ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`}>
+                        <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed} className={`toolbar-slider ${activeItem.presMovement === 'Pan' || activeItem.presMovement === 'Zoom' ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
+                        <div className={`slider-headers ${activeItem.presMovement === 'Pan' || activeItem.presMovement === 'Zoom' ? "" : "none"}`}>
                             <div className={`slider-value ${activeItem.presZoomButton || activeItem.presNavButton ? "" : "none"}`} style={{ left: transitionThumbLocation + '%' }}>{transitionSpeed}s</div>
                             <div className="slider-text">Slow</div>
                             <div className="slider-text"></div>
@@ -784,7 +837,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Roll'}>Roll</div>
                             </div>
                         </div>
-                        <div className="effectDirection">
+                        <div className="effectDirection" style={{ display: effect === 'None' ? "none" : "grid" }}>
                             <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "left" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'left'}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
                             <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "right" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'right'}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
                             <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === "top" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'top'}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
@@ -863,6 +916,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div title="Freeform" className={'ribbon-button'} style={{ background: type === 'freeform' ? "#000000" : "#f6f6f6" }} onClick={action(() => { type = "freeform"; })}>Freeform</div>
                         </div>
                     </div>
+                    <div className="ribbon-box">
+                        Preset layouts:
+                        <div className="layout-container">
+                            <div className="layout">
+                                <div className="header">HEADER</div>
+                                <div className="subheader">Content goes here</div>
+                            </div>
+                            <div className="layout">
+                                <div className="header" style={{ gridColumn: 1 / 2, gridRow: 1 }}>HEADER</div>
+                                <div className="subheader" style={{ gridColumn: 1, gridRow: 2 }}>Some content</div>
+                                <div className="subheader" style={{ gridColumn: 2, gridRow: 2 }}>Some more content</div>
+                            </div>
+                            <div className="layout">
+                                <div className="header">HEADER</div>
+                                <div className="subheader">Content goes here</div>
+                            </div>
+                        </div>
+                    </div>
                     <div className="ribbon-final-box">
                         <div className="ribbon-final-button" onClick={() => this.createNewSlide(title, type)}>
                             Create New Slide
@@ -877,10 +948,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return (
             <div className={`dropdown-play ${this.playTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                 <div className="dropdown-play-button" onClick={() => this.startOrResetPres(this.itemIndex)}>
-                    Start from current slide
+                    Present from current slide
                 </div>
                 <div className="dropdown-play-button" onClick={() => this.startOrResetPres(0)}>
-                    Start from first slide
+                    Present from first slide
+                </div>
+            </div>
+        );
+    }
+
+    @computed get presentDropdown() {
+        return (
+            <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={this.updateMinimize}>
+                    Minimize
+                </div>
+                <div className="dropdown-play-button" onClick={() => this.startOrResetPres(0)}>
+                    Sidebar view
                 </div>
             </div>
         );
@@ -916,10 +1000,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (tagDoc.zoomProgressivize) {
             const resize = document.getElementById('resizable');
             if (resize) {
-                resize.style.width = this.checkList(tagDoc, tagDoc["width-indexed"]) + 'px';
-                resize.style.height = this.checkList(tagDoc, tagDoc["height-indexed"]) + 'px';
-                resize.style.top = this.checkList(tagDoc, tagDoc["top-indexed"]) + 'px';
-                resize.style.left = this.checkList(tagDoc, tagDoc["left-indexed"]) + 'px';
+                resize.style.width = this.checkList(tagDoc, tagDoc["viewfinder-width-indexed"]) + 'px';
+                resize.style.height = this.checkList(tagDoc, tagDoc["viewfinder-height-indexed"]) + 'px';
+                resize.style.top = this.checkList(tagDoc, tagDoc["viewfinder-top-indexed"]) + 'px';
+                resize.style.left = this.checkList(tagDoc, tagDoc["viewfinder-left-indexed"]) + 'px';
             }
         }
     }
@@ -938,10 +1022,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (tagDoc.zoomProgressivize) {
             const resize = document.getElementById('resizable');
             if (resize) {
-                resize.style.width = this.checkList(tagDoc, tagDoc["width-indexed"]) + 'px';
-                resize.style.height = this.checkList(tagDoc, tagDoc["height-indexed"]) + 'px';
-                resize.style.top = this.checkList(tagDoc, tagDoc["top-indexed"]) + 'px';
-                resize.style.left = this.checkList(tagDoc, tagDoc["left-indexed"]) + 'px';
+                resize.style.width = this.checkList(tagDoc, tagDoc["viewfinder-width-indexed"]) + 'px';
+                resize.style.height = this.checkList(tagDoc, tagDoc["viewfinder-height-indexed"]) + 'px';
+                resize.style.top = this.checkList(tagDoc, tagDoc["viewfinder-top-indexed"]) + 'px';
+                resize.style.left = this.checkList(tagDoc, tagDoc["viewfinder-left-indexed"]) + 'px';
             }
         }
     }
@@ -976,18 +1060,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             </div>
                         </div>
                         <div className="ribbon-final-box">
-                            <div className="ribbon-doubleButton">
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "collection" ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Child documents</div>
                                 <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "flex" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Edit</div>
                             </div>
-                            <div className="ribbon-doubleButton">
-                                <div className="ribbon-button" onClick={this.progressivizeZoom}>Internal zoom</div>
-                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.zoomProgressivize ? "#aedef8" : "" }} onClick={this.zoomProgressivize}>Edit</div>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "collection" || targetDoc.type === "image" ? "inline-flex" : "none" }}>
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Internal zoom</div>
+                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Edit</div>
                             </div>
-                            <div className="ribbon-doubleButton">
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "rtf" ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
                                 <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.textProgressivize ? "#aedef8" : "" }} onClick={this.textProgressivize}>Edit</div>
                             </div>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "pdf" ? "inline-flex" : "none" }}>
+                                <div className="ribbon-button" onClick={this.progressivizeText}>Scroll progressivize</div>
+                                <div className="ribbon-button" style={{ display: activeItem.scrollProgressivize ? "flex" : "none", backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div>
+                            </div>
                         </div>
                     </div>
                 </div>
@@ -995,30 +1083,59 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
-    //Progressivize Zoom
+    //Toggle whether the user edits or not
+    @action
+    editZoomProgressivize = (e: React.MouseEvent) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        if (!targetDoc.editZoomProgressivize) {
+            targetDoc.editZoomProgressivize = true;
+        } else {
+            targetDoc.editZoomProgressivize = false;
+        }
+    }
+
+    //Toggle whether the user edits or not
     @action
-    zoomProgressivize = (e: React.MouseEvent) => {
+    editScrollProgressivize = (e: React.MouseEvent) => {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        if (targetDoc?.zoomProgressivize) {
-            targetDoc.zoomProgressivize = false;
+        if (!targetDoc.editScrollProgressivize) {
+            targetDoc.editScrollProgressivize = true;
         } else {
-            targetDoc.zoomProgressivize = true;
+            targetDoc.editScrollProgressivize = false;
         }
     }
 
+    //Progressivize Zoom
+    @action
+    progressivizeScroll = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        activeItem.scrollProgressivize = !activeItem.scrollProgressivize;
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        targetDoc.scrollProgressivize = !targetDoc.zoomProgressivize;
+        CollectionFreeFormDocumentView.setupScroll(targetDoc, true);
+        if (targetDoc.editScrollProgressivize) {
+            targetDoc.editScrollProgressivize = false;
+            targetDoc.currentFrame = 0;
+            targetDoc.lastFrame = 0;
+        }
+    }
+
+    //Progressivize Zoom
     @action
     progressivizeZoom = (e: React.MouseEvent) => {
         e.stopPropagation();
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         activeItem.zoomProgressivize = !activeItem.zoomProgressivize;
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
         targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize;
-        console.log(targetDoc.zoomProgressivize);
-        if (activeItem.zoomProgressivize) {
-            console.log("progressivize");
+        CollectionFreeFormDocumentView.setupZoom(targetDoc, true);
+        if (targetDoc.editZoomProgressivize) {
+            targetDoc.editZoomProgressivize = false;
             targetDoc.currentFrame = 0;
+            targetDoc.lastFrame = 0;
         }
     }
 
@@ -1081,9 +1198,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             targetDoc.editProgressivize = false;
             activeItem.presProgressivize = false;
             targetDoc.presProgressivize = false;
-            docs.forEach((doc, index) => {
-                doc.appearFrame = 0;
-            });
+            // docs.forEach((doc, index) => {
+            //     doc.appearFrame = 0;
+            // });
             targetDoc.currentFrame = 0;
             targetDoc.lastFrame = 0;
         }
@@ -1130,6 +1247,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     private _isDraggingBR = false;
     private _isDraggingBL = false;
     private _isDragging = false;
+    // private _drag = "";
+
+    // onPointerDown = (e: React.PointerEvent): void => {
+    //     e.stopPropagation();
+    //     e.preventDefault();
+    //     if (e.button === 0) {
+    //         this._drag = e.currentTarget.id;
+    //         console.log(this._drag);
+    //     }
+    //     document.removeEventListener("pointermove", this.onPointerMove);
+    //     document.addEventListener("pointermove", this.onPointerMove);
+    //     document.removeEventListener("pointerup", this.onPointerUp);
+    //     document.addEventListener("pointerup", this.onPointerUp);
+    // }
+
 
     //Adds event listener so knows pointer is down and moving
     onPointerMid = (e: React.PointerEvent): void => {
@@ -1203,87 +1335,136 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     onPointerMove = (e: PointerEvent): void => {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        const tagDocView = DocumentManager.Instance.getDocumentView(targetDoc);
         e.stopPropagation();
         e.preventDefault();
         const doc = document.getElementById('resizable');
-        if (doc) {
+        if (doc && tagDocView) {
+            console.log(tagDocView.props.ScreenToLocalTransform().Scale);
             let height = doc.offsetHeight;
             let width = doc.offsetWidth;
             let top = doc.offsetTop;
             let left = doc.offsetLeft;
+            // const newHeightB = height += (e.movementY * NumCast(targetDoc._viewScale));
+            // const newHeightT = height -= (e.movementY * NumCast(targetDoc._viewScale));
+            // const newWidthR = width += (e.movementX * NumCast(targetDoc._viewScale));
+            // const newWidthL = width -= (e.movementX * NumCast(targetDoc._viewScale));
+            // const newLeft = left += (e.movementX * NumCast(targetDoc._viewScale));
+            // const newTop = top += (e.movementY * NumCast(targetDoc._viewScale));
+            // switch (this._drag) {
+            //     case "": break;
+            //     case "resizer-br":
+            //         doc.style.height = newHeightB + 'px';
+            //         doc.style.width = newWidthR + 'px';
+            //         break;
+            //     case "resizer-bl":
+            //         doc.style.height = newHeightB + 'px';
+            //         doc.style.width = newWidthL + 'px';
+            //         doc.style.left = newLeft + 'px';
+            //         break;
+            //     case "resizer-tr":
+            //         doc.style.width = newWidthR + 'px';
+            //         doc.style.height = newHeightT + 'px';
+            //         doc.style.top = newTop + 'px';
+            //     case "resizer-tl":
+            //         doc.style.width = newWidthL + 'px';
+            //         doc.style.height = newHeightT + 'px';
+            //         doc.style.top = newTop + 'px';
+            //         doc.style.left = newLeft + 'px';
+            //     case "resizable":
+            //         doc.style.top = newTop + 'px';
+            //         doc.style.left = newLeft + 'px';
+            // }
             //Bottom right
             if (this._isDraggingBR) {
-                const newHeight = height += e.movementY;
+                const newHeight = height += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.height = newHeight + 'px';
-                const newWidth = width += e.movementX;
+                const newWidth = width += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.width = newWidth + 'px';
                 // Bottom left
             } else if (this._isDraggingBL) {
-                const newHeight = height += e.movementY;
+                const newHeight = height += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.height = newHeight + 'px';
-                const newWidth = width -= e.movementX;
+                const newWidth = width -= (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.width = newWidth + 'px';
-                const newLeft = left += e.movementX;
+                const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.left = newLeft + 'px';
                 // Top right
             } else if (this._isDraggingTR) {
-                const newWidth = width += e.movementX;
+                const newWidth = width += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.width = newWidth + 'px';
-                const newHeight = height -= e.movementY;
+                const newHeight = height -= (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.height = newHeight + 'px';
-                const newTop = top += e.movementY;
+                const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.top = newTop + 'px';
                 // Top left
             } else if (this._isDraggingTL) {
-                const newWidth = width -= e.movementX;
+                const newWidth = width -= (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.width = newWidth + 'px';
-                const newHeight = height -= e.movementY;
+                const newHeight = height -= (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.height = newHeight + 'px';
-                const newTop = top += e.movementY;
+                const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.top = newTop + 'px';
-                const newLeft = left += e.movementX;
+                const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.left = newLeft + 'px';
             } else if (this._isDragging) {
-                const newTop = top += e.movementY;
+                const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.top = newTop + 'px';
-                const newLeft = left += e.movementX;
+                const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
                 doc.style.left = newLeft + 'px';
             }
-            this.updateList(targetDoc, targetDoc["width-indexed"], width);
-            this.updateList(targetDoc, targetDoc["height-indexed"], height);
-            this.updateList(targetDoc, targetDoc["top-indexed"], top);
-            this.updateList(targetDoc, targetDoc["left-indexed"], left);
+            this.updateList(targetDoc, targetDoc["viewfinder-width-indexed"], width);
+            this.updateList(targetDoc, targetDoc["viewfinder-height-indexed"], height);
+            this.updateList(targetDoc, targetDoc["viewfinder-top-indexed"], top);
+            this.updateList(targetDoc, targetDoc["viewfinder-left-indexed"], left);
         }
     }
 
     @action
     checkList = (doc: Doc, list: any): number => {
         const x: List<number> = list;
-        return x[NumCast(doc.currentFrame)];
+        if (x && x.length >= NumCast(doc.currentFrame) + 1) {
+            return x[NumCast(doc.currentFrame)];
+        } else {
+            x.length = NumCast(doc.currentFrame) + 1;
+            x[NumCast(doc.currentFrame)] = x[NumCast(doc.currentFrame) - 1];
+            return x[NumCast(doc.currentFrame)];
+        }
+
     }
 
     @action
     updateList = (doc: Doc, list: any, val: number) => {
         const x: List<number> = list;
-        x[NumCast(doc.currentFrame)] = val;
-        list = x;
+        if (x && x.length >= NumCast(doc.currentFrame) + 1) {
+            x[NumCast(doc.currentFrame)] = val;
+            list = x;
+        } else {
+            x.length = NumCast(doc.currentFrame) + 1;
+            x[NumCast(doc.currentFrame)] = val;
+            list = x;
+        }
+
     }
 
+    // scale: NumCast(targetDoc._viewScale),
     @computed get zoomProgressivizeContainer() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
-        CollectionFreeFormDocumentView.setupZoom(targetDoc, true);
-
-        return (
-            <div id="resizable" className="resizable" onPointerDown={this.onPointerMid} style={{ width: this.checkList(targetDoc, targetDoc["width-indexed"]), height: this.checkList(targetDoc, targetDoc["height-indexed"]), top: this.checkList(targetDoc, targetDoc["top-indexed"]), left: this.checkList(targetDoc, targetDoc["left-indexed"]), position: 'absolute' }}>
-                <div className='resizers'>
-                    <div className='resizer top-left' onPointerDown={this.onPointerTL}></div>
-                    <div className='resizer top-right' onPointerDown={this.onPointerTR}></div>
-                    <div className='resizer bottom-left' onPointerDown={this.onPointerBL}></div>
-                    <div className='resizer bottom-right' onPointerDown={this.onPointerBR}></div>
-                </div>
-            </div>
-        );
+        if (targetDoc.editZoomProgressivize) {
+            return (
+                <>
+                    <div id="resizable" className="resizable" onPointerDown={this.onPointerMid} style={{ width: this.checkList(targetDoc, targetDoc["viewfinder-width-indexed"]), height: this.checkList(targetDoc, targetDoc["viewfinder-height-indexed"]), top: this.checkList(targetDoc, targetDoc["viewfinder-top-indexed"]), left: this.checkList(targetDoc, targetDoc["viewfinder-left-indexed"]), position: 'absolute' }}>
+                        <div className='resizers'>
+                            <div id="resizer-tl" className='resizer top-left' onPointerDown={this.onPointerTL}></div>
+                            <div id="resizer-tr" className='resizer top-right' onPointerDown={this.onPointerTR}></div>
+                            <div id="resizer-bl" className='resizer bottom-left' onPointerDown={this.onPointerBL}></div>
+                            <div id="resizer-br" className='resizer bottom-right' onPointerDown={this.onPointerBR}></div>
+                        </div>
+                    </div>
+                </>
+            );
+        } else return null;
     }
 
     @computed get progressivizeChildDocs() {
@@ -1341,9 +1522,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return (<div></div>);
     }
 
-    @observable
-    toolbarWidth = (): number => {
-        console.log(this.props.PanelWidth());
+    @computed
+    get toolbarWidth(): number {
         const width = this.props.PanelWidth();
         return width;
     }
@@ -1361,8 +1541,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}><div className={`toolbar-button ${this.pathBoolean ? "active" : ""}`}>
                         <FontAwesomeIcon icon={"exchange-alt"} onClick={this.viewPaths} />
                     </div></Tooltip>
-                    <Tooltip title={<><div className="dash-tooltip">{this.expandBoolean ? "Expand all" : "Minimize all"}</div></>}>
-                        <div className={`toolbar-button ${this.expandBoolean ? "" : "active"}`} onClick={() => { this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = false; else doc.presExpandInlineButton = true; }); }}>
+                    <Tooltip title={<><div className="dash-tooltip">{this.expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
+                        <div className={`toolbar-button ${this.expandBoolean ? "active" : ""}`} onClick={() => { this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = true; else doc.presExpandInlineButton = false; }); }}>
                             <FontAwesomeIcon icon={"eye"} />
                         </div>
                     </Tooltip>
@@ -1370,13 +1550,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <div className="toolbar-divider" />
                     <Tooltip title={<><div className="dash-tooltip">{"Transitions"}</div></>}><div className={`toolbar-button ${this.transitionTools ? "active" : ""}`} onClick={this.toggleTransitionTools}>
                         <FontAwesomeIcon icon={"rocket"} />
-                        <div style={{ display: this.toolbarWidth() > 380 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Transitions</div>
+                        <div style={{ display: this.props.PanelWidth() > 430 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Transitions</div>
                         <FontAwesomeIcon className={`dropdown ${this.transitionTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
                     <div className="toolbar-divider" />
                     <Tooltip title={<><div className="dash-tooltip">{"Progressivize"}</div></>}><div className={`toolbar-button ${this.progressivizeTools ? "active" : ""}`} onClick={this.toggleProgressivize}>
                         <FontAwesomeIcon icon={"tasks"} />
-                        <div style={{ display: this.toolbarWidth() > 380 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Progressivize</div>
+                        <div style={{ display: this.props.PanelWidth() > 430 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Progressivize</div>
                         <FontAwesomeIcon className={`dropdown ${this.progressivizeTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
                     <div className="toolbar-divider" />
@@ -1401,9 +1581,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
                         <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
                     </div>
-                    <Fade left when={this.moreInfoTools}>
-                        <h1>uppercase</h1>
-                    </Fade>
                     <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
                         <div className={`toolbar-moreInfo ${this.moreInfoTools ? "active" : ""}`}>
                             <div className="toolbar-moreInfoBall" />
@@ -1425,22 +1602,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     onPointerDown={e => e.stopPropagation()}
                     onChange={this.viewChanged}
                     value={mode}>
-                    <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Invalid}>Min</option>
+                    {/* <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Invalid}>Min</option> */}
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>List</option>
-                    <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Time}>Time</option>
+                    {/* <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Time}>Time</option> */}
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel}>Slides</option>
                 </select>
                 <div className="presBox-presentPanel">
-                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title={"Reset Presentation" + this.layoutDoc.presStatus ? "" : " From Start"} style={{ gridColumn: 2 }} onClick={() => this.startOrResetPres(0)}>
-                        <FontAwesomeIcon icon={"clock"} /> &nbsp;
-                        <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
-                        <div className="toolbar-divider" style={{ marginLeft: 5 }} />
-                        <FontAwesomeIcon onClick={e => { e.stopPropagation; this.togglePlay(); }} className="dropdown" icon={"angle-down"} />
-                        {this.playDropdown}
-                    </div>
-                    <div className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`} title="Present" onClick={() => this.layoutDoc.presStatus = "manual"}>
-                        <FontAwesomeIcon className="present-icon" icon={"play-circle"} /> Present
-                    </div>
+                    <span className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title={"Reset Presentation" + this.layoutDoc.presStatus ? "" : " From Start"} style={{ minWidth: 60, gridColumn: 2 }}>
+                        <div className="presBox-button-left" onClick={() => this.startOrResetPres(0)}>
+                            <FontAwesomeIcon icon={"clock"} /> &nbsp;
+                            <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
+                        </div>
+                        <div className={`presBox-button-right ${this.playTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePlay(); }}>
+                            <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.playTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
+                            {this.playDropdown}
+                        </div>
+                    </span>
+                    <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`} title="Present">
+                        <div className="presBox-button-left" onClick={() => this.layoutDoc.presStatus = "manual"}><FontAwesomeIcon icon={"play-circle"} /> &nbsp; Present </div>
+                        <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePresent(); }}>
+                            <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
+                            {this.presentDropdown}
+                        </div>
+                    </span>
                     <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title="Back" onClick={this.back}>
                         <FontAwesomeIcon icon={"arrow-left"} />
                     </div>
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 6c6bad06a..4d1195808 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -260,11 +260,11 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     <div className="presElementBox-name">
                         {`${this.targetDoc?.title}`}
                     </div>
-                    <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presElementBox-time">{this.transition}</div></Tooltip>
-                    <Tooltip title={<><div className="dash-tooltip">{"Duration of visibility"}</div></>}><div className="presElementBox-time">{this.duration}</div></Tooltip>
+                    <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.transition}</div></Tooltip>
+                    <Tooltip title={<><div className="dash-tooltip">{"Duration of visibility"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.duration}</div></Tooltip>
                     <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><div
                         className="presElementBox-closeIcon"
-                        onPointerDown={e => e.stopPropagation()}
+                        // onPointerDown={e => e.stopPropagation()}
                         onClick={e => {
                             this.props.removeDocument?.(this.rootDoc);
                             e.stopPropagation();
-- 
cgit v1.2.3-70-g09d2


From b1a7c8c965ff93eca4c002f51cf67df4b8ad21ba Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Thu, 30 Jul 2020 20:55:36 +0800
Subject: pres collection

presentation is always associated with a single collection
---
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  42 +++++---
 src/client/views/nodes/PresBox.tsx                 | 119 +++++++++++++--------
 src/client/views/pdf/PDFViewer.tsx                 |   9 +-
 3 files changed, 109 insertions(+), 61 deletions(-)

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

diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 5d1db6de2..c29547eac 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -11,13 +11,15 @@ import { Document } from "../../../fields/documentSchemas";
 import { TraceMobx } from "../../../fields/util";
 import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
 import { List } from "../../../fields/List";
-import { numberRange } from "../../../Utils";
+import { numberRange, smoothScroll } from "../../../Utils";
 import { ComputedField } from "../../../fields/ScriptField";
 import { listSpec } from "../../../fields/Schema";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal';
 import { PresBox } from "./PresBox";
 import { InkingStroke } from "../InkingStroke";
+import { PDFViewer } from "../pdf/PDFViewer";
+import { PDFBox } from "./PDFBox";
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -76,32 +78,54 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     public static getValues(doc: Doc, time: number) {
         const timecode = Math.round(time);
         return ({
-            h: Cast(doc["h-indexed"], listSpec("number"), [NumCast(doc._height)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number),
-            w: Cast(doc["w-indexed"], listSpec("number"), [NumCast(doc._width)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number),
+            h: Cast(doc["h-indexed"], listSpec("number"), [NumCast(doc._height)]).reduce((p, h, i) => (i <= timecode && h !== undefined) || p === undefined ? h : p, undefined as any as number),
+            w: Cast(doc["w-indexed"], listSpec("number"), [NumCast(doc._width)]).reduce((p, w, i) => (i <= timecode && w !== undefined) || p === undefined ? w : p, undefined as any as number),
             x: Cast(doc["x-indexed"], listSpec("number"), [NumCast(doc.x)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number),
             y: Cast(doc["y-indexed"], listSpec("number"), [NumCast(doc.y)]).reduce((p, y, i) => (i <= timecode && y !== undefined) || p === undefined ? y : p, undefined as any as number),
+            scroll: Cast(doc["scroll-indexed"], listSpec("number"), [NumCast(doc._scrollTop, 0)]).reduce((p, s, i) => (i <= timecode && s !== undefined) || p === undefined ? s : p, undefined as any as number),
             opacity: Cast(doc["opacity-indexed"], listSpec("number"), [NumCast(doc.opacity, 1)]).reduce((p, o, i) => i <= timecode || p === undefined ? o : p, undefined as any as number),
         });
     }
 
-    public static setValues(time: number, d: Doc, x?: number, y?: number, h?: number, w?: number, opacity?: number) {
+    public static setValues(time: number, d: Doc, x?: number, y?: number, h?: number, w?: number, scroll?: number, opacity?: number) {
         const timecode = Math.round(time);
         const hindexed = Cast(d["h-indexed"], listSpec("number"), []).slice();
         const windexed = Cast(d["w-indexed"], listSpec("number"), []).slice();
         const xindexed = Cast(d["x-indexed"], listSpec("number"), []).slice();
         const yindexed = Cast(d["y-indexed"], listSpec("number"), []).slice();
         const oindexed = Cast(d["opacity-indexed"], listSpec("number"), []).slice();
+        const scrollIndexed = Cast(d["scroll-indexed"], listSpec("number"), []).slice();
         xindexed[timecode] = x as any as number;
         yindexed[timecode] = y as any as number;
         hindexed[timecode] = h as any as number;
         windexed[timecode] = w as any as number;
         oindexed[timecode] = opacity as any as number;
+        scrollIndexed[timecode] = scroll as any as number;
         d["x-indexed"] = new List<number>(xindexed);
         d["y-indexed"] = new List<number>(yindexed);
         d["h-indexed"] = new List<number>(hindexed);
         d["w-indexed"] = new List<number>(windexed);
         d["opacity-indexed"] = new List<number>(oindexed);
+        d["scroll-indexed"] = new List<number>(scrollIndexed);
     }
+
+    public static updateScrollframe(doc: Doc, time: number) {
+        let _pdfViewer: PDFViewer | undefined;
+        const timecode = Math.round(time);
+        const scrollIndexed = Cast(doc['scroll-indexed'], listSpec("number"), null);
+        scrollIndexed?.length <= timecode + 1 && scrollIndexed.push(undefined as any as number);
+        setTimeout(() => doc.dataTransition = "inherit", 1010);
+    }
+
+    public static setupScroll(doc: Doc, timecode: number, scrollProgressivize: boolean = false) {
+        const scrollList = new List<number>();
+        scrollList[timecode] = NumCast(doc._scrollTop);
+        doc["scroll-indexed"] = scrollList;
+        doc.activeFrame = ComputedField.MakeFunction("self.currentFrame");
+        doc._scrollTop = ComputedField.MakeInterpolated("scroll", "activeFrame");
+    }
+
+
     public static updateKeyframe(docs: Doc[], time: number) {
         const timecode = Math.round(time);
         docs.forEach(doc => {
@@ -130,10 +154,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         const height = new List<number>();
         const top = new List<number>();
         const left = new List<number>();
-        // width.push(100);
-        // height.push(100);
-        // top.push(0);
-        // left.push(0);
         width.push(NumCast(doc.width));
         height.push(NumCast(doc.height));
         top.push(NumCast(doc.height) / -2);
@@ -144,12 +164,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         doc["viewfinder-left-indexed"] = left;
     }
 
-    public static setupScroll(doc: Doc, scrollProgressivize: boolean = false) {
-        const scrollList = new List<number>();
-        scrollList.push(NumCast(doc._scrollTop));
-        doc["scroll-indexed"] = scrollList;
-    }
-
     public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) {
         docs.forEach((doc, i) => {
             if (!doc.appearFrame) doc.appearFrame = i;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 221f1e6a0..95054205b 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -78,7 +78,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         document.removeEventListener("keydown", this.keyEvents, true);
     }
 
-    updateCurrentPresentation = () => Doc.UserDoc().activePresentation = this.rootDoc;
+    updateCurrentPresentation = () => {
+        Doc.UserDoc().activePresentation = this.rootDoc;
+        if (this.itemIndex >= 0) {
+            const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
+            const srcContext = Cast(presTargetDoc.context, Doc, null);
+            if (srcContext) this.rootDoc.presCollection = srcContext;
+            else this.rootDoc.presCollection = presTargetDoc;
+        }
+    }
 
     @undoBatch
     @action
@@ -149,9 +157,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             //If so making sure to zoom out, which goes back to state before zooming action
             let prevSelected = this.itemIndex;
             let didZoom = docAtCurrent.zoomButton;
-            for (; !didZoom && prevSelected > 0 && this.childDocs[prevSelected].groupButton; prevSelected--) {
-                didZoom = this.childDocs[prevSelected].zoomButton;
-            }
+            // for (; !didZoom && prevSelected > 0 && this.childDocs[prevSelected].groupButton; prevSelected--) {
+            //     didZoom = this.childDocs[prevSelected].zoomButton;
+            // }
             prevSelected = Math.max(0, prevSelected - 1);
 
             this.gotoDocument(prevSelected, this.itemIndex);
@@ -234,13 +242,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const aliasOfNext = await DocCastAsync(nextTarget.aliasOf);
         const nextContext = aliasOfNext && await DocCastAsync(aliasOfNext.context);
         if (curContext && nextContext) {
+            const collectionDocView = DocumentManager.Instance.getDocumentView(Cast(this.rootDoc.presCollection, Doc, null));
             // Case: Documents are not in the same collection
             if (curContext !== nextContext) {
                 // Current document is contained in the next collection (zoom out)
                 if (curContext.context === nextContext) {
+                    if (collectionDocView) collectionDocView.props.addDocTab(curContext, "replace"); console.log("hiii");
                     console.log("current in next");
                     // Next document is contained in the current collection (zoom in)
                 } else if (nextContext.context === curContext) {
+                    if (collectionDocView) collectionDocView.props.addDocTab(nextContext, "replace"); console.log("hiii2");
                     console.log("next in current");
                 }
                 // No change in parent collection
@@ -395,10 +406,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         });
     }
 
-    updateMinimize = async () => {
-        const docToJump = this.childDocs[0];
-        const aliasOf = await DocCastAsync(docToJump.aliasOf);
-        const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
+    updateMinimize = () => {
+        const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
         if (srcContext) {
             if (srcContext.miniPres) {
                 document.removeEventListener("keydown", this.keyEvents, true);
@@ -535,7 +544,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     //Esc click
     @action
     keyEvents = (e: KeyboardEvent) => {
-        e.stopPropagation;
+        e.stopPropagation();
+        e.preventDefault();
         // switch(e.keyCode) {
         //     case 27: console.log("escape");
         //     case 65 && (e.metaKey || e.altKey):
@@ -635,9 +645,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @undoBatch
     @action
     viewPaths = async () => {
-        const docToJump = this.childDocs[0];
-        const aliasOf = await DocCastAsync(docToJump.aliasOf);
-        const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
+        const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
+        // const docToJump = this.childDocs[0];
+        // const aliasOf = await DocCastAsync(docToJump.aliasOf);
+        // const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
         if (this.pathBoolean) {
             console.log("true");
             if (srcContext) {
@@ -668,10 +679,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const order: JSX.Element[] = [];
         this.childDocs.forEach((doc, index) => {
             const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            order.push(
-                <div className="pathOrder" style={{ top: NumCast(targetDoc.y), left: NumCast(targetDoc.x) }}>
-                    <div className="pathOrder-frame">{index + 1}</div>
-                </div>);
+            const srcContext = Cast(targetDoc.context, Doc, null);
+            if (this.rootDoc.presCollection === srcContext) {
+                order.push(
+                    <div className="pathOrder" style={{ top: NumCast(targetDoc.y), left: NumCast(targetDoc.x) }}>
+                        <div className="pathOrder-frame">{index + 1}</div>
+                    </div>);
+            } else {
+                order.push(
+                    <div className="pathOrder" style={{ top: 0, left: 0 }}>
+                        <div className="pathOrder-frame">{index + 1}</div>
+                    </div>);
+            }
         });
         return order;
     }
@@ -682,24 +701,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         console.log(this.childDocs.length - 1);
         this.childDocs.forEach((doc, index) => {
             const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            if (targetDoc) {
+            const srcContext = Cast(targetDoc.context, Doc, null);
+            if (targetDoc && this.rootDoc.presCollection === srcContext) {
                 const n1x = NumCast(targetDoc.x) + (NumCast(targetDoc._width) / 2);
                 const n1y = NumCast(targetDoc.y) + (NumCast(targetDoc._height) / 2);
-                // const n2x = NumCast(nextTargetDoc.x) + (NumCast(targetDoc._width) / 2);
-                // const n2y = NumCast(nextTargetDoc.y) + (NumCast(targetDoc._height) / 2);
                 if (index = 0) pathPoints = n1x + "," + n1y;
                 else pathPoints = pathPoints + " " + n1x + "," + n1y;
-                // const pathPoints = n1x + "," + n1y + " " + n2x + "," + n2y;
-                // else pathPoints = pathPoints + " " + n1x + "," + n1y;
-                // paths.push(<polyline
-                //     points={pathPoints}
-                //     style={{
-                //         opacity: 1,
-                //         stroke: "#69a6db",
-                //         strokeWidth: 5,
-                //     }}
-                //     markerStart="url(#square)"
-                //     markerEnd="url(#arrow)" />);
+            } else {
+                if (index = 0) pathPoints = 0 + "," + 0;
+                else pathPoints = pathPoints + " " + 0 + "," + 0;
             }
         });
         console.log(pathPoints);
@@ -988,12 +998,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const currentFrame = Cast(tagDoc.currentFrame, "number", null);
         if (currentFrame === undefined) {
             tagDoc.currentFrame = 0;
+            CollectionFreeFormDocumentView.setupScroll(tagDoc, 0);
             CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
         }
         let lastFrame: number = 0;
         childDocs.forEach((doc) => {
             if (NumCast(doc.appearFrame) > lastFrame) lastFrame = NumCast(doc.appearFrame);
         });
+        CollectionFreeFormDocumentView.updateScrollframe(tagDoc, currentFrame);
         CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
         tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1);
         tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), lastFrame);
@@ -1066,14 +1078,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "collection" || targetDoc.type === "image" ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Internal zoom</div>
-                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Edit</div>
+                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Viewfinder</div>
+                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "rtf" ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
-                                <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.textProgressivize ? "#aedef8" : "" }} onClick={this.textProgressivize}>Edit</div>
+                                <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.editTextProgressivize ? "#aedef8" : "" }} onClick={this.editTextProgressivize}>Edit</div>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "pdf" ? "inline-flex" : "none" }}>
-                                <div className="ribbon-button" onClick={this.progressivizeText}>Scroll progressivize</div>
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.scrollProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeScroll}>Scroll progressivize</div>
                                 <div className="ribbon-button" style={{ display: activeItem.scrollProgressivize ? "flex" : "none", backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div>
                             </div>
                         </div>
@@ -1083,6 +1096,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    //Toggle whether the user edits or not
+    @action
+    editSnapZoomProgressivize = (e: React.MouseEvent) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        if (!targetDoc.editSnapZoomProgressivize) {
+            targetDoc.editSnapZoomProgressivize = true;
+        } else {
+            targetDoc.editSnapZoomProgressivize = false;
+        }
+
+    }
+
     //Toggle whether the user edits or not
     @action
     editZoomProgressivize = (e: React.MouseEvent) => {
@@ -1115,7 +1141,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         activeItem.scrollProgressivize = !activeItem.scrollProgressivize;
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         targetDoc.scrollProgressivize = !targetDoc.zoomProgressivize;
-        CollectionFreeFormDocumentView.setupScroll(targetDoc, true);
+        CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc.currentFrame), true);
         if (targetDoc.editScrollProgressivize) {
             targetDoc.editScrollProgressivize = false;
             targetDoc.currentFrame = 0;
@@ -1141,14 +1167,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     //Progressivize Text nodes
     @action
-    textProgressivize = (e: React.MouseEvent) => {
+    editTextProgressivize = (e: React.MouseEvent) => {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         targetDoc.currentFrame = targetDoc.lastFrame;
-        if (targetDoc?.editProgressivize) {
-            targetDoc.editProgressivize = false;
+        if (targetDoc?.editTextProgressivize) {
+            targetDoc.editTextProgressivize = false;
         } else {
-            targetDoc.editProgressivize = true;
+            targetDoc.editTextProgressivize = true;
         }
     }
 
@@ -1340,7 +1366,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         e.preventDefault();
         const doc = document.getElementById('resizable');
         if (doc && tagDocView) {
-            console.log(tagDocView.props.ScreenToLocalTransform().Scale);
+            console.log(tagDocView.props.ContentScaling());
+            const transform = (tagDocView.props.ScreenToLocalTransform().scale(tagDocView.props.ContentScaling())).inverse();
+            console.log(transform);
+            const scale = tagDocView.childScaling();
+            console.log(scale);
             let height = doc.offsetHeight;
             let width = doc.offsetWidth;
             let top = doc.offsetTop;
@@ -1377,17 +1407,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             // }
             //Bottom right
             if (this._isDraggingBR) {
-                const newHeight = height += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newHeight = height += (e.movementY * tagDocView.props.ContentScaling());
                 doc.style.height = newHeight + 'px';
-                const newWidth = width += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newWidth = width += (e.movementX * tagDocView.props.ContentScaling());
                 doc.style.width = newWidth + 'px';
                 // Bottom left
             } else if (this._isDraggingBL) {
-                const newHeight = height += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newHeight = height += (e.movementY * scale);
                 doc.style.height = newHeight + 'px';
-                const newWidth = width -= (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newWidth = width -= (e.movementX * scale);
                 doc.style.width = newWidth + 'px';
-                const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newLeft = left += (e.movementX * scale);
                 doc.style.left = newLeft + 'px';
                 // Top right
             } else if (this._isDraggingTR) {
@@ -1444,7 +1474,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             x[NumCast(doc.currentFrame)] = val;
             list = x;
         }
-
     }
 
     // scale: NumCast(targetDoc._viewScale),
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 30c51d9ca..5b73b00d3 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -9,8 +9,8 @@ import { documentSchema } from "../../../fields/documentSchemas";
 import { Id } from "../../../fields/FieldSymbols";
 import { InkTool } from "../../../fields/InkField";
 import { List } from "../../../fields/List";
-import { createSchema, makeInterface } from "../../../fields/Schema";
-import { ScriptField } from "../../../fields/ScriptField";
+import { createSchema, makeInterface, listSpec } from "../../../fields/Schema";
+import { ScriptField, ComputedField } from "../../../fields/ScriptField";
 import { Cast, NumCast } from "../../../fields/Types";
 import { PdfField } from "../../../fields/URLField";
 import { TraceMobx } from "../../../fields/util";
@@ -343,6 +343,11 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
         this._pdfViewer?.scrollPageIntoView({ pageNumber: Math.min(Math.max(1, p), this._pageSizes.length) });
     }
 
+    @action
+    scrollToFrame = (duration: number, top: number) => {
+        this._mainCont.current && smoothScroll(duration, this._mainCont.current, top);
+    }
+
     @action
     scrollToAnnotation = (scrollToAnnotation: Doc) => {
         if (scrollToAnnotation) {
-- 
cgit v1.2.3-70-g09d2


From cab9d814b06987a43e06cf034c61b246acdec9d3 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Thu, 30 Jul 2020 23:35:06 +0800
Subject: more bug fixes

---
 src/client/views/nodes/PresBox.tsx                 | 173 ++++++---------------
 .../views/presentationview/PresElementBox.tsx      |   2 +-
 2 files changed, 52 insertions(+), 123 deletions(-)

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

diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 95054205b..a22d014ca 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -81,10 +81,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     updateCurrentPresentation = () => {
         Doc.UserDoc().activePresentation = this.rootDoc;
         if (this.itemIndex >= 0) {
-            const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
-            const srcContext = Cast(presTargetDoc.context, Doc, null);
-            if (srcContext) this.rootDoc.presCollection = srcContext;
-            else this.rootDoc.presCollection = presTargetDoc;
+            const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+            const targetDoc = activeItem.presentationTargetDoc ? Cast(activeItem.presentationTargetDoc, Doc, null) : undefined;
+            if (targetDoc) {
+                const srcContext = Cast(targetDoc.context, Doc, null);
+                if (srcContext) this.layoutDoc.presCollection = srcContext;
+            } else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
         }
     }
 
@@ -117,8 +119,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     let newScale = 0.9 * Math.min(Number(panelWidth) / this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]), Number(panelHeight) / this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]));
                     // srcContext._panX = newPanX + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
                     // srcContext._panY = newPanY + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
-                    srcContext._panX = newPanX + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
-                    srcContext._panY = newPanY + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
+                    srcContext._panX = newPanX + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
+                    srcContext._panY = newPanY + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
                     // srcContext._panX = newPanX
                     // srcContext._panY = newPanY
                     srcContext._viewScale = newScale;
@@ -137,13 +139,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             let nextSelected = this.itemIndex + 1;
             this.gotoDocument(nextSelected, this.itemIndex);
 
-            for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) {
-                if (!this.childDocs[nextSelected].groupButton) {
-                    break;
-                } else {
-                    this.gotoDocument(nextSelected, this.itemIndex);
-                }
-            }
+            // for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) {
+            //     if (!this.childDocs[nextSelected].groupButton) {
+            //         break;
+            //     } else {
+            //         this.gotoDocument(nextSelected, this.itemIndex);
+            //     }
+            // }
         }
     }
 
@@ -236,81 +238,45 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         });
     }
 
-    checkCollection = async (curTarget: Doc, nextTarget: Doc) => {
-        const aliasOf = await DocCastAsync(curTarget.aliasOf);
-        const curContext = aliasOf && await DocCastAsync(aliasOf.context);
-        const aliasOfNext = await DocCastAsync(nextTarget.aliasOf);
-        const nextContext = aliasOfNext && await DocCastAsync(aliasOfNext.context);
-        if (curContext && nextContext) {
-            const collectionDocView = DocumentManager.Instance.getDocumentView(Cast(this.rootDoc.presCollection, Doc, null));
-            // Case: Documents are not in the same collection
-            if (curContext !== nextContext) {
-                // Current document is contained in the next collection (zoom out)
-                if (curContext.context === nextContext) {
-                    if (collectionDocView) collectionDocView.props.addDocTab(curContext, "replace"); console.log("hiii");
-                    console.log("current in next");
-                    // Next document is contained in the current collection (zoom in)
-                } else if (nextContext.context === curContext) {
-                    if (collectionDocView) collectionDocView.props.addDocTab(nextContext, "replace"); console.log("hiii2");
-                    console.log("next in current");
-                }
-                // No change in parent collection
-            } else {
-                console.log("same collection");
-            }
-
-        }
-    }
     /**
      * This method makes sure that cursor navigates to the element that
      * has the option open and last in the group. If not in the group, and it has
      * the option open, navigates to that element.
      */
-    navigateToElement = async (curDoc: Doc, fromDocIndex: number) => {
+    navigateToElement = (curDoc: Doc) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        const srcContext = Cast(targetDoc.context, Doc, null);
+        const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
+        const collectionDocView = DocumentManager.Instance.getDocumentView(presCollection);
+        console.log("NC: " + srcContext.title);
+        console.log("PC: " + presCollection.title);
+        if (collectionDocView) {
+            if (srcContext !== presCollection) {
+                console.log(collectionDocView);
+                collectionDocView.props.addDocTab(srcContext, "inPlace");
+            }
+        } else if (srcContext) {
+            this.props.addDocTab(srcContext, "onRight");
+        } else if (!srcContext) {
+            this.props.addDocTab(targetDoc, "onRight");
+        }
         this.updateCurrentPresentation();
         const docToJump = curDoc;
         const willZoom = false;
 
-        const nextTarget = curDoc;
-        const curTarget = this.childDocs[fromDocIndex];
-        this.checkCollection(curTarget, nextTarget);
-        // const presDocs = DocListCast(this.dataDoc[this.props.fieldKey]);
-        // let nextSelected = presDocs.indexOf(curDoc);
-        // const currentDocGroups: Doc[] = [];
-        // for (; nextSelected < presDocs.length - 1; nextSelected++) {
-        //     if (!presDocs[nextSelected + 1].groupButton) {
-        //         break;
-        //     }
-        //     currentDocGroups.push(presDocs[nextSelected]);
-        // }
-
-        // currentDocGroups.forEach((doc: Doc, index: number) => {
-        //     if (doc.presNavButton) {
-        //         docToJump = doc;
-        //         willZoom = false;
-        //     }
-        //     if (doc.presZoomButton) {
-        //         docToJump = doc;
-        //         willZoom = true;
-        //     }
-        // });
-
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
-        const aliasOf = await DocCastAsync(docToJump.aliasOf);
-        const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
         if (docToJump === curDoc) {
             //checking if curDoc has navigation open
-            const target = (await DocCastAsync(curDoc.presentationTargetDoc)) || curDoc;
-            if (curDoc.presNavButton && target) {
-                DocumentManager.Instance.jumpToDocument(target, false, undefined, srcContext);
-            } else if (curDoc.presZoomButton && target) {
+            if (curDoc.presNavButton && targetDoc) {
+                DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext);
+            } else if (curDoc.presZoomButton && targetDoc) {
                 //awaiting jump so that new scale can be found, since jumping is async
-                await DocumentManager.Instance.jumpToDocument(target, true, undefined, srcContext);
+                DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext);
             }
         } else {
             //awaiting jump so that new scale can be found, since jumping is async
-            const presTargetDoc = await DocCastAsync(docToJump.presentationTargetDoc);
-            presTargetDoc && await DocumentManager.Instance.jumpToDocument(presTargetDoc, willZoom, undefined, srcContext);
+            targetDoc && DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext);
         }
     }
 
@@ -325,11 +291,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             if (presTargetDoc?.lastFrame !== undefined) {
                 presTargetDoc.currentFrame = 0;
             }
-            // if (this.layoutDoc.presStatus === "edit") {
-            //     this.layoutDoc.presStatus = true;
-            //     this.startPresentation(index);
-            // }
-            this.navigateToElement(this.childDocs[index], fromDoc);
+            this.navigateToElement(this.childDocs[index]);
             this._selectedArray = [this.childDocs[index]];
             // this.hideIfNotPresented(index);
             // this.showAfterPresented(index);
@@ -361,22 +323,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     this.layoutDoc.presStatus = "manual";
                 }
             }, targetDoc.presDuration ? NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition) : 2000);
-            // for (let i = this.itemIndex + 1; i <= this.childDocs.length; i++) {
-            //     if (this.itemIndex + 1 === this.childDocs.length) {
-            //         clearTimeout(this._presTimer);
-            //         this.layoutDoc.presStatus = "manual";
-            //     } else timer = setTimeout(() => { console.log(i); this.next(); }, i * 2000);
-            // }
-
         }
-
-        // if (this.layoutDoc.presStatus) {
-        //     this.resetPresentation();
-        // } else {
-        //     this.layoutDoc.presStatus = true;
-        //     this.startPresentation(0);
-        //     this.gotoDocument(0, this.itemIndex);
-        // }
     }
 
     //The function that resets the presentation by removing every action done by it. It also
@@ -410,19 +357,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
         if (srcContext) {
             if (srcContext.miniPres) {
-                document.removeEventListener("keydown", this.keyEvents, true);
+                document.removeEventListener("keydown", this.keyEvents, false);
                 srcContext.miniPres = false;
-                Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
+                // Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
                 CollectionDockingView.AddRightSplit(this.rootDoc);
-                this.layoutDoc.inOverlay = false;
+                // this.layoutDoc.inOverlay = false;
             } else {
-                document.addEventListener("keydown", this.keyEvents, true);
+                document.addEventListener("keydown", this.keyEvents, false);
                 srcContext.miniPres = true;
                 this.props.addDocTab?.(this.rootDoc, "close");
-                Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
+                // Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
             }
-
-
         }
         // if (srcContext) {
         //     Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
@@ -491,11 +436,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) &&
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
 
-    // render() {
-    // const presOrderedDocs = DocListCast(this.rootDoc.presOrderedDocs);
-    // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
-    //     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
-
     // KEYS
     @observable _selectedArray: Doc[] = [];
 
@@ -516,14 +456,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         // this._selectedArray = [];
         this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex));
         // this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
-        console.log(this._selectedArray);
+        // console.log(this._selectedArray);
     }
 
     //Command click
     @action
     multiSelect = (doc: Doc) => {
         this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
-        console.log(this._selectedArray);
     }
 
     //Shift click
@@ -536,7 +475,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 this._selectedArray.push(this.childDocs[i]);
             }
         }
-        console.log(this._selectedArray);
     }
 
 
@@ -646,9 +584,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @action
     viewPaths = async () => {
         const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
-        // const docToJump = this.childDocs[0];
-        // const aliasOf = await DocCastAsync(docToJump.aliasOf);
-        // const srcContext = aliasOf && await DocCastAsync(aliasOf.context);
         if (this.pathBoolean) {
             console.log("true");
             if (srcContext) {
@@ -696,7 +631,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
     @computed get paths() {
-        // const paths = []; //List of all of the paths that need to be added
         let pathPoints = "";
         console.log(this.childDocs.length - 1);
         this.childDocs.forEach((doc, index) => {
@@ -713,7 +647,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             }
         });
         console.log(pathPoints);
-        // return paths;
         return (<polyline
             points={pathPoints}
             style={{
@@ -826,15 +759,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="slider-text"></div>
                             <div className="slider-text">Long</div>
                         </div>
-                        {/* <div title="Fade After" className={`ribbon-button ${activeItem.presFadeButton ? "active" : ""}`} onClick={this.onFadeDocumentAfterPresentedClick}>Fade After</div> */}
-                        {/* <div title="Hide After" className={`ribbon-button ${activeItem.presHideTillShownButton ? "active" : ""}`} onClick={() => console.log("hide before")}>Hide Before</div> */}
-                        {/* <div title="Hide Before" className={`ribbon-button ${activeItem.presHideAfterButton ? "active" : ""}`} onClick={() => console.log("hide after")}>Hide After</div> */}
                     </div>
                     <div className="ribbon-box">
                         Effects
                         <div className="presBox-dropdown"
                             onPointerDown={e => e.stopPropagation()}
-                        // onClick={() => this.dropdownToggle('Movement')}
                         >
                             {effect}
                             <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
@@ -1366,11 +1295,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         e.preventDefault();
         const doc = document.getElementById('resizable');
         if (doc && tagDocView) {
-            console.log(tagDocView.props.ContentScaling());
-            const transform = (tagDocView.props.ScreenToLocalTransform().scale(tagDocView.props.ContentScaling())).inverse();
-            console.log(transform);
+
             const scale = tagDocView.childScaling();
-            console.log(scale);
+            console.log("childScaling: " + scale);
+            const scale2 = tagDocView.props.ScreenToLocalTransform().Scale;
+            console.log("ScreenToLocal...Scale: " + scale2);
             let height = doc.offsetHeight;
             let width = doc.offsetWidth;
             let top = doc.offsetTop;
@@ -1407,9 +1336,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             // }
             //Bottom right
             if (this._isDraggingBR) {
-                const newHeight = height += (e.movementY * tagDocView.props.ContentScaling());
+                const newHeight = height += (e.movementY * scale2);
                 doc.style.height = newHeight + 'px';
-                const newWidth = width += (e.movementX * tagDocView.props.ContentScaling());
+                const newWidth = width += (e.movementX * scale2);
                 doc.style.width = newWidth + 'px';
                 // Bottom left
             } else if (this._isDraggingBL) {
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 4d1195808..1c04fdf56 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -277,7 +277,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                 </>}
                 <div className="presElementBox-highlight" style={{ display: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "block" : "none" }} />
                 <div className="presElementBox-buttons" style={{ display: this.rootDoc.presExpandInlineButton ? "grid" : "none" }}>
-                    <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search-plus"} onPointerDown={e => e.stopPropagation()} /></button>
+                    <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Navigate" className={pbi + (this.rootDoc.presNavButton ? "-selected" : "")} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Hide Before" className={pbi + (this.rootDoc.presHideTillShownButton ? "-selected" : "")} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={"file"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Hide After" className={pbi + (this.rootDoc.presHideAfterButton ? "-selected" : "")} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button>
-- 
cgit v1.2.3-70-g09d2


From ddd6806e5684608a95d3c00357db730bdbf203c9 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Sat, 1 Aug 2020 15:11:58 +0800
Subject: small changes

---
 src/client/views/nodes/PresBox.tsx                 | 23 +++++++++++-----------
 .../views/presentationview/PresElementBox.tsx      |  5 +----
 2 files changed, 13 insertions(+), 15 deletions(-)

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

diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index a22d014ca..b5f3fc204 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -63,6 +63,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.rootDoc._forceRenderEngine = "timeline";
         this.rootDoc._replacedChrome = "replaced";
         this.layoutDoc.presStatus = "edit";
+        this.layoutDoc._gridGap = 5;
         // document.addEventListener("keydown", this.keyEvents, false);
     }
 
@@ -80,14 +81,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     updateCurrentPresentation = () => {
         Doc.UserDoc().activePresentation = this.rootDoc;
-        if (this.itemIndex >= 0) {
-            const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-            const targetDoc = activeItem.presentationTargetDoc ? Cast(activeItem.presentationTargetDoc, Doc, null) : undefined;
-            if (targetDoc) {
-                const srcContext = Cast(targetDoc.context, Doc, null);
-                if (srcContext) this.layoutDoc.presCollection = srcContext;
-            } else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
-        }
     }
 
     @undoBatch
@@ -136,7 +129,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             }
             // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
         } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
-            let nextSelected = this.itemIndex + 1;
+            const nextSelected = this.itemIndex + 1;
             this.gotoDocument(nextSelected, this.itemIndex);
 
             // for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) {
@@ -249,16 +242,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const srcContext = Cast(targetDoc.context, Doc, null);
         const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
         const collectionDocView = DocumentManager.Instance.getDocumentView(presCollection);
+        if (this.itemIndex >= 0) {
+            if (targetDoc) {
+                if (srcContext) this.layoutDoc.presCollection = srcContext;
+            } else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
+        }
         console.log("NC: " + srcContext.title);
         console.log("PC: " + presCollection.title);
         if (collectionDocView) {
             if (srcContext !== presCollection) {
+                console.log("Case 1: new srcContext inside of current collection so add a new tab to the current pres collection");
                 console.log(collectionDocView);
                 collectionDocView.props.addDocTab(srcContext, "inPlace");
             }
         } else if (srcContext) {
+            console.log("Case 2: srcContext - not open and collection containing this document exists, so open collection that contains it and then await zooming in on document");
             this.props.addDocTab(srcContext, "onRight");
         } else if (!srcContext) {
+            console.log("Case 3: !srcContext - no collection containing this document, therefore open document itself on right");
             this.props.addDocTab(targetDoc, "onRight");
         }
         this.updateCurrentPresentation();
@@ -382,7 +383,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         //         Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
         //     }
         // }
-    };
+    }
 
     @undoBatch
     viewChanged = action((e: React.ChangeEvent) => {
@@ -390,7 +391,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const viewType = e.target.selectedOptions[0].value as CollectionViewType;
         viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
         // this.updateMinimize(this.rootDoc._viewType = viewType);
-        if (viewType === CollectionViewType.Stacking) this.rootDoc._gridGap = 5;
+        if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 5;
     });
 
     @undoBatch
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 1c04fdf56..a0c7ad94b 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -248,10 +248,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                         console.log("normal click");
                     }
                 }}
-                onPointerDown={e => {
-                    this.props.dropAction;
-                    e.stopPropagation();
-                }}
+                onPointerDown={e => { }}
             >
                 {treecontainer ? (null) : <>
                     <div className="presElementBox-number">
-- 
cgit v1.2.3-70-g09d2


From af592ffc89be5f7026f38ddec89956de9c001ed3 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Sun, 2 Aug 2020 04:42:36 +0800
Subject: drag actions

inc. multiple documents (fixed for all stacking collections)
---
 .../views/collections/CollectionStackingView.tsx   |  24 +++-
 .../CollectionStackingViewFieldColumn.tsx          |   4 +-
 .../views/collections/CollectionTreeView.tsx       |   1 +
 src/client/views/nodes/PresBox.tsx                 | 131 ++++++++++++++++-----
 .../views/presentationview/PresElementBox.tsx      |  52 +++++++-
 5 files changed, 170 insertions(+), 42 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index c56ac9f77..dc6354383 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -286,14 +286,26 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
                 }
             });
             if (super.onInternalDrop(e, de)) {
-                const newDoc = de.complete.docDragData.droppedDocuments[0];
+                const newDocs = de.complete.docDragData.droppedDocuments;
                 const docs = this.childDocList;
                 if (docs) {
-                    if (targInd === -1) targInd = docs.length;
-                    else targInd = docs.indexOf(this.filteredChildren[targInd]);
-                    const srcInd = docs.indexOf(newDoc);
-                    docs.splice(srcInd, 1);
-                    docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, newDoc);
+                    newDocs.map((doc, i) => {
+                        if (i === 0) {
+                            if (targInd === -1) targInd = docs.length;
+                            else targInd = docs.indexOf(this.filteredChildren[targInd]);
+                            const srcInd = docs.indexOf(doc);
+                            docs.splice(srcInd, 1);
+                            docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
+                        } else {
+                            if (targInd === -1) targInd = docs.length;
+                            else targInd = docs.indexOf(this.filteredChildren[targInd]);
+                            const srcInd = docs.indexOf(doc);
+                            const firstInd = docs.indexOf(newDocs[0]);
+                            docs.splice(srcInd, 1);
+                            // docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
+                            docs.splice(firstInd + 1, 0, doc);
+                        }
+                    });
                 }
             }
         }
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 76af70cd1..890ab588c 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -350,7 +350,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             </div> : (null);
         for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `;
         const chromeStatus = this.props.parent.props.Document._chromeStatus;
-
+        const type = this.props.parent.props.Document.type;
         return <>
             {this.props.parent.Document._columnsHideIfEmpty ? (null) : headingView}
             {
@@ -370,7 +370,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                             {this.props.parent.children(this.props.docList, uniqueHeadings.length)}
                             {singleColumn ? (null) : this.props.parent.columnDragger}
                         </div>
-                        {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ?
+                        {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled' && type !== 'presentation') ?
                             <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
                                 style={{ width: style.columnWidth / style.numGroupColumns }}>
                                 <EditableView {...newEditableViewProps} menuCallback={this.menuCallback} />
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 651357e5d..dd823f5d5 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -130,6 +130,7 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
+        console.log("ele");
         this._treedropDisposer?.();
         ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), undefined, this.preTreeDrop.bind(this)), this.doc);
     }
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index b5f3fc204..28e340cf1 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -4,8 +4,8 @@ import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, DocCastAsync, WidthSym } from "../../../fields/Doc";
 import { InkTool } from "../../../fields/InkField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { returnFalse, returnOne, numberRange } from "../../../Utils";
+import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from "../../../fields/Types";
+import { returnFalse, returnOne, numberRange, setupMoveUpEvents, emptyFunction, returnTrue } from "../../../Utils";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
@@ -15,7 +15,7 @@ import { FieldView, FieldViewProps } from './FieldView';
 import "./PresBox.scss";
 import { ViewBoxBaseComponent } from "../DocComponent";
 import { makeInterface, listSpec } from "../../../fields/Schema";
-import { Docs } from "../../documents/Documents";
+import { Docs, DocUtils } from "../../documents/Documents";
 import { PrefetchProxy } from "../../../fields/Proxy";
 import { ScriptField } from "../../../fields/ScriptField";
 import { Scripting } from "../../util/Scripting";
@@ -29,6 +29,7 @@ import { Tooltip } from "@material-ui/core";
 import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
 import { conformsTo } from "lodash";
 import { translate } from "googleapis/build/src/apis/translate";
+import { DragManager, dropActionType } from "../../util/DragManager";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -36,6 +37,7 @@ const PresBoxDocument = makeInterface(documentSchema);
 @observer
 export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>(PresBoxDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
+    private treedropDisposer?: DragManager.DragDropDisposer;
     static Instance: PresBox;
     @observable _isChildActive = false;
     @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); }
@@ -67,9 +69,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         // document.addEventListener("keydown", this.keyEvents, false);
     }
 
-    // componentWillUnmount() {
-    //     document.removeEventListener("keydown", this.keyEvents, false);
-    // }
+    componentWillUnmount() {
+        this.treedropDisposer?.();
+    }
 
     onPointerOver = () => {
         document.addEventListener("keydown", this.keyEvents, true);
@@ -236,21 +238,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
      * has the option open and last in the group. If not in the group, and it has
      * the option open, navigates to that element.
      */
-    navigateToElement = (curDoc: Doc) => {
+    navigateToElement = async (curDoc: Doc) => {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        const srcContext = Cast(targetDoc.context, Doc, null);
-        const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
-        const collectionDocView = DocumentManager.Instance.getDocumentView(presCollection);
+        const srcContext = await DocCastAsync(targetDoc.context);
+        const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
+        const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined;
         if (this.itemIndex >= 0) {
             if (targetDoc) {
                 if (srcContext) this.layoutDoc.presCollection = srcContext;
             } else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
         }
-        console.log("NC: " + srcContext.title);
-        console.log("PC: " + presCollection.title);
+        if (srcContext) console.log("NC: " + srcContext.title);
+        if (presCollection) console.log("PC: " + presCollection.title);
         if (collectionDocView) {
-            if (srcContext !== presCollection) {
+            if (srcContext && srcContext !== presCollection) {
                 console.log("Case 1: new srcContext inside of current collection so add a new tab to the current pres collection");
                 console.log(collectionDocView);
                 collectionDocView.props.addDocTab(srcContext, "inPlace");
@@ -270,14 +272,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (docToJump === curDoc) {
             //checking if curDoc has navigation open
             if (curDoc.presNavButton && targetDoc) {
-                DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext);
+                await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext);
             } else if (curDoc.presZoomButton && targetDoc) {
                 //awaiting jump so that new scale can be found, since jumping is async
-                DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext);
+                await DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext);
             }
         } else {
             //awaiting jump so that new scale can be found, since jumping is async
-            targetDoc && DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext);
+            targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext);
         }
     }
 
@@ -424,9 +426,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
     addDocumentFilter = (doc: Doc | Doc[]) => {
         const docs = doc instanceof Doc ? [doc] : doc;
-        docs.forEach(doc => {
-            doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
-            !this.childDocs.includes(doc) && (doc.presZoomButton = true);
+        docs.forEach((doc, i) => {
+            if (this.childDocs.includes(doc)) {
+                console.log(docs.length);
+                console.log(i + 1);
+                if (docs.length === i + 1) return false;
+            } else {
+                doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
+                !this.childDocs.includes(doc) && (doc.presZoomButton = true);
+            }
         });
         return true;
     }
@@ -439,6 +447,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     // KEYS
     @observable _selectedArray: Doc[] = [];
+    @observable _eleArray: HTMLElement[] = [];
 
     @computed get listOfSelected() {
         const list = this._selectedArray.map((doc: Doc, index: any) => {
@@ -462,18 +471,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     //Command click
     @action
-    multiSelect = (doc: Doc) => {
+    multiSelect = (doc: Doc, ref: HTMLElement) => {
         this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
+        this._eleArray.push(ref);
     }
 
     //Shift click
     @action
-    shiftSelect = (doc: Doc) => {
+    shiftSelect = (doc: Doc, ref: HTMLElement) => {
         this._selectedArray = [];
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         if (activeItem) {
             for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) {
                 this._selectedArray.push(this.childDocs[i]);
+                this._eleArray.push(ref);
             }
         }
     }
@@ -1552,9 +1563,68 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
+
+
+    protected createPresDropTarget = (ele: HTMLDivElement) => {
+        console.log("created?");
+        this.treedropDisposer?.();
+        ele && (this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this)));
+        if (ele) {
+            console.log("ele: " + ele.className)
+        }
+    }
+
+    protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, targetAction: dropActionType) {
+        console.log("preDrop?")
+        if (de.complete.docDragData) {
+            // if targetDropAction is, say 'alias', but we're just dragging within a collection, we want to ignore the targetAction.
+            // otherwise, the targetAction should become the actual action (which can still be overridden by the userDropAction -eg, shift/ctrl keys)
+            if (targetAction && !de.complete.docDragData.draggedDocuments.some(d => d.context === this.props.Document && this.childDocs.includes(d))) {
+                de.complete.docDragData.dropAction = targetAction;
+            }
+            e.stopPropagation();
+        }
+    }
+
+    @action
+    protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
+        console.log("drop in pres")
+        const docDragData = de.complete.docDragData;
+        ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData });
+        if (docDragData && this.props.addDocument) {
+            console.log("docDragData && this.props.addDocument");
+            let added = false;
+            const dropaction = docDragData.dropAction || docDragData.userDropAction;
+            if (dropaction && dropaction !== "move") {
+                console.log("dropaction && dropaction !== move");
+                added = this.props.addDocument(docDragData.droppedDocuments);
+            } else if (docDragData.moveDocument) {
+                console.log("docDragData.moveDocument");
+                const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d);
+                const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d);
+                const res = addedDocs.length ? this.props.addDocument(addedDocs) : true;
+                if (movedDocs.length) {
+                    const canAdd = this.props.Document._viewType === CollectionViewType.Pile || de.embedKey ||
+                        Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document);
+                    added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.props.addDocument : returnFalse);
+                } else added = res;
+            } else {
+                console.log("else");
+                added = this.props.addDocument(docDragData.droppedDocuments);
+            }
+            added && e.stopPropagation();
+            return added;
+        }
+        return false;
+    }
+
     render() {
         this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields
         const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
+        // const addDocument = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => {
+        //     return add(doc, relativeTo ? relativeTo : docs[i], before !== undefined ? before : false);
+        // };
         return <div onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
             <div className="presBox-buttons" style={{ display: this.rootDoc._chromeStatus === "disabled" ? "none" : undefined }}>
                 <select className="presBox-viewPicker"
@@ -1600,7 +1670,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             {this.moreInfoDropdown}
             {this.transitionDropdown}
             {this.progressivizeDropdown}
-            <div className="presBox-listCont" >
+            <div className="presBox-listCont"
+                ref={this.createPresDropTarget}>
                 {mode !== CollectionViewType.Invalid ?
                     <CollectionView {...this.props}
                         ContainingCollectionDoc={this.props.Document}
@@ -1609,11 +1680,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         moveDocument={returnFalse}
                         childOpacity={returnOne}
                         childLayoutTemplate={this.childLayoutTemplate}
-                        filterAddDocument={returnFalse}
+                        filterAddDocument={this.addDocumentFilter}
                         removeDocument={returnFalse}
                         dontRegisterView={true}
                         focus={this.selectElement}
-                        presMultiSelect={this.multiSelect}
+                        // presMultiSelect={this.multiSelect}
                         ScreenToLocalTransform={this.getTransform} />
                     : (null)
                 }
@@ -1632,8 +1703,10 @@ Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, d
 
 
 
-        // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
-        // const presOrderedDocs = DocListCast(activeItem.presOrderedDocs);
-        // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
-        //     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
-        // }
+// console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
+// const presOrderedDocs = DocListCast(activeItem.presOrderedDocs);
+// if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
+//     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
+// }
+
+
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index a0c7ad94b..5fba447db 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -6,7 +6,7 @@ import { documentSchema } from '../../../fields/documentSchemas';
 import { Id } from "../../../fields/FieldSymbols";
 import { createSchema, makeInterface, listSpec } from '../../../fields/Schema';
 import { Cast, NumCast, BoolCast, ScriptCast, StrCast } from "../../../fields/Types";
-import { emptyFunction, emptyPath, returnFalse, returnTrue, returnOne, returnZero, numberRange } from "../../../Utils";
+import { emptyFunction, emptyPath, returnFalse, returnTrue, returnOne, returnZero, numberRange, setupMoveUpEvents } from "../../../Utils";
 import { Transform } from "../../util/Transform";
 import { CollectionViewType } from '../collections/CollectionView';
 import { ViewBoxBaseComponent } from '../DocComponent';
@@ -18,6 +18,10 @@ import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocum
 import { PresBox } from "../nodes/PresBox";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { Tooltip } from "@material-ui/core";
+import { DragManager } from "../../util/DragManager";
+import { undoBatch } from "../../util/UndoManager";
+import { DocUtils } from "../../documents/Documents";
+import { DocumentManager } from "../../util/DocumentManager";
 
 export const presSchema = createSchema({
     presentationTargetDoc: Doc,
@@ -40,6 +44,7 @@ const PresDocument = makeInterface(presSchema, documentSchema);
 @observer
 export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDocument>(PresDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); }
+    private _treedropDisposer?: DragManager.DragDropDisposer;
     _heightDisposer: IReactionDisposer | undefined;
     // these fields are conditionally computed fields on the layout document that take this document as a parameter
     @computed get indexInPres() { return Number(this.lookupField("indexInPres")); }  // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
@@ -180,13 +185,13 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
      * The function that is responsible for rendering a preview or not for this
      * presentation element.
      */
+
     @computed get renderEmbeddedInline() {
         return !this.rootDoc.presExpandInlineButton || !this.targetDoc ? (null) :
             <div className="presElementBox-embedded" style={{ height: this.embedHeight(), width: this.embedWidth() }}>
                 <ContentFittingDocumentView
                     Document={this.targetDoc}
                     DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
-                    dragDivName={"collectionFreeFormDocumentView-container"}
                     LibraryPath={emptyPath}
                     fitToBox={true}
                     backgroundColor={this.props.backgroundColor}
@@ -230,6 +235,30 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         return "M: " + transitionInS + "s";
     }
 
+    private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
+
+    headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+        e.stopPropagation();
+        e.preventDefault();
+        setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
+    }
+
+    startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
+        // const ele: HTMLElement[] = PresBox.Instance._eleArray.map(doc => doc);
+        const activeItem = this.rootDoc;
+        const dragData = new DragManager.DocumentDragData(PresBox.Instance._selectedArray.map(doc => doc));
+        // let value = this.getValue(this._heading);
+        // value = typeof value === "string" ? `"${value}"` : value;
+        if (activeItem) {
+            DragManager.StartDocumentDrag(PresBox.Instance._eleArray.map(ele => ele), dragData, e.clientX, e.clientY);
+            activeItem.dragging = true;
+            return true;
+        }
+        return false;
+    }
+
+
+
     render() {
         const treecontainer = this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Tree;
         const className = "presElementBox-item" + (this.itemIndex === this.indexInPres ? " presElementBox-active" : "");
@@ -237,18 +266,31 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : (
             <div className={className} key={this.props.Document[Id] + this.indexInPres}
                 style={{ outlineWidth: Doc.IsBrushed(this.targetDoc) ? `1px` : "0px", }}
+                ref={this._itemRef}
                 onClick={e => {
+                    if (this.props.active(true) || PresBox.Instance._selectedArray.includes(this.rootDoc)) {
+                        e.stopPropagation();
+                        e.preventDefault();
+                    }
                     if (e.ctrlKey || e.metaKey) {
-                        PresBox.Instance.multiSelect(this.rootDoc);
+                        PresBox.Instance.multiSelect(this.rootDoc, this._itemRef.current!);
                         console.log("cmmd click");
                     } else if (e.shiftKey) {
-                        PresBox.Instance.shiftSelect(this.rootDoc);
+                        PresBox.Instance.shiftSelect(this.rootDoc, this._itemRef.current!);
                     } else {
                         this.props.focus(this.rootDoc); e.stopPropagation();
+                        PresBox.Instance._eleArray = [];
+                        PresBox.Instance._eleArray.push(this._itemRef.current!);
                         console.log("normal click");
                     }
                 }}
-                onPointerDown={e => { }}
+                // onClick={e => {
+                //     if (this.props.active(true)) {
+                //         e.stopPropagation();
+                //         e.preventDefault();
+                //     }
+                // }}
+                onPointerDown={this.headerDown}
             >
                 {treecontainer ? (null) : <>
                     <div className="presElementBox-number">
-- 
cgit v1.2.3-70-g09d2


From 1987cf9c4585fce9fe897c5146ebed1bf45ecd64 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Sun, 2 Aug 2020 23:30:12 +0800
Subject: internal nav in topmost collection

---
 src/client/views/nodes/DocumentView.tsx            |   3 +-
 src/client/views/nodes/PresBox.tsx                 | 231 ++++++++++++---------
 .../views/presentationview/PresElementBox.scss     |   4 +-
 .../views/presentationview/PresElementBox.tsx      |  33 ++-
 4 files changed, 151 insertions(+), 120 deletions(-)

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

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c47edefd6..37d561954 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -954,13 +954,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document);
         const borderRounding = this.layoutDoc.borderRounding;
         const localScale = fullDegree;
-
         const highlightColors = Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ?
             ["transparent", "#65350c", "#65350c", "yellow", "magenta", "cyan", "orange"] :
             ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"];
         const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"];
         let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc._viewType !== CollectionViewType.Linear && this.props.Document.type !== DocumentType.INK;
-        highlighting = highlighting && this.props.focus !== emptyFunction;  // bcz: hack to turn off highlighting onsidebar panel documents.  need to flag a document as not highlightable in a more direct way
+        highlighting = highlighting && this.props.focus !== emptyFunction && this.layoutDoc.title !== "[pres element template]";  // bcz: hack to turn off highlighting onsidebar panel documents.  need to flag a document as not highlightable in a more direct way
         const topmost = this.topMost ? "-topmost" : "";
         return <div className={`documentView-node${topmost}`}
             id={this.props.Document[Id]}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 28e340cf1..c04c6c409 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -5,13 +5,14 @@ import { observer } from "mobx-react";
 import { Doc, DocListCast, DocCastAsync, WidthSym } from "../../../fields/Doc";
 import { InkTool } from "../../../fields/InkField";
 import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from "../../../fields/Types";
-import { returnFalse, returnOne, numberRange, setupMoveUpEvents, emptyFunction, returnTrue } from "../../../Utils";
+import { returnFalse, returnOne, numberRange, returnTrue } from "../../../Utils";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
 import { CollectionDockingView, DockedFrameRenderer } from "../collections/CollectionDockingView";
 import { CollectionView, CollectionViewType } from "../collections/CollectionView";
 import { FieldView, FieldViewProps } from './FieldView';
+import { DocumentType } from "../../documents/DocumentTypes";
 import "./PresBox.scss";
 import { ViewBoxBaseComponent } from "../DocComponent";
 import { makeInterface, listSpec } from "../../../fields/Schema";
@@ -30,6 +31,7 @@ import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
 import { conformsTo } from "lodash";
 import { translate } from "googleapis/build/src/apis/translate";
 import { DragManager, dropActionType } from "../../util/DragManager";
+import { actionAsync } from "mobx-utils";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -92,55 +94,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
         const lastFrame = Cast(presTargetDoc.lastFrame, "number", null);
         const curFrame = NumCast(presTargetDoc.currentFrame);
+        let internalFrames: boolean = false;
+        if (presTargetDoc.presProgressivize || presTargetDoc.zoomProgressivize || presTargetDoc.scrollProgressivize) internalFrames = true;
         // Case 1: There are still other frames and should go through all frames before going to next slide
-        if (lastFrame !== undefined && curFrame < lastFrame) {
+        if (internalFrames && lastFrame !== undefined && curFrame < lastFrame) {
             presTargetDoc._viewTransition = "all 1s";
             setTimeout(() => presTargetDoc._viewTransition = undefined, 1010);
             presTargetDoc.currentFrame = curFrame + 1;
-            if (presTargetDoc.zoomProgressivize) {
-                const srcContext = Cast(presTargetDoc.context, Doc, null);
-                const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
-                if (srcContext && srcDocView) {
-                    const layoutdoc = Doc.Layout(presTargetDoc);
-                    const panelWidth: number = srcDocView.props.PanelWidth();
-                    const panelHeight: number = srcDocView.props.PanelHeight();
-                    console.log("srcDocView: " + srcDocView.props.PanelWidth());
-                    // console.log("layoutdoc._width: " + layoutdoc._width);
-                    // console.log("srcContext._width: " + srcContext._width);
-                    const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2;
-                    const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2;
-                    // const newPanX = NumCast(presTargetDoc.x) + panelWidth / 2;
-                    // const newPanY = NumCast(presTargetDoc.y) + panelHeight / 2;
-                    let newScale = 0.9 * Math.min(Number(panelWidth) / this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]), Number(panelHeight) / this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]));
-                    // srcContext._panX = newPanX + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
-                    // srcContext._panY = newPanY + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
-                    srcContext._panX = newPanX + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
-                    srcContext._panY = newPanY + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
-                    // srcContext._panX = newPanX
-                    // srcContext._panY = newPanY
-                    srcContext._viewScale = newScale;
-                    console.log("X: " + srcContext._panX + ", Y: " + srcContext._panY + ", Scale: " + srcContext._viewScale);
-                    const resize = document.getElementById('resizable');
-                    if (resize) {
-                        resize.style.width = this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) + 'px';
-                        resize.style.height = this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) + 'px';
-                        resize.style.top = this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + 'px';
-                        resize.style.left = this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + 'px';
-                    }
-                }
-            }
+            if (presTargetDoc.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc);
             // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
         } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
             const nextSelected = this.itemIndex + 1;
             this.gotoDocument(nextSelected, this.itemIndex);
-
-            // for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) {
-            //     if (!this.childDocs[nextSelected].groupButton) {
-            //         break;
-            //     } else {
-            //         this.gotoDocument(nextSelected, this.itemIndex);
-            //     }
-            // }
         }
     }
 
@@ -163,6 +128,58 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    zoomProgressivizeNext = (presTargetDoc: Doc) => {
+        const srcContext = Cast(presTargetDoc.context, Doc, null);
+        const docView = DocumentManager.Instance.getDocumentView(presTargetDoc);
+        const vfLeft: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]);
+        const vfWidth: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]);
+        const vfTop: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]);
+        const vfHeight: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]);
+        // Case 1: document that is not a Golden Layout tab
+        if (srcContext) {
+            console.log("CASE 1");
+            const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
+            if (srcDocView) {
+                const layoutdoc = Doc.Layout(presTargetDoc);
+                const panelWidth: number = srcDocView.props.PanelWidth();
+                const panelHeight: number = srcDocView.props.PanelHeight();
+                console.log("srcDocView: " + srcDocView.props.PanelWidth());
+                // console.log("layoutdoc._width: " + layoutdoc._width);
+                // console.log("srcContext._width: " + srcContext._width);
+                const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2;
+                const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2;
+                // const newPanX = NumCast(presTargetDoc.x) + panelWidth / 2;
+                // const newPanY = NumCast(presTargetDoc.y) + panelHeight / 2;
+                let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
+                // srcContext._panX = newPanX + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
+                // srcContext._panY = newPanY + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
+                srcContext._panX = newPanX + (vfLeft + (vfWidth / 2));
+                srcContext._panY = newPanY + (vfTop + (vfHeight / 2));
+                // srcContext._panX = newPanX
+                // srcContext._panY = newPanY
+                srcContext._viewScale = newScale;
+                console.log("X: " + srcContext._panX + ", Y: " + srcContext._panY + ", Scale: " + srcContext._viewScale);
+            }
+        }
+        // Case 2: document is the containing collection
+        if (docView && !srcContext) {
+            console.log("CASE 2");
+            const panelWidth: number = docView.props.PanelWidth();
+            const panelHeight: number = docView.props.PanelHeight();
+            let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
+            presTargetDoc._panX = vfLeft + (vfWidth / 2);
+            presTargetDoc._panY = vfTop + (vfWidth / 2);
+            presTargetDoc._viewScale = newScale;
+        }
+        const resize = document.getElementById('resizable');
+        if (resize) {
+            resize.style.width = vfWidth + 'px';
+            resize.style.height = vfHeight + 'px';
+            resize.style.top = vfTop + 'px';
+            resize.style.left = vfLeft + 'px';
+        }
+    }
+
 
     @action
     onHideDocumentUntilPressClick = () => {
@@ -440,14 +457,28 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
     childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement;
     removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc);
-    getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
+    getTransform = () => this.props.ScreenToLocalTransform();// listBox padding-left and pres-box-cont minHeight - .translate(-5, -65)
     panelHeight = () => this.props.PanelHeight() - 40;
     active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) &&
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
 
     // KEYS
     @observable _selectedArray: Doc[] = [];
+    @observable _sortedSelectedArray: Doc[] = [];
     @observable _eleArray: HTMLElement[] = [];
+    @observable _dragArray: HTMLElement[] = [];
+
+    //TODO: Update to radix / quick sort
+    @action
+    sortArray = (): Doc[] => {
+        const sort: Doc[] = this._selectedArray;
+        this.childDocs.forEach((doc, i) => {
+            if (this._selectedArray.includes(doc)) {
+                sort.push(doc);
+            }
+        });
+        return sort;
+    }
 
     @computed get listOfSelected() {
         const list = this._selectedArray.map((doc: Doc, index: any) => {
@@ -473,6 +504,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @action
     multiSelect = (doc: Doc, ref: HTMLElement) => {
         this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
+        const ele = ref.getElementsByClassName("stacking");
         this._eleArray.push(ref);
     }
 
@@ -1013,16 +1045,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             </div>
                         </div>
                         <div className="ribbon-final-box">
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "collection" ? "inline-flex" : "none" }}>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Child documents</div>
                                 <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "flex" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Edit</div>
                             </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "collection" || targetDoc.type === "image" ? "inline-flex" : "none" }}>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL || targetDoc.type === "image" ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Internal zoom</div>
                                 <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Viewfinder</div>
                                 <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div>
                             </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === "rtf" ? "inline-flex" : "none" }}>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
                                 <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.editTextProgressivize ? "#aedef8" : "" }} onClick={this.editTextProgressivize}>Edit</div>
                             </div>
@@ -1178,7 +1210,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const x: List<number> = xlist;
         const y: List<number> = ylist;
         const tags: JSX.Element[] = [];
-        let pathPoints = ""; //List of all of the paths that need to be added
+        let pathPoints = ""; //List of all of the pathpoints that need to be added
         // console.log(x);
         // console.log(x.length);
         // console.log(x[0]);
@@ -1566,58 +1598,58 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
 
 
-    protected createPresDropTarget = (ele: HTMLDivElement) => {
-        console.log("created?");
-        this.treedropDisposer?.();
-        ele && (this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this)));
-        if (ele) {
-            console.log("ele: " + ele.className)
-        }
-    }
+    // protected createPresDropTarget = (ele: HTMLDivElement) => {
+    //     console.log("created?");
+    //     this.treedropDisposer?.();
+    //     ele && (this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this)));
+    //     if (ele) {
+    //         console.log("ele: " + ele.className)
+    //     }
+    // }
 
-    protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, targetAction: dropActionType) {
-        console.log("preDrop?")
-        if (de.complete.docDragData) {
-            // if targetDropAction is, say 'alias', but we're just dragging within a collection, we want to ignore the targetAction.
-            // otherwise, the targetAction should become the actual action (which can still be overridden by the userDropAction -eg, shift/ctrl keys)
-            if (targetAction && !de.complete.docDragData.draggedDocuments.some(d => d.context === this.props.Document && this.childDocs.includes(d))) {
-                de.complete.docDragData.dropAction = targetAction;
-            }
-            e.stopPropagation();
-        }
-    }
+    // protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, targetAction: dropActionType) {
+    //     console.log("preDrop?")
+    //     if (de.complete.docDragData) {
+    //         // if targetDropAction is, say 'alias', but we're just dragging within a collection, we want to ignore the targetAction.
+    //         // otherwise, the targetAction should become the actual action (which can still be overridden by the userDropAction -eg, shift/ctrl keys)
+    //         if (targetAction && !de.complete.docDragData.draggedDocuments.some(d => d.context === this.props.Document && this.childDocs.includes(d))) {
+    //             de.complete.docDragData.dropAction = targetAction;
+    //         }
+    //         e.stopPropagation();
+    //     }
+    // }
 
-    @action
-    protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
-        console.log("drop in pres")
-        const docDragData = de.complete.docDragData;
-        ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData });
-        if (docDragData && this.props.addDocument) {
-            console.log("docDragData && this.props.addDocument");
-            let added = false;
-            const dropaction = docDragData.dropAction || docDragData.userDropAction;
-            if (dropaction && dropaction !== "move") {
-                console.log("dropaction && dropaction !== move");
-                added = this.props.addDocument(docDragData.droppedDocuments);
-            } else if (docDragData.moveDocument) {
-                console.log("docDragData.moveDocument");
-                const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d);
-                const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d);
-                const res = addedDocs.length ? this.props.addDocument(addedDocs) : true;
-                if (movedDocs.length) {
-                    const canAdd = this.props.Document._viewType === CollectionViewType.Pile || de.embedKey ||
-                        Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document);
-                    added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.props.addDocument : returnFalse);
-                } else added = res;
-            } else {
-                console.log("else");
-                added = this.props.addDocument(docDragData.droppedDocuments);
-            }
-            added && e.stopPropagation();
-            return added;
-        }
-        return false;
-    }
+    // @action
+    // protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
+    //     console.log("drop in pres")
+    //     const docDragData = de.complete.docDragData;
+    //     ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData });
+    //     if (docDragData && this.props.addDocument) {
+    //         console.log("docDragData && this.props.addDocument");
+    //         let added = false;
+    //         const dropaction = docDragData.dropAction || docDragData.userDropAction;
+    //         if (dropaction && dropaction !== "move") {
+    //             console.log("dropaction && dropaction !== move");
+    //             added = this.props.addDocument(docDragData.droppedDocuments);
+    //         } else if (docDragData.moveDocument) {
+    //             console.log("docDragData.moveDocument");
+    //             const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d);
+    //             const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d);
+    //             const res = addedDocs.length ? this.props.addDocument(addedDocs) : true;
+    //             if (movedDocs.length) {
+    //                 const canAdd = this.props.Document._viewType === CollectionViewType.Pile || de.embedKey ||
+    //                     Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document);
+    //                 added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.props.addDocument : returnFalse);
+    //             } else added = res;
+    //         } else {
+    //             console.log("else");
+    //             added = this.props.addDocument(docDragData.droppedDocuments);
+    //         }
+    //         added && e.stopPropagation();
+    //         return added;
+    //     }
+    //     return false;
+    // }
 
     render() {
         this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields
@@ -1670,8 +1702,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             {this.moreInfoDropdown}
             {this.transitionDropdown}
             {this.progressivizeDropdown}
-            <div className="presBox-listCont"
-                ref={this.createPresDropTarget}>
+            <div className="presBox-listCont">
+                {/* ref={this.createPresDropTarget}> */}
                 {mode !== CollectionViewType.Invalid ?
                     <CollectionView {...this.props}
                         ContainingCollectionDoc={this.props.Document}
@@ -1685,6 +1717,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         dontRegisterView={true}
                         focus={this.selectElement}
                         // presMultiSelect={this.multiSelect}
+                        // ScreenToLocalTransform={Transform.Identity} />
                         ScreenToLocalTransform={this.getTransform} />
                     : (null)
                 }
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index c87a1583a..159cb5f8a 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -2,7 +2,7 @@
     display: grid;
     grid-template-columns: max-content max-content max-content;
     background-color: #d5dce2;
-    box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.25);
+    // box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.25);
     position: relative;
     pointer-events: all;
     width: 100%;
@@ -44,7 +44,7 @@
 
 .presElementBox-item:hover {
     transition: all .1s;
-    background: #AAAAAA;
+    background: #98b7da;
     border-radius: 6px;
 }
 
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 5fba447db..a27d5ef16 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -19,9 +19,6 @@ import { PresBox } from "../nodes/PresBox";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { Tooltip } from "@material-ui/core";
 import { DragManager } from "../../util/DragManager";
-import { undoBatch } from "../../util/UndoManager";
-import { DocUtils } from "../../documents/Documents";
-import { DocumentManager } from "../../util/DocumentManager";
 
 export const presSchema = createSchema({
     presentationTargetDoc: Doc,
@@ -44,7 +41,6 @@ const PresDocument = makeInterface(presSchema, documentSchema);
 @observer
 export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDocument>(PresDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); }
-    private _treedropDisposer?: DragManager.DragDropDisposer;
     _heightDisposer: IReactionDisposer | undefined;
     // these fields are conditionally computed fields on the layout document that take this document as a parameter
     @computed get indexInPres() { return Number(this.lookupField("indexInPres")); }  // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
@@ -178,14 +174,13 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
     }
 
     embedHeight = () => 100;
-    embedWidth = () => this.props.PanelWidth() - 20;
+    // embedWidth = () => this.props.PanelWidth();
     // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight);
-    // embedWidth = () => this.props.PanelWidth() - 20;
+    embedWidth = () => this.props.PanelWidth() - 20;
     /**
      * The function that is responsible for rendering a preview or not for this
      * presentation element.
      */
-
     @computed get renderEmbeddedInline() {
         return !this.rootDoc.presExpandInlineButton || !this.targetDoc ? (null) :
             <div className="presElementBox-embedded" style={{ height: this.embedHeight(), width: this.embedWidth() }}>
@@ -194,7 +189,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
                     LibraryPath={emptyPath}
                     fitToBox={true}
-                    backgroundColor={this.props.backgroundColor}
+                    backgroundColor={() => "darkgrey"}
                     rootSelected={returnTrue}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
@@ -238,15 +233,21 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
     private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
 
     headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+        const element = document.elementFromPoint(e.clientX, e.clientY)?.parentElement;
         e.stopPropagation();
         e.preventDefault();
-        setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
+        if (element) {
+            console.log(element.className);
+            if (PresBox.Instance._eleArray.includes(element)) {
+                setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
+            }
+        }
     }
 
     startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
         // const ele: HTMLElement[] = PresBox.Instance._eleArray.map(doc => doc);
         const activeItem = this.rootDoc;
-        const dragData = new DragManager.DocumentDragData(PresBox.Instance._selectedArray.map(doc => doc));
+        const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray().map(doc => doc));
         // let value = this.getValue(this._heading);
         // value = typeof value === "string" ? `"${value}"` : value;
         if (activeItem) {
@@ -265,13 +266,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         const pbi = "presElementBox-interaction";
         return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : (
             <div className={className} key={this.props.Document[Id] + this.indexInPres}
-                style={{ outlineWidth: Doc.IsBrushed(this.targetDoc) ? `1px` : "0px", }}
                 ref={this._itemRef}
+                style={{ outlineWidth: Doc.IsBrushed(this.targetDoc) ? `1px` : "0px", }}
                 onClick={e => {
-                    if (this.props.active(true) || PresBox.Instance._selectedArray.includes(this.rootDoc)) {
-                        e.stopPropagation();
-                        e.preventDefault();
-                    }
                     if (e.ctrlKey || e.metaKey) {
                         PresBox.Instance.multiSelect(this.rootDoc, this._itemRef.current!);
                         console.log("cmmd click");
@@ -292,7 +289,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                 // }}
                 onPointerDown={this.headerDown}
             >
-                {treecontainer ? (null) : <>
+                <>
                     <div className="presElementBox-number">
                         {`${this.indexInPres + 1}.`}
                     </div>
@@ -313,7 +310,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     <Tooltip title={<><div className="dash-tooltip">{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}</div></>}><div className={"presElementBox-expand" + (this.rootDoc.presExpandInlineButton ? "-selected" : "")} onClick={e => { e.stopPropagation(); this.presExpandDocumentClick(); }}>
                         <FontAwesomeIcon icon={(this.rootDoc.presExpandInlineButton ? "angle-up" : "angle-down")} onPointerDown={e => e.stopPropagation()} />
                     </div></Tooltip>
-                </>}
+                </>
                 <div className="presElementBox-highlight" style={{ display: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "block" : "none" }} />
                 <div className="presElementBox-buttons" style={{ display: this.rootDoc.presExpandInlineButton ? "grid" : "none" }}>
                     <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} onPointerDown={e => e.stopPropagation()} /></button>
@@ -328,3 +325,5 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         );
     }
 }
+
+// this.layoutDoc.title !== "pres element template"
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 8303cd6389fe9e3c861d7b429bb4e32d3417a895 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Mon, 3 Aug 2020 02:58:31 +0800
Subject: Merge remote-tracking branch 'origin/menu_restructure' into
 presentation_updates

---
 package.json                                       |   6 +-
 src/Utils.ts                                       |   4 +-
 src/client/documents/DocumentTypes.ts              |   1 +
 src/client/documents/Documents.ts                  |  12 +
 src/client/util/CurrentUserUtils.ts                | 116 ++-
 src/client/util/GroupMemberView.scss               |   2 +-
 src/client/util/SelectionManager.ts                |   3 +
 src/client/util/SharingManager.tsx                 |   6 +-
 src/client/views/ContextMenuItem.tsx               |   4 +-
 src/client/views/DocumentButtonBar.tsx             |   8 +-
 src/client/views/DocumentDecorations.tsx           |  19 +-
 src/client/views/EditableView.tsx                  |   2 +-
 src/client/views/MainView.scss                     | 135 +++-
 src/client/views/MainView.tsx                      | 393 ++++++----
 src/client/views/PreviewCursor.tsx                 |   6 +-
 src/client/views/PropertiesButtons.scss            | 119 +++
 src/client/views/PropertiesButtons.tsx             | 598 ++++++++++++++
 .../views/collections/CollectionDockingView.scss   |  16 +-
 .../views/collections/CollectionDockingView.tsx    |  20 +-
 src/client/views/collections/CollectionMenu.tsx    |  79 +-
 .../views/collections/CollectionSchemaView.tsx     |   2 +-
 .../views/collections/CollectionStackingView.tsx   |   1 +
 .../CollectionStackingViewFieldColumn.tsx          |   2 +-
 src/client/views/collections/CollectionSubView.tsx |   2 +-
 .../views/collections/CollectionTreeView.tsx       |   7 +-
 src/client/views/collections/CollectionView.scss   |   1 +
 src/client/views/collections/CollectionView.tsx    |  11 +-
 .../views/collections/ParentDocumentSelector.tsx   |   6 +-
 src/client/views/collections/SchemaTable.tsx       |   8 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  12 +-
 .../collectionFreeForm/FormatShapePane.tsx         |  27 +-
 .../collectionFreeForm/PropertiesView.scss         | 620 +++++++++++++++
 .../collectionFreeForm/PropertiesView.tsx          | 858 +++++++++++++++++++++
 src/client/views/linking/LinkMenuItem.tsx          |   3 +-
 .../views/nodes/ContentFittingDocumentView.tsx     |   3 +
 src/client/views/nodes/DocumentContentsView.tsx    |   3 +-
 src/client/views/nodes/DocumentLinksButton.tsx     |   5 +-
 src/client/views/nodes/DocumentView.tsx            |  62 +-
 src/client/views/nodes/FieldView.tsx               |   1 +
 src/client/views/nodes/FontIconBox.scss            |   2 +-
 src/client/views/nodes/MenuIconBox.scss            |  49 ++
 src/client/views/nodes/MenuIconBox.tsx             |  33 +
 src/client/views/nodes/PresBox.tsx                 |  10 +-
 .../views/nodes/formattedText/DashFieldView.tsx    |   2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   4 +-
 .../views/nodes/formattedText/RichTextMenu.tsx     |  41 +-
 src/client/views/nodes/formattedText/nodes_rts.ts  |   8 +-
 src/fields/Doc.ts                                  |   6 +-
 src/server/ActionUtilities.ts                      |  10 +-
 src/server/ApiManagers/UtilManager.ts              |   1 -
 src/server/DashUploadUtils.ts                      |  27 +-
 src/server/GarbageCollector.ts                     |   6 +-
 src/server/MemoryDatabase.ts                       |   5 +-
 src/server/Message.ts                              |   2 +-
 src/server/ProcessFactory.ts                       |   6 +-
 src/server/Recommender.ts                          | 133 ----
 src/server/RouteManager.ts                         |   8 +-
 src/server/Search.ts                               |   2 +-
 src/server/database.ts                             |   8 +-
 src/server/downsize.ts                             |   2 +-
 src/server/index.ts                                |  34 +-
 src/server/server_Initialization.ts                |  38 +-
 src/server/websocket.ts                            |  27 +-
 63 files changed, 3126 insertions(+), 521 deletions(-)
 create mode 100644 src/client/views/PropertiesButtons.scss
 create mode 100644 src/client/views/PropertiesButtons.tsx
 create mode 100644 src/client/views/collections/collectionFreeForm/PropertiesView.scss
 create mode 100644 src/client/views/collections/collectionFreeForm/PropertiesView.tsx
 create mode 100644 src/client/views/nodes/MenuIconBox.scss
 create mode 100644 src/client/views/nodes/MenuIconBox.tsx
 delete mode 100644 src/server/Recommender.ts

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

diff --git a/package.json b/package.json
index 11af6b2c6..420765e7c 100644
--- a/package.json
+++ b/package.json
@@ -11,8 +11,8 @@
     },
     "scripts": {
         "start-release": "cross-env RELEASE=true NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts",
-        "start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --transpile-only -- src/server/index.ts",
-        "oldstart": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev -- src/server/index.ts",
+        "start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only  -- src/server/index.ts",
+        "oldstart": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug -- src/server/index.ts",
         "debug": "cross-env NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --transpile-only --inspect -- src/server/index.ts",
         "build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 webpack --env production",
         "test": "mocha -r ts-node/register test/**/*.ts",
@@ -260,4 +260,4 @@
         "xoauth2": "^1.2.0",
         "xregexp": "^4.3.0"
     }
-}
+}
\ No newline at end of file
diff --git a/src/Utils.ts b/src/Utils.ts
index a01a94134..0b057dc23 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -1,8 +1,8 @@
 import v4 = require('uuid/v4');
 import v5 = require("uuid/v5");
-import { Socket, Room } from 'socket.io';
-import { Message } from './server/Message';
 import { ColorState } from 'react-color';
+import { Socket } from 'socket.io';
+import { Message } from './server/Message';
 
 export namespace Utils {
     export let DRAG_THRESHOLD = 4;
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 985fcce11..659f78970 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -13,6 +13,7 @@ export enum DocumentType {
     INK = "ink",        // ink stroke
     SCREENSHOT = "screenshot",  // view of a desktop application
     FONTICON = "fonticonbox",   // font icon
+    MENUICON = "menuiconbox",
     QUERY = "query",            // search query
     LABEL = "label",            // simple text label
     BUTTON = "button",          // onClick button
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 0da93aa7a..01cdb1eee 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -31,6 +31,7 @@ import { ColorBox } from "../views/nodes/ColorBox";
 import { ComparisonBox } from "../views/nodes/ComparisonBox";
 import { DocHolderBox } from "../views/nodes/DocHolderBox";
 import { FontIconBox } from "../views/nodes/FontIconBox";
+import { MenuIconBox } from "../views/nodes/MenuIconBox";
 import { FormattedTextBox } from "../views/nodes/formattedText/FormattedTextBox";
 import { ImageBox } from "../views/nodes/ImageBox";
 import { KeyValueBox } from "../views/nodes/KeyValueBox";
@@ -305,6 +306,13 @@ export namespace Docs {
                 layout: { view: FontIconBox, dataField: defaultDataKey },
                 options: { _width: 40, _height: 40, borderRounding: "100%" },
             }],
+            [DocumentType.MENUICON, {
+                layout: { view: MenuIconBox, dataField: defaultDataKey },
+            }],
+            // [DocumentType.RECOMMENDATION, {
+            //     layout: { view: RecommendationsBox, dataField: defaultDataKey },
+            //     options: { _width: 200, _height: 200 },
+            // }],
             [DocumentType.WEBCAM, {
                 layout: { view: DashWebRTCVideo, dataField: defaultDataKey }
             }],
@@ -791,6 +799,10 @@ export namespace Docs {
             return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { hideLinkButton: true, ...(options || {}) });
         }
 
+        export function MenuIconDocument(options?: DocumentOptions) {
+            return InstanceFromProto(Prototypes.get(DocumentType.MENUICON), undefined, { hideLinkButton: true, ...(options || {}) });
+        }
+
         export function PresElementBoxDocument(options?: DocumentOptions) {
             return InstanceFromProto(Prototypes.get(DocumentType.PRESELEMENT), undefined, { ...(options || {}) });
         }
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 6d752832a..b37c91c56 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -38,6 +38,16 @@ export class CurrentUserUtils {
     @observable public static GuestWorkspace: Doc | undefined;
     @observable public static GuestMobile: Doc | undefined;
 
+    @observable public static toolsBtn: any | undefined;
+    @observable public static libraryBtn: any | undefined;
+    @observable public static searchBtn: any | undefined;
+
+    @observable public static toolsStack: any | undefined;
+    @observable public static workspaceStack: any | undefined;
+    @observable public static catalogStack: any | undefined;
+    @observable public static closedStack: any | undefined;
+    @observable public static searchStack: any | undefined;
+
     // sets up the default User Templates - slideView, queryView, descriptionView
     static setupUserTemplateButtons(doc: Doc) {
         if (doc["template-button-query"] === undefined) {
@@ -492,6 +502,46 @@ export class CurrentUserUtils {
         return doc.myItemCreators as Doc;
     }
 
+    static menuBtnDescriptions(): {
+        title: string, icon: string, click: string,
+    }[] {
+        return [
+            { title: "Workspace", icon: "desktop", click: 'scriptContext.selectMenu("Workspace")' },
+            { title: "Catalog", icon: "file", click: 'scriptContext.selectMenu("Catalog")' },
+            { title: "Archive", icon: "archive", click: 'scriptContext.selectMenu("Archive")' },
+            { title: "Import", icon: "upload", click: 'scriptContext.selectMenu("Import")' },
+            { title: "Sharing", icon: "users", click: 'scriptContext.selectMenu("Sharing")' },
+            { title: "Tools", icon: "wrench", click: 'scriptContext.selectMenu("Tools")' },
+            { title: "Help", icon: "question-circle", click: 'scriptContext.selectMenu("Help")' },
+            { title: "Settings", icon: "cog", click: 'scriptContext.selectMenu("Settings")' },
+        ];
+    }
+
+    static setupMenuPanel(doc: Doc) {
+        if (doc.menuStack === undefined) {
+            const buttons = CurrentUserUtils.menuBtnDescriptions();
+            const menuBtns = buttons.map(({ title, icon, click }) => Docs.Create.MenuIconDocument({
+                icon,
+                title,
+                _backgroundColor: "black",
+                stayInCollection: true,
+                _width: 60,
+                _height: 60,
+                onClick: ScriptField.MakeScript(click, { scriptContext: "any" }),
+            }));
+
+            doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, {
+                title: "menuItemPanel",
+                _backgroundColor: "black",
+                _gridGap: 0,
+                _yMargin: 0,
+                _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, lockedPosition: true, _chromeStatus: "disabled",
+            }));
+        }
+        return doc.menuStack as Doc;
+    }
+
+
     // Sets up mobile menu if it is undefined creates a new one, otherwise returns existing menu
     static setupActiveMobileMenu(doc: Doc) {
         if (doc.activeMobileMenu === undefined) {
@@ -601,6 +651,8 @@ export class CurrentUserUtils {
         const creatorBtns = await CurrentUserUtils.setupCreatorButtons(doc);
         const templateBtns = CurrentUserUtils.setupUserTemplateButtons(doc);
 
+        doc["tabs-button-tools"] = undefined;
+
         if (doc.myCreators === undefined) {
             doc.myCreators = new PrefetchProxy(Docs.Create.StackingDocument([creatorBtns, templateBtns], {
                 title: "all Creators", _yMargin: 0, _autoHeight: true, _xMargin: 0,
@@ -617,8 +669,11 @@ export class CurrentUserUtils {
 
         if (doc["tabs-button-tools"] === undefined) {
             const toolsStack = new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc, doc.myColorPicker as Doc], {
-                _width: 500, lockedPosition: true, _chromeStatus: "disabled", title: "tools stack", forceActive: true
+                _width: 500, lockedPosition: true, _chromeStatus: "disabled", hideFilterView: true, title: "tools stack", forceActive: true
             })) as any as Doc;
+
+            CurrentUserUtils.toolsStack = toolsStack;
+
             doc["tabs-button-tools"] = new PrefetchProxy(Docs.Create.ButtonDocument({
                 _width: 35, _height: 25, title: "Tools", _fontSize: "10pt",
                 letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
@@ -627,41 +682,63 @@ export class CurrentUserUtils {
                 dragFactory: toolsStack,
                 removeDropProperties: new List<string>(["lockedPosition"]),
                 stayInCollection: true,
+                hideFilterView: true,
                 targetContainer: new PrefetchProxy(sidebarContainer) as any as Doc,
                 onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel"),
             }));
         }
-        (doc["tabs-button-tools"] as Doc).sourcePanel; // prefetch sourcePanel
-        return doc["tabs-button-tools"] as Doc;
+        (doc["tabs-button-tools"] as any as Doc).sourcePanel; // prefetch sourcePanel
+
+        return doc["tabs-button-tools"] as any as Doc;
     }
 
     static setupWorkspaces(doc: Doc) {
         // setup workspaces library item
+        doc.myWorkspaces === undefined;
         if (doc.myWorkspaces === undefined) {
             doc.myWorkspaces = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "WORKSPACES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true,
+                title: "WORKSPACES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, treeViewOpen: true,
             }));
         }
         const newWorkspace = ScriptField.MakeScript(`createNewWorkspace()`);
         (doc.myWorkspaces as Doc).contextMenuScripts = new List<ScriptField>([newWorkspace!]);
         (doc.myWorkspaces as Doc).contextMenuLabels = new List<string>(["Create New Workspace"]);
 
+        const workspaces = doc.myWorkspaces as Doc;
+
+        CurrentUserUtils.workspaceStack = new PrefetchProxy(Docs.Create.TreeDocument([workspaces], {
+            title: " ", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
+            treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false, treeViewOpen: true,
+            lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
+        })) as any as Doc;
+
         return doc.myWorkspaces as Doc;
     }
     static setupCatalog(doc: Doc) {
+        doc.myCatalog === undefined;
         if (doc.myCatalog === undefined) {
             doc.myCatalog = new PrefetchProxy(Docs.Create.SchemaDocument([], [], {
                 title: "CATALOG", _height: 1000, _fitWidth: true, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false,
-                childDropAction: "alias", targetDropAction: "same", stayInCollection: true,
+                childDropAction: "alias", targetDropAction: "same", stayInCollection: true, treeViewOpen: true,
             }));
         }
+
+        const catalog = doc.myCatalog as Doc;
+
+        CurrentUserUtils.catalogStack = new PrefetchProxy(Docs.Create.TreeDocument([catalog], {
+            title: " ", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
+            treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false, treeViewOpen: true,
+            lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
+        })) as any as Doc;
+
         return doc.myCatalog as Doc;
     }
     static setupRecentlyClosed(doc: Doc) {
         // setup Recently Closed library item
+        doc.myRecentlyClosed === undefined;
         if (doc.myRecentlyClosed === undefined) {
             doc.myRecentlyClosed = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: true, stayInCollection: true,
+                title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, treeViewOpen: true, stayInCollection: true,
             }));
         }
         // this is equivalent to using PrefetchProxies to make sure the recentlyClosed doc is ready
@@ -670,6 +747,14 @@ export class CurrentUserUtils {
         (doc.myRecentlyClosed as Doc).contextMenuScripts = new List<ScriptField>([clearAll!]);
         (doc.myRecentlyClosed as Doc).contextMenuLabels = new List<string>(["Clear All"]);
 
+        const recentlyClosed = doc.myRecentlyClosed as Doc;
+
+        CurrentUserUtils.closedStack = new PrefetchProxy(Docs.Create.TreeDocument([recentlyClosed], {
+            title: " ", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
+            treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false, treeViewOpen: true,
+            lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
+        })) as any as Doc;
+
         return doc.myRecentlyClosed as Doc;
     }
     // setup the Library button which will display the library panel.  This panel includes a collection of workspaces, documents, and recently closed views
@@ -681,7 +766,7 @@ export class CurrentUserUtils {
         if (doc["tabs-button-library"] === undefined) {
             const libraryStack = new PrefetchProxy(Docs.Create.TreeDocument([workspaces, documents, recentlyClosed, doc], {
                 title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
-                treeViewTruncateTitleWidth: 150,
+                treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false,
                 lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
             })) as any as Doc;
             doc["tabs-button-library"] = new PrefetchProxy(Docs.Create.ButtonDocument({
@@ -701,6 +786,7 @@ export class CurrentUserUtils {
 
     // setup the Search button which will display the search panel.
     static setupSearchBtnPanel(doc: Doc, sidebarContainer: Doc) {
+        doc["tabs-button-search"] = undefined;
         if (doc["tabs-button-search"] === undefined) {
             doc["tabs-button-search"] = new PrefetchProxy(Docs.Create.ButtonDocument({
                 _width: 50, _height: 25, title: "Search", _fontSize: "10pt",
@@ -711,8 +797,9 @@ export class CurrentUserUtils {
                 lockedPosition: true,
                 onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel")
             }));
+            CurrentUserUtils.searchStack = new PrefetchProxy(Docs.Create.QueryDocument({ title: "search stack", })) as any as Doc;
         }
-        return doc["tabs-button-search"] as Doc;
+        return doc["tabs-button-search"] as any as Doc;
     }
 
     static setupSidebarContainer(doc: Doc) {
@@ -728,17 +815,17 @@ export class CurrentUserUtils {
     // setup the list of sidebar mode buttons which determine what is displayed in the sidebar
     static async setupSidebarButtons(doc: Doc) {
         const sidebarContainer = CurrentUserUtils.setupSidebarContainer(doc);
-        const toolsBtn = await CurrentUserUtils.setupToolsBtnPanel(doc, sidebarContainer);
-        const libraryBtn = CurrentUserUtils.setupLibraryPanel(doc, sidebarContainer);
-        const searchBtn = CurrentUserUtils.setupSearchBtnPanel(doc, sidebarContainer);
+        CurrentUserUtils.toolsBtn = await CurrentUserUtils.setupToolsBtnPanel(doc, sidebarContainer);
+        CurrentUserUtils.libraryBtn = CurrentUserUtils.setupLibraryPanel(doc, sidebarContainer);
+        CurrentUserUtils.searchBtn = CurrentUserUtils.setupSearchBtnPanel(doc, sidebarContainer);
 
         // Finally, setup the list of buttons to display in the sidebar
         if (doc["tabs-buttons"] === undefined) {
-            doc["tabs-buttons"] = new PrefetchProxy(Docs.Create.StackingDocument([libraryBtn, searchBtn, toolsBtn], {
+            doc["tabs-buttons"] = new PrefetchProxy(Docs.Create.StackingDocument([CurrentUserUtils.libraryBtn, CurrentUserUtils.searchBtn, CurrentUserUtils.toolsBtn], {
                 _width: 500, _height: 80, boxShadow: "0 0", _pivotField: "title", _columnsHideIfEmpty: true, ignoreClick: true, _chromeStatus: "view-mode",
                 title: "sidebar btn row stack", backgroundColor: "dimGray",
             }));
-            (toolsBtn.onClick as ScriptField).script.run({ this: toolsBtn });
+            (CurrentUserUtils.toolsBtn.onClick as ScriptField).script.run({ this: CurrentUserUtils.toolsBtn });
         }
     }
 
@@ -749,7 +836,7 @@ export class CurrentUserUtils {
     })) as any as Doc
 
     static ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({
-        ...opts, dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100
+        ...opts, dropAction: "alias", removeDropProperties: new List<string>(["dropAction"]), _nativeWidth: 40, _nativeHeight: 40, _width: 40, _height: 40
     })) as any as Doc
 
     /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
@@ -855,6 +942,7 @@ export class CurrentUserUtils {
         this.setupDocTemplates(doc); // sets up the template menu of templates
         this.setupRightSidebar(doc);  // sets up the right sidebar collection for mobile upload documents and sharing
         this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
+        this.setupMenuPanel(doc);
         this.setupOverlays(doc);  // documents in overlay layer
         this.setupDockedButtons(doc);  // the bottom bar of font icons
         this.setupDefaultPresentation(doc); // presentation that's initially triggered
diff --git a/src/client/util/GroupMemberView.scss b/src/client/util/GroupMemberView.scss
index 2fc27ed03..2eb164988 100644
--- a/src/client/util/GroupMemberView.scss
+++ b/src/client/util/GroupMemberView.scss
@@ -44,7 +44,7 @@
             background: none;
 
             &:hover {
-                text-overflow: visible;
+                text-overflow: unset;
                 overflow-x: auto;
             }
         }
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 20d881961..05ba00331 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -12,6 +12,7 @@ export namespace SelectionManager {
 
         @observable IsDragging: boolean = false;
         SelectedDocuments: ObservableMap<DocumentView, boolean> = new ObservableMap();
+
         @action
         SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
 
@@ -32,6 +33,7 @@ export namespace SelectionManager {
         }
         @action
         DeselectDoc(docView: DocumentView): void {
+
             if (manager.SelectedDocuments.get(docView)) {
                 manager.SelectedDocuments.delete(docView);
                 docView.props.whenActiveChanged(false);
@@ -40,6 +42,7 @@ export namespace SelectionManager {
         }
         @action
         DeselectAll(): void {
+
             Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false));
             manager.SelectedDocuments.clear();
             Doc.UserDoc().activeSelection = new List<Doc>([]);
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 5896bdf92..000b3e46c 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -72,8 +72,6 @@ export default class SharingManager extends React.Component<{}> {
     @observable private showUserOptions: boolean = false; // whether to show individuals as options when sharing (in the react-select component)
     @observable private showGroupOptions: boolean = false; // // whether to show groups as options when sharing (in the react-select component)
 
-
-
     // private get linkVisible() {
     //     return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false;
     // }
@@ -148,7 +146,7 @@ export default class SharingManager extends React.Component<{}> {
         const members: string[] = JSON.parse(StrCast(group.members));
         const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email));
 
-        const target = this.targetDoc!;
+        const target = targetDoc || this.targetDoc!;
         const ACL = `ACL-${StrCast(group.groupName)}`;
 
         target.author === Doc.CurrentUserEmail && distributeAcls(ACL, permission as SharingPermissions, target);
@@ -222,7 +220,7 @@ export default class SharingManager extends React.Component<{}> {
 
     setInternalSharing = (recipient: ValidatedUser, permission: string) => {
         const { user, notificationDoc } = recipient;
-        const target = this.targetDoc!;
+        const target = targetDoc || this.targetDoc!;
         const key = user.email.replace('.', '_');
         const ACL = `ACL-${key}`;
 
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 81432968d..7e233ec04 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -80,7 +80,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
     render() {
         if ("event" in this.props) {
             return (
-                <div className={"contextMenu-item" + (this.props.selected ? " contextMenu-itemSelected" : "")} onClick={this.handleEvent}>
+                <div className={"contextMenu-item" + (this.props.selected ? " contextMenu-itemSelected" : "")} onPointerDown={this.handleEvent}>
                     {this.props.icon ? (
                         <span className="icon-background">
                             <FontAwesomeIcon icon={this.props.icon} size="sm" />
@@ -95,7 +95,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
             const where = !this.overItem ? "" : this._overPosY < window.innerHeight / 3 ? "flex-start" : this._overPosY > window.innerHeight * 2 / 3 ? "flex-end" : "center";
             const marginTop = !this.overItem ? "" : this._overPosY < window.innerHeight / 3 ? "20px" : this._overPosY > window.innerHeight * 2 / 3 ? "-20px" : "";
             const submenu = !this.overItem ? (null) :
-                <div className="contextMenu-subMenu-cont" style={{ marginLeft: "25%", left: "0px", marginTop }}>
+                <div className="contextMenu-subMenu-cont" style={{ marginLeft: "90%", left: "0px", marginTop }}>
                     {this._items.map(prop => <ContextMenuItem {...prop} key={prop.description} closeMenu={this.props.closeMenu} />)}
                 </div>;
             if (!("noexpand" in this.props)) {
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 6b85616c2..23a3e1684 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -281,7 +281,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
             {DocumentLinksButton.StartLink ? <div className="documentButtonBar-button">
                 <DocumentLinksButton links={this.view0.allLinks} View={this.view0} AlwaysOn={true} InMenu={true} StartLink={false} />
             </div> : null}
-            <div className="documentButtonBar-button">
+            {/* <div className="documentButtonBar-button">
                 {this.templateButton}
             </div>
             <div className="documentButtonBar-button">
@@ -289,16 +289,16 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
             </div>
             <div className="documentButtonBar-button">
                 {this.contextButton}
-            </div>
+            </div> */}
             <div className="documentButtonBar-button">
                 {this.pinButton}
             </div>
-            <div className="documentButtonBar-button" style={{ display: !considerPush ? "none" : "" }}>
+            {/* <div className="documentButtonBar-button" style={{ display: !considerPush ? "none" : "" }}>
                 {this.considerGoogleDocsPush}
             </div>
             <div className="documentButtonBar-button" style={{ display: !considerPull ? "none" : "" }}>
                 {this.considerGoogleDocsPull}
-            </div>
+            </div> */}
         </div>;
     }
 }
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 7fc4a5c99..dd5303904 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,5 +1,5 @@
 import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
-import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faTextHeight, faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes, faAngleLeft, faAngleRight, faAngleDoubleLeft, faAngleDoubleRight, faPause } from '@fortawesome/free-solid-svg-icons';
+import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faTextHeight, faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes, faAngleLeft, faAngleRight, faAngleDoubleLeft, faAngleDoubleRight, faPause, faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, reaction, runInAction, get } from "mobx";
 import { observer } from "mobx-react";
@@ -47,6 +47,7 @@ library.add(faAngleDoubleRight);
 library.add(faAngleLeft);
 library.add(faAngleRight);
 library.add(faPause);
+library.add(faExternalLinkAlt);
 
 @observer
 export class DocumentDecorations extends React.Component<{}, { value: string }> {
@@ -533,12 +534,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 const ink = Cast(doc.data, InkField)?.inkData;
                 if (ink) {
                     const newPoints: { X: number, Y: number }[] = [];
-                    for (var i = 0; i < ink.length; i++) {
+                    ink.forEach(i => {
                         // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
-                        const newX = (doc.x - this._inkDocs[index].x) + (ink[i].X * doc._width) / this._inkDocs[index].width;
-                        const newY = (doc.y - this._inkDocs[index].y) + (ink[i].Y * doc._height) / this._inkDocs[index].height;
+                        const newX = ((doc.x || 0) - this._inkDocs[index].x) + (i.X * (doc._width || 0)) / this._inkDocs[index].width;
+                        const newY = ((doc.y || 0) - this._inkDocs[index].y) + (i.Y * (doc._height || 0)) / this._inkDocs[index].height;
                         newPoints.push({ X: newX, Y: newY });
-                    }
+                    });
                     doc.data = new InkField(newPoints);
 
                 }
@@ -617,9 +618,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 </div>}
             </> :
             <>
-                {minimal ? (null) : <Tooltip title={<><div className="dash-tooltip">Show context menu</div></>} placement="top"><div className="documentDecorations-contextMenu" key="menu" onPointerDown={this.onSettingsDown}>
-                    <FontAwesomeIcon size="lg" icon="cog" />
-                </div></Tooltip>}
+                {/* {minimal ? (null) : <Tooltip title={<><div className="dash-tooltip">Show context menu</div></>} placement="top"><div className="documentDecorations-contextMenu" key="menu" onPointerDown={this.onSettingsDown}>
+                    <FontAwesomeIcon size="lg" icon="bars" />
+                </div></Tooltip>} */}
                 <div className="documentDecorations-title" key="title" onPointerDown={this.onTitleDown} >
                     <span style={{ width: "100%", display: "inline-block", cursor: "move" }}>{`${this.selectionTitle}`}</span>
                 </div>
@@ -666,7 +667,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                                 {"_"}
                             </div></Tooltip>}
                     <Tooltip title={<><div className="dash-tooltip">Open Document In Tab</div></>} placement="top"><div className="documentDecorations-openInTab" onPointerDown={this.onMaximizeDown}>
-                        {SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
+                        {SelectionManager.SelectedDocuments().length === 1 ? <FontAwesomeIcon icon="external-link-alt" className="documentView-minimizedIcon" /> : "..."}
                     </div></Tooltip>
                     <div id="documentDecorations-rotation" className="documentDecorations-rotation"
                         onPointerDown={this.onRotateDown}> ⟲ </div>
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index c7b149842..f9d060681 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -191,7 +191,7 @@ export class EditableView extends React.Component<EditableProps> {
             return (this.props.contents instanceof ObjectField ? (null) :
                 <div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`}
                     ref={this._ref}
-                    style={{ display: this.props.display, minHeight: "20px", height: `${this.props.height ? this.props.height : "auto"}`, maxHeight: `${this.props.maxHeight}` }}
+                    style={{ display: this.props.display, minHeight: "17px", whiteSpace: "nowrap", height: `${this.props.height ? this.props.height : "auto"}`, maxHeight: `${this.props.maxHeight}` }}
                     onClick={this.onClick} placeholder={this.props.placeholder}>
                     <span style={{
                         fontStyle: this.props.fontStyle, fontSize: this.props.fontSize,
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index e1ddbc533..054a409df 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -102,6 +102,44 @@
     user-select: none;
 }
 
+.mainView-propertiesDragger {
+    background-color: rgb(140, 139, 139);
+    height: 55px;
+    width: 15.5px;
+    position: absolute;
+    top: 55%;
+    border: 1px black solid;
+    border-radius: 0;
+    border-top-left-radius: 10px;
+    border-bottom-left-radius: 10px;
+    border-right: unset;
+    z-index: 2;
+
+    .mainView-propertiesDragger-icon {
+        width: 10px;
+        height: 10px;
+        float: left;
+        margin-left: 3px;
+        padding-top: 19px;
+    }
+
+    &:hover {
+        cursor: grab;
+    }
+}
+
+.mainiView-propertiesView {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+    position: absolute;
+    right: 0;
+    top: 0;
+    border-left: solid 1px;
+    z-index: 100000;
+    cursor: auto;
+}
+
 .mainView-flyoutContainer {
     display: flex;
     flex-direction: column;
@@ -114,6 +152,75 @@
     }
 }
 
+.mainView-menuPanel {
+
+    width: 60px;
+    background-color: black;
+    height: 100%;
+    //overflow-y: scroll;
+    //overflow-x: hidden;
+
+
+    .mainView-menuPanel-button {
+        padding: 7px;
+        padding-left: 7px;
+        width: 100%;
+
+        .mainView-menuPanel-button-wrap {
+            width: 45px;
+            /* padding: 5px; */
+            touch-action: none;
+            background: black;
+            transform-origin: top left;
+            /* margin-bottom: 5px; */
+            margin-top: 5px;
+            margin-right: 25px;
+            border-radius: 8px;
+
+            &:hover {
+                background: rgb(61, 61, 61);
+                cursor: pointer;
+            }
+        }
+    }
+
+    .mainView-menuPanel-button-label {
+        color: white;
+        margin-left: px;
+        margin-right: 4px;
+        border-radius: 8px;
+        width: 42px;
+        position: relative;
+        text-align: center;
+        font-size: 8px;
+        margin-top: 1px;
+        letter-spacing: normal;
+        padding: 3px;
+        background-color: inherit;
+    }
+
+    .mainView-menuPanel-button-icon {
+        width: auto;
+        height: 35px;
+        padding: 5px;
+    }
+
+    svg {
+        width: 95% !important;
+        height: 95%;
+    }
+}
+
+.mainView-searchPanel {
+    width: 100%;
+    height: 33px;
+    background-color: black;
+    color: white;
+    text-align: center;
+    vertical-align: middle;
+    padding-top: 6px;
+}
+
 .mainView-mainDiv {
     width: 100%;
     height: 100%;
@@ -162,26 +269,44 @@
     display: flex;
     flex-direction: column;
     z-index: 2;
+
+    .mainView-libraryFlyout-close {
+        right: 6;
+        top: 5;
+        position: absolute;
+        margin-right: 6px;
+        z-index: 10;
+        margin-bottom: 10;
+    }
 }
 
 .mainView-expandFlyoutButton {
     position: absolute;
-    top: 100px;
-    right: 30px;
+    top: 120px;
+    right: 55px;
     cursor: pointer;
 }
 
 .mainView-libraryHandle {
-    width: 20px;
+    width: 28px;
     left: calc(100% - 10px);
-    height: 40px;
+    height: 55px;
     top: 50%;
     border: 1px solid black;
-    border-radius: 5px;
+    border-radius: 8px;
     position: absolute;
     z-index: 2;
     touch-action: none;
     cursor: ew-resize;
+
+    .mainView-libraryHandle-icon {
+        width: 10px;
+        height: 10px;
+        float: right;
+        margin-right: 3px;
+        padding-top: 19px;
+    }
+
 }
 
 .mainView-workspace {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 58478ce92..54b57a887 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,7 +1,6 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faHireAHelper, faBuffer } from '@fortawesome/free-brands-svg-icons';
 import * as fa from '@fortawesome/free-solid-svg-icons';
-import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, configure, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -12,51 +11,55 @@ import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
 import { Id } from '../../fields/FieldSymbols';
 import { List } from '../../fields/List';
 import { listSpec } from '../../fields/Schema';
+import { ScriptField } from '../../fields/ScriptField';
 import { BoolCast, Cast, FieldValue, StrCast } from '../../fields/Types';
 import { TraceMobx } from '../../fields/util';
-import { CurrentUserUtils } from '../util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils, returnEmptyFilter } from '../../Utils';
+import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, Utils } from '../../Utils';
 import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
+import HypothesisAuthenticationManager from '../apis/HypothesisAuthenticationManager';
 import { DocServer } from '../DocServer';
 import { Docs, DocumentOptions } from '../documents/Documents';
 import { DocumentType } from '../documents/DocumentTypes';
+import { CurrentUserUtils } from '../util/CurrentUserUtils';
+import { DocumentManager } from '../util/DocumentManager';
+import GroupManager from '../util/GroupManager';
 import { HistoryUtil } from '../util/History';
-import RichTextMenu from './nodes/formattedText/RichTextMenu';
 import { Scripting } from '../util/Scripting';
+import { SelectionManager } from '../util/SelectionManager';
 import SettingsManager from '../util/SettingsManager';
-import GroupManager from '../util/GroupManager';
 import SharingManager from '../util/SharingManager';
+import { SnappingManager } from '../util/SnappingManager';
 import { Transform } from '../util/Transform';
+import { TimelineMenu } from './animationtimeline/TimelineMenu';
 import { CollectionDockingView } from './collections/CollectionDockingView';
+import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
 import MarqueeOptionsMenu from './collections/collectionFreeForm/MarqueeOptionsMenu';
+import { PropertiesView } from './collections/collectionFreeForm/PropertiesView';
 import { CollectionLinearView } from './collections/CollectionLinearView';
+import CollectionMenu from './collections/CollectionMenu';
 import { CollectionView, CollectionViewType } from './collections/CollectionView';
 import { ContextMenu } from './ContextMenu';
 import { DictationOverlay } from './DictationOverlay';
 import { DocumentDecorations } from './DocumentDecorations';
 import GestureOverlay from './GestureOverlay';
+import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
 import KeyManager from './GlobalKeyHandler';
+import { LinkMenu } from './linking/LinkMenu';
 import "./MainView.scss";
 import { MainViewNotifs } from './MainViewNotifs';
 import { AudioBox } from './nodes/AudioBox';
+import { DocumentLinksButton } from './nodes/DocumentLinksButton';
 import { DocumentView } from './nodes/DocumentView';
+import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import RichTextMenu from './nodes/formattedText/RichTextMenu';
+import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
+import { LinkDocPreview } from './nodes/LinkDocPreview';
 import { RadialMenu } from './nodes/RadialMenu';
+import { TaskCompletionBox } from './nodes/TaskCompletedBox';
 import { OverlayView } from './OverlayView';
 import PDFMenu from './pdf/PDFMenu';
 import { PreviewCursor } from './PreviewCursor';
-import { ScriptField } from '../../fields/ScriptField';
-import { TimelineMenu } from './animationtimeline/TimelineMenu';
-import { SnappingManager } from '../util/SnappingManager';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
-import { DocumentManager } from '../util/DocumentManager';
-import { DocumentLinksButton } from './nodes/DocumentLinksButton';
-import { LinkMenu } from './linking/LinkMenu';
-import { LinkDocPreview } from './nodes/LinkDocPreview';
-import { TaskCompletionBox } from './nodes/TaskCompletedBox';
-import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
-import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
-import HypothesisAuthenticationManager from '../apis/HypothesisAuthenticationManager';
-import CollectionMenu from './collections/CollectionMenu';
+import { undoBatch } from '../util/UndoManager';
 
 @observer
 export class MainView extends React.Component {
@@ -69,8 +72,8 @@ export class MainView extends React.Component {
 
     @observable private _panelWidth: number = 0;
     @observable private _panelHeight: number = 0;
-    @observable private _flyoutTranslate: boolean = true;
-    @observable public flyoutWidth: number = 250;
+    @observable private _flyoutTranslate: boolean = false;
+    @observable public flyoutWidth: number = 0;
     private get darkScheme() { return BoolCast(Cast(this.userDoc?.activeWorkspace, Doc, null)?.darkScheme); }
 
     @computed private get userDoc() { return Doc.UserDoc(); }
@@ -78,7 +81,27 @@ export class MainView extends React.Component {
     @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs && docs.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
     @computed public get sidebarButtonsDoc() { return Cast(this.userDoc["tabs-buttons"], Doc) as Doc; }
 
+    @observable public sidebarContent: any = this.userDoc?.["tabs-panelContainer"];
+    @observable public panelContent: string = "none";
+    @observable public showProperties: boolean = false;
     public isPointerDown = false;
+    @computed get selectedDocumentView() {
+        if (SelectionManager.SelectedDocuments().length) {
+            return SelectionManager.SelectedDocuments()[0];
+        } else { return undefined; }
+    }
+
+    @observable _propertiesWidth: number = 0;
+    propertiesWidth = () => Math.max(0, Math.min(this._panelWidth - 50, this._propertiesWidth));
+
+    @computed get propertiesIcon() {
+        if (this.propertiesWidth() < 10) {
+            return "chevron-left";
+        } else {
+            return "chevron-right";
+        }
+    }
+    @observable propertiesDownX: number | undefined;
 
     componentDidMount() {
         DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_viewType", "_chromeStatus"]); // can play with these fields on someone else's
@@ -148,7 +171,10 @@ export class MainView extends React.Component {
             fa.faEye, fa.faArrowsAlt, fa.faQuoteLeft, fa.faSortAmountDown, fa.faAlignLeft, fa.faAlignCenter, fa.faAlignRight, fa.faHeading, fa.faRulerCombined,
             fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faChevronLeft, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript,
             fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper,
-            fa.faBezierCurve, fa.faCircle, fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, fa.faAngleUp, fa.faAngleDown, fa.faPlayCircle, fa.faClock,
+            fa.faDesktop, fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle,
+            fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand, fa.faUndo, fa.faSlidersH);
+        //Pres trail icons (just for the sake of merging)
+        library.add(fa.faAngleUp, fa.faAngleDown, fa.faPlayCircle, fa.faClock,
             fa.faRocket, fa.faExchangeAlt, faBuffer);
         this.initEventListeners();
         this.initAuthenticationRouters();
@@ -211,7 +237,7 @@ export class MainView extends React.Component {
         const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
-            _width: this._panelWidth * .7,
+            _width: this._panelWidth * .7 - this.propertiesWidth(),
             _height: this._panelHeight,
             title: "Collection " + workspaceCount,
         };
@@ -277,16 +303,21 @@ export class MainView extends React.Component {
 
     @action
     onResize = (r: any) => {
-        this._panelWidth = r.offset.width;
+        this._panelWidth = r.offset.width;// - this.propertiesWidth();
         this._panelHeight = r.offset.height;
     }
-    getPWidth = () => this._panelWidth;
+
+    @action
+    getPWidth = () => this._panelWidth - this.propertiesWidth()
+
     getPHeight = () => this._panelHeight;
     getContentsHeight = () => this._panelHeight - this._buttonBarHeight;
 
-    defaultBackgroundColors = (doc: Doc) => {
+    defaultBackgroundColors = (doc: Opt<Doc>) => {
+        if (this.panelContent === doc?.title) return "lightgrey";
         if (this.darkScheme) {
             switch (doc?.type) {
+                case DocumentType.MENUICON: return "white";
                 case DocumentType.RTF || DocumentType.LABEL || DocumentType.BUTTON: return "#2d2d2d";
                 case DocumentType.LINK:
                 case DocumentType.COL: {
@@ -296,6 +327,7 @@ export class MainView extends React.Component {
             }
         } else {
             switch (doc?.type) {
+                case DocumentType.MENUICON: return "black";
                 case DocumentType.RTF: return "#f1efeb";
                 case DocumentType.BUTTON:
                 case DocumentType.LABEL: return "lightgray";
@@ -308,7 +340,8 @@ export class MainView extends React.Component {
         }
     }
     @computed get mainDocView() {
-        return <DocumentView Document={this.mainContainer!}
+        return <DocumentView
+            Document={this.mainContainer!}
             DataDoc={undefined}
             LibraryPath={emptyPath}
             addDocument={undefined}
@@ -324,7 +357,6 @@ export class MainView extends React.Component {
             NativeWidth={returnZero}
             PanelWidth={this.getPWidth}
             PanelHeight={this.getPHeight}
-            renderDepth={0}
             focus={emptyFunction}
             parentActive={returnTrue}
             whenActiveChanged={emptyFunction}
@@ -332,103 +364,63 @@ export class MainView extends React.Component {
             docFilters={returnEmptyFilter}
             ContainingCollectionView={undefined}
             ContainingCollectionDoc={undefined}
+            renderDepth={-1}
         />;
     }
     @computed get dockingContent() {
         TraceMobx();
         const mainContainer = this.mainContainer;
         const width = this.flyoutWidth;
-        return <Measure offset onResize={this.onResize}>
-            {({ measureRef }) =>
-                <div ref={measureRef} className="mainContent-div" onDrop={this.onDrop} style={{ width: `calc(100% - ${width}px)` }}>
-                    {!mainContainer ? (null) : this.mainDocView}
-                </div>
-            }
-        </Measure>;
-    }
-
-    _canClick = false;
-    onPointerDown = (e: React.PointerEvent) => {
-        if (this._flyoutTranslate) {
-            this._canClick = true;
-            this._flyoutSizeOnDown = e.clientX;
-            document.removeEventListener("pointermove", this.onPointerMove);
-            document.removeEventListener("pointerup", this.onPointerUp);
-            document.addEventListener("pointermove", this.onPointerMove);
-            document.addEventListener("pointerup", this.onPointerUp);
-            e.stopPropagation();
-            e.preventDefault();
-        }
+        return <div className="mainContent-div" onDrop={this.onDrop} style={{ width: `calc(100% - ${width}px)` }}>
+            {!mainContainer ? (null) : this.mainDocView}
+        </div>;
     }
 
     @action
-    pointerLeaveDragger = () => {
-        if (!this._flyoutTranslate) {
-            this.flyoutWidth = 0;
-            this._flyoutTranslate = true;
-        }
+    onPropertiesPointerDown = (e: React.PointerEvent) => {
+        setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
+            this._propertiesWidth = this._panelWidth - e.clientX;
+            return false;
+        }), returnFalse, action(() => this._propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._panelWidth - 50, 250) : 0), false);
     }
 
     @action
-    onPointerMove = (e: PointerEvent) => {
-        this.flyoutWidth = Math.max(e.clientX, 0);
-        Math.abs(this.flyoutWidth - this._flyoutSizeOnDown) > 6 && (this._canClick = false);
-        this.sidebarButtonsDoc._columnWidth = this.flyoutWidth / 3 - 30;
-    }
-    @action
-    onPointerUp = (e: PointerEvent) => {
-        if (Math.abs(e.clientX - this._flyoutSizeOnDown) < 4 && this._canClick) {
-            this.flyoutWidth = this.flyoutWidth < 15 ? 250 : 0;
-            this.flyoutWidth && (this.sidebarButtonsDoc._columnWidth = this.flyoutWidth / 3 - 30);
+    onFlyoutPointerDown = (e: React.PointerEvent) => {
+        this.panelContent = "none";
+        if (this._flyoutTranslate) {
+            setupMoveUpEvents(this, e, action((e: PointerEvent) => {
+                this.flyoutWidth = Math.max(e.clientX, 0);
+                this.sidebarButtonsDoc._columnWidth = this.flyoutWidth / 3 - 30;
+                return false;
+            }), emptyFunction, action(() => {
+                this.flyoutWidth = this.flyoutWidth < 15 ? 250 : 0;
+                this.flyoutWidth && (this.sidebarButtonsDoc._columnWidth = this.flyoutWidth / 3 - 30);
+            }));
         }
-        document.removeEventListener("pointermove", this.onPointerMove);
-        document.removeEventListener("pointerup", this.onPointerUp);
     }
+
     flyoutWidthFunc = () => this.flyoutWidth;
     addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => {
         return where === "close" ? CollectionDockingView.CloseRightSplit(doc) :
             doc.dockingConfig ? this.openWorkspace(doc) :
                 CollectionDockingView.AddRightSplit(doc, libraryPath);
     }
-    sidebarScreenToLocal = () => new Transform(0, (RichTextMenu.Instance.Pinned ? -35 : 0) + (CollectionMenu.Instance.Pinned ? -35 : 0), 1);
+    sidebarScreenToLocal = () => new Transform(0, (CollectionMenu.Instance.Pinned ? -35 : 0), 1);
+    //sidebarScreenToLocal = () => new Transform(0, (RichTextMenu.Instance.Pinned ? -35 : 0) + (CollectionMenu.Instance.Pinned ? -35 : 0), 1);
     mainContainerXf = () => this.sidebarScreenToLocal().translate(0, -this._buttonBarHeight);
 
+    @computed get closePosition() { return 55 + this.flyoutWidth; }
     @computed get flyout() {
-        const sidebarContent = this.userDoc?.["tabs-panelContainer"];
-        if (!(sidebarContent instanceof Doc)) {
-            return (null);
-        }
-        return <div className="mainView-flyoutContainer" >
-            <div className="mainView-tabButtons" style={{ height: `${this._buttonBarHeight - 10/*margin-top*/}px`, backgroundColor: StrCast(this.sidebarButtonsDoc.backgroundColor) }}>
-                <DocumentView
-                    Document={this.sidebarButtonsDoc}
-                    DataDoc={undefined}
-                    LibraryPath={emptyPath}
-                    addDocument={undefined}
-                    rootSelected={returnTrue}
-                    addDocTab={this.addDocTabFunc}
-                    pinToPres={emptyFunction}
-                    removeDocument={undefined}
-                    onClick={undefined}
-                    ScreenToLocalTransform={this.sidebarScreenToLocal}
-                    ContentScaling={returnOne}
-                    NativeHeight={returnZero}
-                    NativeWidth={returnZero}
-                    PanelWidth={this.flyoutWidthFunc}
-                    PanelHeight={this.getPHeight}
-                    renderDepth={0}
-                    focus={emptyFunction}
-                    backgroundColor={this.defaultBackgroundColors}
-                    parentActive={returnTrue}
-                    whenActiveChanged={emptyFunction}
-                    bringToFront={emptyFunction}
-                    docFilters={returnEmptyFilter}
-                    ContainingCollectionView={undefined}
-                    ContainingCollectionDoc={undefined} />
-            </div>
-            <div className="mainView-contentArea" style={{ position: "relative", height: `calc(100% - ${this._buttonBarHeight}px)`, width: "100%", overflow: "visible" }}>
+        if (!this.sidebarContent) return null;
+        return <div className="mainView-libraryFlyout">
+            <div className="mainView-contentArea" style={{ position: "relative", height: `100%`, width: "100%", overflow: "visible" }}>
+                {this.flyoutWidth > 0 ? <div className="mainView-libraryFlyout-close"
+                    onPointerDown={this.closeFlyout}>
+                    <FontAwesomeIcon icon="times" color="black" size="sm" />
+                </div> : null}
+
                 <DocumentView
-                    Document={sidebarContent}
+                    Document={this.sidebarContent}
                     DataDoc={undefined}
                     LibraryPath={emptyPath}
                     addDocument={undefined}
@@ -451,52 +443,162 @@ export class MainView extends React.Component {
                     bringToFront={emptyFunction}
                     docFilters={returnEmptyFilter}
                     ContainingCollectionView={undefined}
-                    ContainingCollectionDoc={undefined} />
-                <div className="buttonContainer" >
-                    <button className="mainView-settings" key="settings" onClick={() => SettingsManager.Instance.open()}>
-                        <FontAwesomeIcon icon="cog" size="lg" />
-                    </button>
-                </div>
+                    ContainingCollectionDoc={undefined}
+                    relative={true}
+                />
             </div>
-            {this.docButtons}
+            {this.docButtons}</div>;
+    }
+
+    @computed get menuPanel() {
+
+        return <div className="mainView-menuPanel">
+            <DocumentView
+                Document={Doc.UserDoc().menuStack as Doc}
+                DataDoc={undefined}
+                LibraryPath={emptyPath}
+                addDocument={undefined}
+                addDocTab={this.addDocTabFunc}
+                pinToPres={emptyFunction}
+                NativeHeight={returnZero}
+                NativeWidth={returnZero}
+                rootSelected={returnTrue}
+                removeDocument={returnFalse}
+                onClick={undefined}
+                ScreenToLocalTransform={this.mainContainerXf}
+                ContentScaling={returnOne}
+                PanelWidth={() => 70}
+                PanelHeight={this.getContentsHeight}
+                renderDepth={0}
+                focus={emptyFunction}
+                backgroundColor={this.defaultBackgroundColors}
+                parentActive={returnTrue}
+                whenActiveChanged={emptyFunction}
+                bringToFront={emptyFunction}
+                docFilters={returnEmptyFilter}
+                ContainingCollectionView={undefined}
+                ContainingCollectionDoc={undefined}
+                relative={true}
+                scriptContext={this}
+            />
+        </div>;
+    }
+
+
+    @action @undoBatch
+    closeFlyout = () => {
+        this.panelContent = "none";
+        this.flyoutWidth = 0;
+    }
+
+    get groupManager() { return GroupManager.Instance; }
+
+    @action @undoBatch
+    selectMenu = (str: string) => {
+        if (this.panelContent === str && this.flyoutWidth !== 0) {
+            this.panelContent = "none";
+            this.flyoutWidth = 0;
+        } else {
+            this.panelContent = str;
+            switch (this.panelContent) {
+                case "Tools": this.sidebarContent.proto = CurrentUserUtils.toolsStack; break;
+                case "Workspace": this.sidebarContent.proto = CurrentUserUtils.workspaceStack; break;
+                case "Catalog": this.sidebarContent.proto = CurrentUserUtils.catalogStack; break;
+                case "Archive": this.sidebarContent.proto = CurrentUserUtils.closedStack; break;
+                case "Settings": this.sidebarContent.proto = SettingsManager.Instance.open(); break;
+                case "Sharing": this.sidebarContent.proto = GroupManager.Instance.open(); break;
+            }
+            if (str === "Settings" || str === "Sharing" || str === "Help") {
+                this.panelContent = "none";
+                this.flyoutWidth = 0;
+            } else {
+                MainView.expandFlyout();
+            }
+        }
+        return true;
+    }
+
+    @action @undoBatch
+    closeProperties = () => {
+        this._propertiesWidth = 0;
+    }
+
+    @computed get propertiesView() {
+        TraceMobx();
+        return <div className="mainView-propertiesView" style={{
+            overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
+        }}>
+            <PropertiesView
+                width={this.propertiesWidth()}
+                height={this._panelHeight}
+                renderDepth={1}
+                ScreenToLocalTransform={Transform.Identity}
+                onDown={this.closeProperties}
+            />
         </div>;
     }
 
+    @computed get mainInnerContent() {
+        const rightFlyout = this.propertiesWidth() - 1;
+        return <>
+            {this.menuPanel}
+            <div style={{ display: "contents", flexDirection: "row", position: "relative" }}>
+                <div className="mainView-flyoutContainer" style={{ width: this.flyoutWidth }}>
+                    {this.flyoutWidth !== 0 ? <div className="mainView-libraryHandle"
+                        onPointerDown={this.onFlyoutPointerDown}
+                        style={{ backgroundColor: this.defaultBackgroundColors(undefined) }}>
+                        <span title="library View Dragger" style={{
+                            width: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "100%" : "3vw",
+                            //height: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "100%" : "100vh",
+                            position: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "absolute" : "fixed",
+                            top: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "" : "0"
+                        }} />
+                        <div className="mainview-libraryHandle-icon">
+                            <FontAwesomeIcon icon="chevron-left" color="black" size="sm" /> </div>
+                    </div> : null}
+                    <div className="mainView-libraryFlyout" style={{
+                        //transformOrigin: this._flyoutTranslate ? "" : "left center",
+                        transition: this._flyoutTranslate ? "" : "width .5s",
+                        //transform: `scale(${this._flyoutTranslate ? 1 : 0.8})`,
+                        boxShadow: this._flyoutTranslate ? "" : "rgb(156, 147, 150) 0.2vw 0.2vw 0.2vw"
+                    }}>
+                        {this.flyout}
+                        {this.expandButton}
+                    </div>
+                </div>
+                {this.dockingContent}
+                {this.showProperties ? (null) :
+                    <div className="mainView-propertiesDragger" title="Properties View Dragger" onPointerDown={this.onPropertiesPointerDown}
+                        style={{ right: rightFlyout, top: "45%" }}>
+                        <div className="mainView-propertiesDragger-icon">
+                            <FontAwesomeIcon icon={this.propertiesIcon} color="white" size="sm" /> </div>
+                    </div>
+                }
+                {this.propertiesWidth() < 10 ? (null) :
+                    <div style={{ width: this.propertiesWidth() }}> {this.propertiesView} </div>}
+            </div>
+        </>;
+    }
+
     @computed get mainContent() {
-        const sidebar = this.userDoc?.["tabs-panelContainer"];
-        const n = (RichTextMenu.Instance?.Pinned ? 1 : 0) + (CollectionMenu.Instance?.Pinned ? 1 : 0);
+        //const n = (RichTextMenu.Instance?.Pinned ? 1 : 0) + (CollectionMenu.Instance?.Pinned ? 1 : 0);
+        const n = (CollectionMenu.Instance?.Pinned ? 1 : 0);
         const height = `calc(100% - ${n * Number(ANTIMODEMENU_HEIGHT.replace("px", ""))}px)`;
-        return !this.userDoc || !(sidebar instanceof Doc) ? (null) : (
-            <div className="mainView-mainContent" style={{
-                color: this.darkScheme ? "rgb(205,205,205)" : "black",
-                //change to times 2 for both pinned
-                height,
-                width: (FormatShapePane.Instance?.Pinned) ? `calc(100% - 200px)` : "100%"
-            }} >
-                <div style={{ display: "contents", flexDirection: "row", position: "relative" }}>
-                    <div className="mainView-flyoutContainer" onPointerLeave={this.pointerLeaveDragger} style={{ width: this.flyoutWidth }}>
-                        <div className="mainView-libraryHandle" onPointerDown={this.onPointerDown}
-                            style={{ backgroundColor: this.defaultBackgroundColors(sidebar) }}>
-                            <span title="library View Dragger" style={{
-                                width: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "100%" : "3vw",
-                                //height: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "100%" : "100vh",
-                                position: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "absolute" : "fixed",
-                                top: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "" : "0"
-                            }} />
-                        </div>
-                        <div className="mainView-libraryFlyout" style={{
-                            //transformOrigin: this._flyoutTranslate ? "" : "left center",
-                            transition: this._flyoutTranslate ? "" : "width .5s",
-                            //transform: `scale(${this._flyoutTranslate ? 1 : 0.8})`,
-                            boxShadow: this._flyoutTranslate ? "" : "rgb(156, 147, 150) 0.2vw 0.2vw 0.8vw"
-                        }}>
-                            {this.flyout}
-                            {this.expandButton}
-                        </div>
+        const pinned = FormatShapePane.Instance?.Pinned;
+        const innerContent = this.mainInnerContent;
+        return !this.userDoc ? (null) : (
+            <Measure offset onResize={this.onResize}>
+                {({ measureRef }) =>
+                    <div className="mainView-mainContent" ref={measureRef} style={{
+                        color: this.darkScheme ? "rgb(205,205,205)" : "black",
+                        //change to times 2 for both pinned
+                        height,
+                        width: pinned ? `calc(100% - 200px)` : "100%"
+                    }} >
+                        {innerContent}
                     </div>
-                    {this.dockingContent}
-                </div>
-            </div>);
+                }
+            </Measure>);
     }
 
     public static expandFlyout = action(() => {
@@ -506,7 +608,7 @@ export class MainView extends React.Component {
     });
 
     @computed get expandButton() {
-        return !this._flyoutTranslate ? (<div className="mainView-expandFlyoutButton" title="Re-attach sidebar" onPointerDown={MainView.expandFlyout}><FontAwesomeIcon icon="chevron-right" color="grey" size="lg" /></div>) : (null);
+        return !this._flyoutTranslate ? (<div className="mainView-expandFlyoutButton" title="Re-attach sidebar" onPointerDown={MainView.expandFlyout}></div>) : (null);
     }
 
     addButtonDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && Doc.AddDocToList(Doc.UserDoc().dockedBtns as Doc, "data", doc), true);
@@ -600,8 +702,16 @@ export class MainView extends React.Component {
         </svg>;
     }
 
+    @computed get search() {
+        return <div className="mainView-searchPanel">
+            <div style={{ float: "left", marginLeft: "10px" }}>{Doc.CurrentUserEmail}</div>
+            <div>SEARCH GOES HERE</div>
+        </div>;
+    }
+
     render() {
         return (<div className={"mainView-container" + (this.darkScheme ? "-dark" : "")} ref={this._mainViewRef}>
+
             {this.inkResources}
             <DictationOverlay />
             <SharingManager />
@@ -610,9 +720,10 @@ export class MainView extends React.Component {
             <GoogleAuthenticationManager />
             <HypothesisAuthenticationManager />
             <DocumentDecorations />
+            {/* {this.search} */}
             <CollectionMenu />
             <FormatShapePane />
-            <RichTextMenu key="rich" />
+            <div style={{ display: "none" }}><RichTextMenu key="rich" /></div>
             {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
             {DocumentLinksButton.EditLink ? <LinkMenu location={DocumentLinksButton.EditLinkLoc} docView={DocumentLinksButton.EditLink} addDocTab={DocumentLinksButton.EditLink.props.addDocTab} changeFlyout={emptyFunction} /> : (null)}
             {LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} backgroundColor={this.defaultBackgroundColors}
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index b4116e980..d7034fcfb 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -112,10 +112,10 @@ export class PreviewCursor extends React.Component<{}> {
                 } else if (e.clipboardData.items.length) {
                     const batch = UndoManager.StartBatch("collection view drop");
                     const files: File[] = [];
-                    for (let i = 0; i < e.clipboardData.items.length; i++) {
-                        const file = e.clipboardData.items[i].getAsFile();
+                    Array.from(e.clipboardData.items).forEach(item => {
+                        const file = item.getAsFile();
                         file && files.push(file);
-                    }
+                    });
                     const generatedDocuments = await DocUtils.uploadFilesToDocs(files, { x: newPoint[0], y: newPoint[1] });
                     generatedDocuments.forEach(PreviewCursor._addDocument);
                     batch.end();
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
new file mode 100644
index 000000000..e099122c4
--- /dev/null
+++ b/src/client/views/PropertiesButtons.scss
@@ -0,0 +1,119 @@
+@import "globalCssVariables";
+
+$linkGap : 3px;
+
+.propertiesButtons-linkFlyout {
+    grid-column: 2/4;
+}
+
+.propertiesButtons-linkButton-empty:hover {
+    background: $main-accent;
+    transform: scale(1.05);
+    cursor: pointer;
+}
+
+.propertiesButtons-linkButton-nonempty:hover {
+    background: $main-accent;
+    transform: scale(1.05);
+    cursor: pointer;
+}
+
+.propertiesButtons-linkButton-empty,
+.propertiesButtons-linkButton-nonempty {
+    height: 30px;
+    width: 30px;
+    border-radius: 5px;
+    opacity: 0.9;
+    pointer-events: auto;
+    background-color: #121721;
+    color: #fcfbf7;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    font-size: 75%;
+    transition: transform 0.2s;
+    text-align: center;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-right: 10px;
+
+    &:hover {
+        background: $main-accent;
+        transform: scale(1.05);
+        cursor: pointer;
+    }
+}
+
+.propertiesButtons {
+    margin-top: $linkGap;
+    grid-column: 1/4;
+    width: max-content;
+    height: auto;
+    display: flex;
+    flex-direction: row;
+    overflow-x: visible;
+}
+
+.onClickFlyout-editScript {
+    text-align: center;
+    border: 0.5px solid grey;
+    background-color: rgb(230, 230, 230);
+    border-radius: 9px;
+    padding: 4px;
+}
+
+
+.propertiesButtons-button {
+    pointer-events: auto;
+    padding-right: 5px;
+    width: 25px;
+    border-radius: 5px;
+    margin-right: 18px;
+}
+
+.propertiesButtons-linker {
+    height: 30px;
+    width: 30px;
+    text-align: center;
+    border-radius: 5px;
+    pointer-events: auto;
+    color: $dark-color;
+    border: $dark-color 1px solid;
+    transition: 0.2s ease all;
+    margin-right: 5px;
+}
+
+.propertiesButtons-linker:hover {
+    cursor: pointer;
+    transform: scale(1.05);
+}
+
+
+@-moz-keyframes spin {
+    100% {
+        -moz-transform: rotate(360deg);
+    }
+}
+
+@-webkit-keyframes spin {
+    100% {
+        -webkit-transform: rotate(360deg);
+    }
+}
+
+@keyframes spin {
+    100% {
+        -webkit-transform: rotate(360deg);
+        transform: rotate(360deg);
+    }
+}
+
+@keyframes shadow-pulse {
+    0% {
+        box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.8);
+    }
+
+    100% {
+        box-shadow: 0 0 0 10px rgba(0, 255, 0, 0);
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
new file mode 100644
index 000000000..59e7cc7c8
--- /dev/null
+++ b/src/client/views/PropertiesButtons.tsx
@@ -0,0 +1,598 @@
+import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
+import { faArrowAltCircleDown, faArrowAltCircleRight, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faPhotoVideo, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, computed, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { Doc, DocListCast } from "../../fields/Doc";
+import { RichTextField } from '../../fields/RichTextField';
+import { Cast, NumCast, BoolCast } from "../../fields/Types";
+import { emptyFunction, setupMoveUpEvents, Utils } from "../../Utils";
+import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
+import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
+import { Docs, DocUtils } from '../documents/Documents';
+import { DragManager } from '../util/DragManager';
+import { CollectionDockingView, DockedFrameRenderer } from './collections/CollectionDockingView';
+import { ParentDocSelector } from './collections/ParentDocumentSelector';
+import './collections/ParentDocumentSelector.scss';
+import './PropertiesButtons.scss';
+import { MetadataEntryMenu } from './MetadataEntryMenu';
+import { DocumentView } from './nodes/DocumentView';
+import { GoogleRef } from "./nodes/formattedText/FormattedTextBox";
+import { TemplateMenu } from "./TemplateMenu";
+import { Template, Templates } from "./Templates";
+import React = require("react");
+import { Tooltip } from '@material-ui/core';
+import { SelectionManager } from '../util/SelectionManager';
+import SharingManager from '../util/SharingManager';
+import { GooglePhotos } from '../apis/google_docs/GooglePhotosClientUtils';
+import { ImageField } from '../../fields/URLField';
+import { undoBatch, UndoManager } from '../util/UndoManager';
+import { DocumentType } from '../documents/DocumentTypes';
+import { CollectionFreeFormView } from './collections/collectionFreeForm/CollectionFreeFormView';
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
+
+library.add(faLink);
+library.add(faTag);
+library.add(faTimes);
+library.add(faArrowAltCircleDown);
+library.add(faArrowAltCircleUp);
+library.add(faArrowAltCircleRight);
+library.add(faStopCircle);
+library.add(faCheckCircle);
+library.add(faCloudUploadAlt);
+library.add(faSyncAlt);
+library.add(faShare);
+library.add(faPhotoVideo);
+
+const cloud: IconProp = "cloud-upload-alt";
+const fetch: IconProp = "sync-alt";
+
+enum UtilityButtonState {
+    Default,
+    OpenRight,
+    OpenExternally
+}
+
+@observer
+export class PropertiesButtons extends React.Component<{}, {}> {
+    private _dragRef = React.createRef<HTMLDivElement>();
+    private _pullAnimating = false;
+    private _pushAnimating = false;
+    private _pullColorAnimating = false;
+
+    @observable private pushIcon: IconProp = "arrow-alt-circle-up";
+    @observable private pullIcon: IconProp = "arrow-alt-circle-down";
+    @observable private pullColor: string = "white";
+    @observable public isAnimatingFetch = false;
+    @observable public isAnimatingPulse = false;
+
+    @observable private openHover: UtilityButtonState = UtilityButtonState.Default;
+
+    @observable public static Instance: PropertiesButtons;
+    public static hasPushedHack = false;
+    public static hasPulledHack = false;
+
+
+    @computed get selectedDocumentView() {
+        if (SelectionManager.SelectedDocuments().length) {
+            return SelectionManager.SelectedDocuments()[0];
+        } else { return undefined; }
+    }
+    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
+    @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; }
+
+    @computed get onClick() { return this.selectedDoc?.onClickBehavior ? this.selectedDoc?.onClickBehavior : "nothing"; }
+
+    public startPullOutcome = action((success: boolean) => {
+        if (!this._pullAnimating) {
+            this._pullAnimating = true;
+            this.pullIcon = success ? "check-circle" : "stop-circle";
+            setTimeout(() => runInAction(() => {
+                this.pullIcon = "arrow-alt-circle-down";
+                this._pullAnimating = false;
+            }), 1000);
+        }
+    });
+
+    public startPushOutcome = action((success: boolean) => {
+        this.isAnimatingPulse = false;
+        if (!this._pushAnimating) {
+            this._pushAnimating = true;
+            this.pushIcon = success ? "check-circle" : "stop-circle";
+            setTimeout(() => runInAction(() => {
+                this.pushIcon = "arrow-alt-circle-up";
+                this._pushAnimating = false;
+            }), 1000);
+        }
+    });
+
+    public setPullState = action((unchanged: boolean) => {
+        this.isAnimatingFetch = false;
+        if (!this._pullColorAnimating) {
+            this._pullColorAnimating = true;
+            this.pullColor = unchanged ? "lawngreen" : "red";
+            setTimeout(this.clearPullColor, 1000);
+        }
+    });
+
+    private clearPullColor = action(() => {
+        this.pullColor = "white";
+        this._pullColorAnimating = false;
+    });
+
+    @computed
+    get considerGoogleDocsPush() {
+        const targetDoc = this.selectedDoc;
+        const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
+        const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none";
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{`${published ? "Push" : "Publish"} to Google Docs`}</div></>}>
+            <div
+                className="propertiesButtons-linker"
+                style={{ animation }}
+                onClick={async () => {
+                    await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
+                    !published && runInAction(() => this.isAnimatingPulse = true);
+                    PropertiesButtons.hasPushedHack = false;
+                    targetDoc[Pushes] = NumCast(targetDoc[Pushes]) + 1;
+                }}>
+                <FontAwesomeIcon className="documentdecorations-icon" icon={published ? (this.pushIcon as any) : cloud} size={published ? "sm" : "xs"} />
+            </div></Tooltip>;
+    }
+
+    @computed
+    get considerGoogleDocsPull() {
+        const targetDoc = this.selectedDoc;
+        const dataDoc = targetDoc && Doc.GetProto(targetDoc);
+        const animation = this.isAnimatingFetch ? "spin 0.5s linear infinite" : "none";
+
+        const title = (() => {
+            switch (this.openHover) {
+                default:
+                case UtilityButtonState.Default: return `${!dataDoc?.unchanged ? "Pull from" : "Fetch"} Google Docs`;
+                case UtilityButtonState.OpenRight: return "Open in Right Split";
+                case UtilityButtonState.OpenExternally: return "Open in new Browser Tab";
+            }
+        })();
+
+        return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{title}</div></>}>
+            <div className="propertiesButtons-linker"
+                style={{ backgroundColor: this.pullColor }}
+                onPointerEnter={action(e => {
+                    if (e.altKey) {
+                        this.openHover = UtilityButtonState.OpenExternally;
+                    } else if (e.shiftKey) {
+                        this.openHover = UtilityButtonState.OpenRight;
+                    }
+                })}
+                onPointerLeave={action(() => this.openHover = UtilityButtonState.Default)}
+                onClick={async e => {
+                    const googleDocUrl = `https://docs.google.com/document/d/${dataDoc[GoogleRef]}/edit`;
+                    if (e.shiftKey) {
+                        e.preventDefault();
+                        let googleDoc = await Cast(dataDoc.googleDoc, Doc);
+                        if (!googleDoc) {
+                            const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, UseCors: false };
+                            googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
+                            dataDoc.googleDoc = googleDoc;
+                        }
+                        CollectionDockingView.AddRightSplit(googleDoc);
+                    } else if (e.altKey) {
+                        e.preventDefault();
+                        window.open(googleDocUrl);
+                    } else {
+                        this.clearPullColor();
+                        PropertiesButtons.hasPulledHack = false;
+                        targetDoc[Pulls] = NumCast(targetDoc[Pulls]) + 1;
+                        dataDoc.unchanged && runInAction(() => this.isAnimatingFetch = true);
+                    }
+                }}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm"
+                    style={{ WebkitAnimation: animation, MozAnimation: animation }}
+                    icon={(() => {
+                        switch (this.openHover) {
+                            default:
+                            case UtilityButtonState.Default: return dataDoc.unchanged === false ? (this.pullIcon as any) : fetch;
+                            case UtilityButtonState.OpenRight: return "arrow-alt-circle-right";
+                            case UtilityButtonState.OpenExternally: return "share";
+                        }
+                    })()}
+                />
+            </div></Tooltip>;
+    }
+    @computed
+    get pinButton() {
+        const targetDoc = this.selectedDoc;
+        const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}>
+            <div className="propertiesButtons-linker"
+                style={{ backgroundColor: isPinned ? "white" : "rgb(37, 43, 51)", color: isPinned ? "black" : "white" }}
+                onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
+                />
+            </div></Tooltip>;
+    }
+
+    @computed
+    get metadataButton() {
+        //const view0 = this.view0;
+        if (this.selectedDoc) {
+            return <Tooltip title={<><div className="dash-tooltip">Show metadata panel</div></>}>
+                <div className="propertiesButtons-linkFlyout">
+                    <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+                        content={<MetadataEntryMenu docs={[this.selectedDoc]} suggestWithFunction />  /* tfs: @bcz This might need to be the data document? */}>
+                        <div className={"propertiesButtons-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
+                            {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" />}
+                        </div>
+                    </Flyout>
+                </div></Tooltip>;
+        } else {
+            return null;
+        }
+
+    }
+
+    @observable _aliasDown = false;
+    onAliasButtonDown = (e: React.PointerEvent): void => {
+        setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction);
+    }
+    onAliasButtonMoved = () => {
+        if (this._dragRef.current) {
+            const dragDocView = this.selectedDocumentView!;
+            const dragData = new DragManager.DocumentDragData([dragDocView.props.Document]);
+            const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+            dragData.dropAction = "alias";
+            DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, {
+                offsetX: dragData.offset[0],
+                offsetY: dragData.offset[1],
+                hideSource: false
+            });
+            return true;
+        }
+        return false;
+    }
+
+    @computed
+    get templateButton() {
+        const docView = this.selectedDocumentView;
+        const templates: Map<Template, boolean> = new Map();
+        const views = [this.selectedDocumentView];
+        Array.from(Object.values(Templates.TemplateList)).map(template =>
+            templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean)));
+        return !docView ? (null) :
+            <Tooltip title={<><div className="dash-tooltip">Customize layout</div></>}>
+                <div className="propertiesButtons-linkFlyout">
+                    <Flyout anchorPoint={anchorPoints.LEFT_TOP} //onOpen={action(() => this._aliasDown = true)} onClose={action(() => this._aliasDown = false)}
+                        content={<TemplateMenu docViews={views.filter(v => v).map(v => v as DocumentView)} templates={templates} />}>
+                        <div className={"propertiesButtons-linkButton-empty"} >
+                            {<FontAwesomeIcon className="documentdecorations-icon" icon="edit" size="sm" />}
+                        </div>
+                    </Flyout>
+                </div></Tooltip>;
+    }
+
+    onCopy = () => {
+        if (this.selectedDoc && this.selectedDocumentView) {
+            const copy = Doc.MakeCopy(this.selectedDocumentView.props.Document, true);
+            copy.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width);
+            copy.y = NumCast(this.selectedDoc.y) + 30;
+            this.selectedDocumentView.props.addDocument?.(copy);
+        }
+    }
+
+    @computed
+    get copyButton() {
+        const targetDoc = this.selectedDoc;
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Tap or Drag to create an alias"}</div></>}>
+            <div className={"propertiesButtons-linkButton-empty"}
+                ref={this._dragRef}
+                onPointerDown={this.onAliasButtonDown}
+                onClick={this.onCopy}>
+                {<FontAwesomeIcon className="documentdecorations-icon" icon="copy" size="sm" />}
+            </div>
+        </Tooltip>;
+    }
+
+    @action
+    onLock = () => {
+        this.selectedDocumentView?.toggleLockPosition();
+    }
+
+    @computed
+    get lockButton() {
+        const targetDoc = this.selectedDoc;
+        return !targetDoc ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{this.selectedDoc?.lockedPosition ?
+                "Unlock Position" : "Lock Position"}</div></>}>
+            <div className={"propertiesButtons-linkButton-empty"}
+                onPointerDown={this.onLock} >
+                {<FontAwesomeIcon className="documentdecorations-icon"
+                    icon={BoolCast(this.selectedDoc?.lockedPosition) ? "unlock" : "lock"} size="sm" />}
+            </div>
+        </Tooltip>;
+    }
+
+    @computed
+    get downloadButton() {
+        const targetDoc = this.selectedDoc;
+        return !targetDoc ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{"Download Document"}</div></>}>
+            <div className={"propertiesButtons-linkButton-empty"}
+                onPointerDown={async () => {
+                    if (this.selectedDocumentView?.props.Document) {
+                        Doc.Zip(this.selectedDocumentView?.props.Document);
+                    }
+                }}>
+                {<FontAwesomeIcon className="propertiesButtons-icon"
+                    icon="download" size="sm" />}
+            </div>
+        </Tooltip>;
+    }
+
+    @computed
+    get deleteButton() {
+        const targetDoc = this.selectedDoc;
+        return !targetDoc ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{"Delete Document"}</div></>}>
+            <div className={"propertiesButtons-linkButton-empty"}
+                onPointerDown={() => {
+                    this.selectedDocumentView?.props.ContainingCollectionView?.removeDocument(this.selectedDocumentView?.props.Document);
+                }}>
+                {<FontAwesomeIcon className="propertiesButtons-icon"
+                    icon="trash-alt" size="sm" />}
+            </div>
+        </Tooltip>;
+    }
+
+    @computed
+    get sharingButton() {
+        const targetDoc = this.selectedDoc;
+        return !targetDoc ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{"Share Document"}</div></>}>
+            <div className={"propertiesButtons-linkButton-empty"}
+                onPointerDown={() => {
+                    if (this.selectedDocumentView) {
+                        SharingManager.Instance.open(this.selectedDocumentView);
+                    }
+                }}>
+                {<FontAwesomeIcon className="propertiesButtons-icon"
+                    icon="users" size="sm" />}
+            </div>
+        </Tooltip>;
+    }
+
+    @computed
+    get onClickButton() {
+        if (this.selectedDoc) {
+            return <Tooltip title={<><div className="dash-tooltip">Choose onClick behavior</div></>}>
+                <div className="propertiesButtons-linkFlyout">
+                    <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+                        content={this.onClickFlyout}>
+                        <div className={"propertiesButtons-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
+                            {<FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="sm" />}
+                        </div>
+                    </Flyout>
+                </div></Tooltip>;
+        } else {
+            return null;
+        }
+    }
+
+    @action
+    handleOptionChange = (e: any) => {
+        const value = e.target.value;
+        this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value);
+        if (value === "nothing") {
+            this.selectedDocumentView?.noOnClick();
+        } else if (value === "enterPortal") {
+            this.selectedDocumentView?.noOnClick();
+            this.selectedDocumentView?.makeIntoPortal();
+        } else if (value === "toggleDetail") {
+            this.selectedDocumentView?.noOnClick();
+            this.selectedDocumentView?.toggleDetail();
+        } else if (value === "linkInPlace") {
+            this.selectedDocumentView?.noOnClick();
+            this.selectedDocumentView?.toggleFollowLink("inPlace", true, false);
+        } else if (value === "linkOnRight") {
+            this.selectedDocumentView?.noOnClick();
+            this.selectedDocumentView?.toggleFollowLink("onRight", false, false);
+        }
+    }
+
+    @undoBatch @action
+    editOnClickScript = () => {
+        if (this.selectedDoc) {
+            DocUtils.makeCustomViewClicked(this.selectedDoc, undefined, "onClick");
+        }
+    }
+
+    @computed
+    get onClickFlyout() {
+        return <div><form>
+            <div className="radio">
+                <label>
+                    <input type="radio" value="nothing"
+                        checked={this.onClick === 'nothing'}
+                        onChange={this.handleOptionChange} />
+                    Select Document
+                </label>
+            </div>
+            <div className="radio">
+                <label>
+                    <input type="radio" value="enterPortal"
+                        checked={this.onClick === 'enterPortal'}
+                        onChange={this.handleOptionChange} />
+                    Enter Portal
+                </label>
+            </div>
+            <div className="radio">
+                <label>
+                    <input type="radio" value="toggleDetail"
+                        checked={this.onClick === 'toggleDetail'}
+                        onChange={this.handleOptionChange} />
+                    Toggle Detail
+                </label>
+            </div>
+            <div className="radio">
+                <label>
+                    <input type="radio" value="linkInPlace"
+                        checked={this.onClick === 'linkInPlace'}
+                        onChange={this.handleOptionChange} />
+                    Follow Link
+                </label>
+            </div>
+            <div className="radio">
+                <label>
+                    <input type="radio" value="linkOnRight"
+                        checked={this.onClick === 'linkOnRight'}
+                        onChange={this.handleOptionChange} />
+                    Open Link on Right
+                </label>
+            </div>
+        </form>
+            <div onPointerDown={this.editOnClickScript} className="onClickFlyout-editScript"> Edit onClick Script</div>
+        </div>;
+    }
+
+    @computed
+    get googlePhotosButton() {
+        const targetDoc = this.selectedDoc;
+        return !targetDoc ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{"Export to Google Photos"}</div></>}>
+            <div className={"propertiesButtons-linkButton-empty"}
+                onPointerDown={() => {
+                    if (this.selectedDocumentView) {
+                        GooglePhotos.Export.CollectionToAlbum({ collection: this.selectedDocumentView.Document }).then(console.log);
+                    }
+                }}>
+                {<FontAwesomeIcon className="documentdecorations-icon"
+                    icon="cloud-upload-alt" size="sm" />}
+            </div>
+        </Tooltip>;
+    }
+
+    @computed
+    get clustersButton() {
+        const targetDoc = this.selectedDoc;
+        return !targetDoc ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{this.selectedDoc?.useClusters ? "Stop Showing Clusters" : "Show Clusters"}</div></>}>
+            <div className={"propertiesButtons-linkButton-empty"}
+                style={{ backgroundColor: this.selectedDoc?.useClusters ? "#a0a0a0" : "" }}
+                onPointerDown={this.changeClusters}>
+                {<FontAwesomeIcon className="documentdecorations-icon"
+                    color={this.selectedDoc?.useClusters ? "black" : "white"}
+                    icon="braille" size="sm" />}
+            </div>
+        </Tooltip>;
+    }
+
+    @action @undoBatch
+    changeFitToBox = () => {
+        this.selectedDoc && (this.selectedDoc._fitToBox = !this.selectedDoc._fitToBox);
+    }
+
+    @action @undoBatch
+    changeClusters = () => {
+        this.selectedDoc && (this.selectedDoc.useClusters = !this.selectedDoc.useClusters);
+    }
+
+    @computed
+    get fitContentButton() {
+        const targetDoc = this.selectedDoc;
+        return !targetDoc ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{this.selectedDoc?._fitToBox ? "Stop Fitting Content" : "Fit Content"}</div></>}>
+            <div className={"propertiesButtons-linkButton-empty"}
+                style={{ backgroundColor: this.selectedDoc?._fitToBox ? "#a0a0a0" : "" }}
+                onPointerDown={this.changeFitToBox}>
+                {<FontAwesomeIcon className="documentdecorations-icon"
+                    color={this.selectedDoc?._fitToBox ? "black" : "white"}
+                    icon="expand" size="sm" />}
+            </div>
+        </Tooltip>;
+    }
+
+    // @computed
+    // get importButton() {
+    //     const targetDoc = this.selectedDoc;
+    //     return !targetDoc ? (null) : <Tooltip
+    //         title={<><div className="dash-tooltip">{"Import a Document"}</div></>}>
+    //         <div className={"propertiesButtons-linkButton-empty"}
+    //             onPointerDown={() => {
+    //                 if (this.selectedDocumentView) {
+    //                     CollectionFreeFormView.importDocument(100, 100);
+    //                 }
+    //             }}>
+    //             {<FontAwesomeIcon className="documentdecorations-icon"
+    //                 icon="upload" size="sm" />}
+    //         </div>
+    //     </Tooltip>;
+    // }
+
+
+    render() {
+        if (!this.selectedDoc) return (null);
+
+        const isText = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof RichTextField;
+        const considerPull = isText && this.considerGoogleDocsPull;
+        const considerPush = isText && this.considerGoogleDocsPush;
+        const isImage = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof ImageField;
+        const isCollection = this.selectedDoc.type === DocumentType.COL ? true : false;
+        const isFreeForm = this.selectedDoc._viewType === "freeform" ? true : false;
+
+        return <div><div className="propertiesButtons" style={{ paddingBottom: "5.5px" }}>
+            <div className="propertiesButtons-button">
+                {this.templateButton}
+            </div>
+            {/* <div className="propertiesButtons-button">
+                {this.metadataButton}
+            </div> */}
+            <div className="propertiesButtons-button">
+                {this.pinButton}
+            </div>
+            <div className="propertiesButtons-button">
+                {this.copyButton}
+            </div>
+            <div className="propertiesButtons-button">
+                {this.lockButton}
+            </div>
+            <div className="propertiesButtons-button">
+                {this.downloadButton}
+            </div>
+        </div>
+            <div className="propertiesButtons">
+                <div className="propertiesButtons-button">
+                    {this.deleteButton}
+                </div>
+                <div className="propertiesButtons-button">
+                    {this.onClickButton}
+                </div>
+                <div className="propertiesButtons-button">
+                    {this.sharingButton}
+                </div>
+                <div className="propertiesButtons-button" style={{ display: !considerPush ? "none" : "" }}>
+                    {this.considerGoogleDocsPush}
+                </div>
+                <div className="propertiesButtons-button" style={{ display: !considerPull ? "none" : "" }}>
+                    {this.considerGoogleDocsPull}
+                </div>
+                <div className="propertiesButtons-button" style={{ display: !isImage ? "none" : "" }}>
+                    {this.googlePhotosButton}
+                </div>
+                {/* <div className="propertiesButtons-button" style={{ display: !isCollection ? "none" : "" }}>
+                    {this.importButton}
+                </div> */}
+
+                <div className="propertiesButtons-button" style={{ display: !isFreeForm ? "none" : "" }}>
+                    {this.clustersButton}
+                </div>
+
+                <div className="propertiesButtons-button" style={{ display: !isFreeForm ? "none" : "" }}>
+                    {this.fitContentButton}
+                </div>
+
+            </div>
+        </div>;
+    }
+}
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index 9b14df760..6d93b2ba8 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -12,6 +12,7 @@
         width: 100%;
         height: 100%;
         position: absolute;
+
         .miniThumb {
             background: #25252525;
             position: absolute;
@@ -89,6 +90,7 @@
     transform: translate(0px, -3px);
     cursor: grab;
 }
+
 .lm_title.focus-visible {
     cursor: text;
 }
@@ -96,23 +98,25 @@
 .lm_title_wrap {
     overflow: hidden;
     height: 19px;
-    margin-top: -3px;
-    display:inline-block;
+    margin-top: -2px;
+    display: inline-block;
 }
+
 .lm_active .lm_title {
     border: solid 1px lightgray;
 }
+
 .lm_header .lm_tab .lm_close_tab {
     position: absolute;
     text-align: center;
 }
 
 .lm_header .lm_tab {
-    padding-right : 20px;
+    padding-right: 20px;
 }
 
 .lm_popout {
-    display:none;
+    display: none;
 }
 
 .messageCounter {
@@ -135,6 +139,7 @@
     position: absolute;
     top: 0;
     left: 0;
+
     // overflow: hidden;  // bcz: menus don't show up when this is on (e.g., the parentSelectorMenu)
     .collectionDockingView-gear {
         padding-left: 5px;
@@ -142,7 +147,10 @@
         width: 18px;
         display: inline-block;
         margin: auto;
+
+        display: none;
     }
+
     .collectionDockingView-dragAsDocument {
         touch-action: none;
         position: absolute;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index f658e9816..d685fac4e 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -1,9 +1,8 @@
 import 'golden-layout/src/css/goldenlayout-base.css';
 import 'golden-layout/src/css/goldenlayout-dark-theme.css';
-import { action, computed, Lambda, observable, reaction, runInAction, trace } from "mobx";
+import { action, computed, Lambda, observable, reaction, runInAction, trace, IReactionDisposer } from "mobx";
 import { observer } from "mobx-react";
 import * as ReactDOM from 'react-dom';
-import Measure from "react-measure";
 import * as GoldenLayout from "../../../client/goldenLayout";
 import { DateField } from '../../../fields/DateField';
 import { Doc, DocListCast, Field, Opt, DataSym } from "../../../fields/Doc";
@@ -507,7 +506,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
             const doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId) as Doc;
             if (doc instanceof Doc) {
-                //tab.titleElement[0].outerHTML = `<input class='lm_title' style="background:black" value='${doc.title}' />`;
                 tab.titleElement[0].onclick = (e: any) => tab.titleElement[0].focus();
                 tab.titleElement[0].onchange = (e: any) => {
                     tab.titleElement[0].size = e.currentTarget.value.length + 1;
@@ -522,6 +520,10 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                 gearSpan.style.paddingLeft = "0px";
                 gearSpan.style.paddingRight = "12px";
                 const stack = tab.contentItem.parent;
+                tab.element[0].onpointerdown = (e: any) => {
+                    const view = DocumentManager.Instance.getDocumentView(doc);
+                    view && SelectionManager.SelectDoc(view, false);
+                };
                 // shifts the focus to this tab when another tab is dragged over it
                 tab.element[0].onmouseenter = (e: any) => {
                     if (!this._isPointerDown || !SnappingManager.GetIsDragging()) return;
@@ -676,10 +678,15 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     @observable private _panelHeight = 0;
     @observable private _document: Opt<Doc>;
     @observable private _isActive: boolean = false;
+    _tabReaction: IReactionDisposer | undefined;
 
     get _stack(): any {
         return (this.props as any).glContainer.parent.parent;
     }
+    get _tab(): any {
+        const tab = (this.props as any).glContainer.tab.element[0] as HTMLElement;
+        return tab.getElementsByClassName("lm_title")?.[0];
+    }
     constructor(props: any) {
         super(props);
         DocServer.GetRefField(this.props.documentId).then(action((f: Opt<Field>) => this._document = f as Doc));
@@ -740,9 +747,16 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         this.props.glContainer.layoutManager.on("activeContentItemChanged", this.onActiveContentItemChanged);
         this.props.glContainer.on("tab", this.onActiveContentItemChanged);
         this.onActiveContentItemChanged();
+        this._tabReaction = reaction(() => ({ views: SelectionManager.SelectedDocuments(), color: StrCast(this._document?._backgroundColor, "white") }),
+            (data) => {
+                const selected = data.views.some(v => Doc.AreProtosEqual(v.props.Document, this._document));
+                this._tab.style.backgroundColor = selected ? data.color : "";
+            }
+        );
     }
 
     componentWillUnmount() {
+        this._tabReaction?.();
         this.props.glContainer.layoutManager.off("activeContentItemChanged", this.onActiveContentItemChanged);
         this.props.glContainer.off("tab", this.onActiveContentItemChanged);
     }
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 0ca86172f..fdd1b4e81 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -25,6 +25,8 @@ import { SelectionManager } from "../../util/SelectionManager";
 import { DocumentView } from "../nodes/DocumentView";
 import { ColorState } from "react-color";
 import { ObjectField } from "../../../fields/ObjectField";
+import RichTextMenu from "../nodes/formattedText/RichTextMenu";
+import { RichTextField } from "../../../fields/RichTextField";
 import { ScriptField } from "../../../fields/ScriptField";
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { DocUtils } from "../../documents/Documents";
@@ -47,7 +49,7 @@ export default class CollectionMenu extends AntimodeMenu {
 
     componentDidMount() {
         reaction(() => SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0],
-            (doc) => doc && this.SetSelection(doc))
+            (doc) => doc && this.SetSelection(doc));
     }
 
     @action
@@ -160,7 +162,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
         initialize: (button: Doc) => { button['target-docFilters'] = this.target._docFilters instanceof ObjectField ? ObjectField.MakeCopy(this.target._docFilters as any as ObjectField) : ""; },
     };
 
-    _freeform_commands = [this._viewCommand, this._saveFilterCommand, this._fitContentCommand, this._clusterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand];
+    @computed get _freeform_commands() { return Doc.UserDoc().noviceMode ? [this._viewCommand, this._saveFilterCommand] : [this._viewCommand, this._saveFilterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; }
+
     _stacking_commands = [this._contentCommand, this._templateCommand];
     _masonry_commands = [this._contentCommand, this._templateCommand];
     _schema_commands = [this._templateCommand, this._narrativeCommand];
@@ -308,18 +311,32 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
         </div>;
     }
 
+    @computed get selectedDocumentView() {
+        if (SelectionManager.SelectedDocuments().length) {
+            return SelectionManager.SelectedDocuments()[0];
+        } else { return undefined; }
+    }
+    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
+    @computed get isText() {
+        if (this.selectedDoc) {
+            return this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof RichTextField;
+        }
+        else return false;
+    }
+
     render() {
         return (
             <div className="collectionMenu-cont" >
                 <div className="collectionMenu">
                     <div className="collectionViewBaseChrome">
-                        {this.props.type === CollectionViewType.Invalid || this.props.type === CollectionViewType.Docking ? (null) : this.viewModes}
-                        {this.props.type === CollectionViewType.Docking ? (null) : this.templateChrome}
-                        <div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: "grid" }}>
+                        {this.props.type === CollectionViewType.Invalid ||
+                            this.props.type === CollectionViewType.Docking || this.isText ? (null) : this.viewModes}
+                        {this.props.type === CollectionViewType.Docking || this.isText ? (null) : this.templateChrome}
+                        {/* <div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: "grid" }}>
                             <button className={"antimodeMenu-button"} onClick={this.toggleViewSpecs} >
                                 <FontAwesomeIcon icon="filter" size="lg" />
                             </button>
-                        </div>
+                        </div> */}
 
                         {this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? (null) : <button className={"antimodeMenu-button"} key="float"
                             style={{ backgroundColor: !this.props.docView.layoutDoc.isAnnotating ? "121212" : undefined, borderRight: "1px solid gray" }}
@@ -356,6 +373,20 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
     @computed get childDocs() {
         return DocListCast(this.dataField);
     }
+
+    @computed get selectedDocumentView() {
+        if (SelectionManager.SelectedDocuments().length) {
+            return SelectionManager.SelectedDocuments()[0];
+        } else { return undefined; }
+    }
+    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
+    @computed get isText() {
+        if (this.selectedDoc) {
+            return this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof RichTextField;
+        }
+        else return false;
+    }
+
     @undoBatch
     @action
     nextKeyframe = (): void => {
@@ -384,6 +415,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
     miniMap = (): void => {
         this.document.hideMinimap = !this.document.hideMinimap;
     }
+
     private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""];
     private _width = ["1", "5", "10", "100"];
     // private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"];
@@ -523,40 +555,44 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
     }
 
     @computed get formatPane() {
-        return <button className="antimodeMenu-button" key="format" title="toggle foramatting pane"
-            onPointerDown={action(e => FormatShapePane.Instance.Pinned = !FormatShapePane.Instance.Pinned)}
-            style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
-            <FontAwesomeIcon icon="angle-double-right" size="lg" />
-        </button>;
+        // return <button className="antimodeMenu-button" key="format" title="toggle foramatting pane"
+        //     onPointerDown={action(e => FormatShapePane.Instance.Pinned = !FormatShapePane.Instance.Pinned)}
+        //     style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
+        //     <FontAwesomeIcon icon="angle-double-right" size="lg" />
+        // </button>;
+        return null;
     }
 
     render() {
         return !this.props.docView.layoutDoc ? (null) : <div className="collectionFreeFormMenu-cont">
-            {this.props.docView.props.renderDepth !== 0 ? (null) :
+            {this.props.docView.props.renderDepth !== 0 || this.isText ? (null) :
                 <div key="map" title="mini map" className="backKeyframe" onClick={this.miniMap}>
                     <FontAwesomeIcon icon={"map"} size={"lg"} />
                 </div>
             }
-            <div key="back" title="back frame" className="backKeyframe" onClick={this.prevKeyframe}>
+            {!!!this.isText ? <div key="back" title="back frame" className="backKeyframe" onClick={this.prevKeyframe}>
                 <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
-            </div>
-            <div key="num" title="toggle view all" className="numKeyframe" style={{ backgroundColor: this.document.editing ? "#759c75" : "#c56565" }}
+            </div> : null}
+            {!!!this.isText ? <div key="num" title="toggle view all" className="numKeyframe" style={{ backgroundColor: this.document.editing ? "#759c75" : "#c56565" }}
                 onClick={action(() => this.document.editing = !this.document.editing)} >
                 {NumCast(this.document.currentFrame)}
-            </div>
-            <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={this.nextKeyframe}>
+            </div> : null}
+            {!!!this.isText ? <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={this.nextKeyframe}>
                 <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
-            </div>
+            </div> : null}
 
-            {!this.props.isOverlay || this.document.type !== DocumentType.WEB ? (null) :
+            {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText ? (null) :
                 <button className={"antimodeMenu-button"} key="hypothesis"
-                    style={{ backgroundColor: !this.props.docView.layoutDoc.isAnnotating ? "121212" : undefined, borderRight: "1px solid gray" }}
+                    style={{
+                        backgroundColor: !this.props.docView.layoutDoc.isAnnotating ? "121212" : undefined,
+                        borderRight: "1px solid gray"
+                    }}
                     title="Use Hypothesis"
                     onClick={() => this.props.docView.layoutDoc.isAnnotating = !this.props.docView.layoutDoc.isAnnotating}>
                     <FontAwesomeIcon icon={["fab", "hire-a-helper"]} size={"lg"} />
                 </button>
             }
-            {!this.props.isOverlay || this.props.docView.layoutDoc.isAnnotating ?
+            {(!this.props.isOverlay || this.props.docView.layoutDoc.isAnnotating) && !this.isText ?
                 <>
                     {this.drawButtons}
                     {this.widthPicker}
@@ -566,6 +602,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
                 </> :
                 (null)
             }
+            {this.isText ? <RichTextMenu key="rich" /> : null}
         </div>;
     }
 }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 5553bbbb7..f67e049fd 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -253,7 +253,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             <div className="collectionSchema-headerMenu-group">
                 <div onClick={() => this.typesDropdownChange(!this._openTypes)}>
                     <label>Column type:</label>
-                    <FontAwesomeIcon icon={"caret-down"} size="sm" style={{ float: "right" }} />
+                    <FontAwesomeIcon icon={"caret-down"} size="lg" style={{ float: "right" }} />
                 </div>
                 {this._openTypes ? allColumnTypes : justColType}
             </div >
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 425dc90e4..a104ac011 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -227,6 +227,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
             addDocTab={this.addDocTab}
             bringToFront={returnFalse}
             ContentScaling={returnOne}
+            scriptContext={this.props.scriptContext}
             pinToPres={this.props.pinToPres}
         />;
     }
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 26d2ee8a3..68c233a16 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -351,7 +351,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             {this.props.parent.Document._columnsHideIfEmpty ? (null) : headingView}
             {
                 this.collapsed ? (null) :
-                    <div style={{ marginTop: 5 }}>
+                    <div>
                         <div key={`${heading}-stack`} className={`collectionStackingView-masonry${singleColumn ? "Single" : "Grid"}`}
                             style={{
                                 padding: singleColumn ? `${columnYMargin}px ${0}px ${style.yMargin}px ${0}px` : `${columnYMargin}px ${0}px`,
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 9f78c15eb..c90e85271 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -296,7 +296,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
                             const reg = new RegExp(Utils.prepend(""), "g");
                             const modHtml = srcUrl ? html.replace(reg, srcUrl) : html;
                             const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: "-web page-", _width: 300, _height: 300 });
-                            Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc)["text"] = text;
+                            Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc).text = text;
                             this.props.addDocument(htmlDoc);
                             if (srcWeb) {
                                 const focusNode = (SelectionManager.SelectedDocuments()[0].ContentDiv?.getElementsByTagName("iframe")[0].contentDocument?.getSelection()?.focusNode as any);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index b8996c178..e5c4b9187 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -90,7 +90,10 @@ class TreeView extends React.Component<TreeViewProps> {
     get displayName() { return "TreeView(" + this.doc.title + ")"; }  // this makes mobx trace() statements more descriptive
     get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.doc.defaultExpandedView, this.noviceMode ? "layout" : "fields"); }
     @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
-    set treeViewOpen(c: boolean) { if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c; else this.doc.treeViewOpen = this._overrideTreeViewOpen = c; }
+    set treeViewOpen(c: boolean) {
+        if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c;
+        else this.doc.treeViewOpen = this._overrideTreeViewOpen = c;
+    }
     @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && !this.doc.treeViewPreventOpen && BoolCast(this.doc.treeViewOpen)) || this._overrideTreeViewOpen; }
     @computed get treeViewExpandedView() { return StrCast(this.doc.treeViewExpandedView, this.defaultExpandedView); }
     @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.containingCollection.maxEmbedHeight, 200); }
@@ -101,7 +104,7 @@ class TreeView extends React.Component<TreeViewProps> {
         const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined;
         return ((this.props.dataDoc ? DocListCast(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field
             (layout ? DocListCast(layout[field]) : undefined) || // else if there's a layout doc, display it's fields
-            DocListCast(this.doc[field])) as Doc[]; // otherwise use the document's data field
+            DocListCast(this.doc[field])); // otherwise use the document's data field
     }
     @computed get childDocs() { return this.childDocList(this.fieldKey); }
     @computed get childLinks() { return this.childDocList("links"); }
diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss
index b630f9cf8..a5aef86de 100644
--- a/src/client/views/collections/CollectionView.scss
+++ b/src/client/views/collections/CollectionView.scss
@@ -24,6 +24,7 @@
         border-right: unset;
         z-index: 2;
     }
+
     .collectionTimeView-treeView {
         display: flex;
         flex-direction: column;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 7e7ea6786..62e8dc26a 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -78,6 +78,7 @@ export interface CollectionViewCustomProps {
     childLayoutTemplate?: () => Opt<Doc>;  // specify a layout Doc template to use for children of the collection
     childLayoutString?: string;  // specify a layout string to use for children of the collection
     childOpacity?: () => number;
+    hideFilter?: true;
 }
 
 export interface CollectionRenderProps {
@@ -309,7 +310,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
 
             const options = cm.findByDescription("Options...");
             const optionItems = options && "subitems" in options ? options.subitems : [];
-            optionItems.splice(0, 0, { description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" });
+            !Doc.UserDoc().noviceMode ? optionItems.splice(0, 0, { description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }) : null;
             if (this.props.Document.childLayout instanceof Doc) {
                 optionItems.push({ description: "View Child Layout", event: () => this.props.addDocTab(this.props.Document.childLayout as Doc, "onRight"), icon: "project-diagram" });
             }
@@ -368,7 +369,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
     get _facetWidth() { return NumCast(this.props.Document._facetWidth); }
     set _facetWidth(value) { this.props.Document._facetWidth = value; }
 
-    bodyPanelWidth = () => this.props.PanelWidth() - this.facetWidth();
+    bodyPanelWidth = () => this.props.PanelWidth();
     facetWidth = () => Math.max(0, Math.min(this.props.PanelWidth() - 25, this._facetWidth));
 
     @computed get dataDoc() {
@@ -490,6 +491,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             return false;
         }), returnFalse, action(() => this._facetWidth = this.facetWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0), false);
     }
+
     filterBackground = () => "rgba(105, 105, 105, 0.432)";
     get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; } // this makes the tree view collection ignore these filters (otherwise, the filters would filter themselves)
     @computed get scriptField() {
@@ -559,6 +561,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 </div>
             </div>;
     }
+
     childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null);
     childLayoutString = this.props.childLayoutString || StrCast(this.props.Document.childLayoutString);
 
@@ -588,11 +591,11 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                         Utils.CorsProxy(Cast(d.data, ImageField)!.url.href) : Cast(d.data, ImageField)!.url.href
                     :
                     ""))}
-            {(!this.props.isSelected() && !this.props.Document.forceActive) || this.props.Document.hideFilterView ? (null) :
+            {/* {(!this.props.isSelected() && !this.props.Document.forceActive) || this.props.Document.hideFilterView ? (null) :
                 <div className="collectionView-filterDragger" title="library View Dragger" onPointerDown={this.onPointerDown}
                     style={{ right: this.facetWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }} />
             }
-            {this.facetWidth() < 10 ? (null) : this.filterView}
+            {this.facetWidth() < 10 ? (null) : this.filterView}  */}
         </div>);
     }
 }
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index 8c0b8de9d..532dd6abc 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -42,14 +42,14 @@ export class SelectorContextMenu extends React.Component<SelectorProps> {
     async fetchDocuments() {
         const aliases = (await SearchUtil.GetAliasesOfDocument(this.props.Document));
         const containerProtoSets = await Promise.all(aliases.map(async alias =>
-            await Promise.all((await SearchUtil.Search("", true, { fq: `data_l:"${alias[Id]}"` })).docs)));
+            ((await SearchUtil.Search("", true, { fq: `data_l:"${alias[Id]}"` })).docs)));
         const containerProtos = containerProtoSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>());
         const containerSets = await Promise.all(Array.from(containerProtos.keys()).map(async container => {
-            return (await SearchUtil.GetAliasesOfDocument(container));
+            return (SearchUtil.GetAliasesOfDocument(container));
         }));
         const containers = containerSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>());
         const doclayoutSets = await Promise.all(Array.from(containers.keys()).map(async (dp) => {
-            return (await SearchUtil.GetAliasesOfDocument(dp));
+            return (SearchUtil.GetAliasesOfDocument(dp));
         }));
         const doclayouts = Array.from(doclayoutSets.reduce((p, set) => { set.map(s => p.add(s)); return p; }, new Set<Doc>()).keys());
         runInAction(() => {
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index cde795098..7e2840c2c 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -148,7 +148,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     @action
-    changeTitleMode = () => this._showTitleDropdown = !this._showTitleDropdown;
+    changeTitleMode = () => this._showTitleDropdown = !this._showTitleDropdown
 
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
@@ -208,7 +208,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 }}>
                 {col.heading}</div>;
 
-            const sortIcon = col.desc === undefined ? "circle" : col.desc === true ? "caret-down" : "caret-up";
+            const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up";
 
             const header =
                 <div //className="collectionSchemaView-header"
@@ -224,12 +224,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                         {keysDropdown}
                     </div>
                     <div onClick={e => this.changeSorting(col)}
-                        style={{ paddingRight: "6px", display: "inline" }}>
+                        style={{ paddingRight: "6px", marginLeft: "4px", display: "inline" }}>
                         <FontAwesomeIcon icon={sortIcon} size="sm" />
                     </div>
                     <div onClick={e => this.props.openHeader(col, e.clientX, e.clientY)}
                         style={{ float: "right", paddingRight: "6px" }}>
-                        <FontAwesomeIcon icon={"compass"} size="sm" />
+                        <FontAwesomeIcon icon={"cog"} size="sm" />
                     </div>
                 </div>;
 
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 151acb64d..109808956 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1145,7 +1145,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
     @action
     componentDidMount() {
         super.componentDidMount?.();
-        this._layoutComputeReaction = reaction(() => { TraceMobx(); return this.doLayoutComputation },
+        this._layoutComputeReaction = reaction(() => this.doLayoutComputation,
             (elements) => this._layoutElements = elements || [],
             { fireImmediately: true, name: "doLayout" });
 
@@ -1240,13 +1240,15 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         const appearanceItems = appearance && "subitems" in appearance ? appearance.subitems : [];
         appearanceItems.push({ description: "Reset View", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
         appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
-        appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" });
+        !Doc.UserDoc().noviceMode ? appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" }) : null;
         !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" });
 
         const viewctrls = ContextMenu.Instance.findByDescription("UI Controls...");
         const viewCtrlItems = viewctrls && "subitems" in viewctrls ? viewctrls.subitems : [];
-        viewCtrlItems.push({ description: (Doc.UserDoc().showSnapLines ? "Hide" : "Show") + " Snap Lines", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" });
-        viewCtrlItems.push({ description: (this.Document.useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" });
+
+
+        !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (Doc.UserDoc().showSnapLines ? "Hide" : "Show") + " Snap Lines", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" }) : null;
+        !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (this.Document.useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }) : null;
         !viewctrls && ContextMenu.Instance.addItem({ description: "UI Controls...", subitems: viewCtrlItems, icon: "eye" });
 
         const options = ContextMenu.Instance.findByDescription("Options...");
@@ -1291,7 +1293,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                         setTimeout(() => {
                             SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => {
                                 docs.docs.forEach(d => LinkManager.Instance.addLink(d));
-                            })
+                            });
                         }, 2000); // need to give solr some time to update so that this query will find any link docs we've added.
                     }
                 }
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
index ddc282e57..6263be261 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
@@ -13,7 +13,6 @@ import AntimodeMenu from "../../AntimodeMenu";
 import "./FormatShapePane.scss";
 import { undoBatch } from "../../../util/UndoManager";
 import { ColorState, SketchPicker } from 'react-color';
-import { DocumentView } from "../../../views/nodes/DocumentView"
 
 @observer
 export default class FormatShapePane extends AntimodeMenu {
@@ -124,12 +123,12 @@ export default class FormatShapePane extends AntimodeMenu {
                     console.log(ink);
                     if (ink) {
                         const newPoints: { X: number, Y: number }[] = [];
-                        for (var j = 0; j < ink.length; j++) {
+                        ink.forEach(i => {
                             // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
-                            const newX = (doc.x - oldX) + (ink[j].X * doc._width) / oldWidth;
-                            const newY = (doc.y - oldY) + (ink[j].Y * doc._height) / oldHeight;
+                            const newX = ((doc.x || 0) - oldX) + (i.X * (doc._width || 0)) / oldWidth;
+                            const newY = ((doc.y || 0) - oldY) + (i.Y * (doc._height || 0)) / oldHeight;
                             newPoints.push({ X: newX, Y: newY });
-                        }
+                        });
                         doc.data = new InkField(newPoints);
                     }
                 }
@@ -148,12 +147,12 @@ export default class FormatShapePane extends AntimodeMenu {
                     console.log(ink);
                     if (ink) {
                         const newPoints: { X: number, Y: number }[] = [];
-                        for (var j = 0; j < ink.length; j++) {
+                        ink.forEach(i => {
                             // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
-                            const newX = (doc.x - oldX) + (ink[j].X * doc._width) / oldWidth;
-                            const newY = (doc.y - oldY) + (ink[j].Y * doc._height) / oldHeight;
+                            const newX = ((doc.x || 0) - oldX) + (i.X * (doc._width || 0)) / oldWidth;
+                            const newY = ((doc.y || 0) - oldY) + (i.Y * (doc._height || 0)) / oldHeight;
                             newPoints.push({ X: newX, Y: newY });
-                        }
+                        });
                         doc.data = new InkField(newPoints);
                     }
                 }
@@ -191,11 +190,11 @@ export default class FormatShapePane extends AntimodeMenu {
                 if (ink) {
 
                     const newPoints: { X: number, Y: number }[] = [];
-                    for (var i = 0; i < ink.length; i++) {
-                        const newX = Math.cos(angle) * (ink[i].X - _centerPoints[index].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].X;
-                        const newY = Math.sin(angle) * (ink[i].X - _centerPoints[index].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].Y;
+                    ink.forEach(i => {
+                        const newX = Math.cos(angle) * (i.X - _centerPoints[index].X) - Math.sin(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].X;
+                        const newY = Math.sin(angle) * (i.X - _centerPoints[index].X) + Math.cos(angle) * (i.Y - _centerPoints[index].Y) + _centerPoints[index].Y;
                         newPoints.push({ X: newX, Y: newY });
-                    }
+                    });
                     doc.data = new InkField(newPoints);
                     const xs = newPoints.map(p => p.X);
                     const ys = newPoints.map(p => p.Y);
@@ -395,12 +394,12 @@ export default class FormatShapePane extends AntimodeMenu {
     @computed get widInput() { return this.inputBox("wid", this.shapeWid, (val: string) => this.shapeWid = val); }
     @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; return true; }, "∠:", "rot", this.shapeRot, (val: string) => this.shapeRot = val, ""); }
 
-    @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); }
     @computed get YpsInput() { return this.inputBox("Yps", this.shapeYps, (val: string) => this.shapeYps = val); }
 
     @computed get controlPoints() { return this.controlPointsButton(); }
     @computed get lockRatio() { return this.lockRatioButton(); }
     @computed get rotate90() { return this.rotate90Button(); }
+    @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); }
 
 
     @computed get propertyGroupItems() {
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
new file mode 100644
index 000000000..74f32275a
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -0,0 +1,620 @@
+.propertiesView {
+
+    background-color: rgb(205, 205, 205);
+    height: 100%;
+    font-family: "Noto Sans";
+    cursor: auto;
+
+    overflow-x: visible;
+    overflow-y: visible;
+
+    .propertiesView-title {
+        background-color: rgb(159, 159, 159);
+        text-align: center;
+        padding-top: 12px;
+        padding-bottom: 12px;
+        display: flex;
+        font-size: 18px;
+        font-weight: bold;
+        justify-content: center;
+
+        .propertiesView-title-icon {
+            width: 20px;
+            height: 20px;
+            padding-left: 38px;
+            margin-top: -5px;
+            right: 19;
+            position: absolute;
+
+            &:hover {
+                color: grey;
+                cursor: pointer;
+            }
+
+        }
+
+    }
+
+    .propertiesView-name {
+        border-bottom: 1px solid black;
+        padding: 8.5px;
+        font-size: 12.5px;
+
+        &:hover {
+            cursor: pointer;
+        }
+    }
+
+    .propertiesView-settings {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+        font-size: 12.5px;
+        font-weight: bold;
+
+        .propertiesView-settings-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            .propertiesView-settings-title-icon {
+                float: right;
+                right: 0;
+                position: absolute;
+                margin-left: 2px;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-settings-content {
+            margin-left: 12px;
+            padding-bottom: 10px;
+            padding-top: 8px;
+        }
+
+    }
+
+    .propertiesView-sharing {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-sharing-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            .propertiesView-sharing-title-icon {
+                float: right;
+                right: 0;
+                position: absolute;
+                margin-left: 2px;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-sharing-content {
+            font-size: 10px;
+            padding: 10px;
+            margin-left: 5px;
+        }
+    }
+
+    .propertiesView-appearance {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-appearance-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            .propertiesView-appearance-title-icon {
+                float: right;
+                right: 0;
+                position: absolute;
+                margin-left: 2px;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-appearance-content {
+            font-size: 10px;
+            padding: 10px;
+            margin-left: 5px;
+        }
+    }
+
+    .propertiesView-transform {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-transform-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            .propertiesView-transform-title-icon {
+                float: right;
+                right: 0;
+                position: absolute;
+                margin-left: 2px;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-transform-content {
+            font-size: 10px;
+            padding: 10px;
+            margin-left: 5px;
+        }
+    }
+
+    .notify-button {
+        padding: 2px;
+        width: 12px;
+        height: 12px;
+        background-color: black;
+        border-radius: 10px;
+        padding-left: 2px;
+        padding-right: 2px;
+        margin-top: 2px;
+        margin-left: 3px;
+
+        .notify-button-icon {
+            width: 6px;
+            height: 6.5px;
+            margin-left: .5px;
+        }
+
+        &:hover {
+            background-color: rgb(158, 158, 158);
+            cursor: pointer;
+        }
+    }
+
+    .expansion-button-icon {
+        width: 11px;
+        height: 11px;
+        color: black;
+        margin-left: 27px;
+
+        &:hover {
+            color: rgb(131, 131, 131);
+            cursor: pointer;
+        }
+    }
+
+    .propertiesView-sharingTable {
+
+        border: 1px solid black;
+        padding: 5px;
+        border-radius: 6px;
+        /* width: 170px; */
+        margin-right: 10px;
+        background-color: #ececec;
+        max-height: 130px;
+        overflow-y: scroll;
+
+        .propertiesView-sharingTable-item {
+
+            display: flex;
+            padding: 3px;
+            align-items: center;
+            border-bottom: 0.5px solid grey;
+
+            &:hover .propertiesView-sharingTable-item-name {
+                overflow-x: unset;
+                white-space: unset;
+                overflow-wrap: break-word;
+            }
+
+            .propertiesView-sharingTable-item-name {
+                font-weight: bold;
+                width: 80px;
+                overflow-x: hidden;
+                display: inline-block;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+            }
+
+            .propertiesView-sharingTable-item-permission {
+                display: flex;
+                right: 34;
+                float: right;
+                position: absolute;
+
+                .permissions-select {
+                    z-index: 1;
+                    border: none;
+                    background-color: inherit;
+                    width: 75px;
+                    text-align: justify; // for Edge
+                    text-align-last: end;
+
+                    &:hover {
+                        cursor: pointer;
+                    }
+                }
+            }
+
+            &:last-child {
+                border-bottom: none;
+            }
+        }
+    }
+
+    .propertiesView-fields {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-fields-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            .propertiesView-fields-title-name {
+                font-size: 12.5px;
+                font-weight: bold;
+                white-space: nowrap;
+                width: 35px;
+                display: flex;
+            }
+
+            .propertiesView-fields-title-icon {
+                float: right;
+                right: 0;
+                position: absolute;
+                margin-left: 2px;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-fields-checkbox {
+            float: right;
+            height: 20px;
+            margin-top: -9px;
+
+            .propertiesView-fields-checkbox-text {
+                font-size: 7px;
+                margin-top: -10px;
+                margin-left: 6px;
+            }
+        }
+
+        .propertiesView-fields-content {
+            font-size: 10px;
+            margin-left: 2px;
+            padding: 10px;
+
+            &:hover {
+                cursor: pointer;
+            }
+        }
+    }
+
+    .field {
+        display: flex;
+        font-size: 7px;
+        background-color: #e8e8e8;
+        padding-right: 3px;
+        border: 0.5px solid grey;
+        border-radius: 5px;
+        padding-left: 3px;
+    }
+
+    .uneditable-field {
+        display: flex;
+        overflow-y: visible;
+        margin-bottom: 2px;
+
+        &:hover {
+            cursor: auto;
+        }
+    }
+
+    .propertiesView-layout {
+
+        .propertiesView-layout-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            .propertiesView-layout-title-icon {
+                float: right;
+                right: 0;
+                position: absolute;
+                margin-left: 2px;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-layout-content {
+            overflow: hidden;
+            padding: 10px;
+        }
+
+    }
+}
+
+.inking-button {
+
+    display: flex;
+
+    .inking-button-points {
+        background-color: #333333;
+        padding: 7px;
+        border-radius: 7px;
+        margin-right: 32px;
+        width: 32;
+        height: 32;
+        padding-top: 9px;
+        margin-left: 18px;
+
+        &:hover {
+            background: rgb(131, 131, 131);
+            transform: scale(1.05);
+            cursor: pointer;
+        }
+    }
+
+    .inking-button-lock {
+        background-color: #333333;
+        padding: 7px;
+        border-radius: 7px;
+        margin-right: 32px;
+        width: 32;
+        height: 32;
+        padding-top: 9px;
+        padding-left: 10px;
+
+        &:hover {
+            background: rgb(131, 131, 131);
+            transform: scale(1.05);
+            cursor: pointer;
+        }
+    }
+
+    .inking-button-rotate {
+        background-color: #333333;
+        padding: 7px;
+        border-radius: 7px;
+        width: 32;
+        height: 32;
+        padding-top: 9px;
+        padding-left: 10px;
+
+        &:hover {
+            background: rgb(131, 131, 131);
+            transform: scale(1.05);
+            cursor: pointer;
+        }
+    }
+}
+
+.inputBox-duo {
+    display: flex;
+}
+
+.inputBox {
+
+    margin-top: 10px;
+    display: flex;
+    height: 19px;
+    margin-right: 15px;
+
+    .inputBox-title {
+        font-size: 12px;
+        padding-right: 5px;
+    }
+
+    .inputBox-input {
+        font-size: 10px;
+        width: 50px;
+        margin-right: 1px;
+        border-radius: 3px;
+
+        &:hover {
+            cursor: pointer;
+        }
+    }
+
+    .inputBox-button {
+
+        .inputBox-button-up {
+            background-color: #333333;
+            height: 9px;
+            padding-left: 3px;
+            padding-right: 3px;
+            padding-top: 1px;
+            padding-bottom: 1px;
+            border-radius: 1.5px;
+
+            &:hover {
+                background: rgb(131, 131, 131);
+                transform: scale(1.05);
+                cursor: pointer;
+            }
+        }
+
+        .inputBox-button-down {
+            background-color: #333333;
+            height: 9px;
+            padding-left: 3px;
+            padding-right: 3px;
+            padding-top: 1px;
+            padding-bottom: 1px;
+            border-radius: 1.5px;
+
+            &:hover {
+                background: rgb(131, 131, 131);
+                transform: scale(1.05);
+                cursor: pointer;
+            }
+        }
+
+    }
+}
+
+.color-palette {
+    width: 160px;
+    height: 360;
+}
+
+.strokeAndFill {
+    display: flex;
+    margin-top: 10px;
+
+    .fill {
+        margin-right: 40px;
+        display: flex;
+        padding-bottom: 7px;
+        margin-left: 35px;
+
+        .fill-title {
+            font-size: 12px;
+            margin-right: 2px;
+        }
+
+        .fill-button {
+            padding-top: 2px;
+            margin-top: -1px;
+        }
+    }
+
+    .stroke {
+        display: flex;
+
+        .stroke-title {
+            font-size: 12px;
+        }
+
+        .stroke-button {
+            padding-top: 2px;
+            margin-left: 2px;
+            margin-top: -1px;
+        }
+    }
+}
+
+.widthAndDash {
+
+    .width {
+        .width-top {
+            display: flex;
+
+            .width-title {
+                font-size: 12;
+                margin-right: 20px;
+                margin-left: 35px;
+                text-align: center;
+            }
+
+            .width-input {
+                margin-right: 30px;
+                margin-top: -10px;
+            }
+        }
+
+        .width-range {
+            margin-right: 1px;
+            margin-bottom: 6;
+        }
+    }
+
+    .arrows {
+
+        display: flex;
+        margin-bottom: 3px;
+
+        .arrows-head {
+
+            display: flex;
+            margin-right: 35px;
+
+            .arrows-head-title {
+                font-size: 10;
+            }
+
+            .arrows-head-input {
+                margin-left: 6px;
+                margin-top: 2px;
+            }
+        }
+
+        .arrows-tail {
+            display: flex;
+
+            .arrows-tail-title {
+                font-size: 10;
+            }
+
+            .arrows-tail-input {
+                margin-left: 6px;
+                margin-top: 2px;
+            }
+        }
+    }
+
+    .dashed {
+
+        display: flex;
+        margin-left: 74px;
+        margin-bottom: 6px;
+
+        .dashed-title {
+            font-size: 10;
+        }
+
+        .dashed-input {
+            margin-left: 6px;
+            margin-top: 2px;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
new file mode 100644
index 000000000..35c7fd425
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -0,0 +1,858 @@
+import React = require("react");
+import { observer } from "mobx-react";
+import "./PropertiesView.scss";
+import { observable, action, computed, runInAction } from "mobx";
+import { Doc, Field, DocListCast, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt } from "../../../../fields/Doc";
+import { DocumentView } from "../../nodes/DocumentView";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { EditableView } from "../../EditableView";
+import { KeyValueBox } from "../../nodes/KeyValueBox";
+import { Cast, NumCast, StrCast } from "../../../../fields/Types";
+import { listSpec } from "../../../../fields/Schema";
+import { ContentFittingDocumentView } from "../../nodes/ContentFittingDocumentView";
+import { returnFalse, returnOne, emptyFunction, emptyPath, returnTrue, returnZero, returnEmptyFilter, Utils } from "../../../../Utils";
+import { Id } from "../../../../fields/FieldSymbols";
+import { Transform } from "../../../util/Transform";
+import { PropertiesButtons } from "../../PropertiesButtons";
+import { SelectionManager } from "../../../util/SelectionManager";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Tooltip, Checkbox, Divider } from "@material-ui/core";
+import SharingManager from "../../../util/SharingManager";
+import { DocumentType } from "../../../documents/DocumentTypes";
+import FormatShapePane from "./FormatShapePane";
+import { SharingPermissions, GetEffectiveAcl } from "../../../../fields/util";
+import { InkField } from "../../../../fields/InkField";
+import { undoBatch } from "../../../util/UndoManager";
+import { ColorState, SketchPicker } from "react-color";
+import AntimodeMenu from "../../AntimodeMenu";
+import "./FormatShapePane.scss";
+import { discovery_v1 } from "googleapis";
+import { PresBox } from "../../nodes/PresBox";
+import { DocumentManager } from "../../../util/DocumentManager";
+
+
+interface PropertiesViewProps {
+    width: number;
+    height: number;
+    renderDepth: number;
+    ScreenToLocalTransform: () => Transform;
+    onDown: (event: any) => void;
+}
+
+@observer
+export class PropertiesView extends React.Component<PropertiesViewProps> {
+
+    @computed get MAX_EMBED_HEIGHT() { return 200; }
+
+    @computed get selectedDocumentView() {
+        if (SelectionManager.SelectedDocuments().length) {
+            return SelectionManager.SelectedDocuments()[0];
+        } else if (PresBox.Instance) {
+            const presSlide = PresBox.Instance._selectedArray[0];
+            const view = DocumentManager.Instance.getDocumentView(presSlide);
+            if (view) return view;
+        } else { return undefined; }
+    }
+    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
+    @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; }
+
+    @observable layoutFields: boolean = false;
+
+    @observable openActions: boolean = true;
+    @observable openSharing: boolean = true;
+    @observable openFields: boolean = true;
+    @observable openLayout: boolean = true;
+    @observable openAppearance: boolean = true;
+    @observable openTransform: boolean = true;
+
+    @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; }
+
+    @action
+    rtfWidth = () => {
+        if (this.selectedDoc) {
+            return Math.min(this.selectedDoc?.[WidthSym](), this.props.width - 20);
+        } else {
+            return 0;
+        }
+    }
+    @action
+    rtfHeight = () => {
+        if (this.selectedDoc) {
+            return this.rtfWidth() <= this.selectedDoc?.[WidthSym]() ? Math.min(this.selectedDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
+        } else {
+            return 0;
+        }
+    }
+
+    @action
+    docWidth = () => {
+        if (this.selectedDoc) {
+            const layoutDoc = this.selectedDoc;
+            const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+            if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20));
+            return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20;
+        } else {
+            return 0;
+        }
+    }
+
+    @action
+    docHeight = () => {
+        if (this.selectedDoc && this.dataDoc) {
+            const layoutDoc = this.selectedDoc;
+            return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => {
+                const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+                if (aspect) return this.docWidth() * aspect;
+                return layoutDoc._fitWidth ? (!this.dataDoc._nativeHeight ? NumCast(this.props.height) :
+                    Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
+                        NumCast(this.props.height)))) :
+                    NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
+            })()));
+        } else {
+            return 0;
+        }
+    }
+
+    @computed get expandedField() {
+        if (this.dataDoc && this.selectedDoc) {
+            const ids: { [key: string]: string } = {};
+            const doc = this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc;
+            doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
+            const rows: JSX.Element[] = [];
+            for (const key of Object.keys(ids).slice().sort()) {
+                const contents = doc[key];
+                if (key[0] === "#") {
+                    rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "2px" }} key={key}>
+                        <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key}</span>
+                    &nbsp;
+                </div>);
+                } else {
+                    let contentElement: (JSX.Element | null)[] | JSX.Element = [];
+                    contentElement = <EditableView key="editableView"
+                        contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
+                        height={13}
+                        fontSize={10}
+                        GetValue={() => Field.toKeyValueString(doc, key)}
+                        SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)}
+                    />;
+                    rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
+                        <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
+                        &nbsp;
+                        {contentElement}
+                    </div>);
+                }
+            }
+            rows.push(<div className="field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
+                <EditableView
+                    key="editableView"
+                    contents={"add key:value or #tags"}
+                    height={13}
+                    fontSize={10}
+                    GetValue={() => ""}
+                    SetValue={this.setKeyValue} />
+            </div>);
+            return rows;
+        }
+    }
+
+    @computed get noviceFields() {
+        if (this.dataDoc && this.selectedDoc) {
+            const ids: { [key: string]: string } = {};
+            const doc = this.dataDoc;
+            doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
+            const rows: JSX.Element[] = [];
+            for (const key of Object.keys(ids).slice().sort()) {
+                if (key[0] === key[0].toUpperCase() || key[0] === "#" || key === "author" || key === "creationDate" || key.indexOf("lastModified") !== -1) {
+                    const contents = doc[key];
+                    if (key[0] === "#") {
+                        rows.push(<div className="uneditable-field" key={key}>
+                            <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key}</span>
+                    &nbsp;
+                </div>);
+                    } else {
+                        const value = Field.toString(contents as Field);
+                        if (key === "author" || key === "creationDate" || key.indexOf("lastModified") !== -1) {
+                            rows.push(<div className="uneditable-field" key={key}>
+                                <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ": "}</span>
+                                <div style={{ whiteSpace: "nowrap", overflowX: "hidden" }}>{value}</div>
+                            </div>);
+                        } else {
+                            let contentElement: (JSX.Element | null)[] | JSX.Element = [];
+                            contentElement = <EditableView key="editableView"
+                                contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
+                                height={13}
+                                fontSize={10}
+                                GetValue={() => Field.toKeyValueString(doc, key)}
+                                SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)}
+                            />;
+
+                            rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
+                                <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
+                            &nbsp;
+                            {contentElement}
+                            </div>);
+                        }
+                    }
+                }
+            }
+            rows.push(<div className="field" key={"newKeyValue"} style={{ marginTop: "3px" }}>
+                <EditableView
+                    key="editableView"
+                    contents={"add key:value or #tags"}
+                    height={13}
+                    fontSize={10}
+                    GetValue={() => ""}
+                    SetValue={this.setKeyValue} />
+            </div>);
+            return rows;
+        }
+    }
+
+
+    setKeyValue = (value: string) => {
+        if (this.selectedDoc && this.dataDoc) {
+            const doc = this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc;
+            if (value.indexOf(":") !== -1) {
+                const newVal = value[0].toUpperCase() + value.substring(1, value.length);
+                KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
+                return true;
+            } else if (value[0] === "#") {
+                const newVal = value + `:'${value}'`;
+                KeyValueBox.SetField(doc, newVal.substring(0, newVal.indexOf(":")), newVal.substring(newVal.indexOf(":") + 1, newVal.length), true);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @computed get layoutPreview() {
+        if (this.selectedDoc) {
+            const layoutDoc = Doc.Layout(this.selectedDoc);
+            const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
+            const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
+            return <div style={{ display: "inline-block", height: panelHeight() }} key={this.selectedDoc[Id]}>
+                <ContentFittingDocumentView
+                    Document={layoutDoc}
+                    DataDoc={this.dataDoc}
+                    LibraryPath={emptyPath}
+                    renderDepth={this.props.renderDepth + 1}
+                    rootSelected={returnFalse}
+                    treeViewDoc={undefined}
+                    backgroundColor={() => "lightgrey"}
+                    fitToBox={false}
+                    FreezeDimensions={true}
+                    NativeWidth={layoutDoc.type ===
+                        StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
+                    NativeHeight={layoutDoc.type ===
+                        StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero}
+                    PanelWidth={panelWidth}
+                    PanelHeight={panelHeight}
+                    focus={returnFalse}
+                    ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                    docFilters={returnEmptyFilter}
+                    ContainingCollectionDoc={undefined}
+                    ContainingCollectionView={undefined}
+                    addDocument={returnFalse}
+                    moveDocument={undefined}
+                    removeDocument={returnFalse}
+                    parentActive={() => false}
+                    whenActiveChanged={emptyFunction}
+                    addDocTab={returnFalse}
+                    pinToPres={emptyFunction}
+                    bringToFront={returnFalse}
+                    ContentScaling={returnOne}
+                    dontRegisterView={true}
+                />
+            </div>;
+        } else {
+            return null;
+        }
+    }
+
+    getPermissionsSelect(user: string) {
+        return <select className="permissions-select"
+            onChange={e => SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, this.selectedDoc!)}>
+            {Object.values(SharingPermissions).map(permission => {
+                return (
+                    <option key={permission} value={permission} selected={this.selectedDoc![`ACL-${user.replace(".", "_")}`] === permission}>
+                        {permission}
+                    </option>);
+            })}
+        </select>;
+    }
+
+    @computed get notifyIcon() {
+        return <Tooltip title={<><div className="dash-tooltip">Notify with message</div></>}>
+            <div className="notify-button">
+                <FontAwesomeIcon className="notify-button-icon" icon="bell" color="white" size="sm" />
+            </div>
+        </Tooltip>;
+    }
+
+    @computed get expansionIcon() {
+        return <Tooltip title={<><div className="dash-tooltip">{"Show more permissions"}</div></>}>
+            <div className="expansion-button" onPointerDown={() => {
+                if (this.selectedDocumentView) {
+                    SharingManager.Instance.open(this.selectedDocumentView);
+                }
+            }}>
+                <FontAwesomeIcon className="expansion-button-icon" icon="ellipsis-h" color="black" size="sm" />
+            </div>
+        </Tooltip>;
+    }
+
+    sharingItem(name: string, effectiveAcl: symbol, permission?: string) {
+        return <div className="propertiesView-sharingTable-item">
+            <div className="propertiesView-sharingTable-item-name" style={{ width: name !== "Me" ? "70px" : "80px" }}> {name} </div>
+            {name !== "Me" ? this.notifyIcon : null}
+            <div className="propertiesView-sharingTable-item-permission">
+                {effectiveAcl === AclAdmin && permission !== "Owner" ? this.getPermissionsSelect(name) : permission}
+                {permission === "Owner" ? this.expansionIcon : null}
+            </div>
+        </div>;
+    }
+
+    @computed get sharingTable() {
+        const AclMap = new Map<symbol, string>([
+            [AclPrivate, SharingPermissions.None],
+            [AclReadonly, SharingPermissions.View],
+            [AclAddonly, SharingPermissions.Add],
+            [AclEdit, SharingPermissions.Edit],
+            [AclAdmin, SharingPermissions.Admin]
+        ]);
+
+        const effectiveAcl = GetEffectiveAcl(this.selectedDoc!);
+        const tableEntries = [];
+
+        if (this.selectedDoc![AclSym]) {
+            for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) {
+                const name = key.substring(4).replace("_", ".");
+                if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author) tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!));
+            }
+        }
+
+        tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : StrCast(this.selectedDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`])));
+        if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner"));
+
+        return <div className="propertiesView-sharingTable">
+            {tableEntries}
+        </div>;
+    }
+
+    @computed get fieldsCheckbox() {
+        return <Checkbox
+            color="primary"
+            onChange={this.toggleCheckbox}
+            checked={this.layoutFields}
+        />;
+    }
+
+    @action
+    toggleCheckbox = () => {
+        this.layoutFields = !this.layoutFields;
+    }
+
+    @computed get editableTitle() {
+        return <EditableView
+            key="editableView"
+            contents={StrCast(this.selectedDoc?.title)}
+            height={25}
+            fontSize={14}
+            GetValue={() => StrCast(this.selectedDoc?.title)}
+            SetValue={this.setTitle} />;
+    }
+
+    @action
+    setTitle = (value: string) => {
+        if (this.dataDoc) {
+            this.selectedDoc && (this.selectedDoc.title = value);
+            KeyValueBox.SetField(this.dataDoc, "title", value, true);
+            return true;
+        }
+        return false;
+    }
+
+
+
+
+
+
+
+
+
+    @undoBatch
+    @action
+    rotate = (angle: number) => {
+        const _centerPoints: { X: number, Y: number }[] = [];
+        if (this.selectedDoc) {
+            const doc = this.selectedDoc;
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                const ink = Cast(doc.data, InkField)?.inkData;
+                if (ink) {
+                    const xs = ink.map(p => p.X);
+                    const ys = ink.map(p => p.Y);
+                    const left = Math.min(...xs);
+                    const top = Math.min(...ys);
+                    const right = Math.max(...xs);
+                    const bottom = Math.max(...ys);
+                    _centerPoints.push({ X: left, Y: top });
+                }
+            }
+
+            var index = 0;
+            if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
+                doc.rotation = Number(doc.rotation) + Number(angle);
+                const ink = Cast(doc.data, InkField)?.inkData;
+                if (ink) {
+
+                    const newPoints: { X: number, Y: number }[] = [];
+                    for (var i = 0; i < ink.length; i++) {
+                        const newX = Math.cos(angle) * (ink[i].X - _centerPoints[index].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].X;
+                        const newY = Math.sin(angle) * (ink[i].X - _centerPoints[index].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].Y;
+                        newPoints.push({ X: newX, Y: newY });
+                    }
+                    doc.data = new InkField(newPoints);
+                    const xs = newPoints.map(p => p.X);
+                    const ys = newPoints.map(p => p.Y);
+                    const left = Math.min(...xs);
+                    const top = Math.min(...ys);
+                    const right = Math.max(...xs);
+                    const bottom = Math.max(...ys);
+
+                    doc._height = (bottom - top);
+                    doc._width = (right - left);
+                }
+                index++;
+            }
+        }
+    }
+
+    @observable _controlBtn: boolean = false;
+    @observable _lock: boolean = false;
+
+    @computed
+    get controlPointsButton() {
+        return <div className="inking-button">
+            <Tooltip title={<><div className="dash-tooltip">{"Edit points"}</div></>}>
+                <div className="inking-button-points" onPointerDown={action(() => this._controlBtn = !this._controlBtn)} style={{ backgroundColor: this._controlBtn ? "black" : "" }}>
+                    <FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
+                </div>
+            </Tooltip>
+            <Tooltip title={<><div className="dash-tooltip">{this._lock ? "Unlock points" : "Lock points"}</div></>}>
+                <div className="inking-button-lock" onPointerDown={action(() => this._lock = !this._lock)} >
+                    <FontAwesomeIcon icon={this._lock ? "unlock" : "lock"} color="white" size="lg" />
+                </div>
+            </Tooltip>
+            <Tooltip title={<><div className="dash-tooltip">{"Rotate 90˚"}</div></>}>
+                <div className="inking-button-rotate" onPointerDown={action(() => this.rotate(Math.PI / 2))}>
+                    <FontAwesomeIcon icon="undo" color="white" size="lg" />
+                </div>
+            </Tooltip>
+        </div>;
+    }
+
+    inputBox = (key: string, value: any, setter: (val: string) => {}, title: string) => {
+        return <div className="inputBox"
+            style={{
+                marginRight: title === "X:" ? "19px" : "",
+                marginLeft: title === "∠:" ? "39px" : ""
+            }}>
+            <div className="inputBox-title"> {title} </div>
+            <input className="inputBox-input"
+                type="text" value={value}
+                onChange={e => setter(e.target.value)} />
+            <div className="inputBox-button">
+                <div className="inputBox-button-up" key="up2"
+                    onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} >
+                    <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
+                </div>
+                <div className="inputbox-Button-down" key="down2"
+                    onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} >
+                    <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
+                </div>
+            </div>
+        </div>;
+    }
+
+    inputBoxDuo = (key: string, value: any, setter: (val: string) => {}, title1: string, key2: string, value2: any, setter2: (val: string) => {}, title2: string) => {
+        return <div className="inputBox-duo">
+            {this.inputBox(key, value, setter, title1)}
+            {title2 === "" ? (null) : this.inputBox(key2, value2, setter2, title2)}
+        </div>;
+    }
+
+    @action
+    upDownButtons = (dirs: string, field: string) => {
+        switch (field) {
+            case "rot": this.rotate((dirs === "up" ? .1 : -.1)); break;
+            // case "rot": this.selectedInk?.forEach(i => i.rootDoc.rotation = NumCast(i.rootDoc.rotation) + (dirs === "up" ? 0.1 : -0.1)); break;
+            case "Xps": this.selectedDoc && (this.selectedDoc.x = NumCast(this.selectedDoc?.x) + (dirs === "up" ? 10 : -10)); break;
+            case "Yps": this.selectedDoc && (this.selectedDoc.y = NumCast(this.selectedDoc?.y) + (dirs === "up" ? 10 : -10)); break;
+            case "stk": this.selectedDoc && (this.selectedDoc.strokeWidth = NumCast(this.selectedDoc?.strokeWidth) + (dirs === "up" ? .1 : -.1)); break;
+            case "wid":
+                const oldWidth = NumCast(this.selectedDoc?._width);
+                const oldHeight = NumCast(this.selectedDoc?._height);
+                const oldX = NumCast(this.selectedDoc?.x);
+                const oldY = NumCast(this.selectedDoc?.y);
+                this.selectedDoc && (this.selectedDoc._width = oldWidth + (dirs === "up" ? 10 : - 10));
+                this._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) / oldWidth * NumCast(this.selectedDoc?._height)));
+                const doc = this.selectedDoc;
+                if (doc?.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
+                    console.log(doc.x, doc.y, doc._height, doc._width);
+                    const ink = Cast(doc.data, InkField)?.inkData;
+                    console.log(ink);
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        for (var j = 0; j < ink.length; j++) {
+                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                            const newX = (NumCast(doc.x) - oldX) + (ink[j].X * NumCast(doc._width)) / oldWidth;
+                            const newY = (NumCast(doc.y) - oldY) + (ink[j].Y * NumCast(doc._height)) / oldHeight;
+                            newPoints.push({ X: newX, Y: newY });
+                        }
+                        doc.data = new InkField(newPoints);
+                    }
+                }
+                break;
+            case "hgt":
+                const oWidth = NumCast(this.selectedDoc?._width);
+                const oHeight = NumCast(this.selectedDoc?._height);
+                const oX = NumCast(this.selectedDoc?.x);
+                const oY = NumCast(this.selectedDoc?.y);
+                this.selectedDoc && (this.selectedDoc._height = oHeight + (dirs === "up" ? 10 : - 10));
+                this._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) / oHeight * NumCast(this.selectedDoc?._width)));
+                const docu = this.selectedDoc;
+                if (docu?.type === DocumentType.INK && docu.x && docu.y && docu._height && docu._width) {
+                    console.log(docu.x, docu.y, docu._height, docu._width);
+                    const ink = Cast(docu.data, InkField)?.inkData;
+                    console.log(ink);
+                    if (ink) {
+                        const newPoints: { X: number, Y: number }[] = [];
+                        for (var j = 0; j < ink.length; j++) {
+                            // (new x — oldx) + (oldxpoint * newWidt)/oldWidth 
+                            const newX = (NumCast(docu.x) - oX) + (ink[j].X * NumCast(docu._width)) / oWidth;
+                            const newY = (NumCast(docu.y) - oY) + (ink[j].Y * NumCast(docu._height)) / oHeight;
+                            newPoints.push({ X: newX, Y: newY });
+                        }
+                        docu.data = new InkField(newPoints);
+                    }
+                }
+                break;
+        }
+    }
+
+    getField(key: string) {
+        //if (this.selectedDoc) {
+        return Field.toString(this.selectedDoc[key] as Field);
+        // } else {
+        //     return undefined as Opt<string>;
+        // }
+    }
+
+    @computed get shapeXps() { return this.getField("x"); }
+    @computed get shapeYps() { return this.getField("y"); }
+    @computed get shapeRot() { return this.getField("rotation"); }
+    @computed get shapeHgt() { return this.getField("_height"); }
+    @computed get shapeWid() { return this.getField("_width"); }
+    set shapeXps(value) { this.selectedDoc && (this.selectedDoc.x = Number(value)); }
+    set shapeYps(value) { this.selectedDoc && (this.selectedDoc.y = Number(value)); }
+    set shapeRot(value) { this.selectedDoc && (this.selectedDoc.rotation = Number(value)); }
+    set shapeWid(value) {
+        const oldWidth = NumCast(this.selectedDoc?._width);
+        this.selectedDoc && (this.selectedDoc._width = Number(value));
+        this._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) * NumCast(this.selectedDoc?._height)) / oldWidth);
+    }
+    set shapeHgt(value) {
+        const oldHeight = NumCast(this.selectedDoc?._height);
+        this.selectedDoc && (this.selectedDoc._height = Number(value));
+        this._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) * NumCast(this.selectedDoc?._width)) / oldHeight);
+    }
+
+    @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => this.shapeHgt = val, "H:", "wid", this.shapeWid, (val: string) => this.shapeWid = val, "W:"); }
+    @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); }
+    @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; return true; }, "∠:", "rot", this.shapeRot, (val: string) => this.shapeRot = val, ""); }
+
+    @observable private _fillBtn = false;
+    @observable private _lineBtn = false;
+
+    private _lastFill = "#D0021B";
+    private _lastLine = "#D0021B";
+    private _lastDash: any = "2";
+
+    @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; }
+    @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; }
+    set colorFil(value) { value && (this._lastFill = value); this.selectedDoc && (this.selectedDoc.fillColor = value ? value : undefined); }
+    set colorStk(value) { value && (this._lastLine = value); this.selectedDoc && (this.selectedDoc.color = value ? value : undefined); }
+
+    colorButton(value: string, setter: () => {}) {
+        return <div className="color-button" key="color" onPointerDown={undoBatch(action(e => setter()))}>
+            <div className="color-button-preview" style={{
+                backgroundColor: value ?? "121212", width: 15, height: 15,
+                display: value === "" || value === "transparent" ? "none" : ""
+            }} />
+            {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -14, position: "fixed" }}>☒</p> : ""}
+        </div>;
+    }
+
+    @undoBatch
+    @action
+    switchStk = (color: ColorState) => {
+        const val = String(color.hex);
+        this.colorStk = val;
+        return true;
+    }
+    @undoBatch
+    @action
+    switchFil = (color: ColorState) => {
+        const val = String(color.hex);
+        this.colorFil = val;
+        return true;
+    }
+
+    colorPicker(setter: (color: string) => {}, type: string) {
+        return <SketchPicker onChange={type === "stk" ? this.switchStk : this.switchFil}
+            presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+                '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+                '#FFFFFF', '#f1efeb', 'transparent']}
+            color={type === "stk" ? this.colorStk : this.colorFil} />;
+    }
+
+    @computed get fillButton() { return this.colorButton(this.colorFil, () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); }
+    @computed get lineButton() { return this.colorButton(this.colorStk, () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); }
+
+    @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color, "fil"); }
+    @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color, "stk"); }
+
+    @computed get strokeAndFill() {
+        return <div>
+            <div key="fill" className="strokeAndFill">
+                <div className="fill">
+                    <div className="fill-title">Fill:</div>
+                    <div className="fill-button">{this.fillButton}</div>
+                </div>
+                <div className="stroke">
+                    <div className="stroke-title"> Stroke: </div>
+                    <div className="stroke-button">{this.lineButton}</div>
+                </div>
+            </div>
+            {this._fillBtn ? this.fillPicker : ""}
+            {this._lineBtn ? this.linePicker : ""}
+        </div>;
+    }
+
+    @computed get solidStk() { return this.selectedDoc?.color && (!this.selectedDoc?.strokeDash || this.selectedDoc?.strokeDash === "0") ? true : false; }
+    @computed get dashdStk() { return this.selectedDoc?.strokeDash || ""; }
+    @computed get unStrokd() { return this.selectedDoc?.color ? true : false; }
+    @computed get widthStk() { return this.getField("strokeWidth") || "1"; }
+    @computed get markHead() { return this.getField("strokeStartMarker") || ""; }
+    @computed get markTail() { return this.getField("strokeEndMarker") || ""; }
+    set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; }
+    set dashdStk(value) {
+        value && (this._lastDash = value) && (this.unStrokd = false);
+        this.selectedDoc && (this.selectedDoc.strokeDash = value ? this._lastDash : undefined);
+    }
+    set widthStk(value) { this.selectedDoc && (this.selectedDoc.strokeWidth = Number(value)); }
+    set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; }
+    set markHead(value) { this.selectedDoc && (this.selectedDoc.strokeStartMarker = value); }
+    set markTail(value) { this.selectedDoc && (this.selectedDoc.strokeEndMarker = value); }
+
+
+    @computed get stkInput() { return this.regInput("stk", this.widthStk, (val: string) => this.widthStk = val); }
+
+
+    regInput = (key: string, value: any, setter: (val: string) => {}) => {
+        return <div className="inputBox">
+            <input className="inputBox-input"
+                type="text" value={value}
+                onChange={e => setter(e.target.value)} />
+            <div className="inputBox-button">
+                <div className="inputBox-button-up" key="up2"
+                    onPointerDown={undoBatch(action(() => this.upDownButtons("up", key)))} >
+                    <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
+                </div>
+                <div className="inputbox-Button-down" key="down2"
+                    onPointerDown={undoBatch(action(() => this.upDownButtons("down", key)))} >
+                    <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
+                </div>
+            </div>
+        </div>;
+    }
+
+    @computed get widthAndDash() {
+        return <div className="widthAndDash">
+            <div className="width">
+                <div className="width-top">
+                    <div className="width-title">Width:</div>
+                    <div className="width-input">{this.stkInput}</div>
+                </div>
+                <input className="width-range" type="range"
+                    defaultValue={Number(this.widthStk)} min={1} max={100}
+                    onChange={undoBatch(action((e) => this.widthStk = e.target.value))} />
+            </div>
+
+            <div className="arrows">
+                <div className="arrows-head">
+                    <div className="arrows-head-title" >Arrow Head: </div>
+                    <input key="markHead" className="arrows-head-input" type="checkbox"
+                        checked={this.markHead !== ""}
+                        onChange={undoBatch(action(() => this.markHead = this.markHead ? "" : "arrow"))} />
+                </div>
+                <div className="arrows-tail">
+                    <div className="arrows-tail-title" >Arrow End: </div>
+                    <input key="markTail" className="arrows-tail-input" type="checkbox"
+                        checked={this.markTail !== ""}
+                        onChange={undoBatch(action(() => this.markTail = this.markTail ? "" : "arrow"))} />
+                </div>
+            </div>
+            <div className="dashed">
+                <div className="dashed-title">Dash:</div>
+                <input key="markHead" className="dashed-input"
+                    type="checkbox" checked={this.dashdStk === "2"}
+                    onChange={this.changeDash} />
+            </div>
+        </div>;
+    }
+
+    @undoBatch @action
+    changeDash = () => {
+        const dash = this.dashdStk;
+        if (dash === "2") {
+            this.dashdStk = "0";
+        } else {
+            this.dashdStk = "2";
+        }
+    }
+
+    @computed get appearanceEditor() {
+        return <div className="appearance-editor">
+            {this.widthAndDash}
+            {this.strokeAndFill}
+        </div>;
+    }
+
+    @computed get transformEditor() {
+        return <div className="transform-editor">
+            {this.controlPointsButton}
+            {this.hgtInput}
+            {this.XpsInput}
+            {this.rotInput}
+        </div>;
+    }
+
+    render() {
+
+        if (!this.selectedDoc) {
+            return <div className="propertiesView" style={{ width: this.props.width }}>
+                <div className="propertiesView-title" style={{ width: this.props.width, paddingLeft: 6 }}>
+                    No Document Selected
+            </div> </div>;
+        }
+
+        const novice = Doc.UserDoc().noviceMode;
+
+        return <div className="propertiesView" style={{ width: this.props.width }} >
+            <div className="propertiesView-title" style={{ width: this.props.width }}>
+                Properties
+                <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
+                    <FontAwesomeIcon icon="times" color="black" size="sm" />
+                </div>
+            </div>
+            <div className="propertiesView-name">
+                {this.editableTitle}
+            </div>
+            <div className="propertiesView-settings">
+                <div className="propertiesView-settings-title"
+                    onPointerDown={() => runInAction(() => { this.openActions = !this.openActions; })}
+                    style={{ backgroundColor: this.openActions ? "black" : "" }}>
+                    Actions
+                    <div className="propertiesView-settings-title-icon">
+                        <FontAwesomeIcon icon={this.openActions ? "caret-down" : "caret-right"} size="lg" color="white" />
+                    </div>
+                </div>
+                {this.openActions ? <div className="propertiesView-settings-content">
+                    <PropertiesButtons />
+                </div> : null}
+            </div>
+            <div className="propertiesView-sharing">
+                <div className="propertiesView-sharing-title"
+                    onPointerDown={() => runInAction(() => { this.openSharing = !this.openSharing; })}
+                    style={{ backgroundColor: this.openSharing ? "black" : "" }}>
+                    Sharing {"&"} Permissions
+                    <div className="propertiesView-sharing-title-icon">
+                        <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+                    </div>
+                </div>
+                {this.openSharing ? <div className="propertiesView-sharing-content">
+                    {this.sharingTable}
+                </div> : null}
+            </div>
+
+
+
+
+            {this.isInk ? <div className="propertiesView-appearance">
+                <div className="propertiesView-appearance-title"
+                    onPointerDown={() => runInAction(() => { this.openAppearance = !this.openAppearance; })}
+                    style={{ backgroundColor: this.openAppearance ? "black" : "" }}>
+                    Appearance
+                    <div className="propertiesView-appearance-title-icon">
+                        <FontAwesomeIcon icon={this.openAppearance ? "caret-down" : "caret-right"} size="lg" color="white" />
+                    </div>
+                </div>
+                {this.openAppearance ? <div className="propertiesView-appearance-content">
+                    {this.appearanceEditor}
+                </div> : null}
+            </div> : null}
+
+            {this.isInk ? <div className="propertiesView-transform">
+                <div className="propertiesView-transform-title"
+                    onPointerDown={() => runInAction(() => { this.openTransform = !this.openTransform; })}
+                    style={{ backgroundColor: this.openTransform ? "black" : "" }}>
+                    Transform
+                    <div className="propertiesView-transform-title-icon">
+                        <FontAwesomeIcon icon={this.openTransform ? "caret-down" : "caret-right"} size="lg" color="white" />
+                    </div>
+                </div>
+                {this.openTransform ? <div className="propertiesView-transform-content">
+                    {this.transformEditor}
+                </div> : null}
+            </div> : null}
+
+
+
+
+
+            <div className="propertiesView-fields">
+                <div className="propertiesView-fields-title"
+                    onPointerDown={() => runInAction(() => { this.openFields = !this.openFields; })}
+                    style={{ backgroundColor: this.openFields ? "black" : "" }}>
+                    <div className="propertiesView-fields-title-name">
+                        Fields {"&"} Tags
+                        <div className="propertiesView-fields-title-icon">
+                            <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
+                    </div>
+                </div>
+                {!novice && this.openFields ? <div className="propertiesView-fields-checkbox">
+                    {this.fieldsCheckbox}
+                    <div className="propertiesView-fields-checkbox-text">Layout</div>
+                </div> : null}
+                {this.openFields ?
+                    <div className="propertiesView-fields-content">
+                        {novice ? this.noviceFields : this.expandedField}
+                    </div> : null}
+            </div>
+            <div className="propertiesView-layout">
+                <div className="propertiesView-layout-title"
+                    onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}
+                    style={{ backgroundColor: this.openLayout ? "black" : "" }}>
+                    Layout
+                    <div className="propertiesView-layout-title-icon"
+                        onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}>
+                        <FontAwesomeIcon icon={this.openLayout ? "caret-down" : "caret-right"} size="lg" color="white" />
+                    </div>
+                </div>
+                {this.openLayout ? <div className="propertiesView-layout-content">{this.layoutPreview}</div> : null}
+            </div>
+        </div>;
+    }
+} 
\ No newline at end of file
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index d1c839c3b..0aabf5319 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -182,7 +182,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
         switch (this.props.destinationDoc.type) {
             case DocumentType.IMG: destinationIcon = "image"; break;
             case DocumentType.COMPARISON: destinationIcon = "columns"; break;
-            case DocumentType.RTF: destinationIcon = "font"; break;
+            case DocumentType.RTF: destinationIcon = "sticky-note"; break;
             case DocumentType.COL: destinationIcon = "folder"; break;
             case DocumentType.WEB: destinationIcon = "globe-asia"; break;
             case DocumentType.SCREENSHOT: destinationIcon = "photo-video"; break;
@@ -196,6 +196,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
             case DocumentType.DOCHOLDER: destinationIcon = "expand"; break;
             case DocumentType.VID: destinationIcon = "video"; break;
             case DocumentType.INK: destinationIcon = "pen-nib"; break;
+            case DocumentType.PDF: destinationIcon = "file"; break;
             default: destinationIcon = "question"; break;
         }
 
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 6081def5d..f7e253f42 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -78,6 +78,9 @@ export class ContentFittingDocumentView extends React.Component<DocumentViewProp
 
     render() {
         TraceMobx();
+        if (this.props.Document.title === "Archive") {
+            console.log("");
+        }
         return (<div className="contentFittingDocumentView" style={{
             width: Math.abs(this.centeringYOffset) > 0.001 ? "auto" : this.props.PanelWidth(),
             height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight(),
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index e8173d103..e3f258b8d 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -18,6 +18,7 @@ import { DocHolderBox } from "./DocHolderBox";
 import { DocumentViewProps } from "./DocumentView";
 import "./DocumentView.scss";
 import { FontIconBox } from "./FontIconBox";
+import { MenuIconBox } from "./MenuIconBox";
 import { FieldView, FieldViewProps } from "./FieldView";
 import { FormattedTextBox } from "./formattedText/FormattedTextBox";
 import { ImageBox } from "./ImageBox";
@@ -189,7 +190,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
                 blacklistedAttrs={[]}
                 renderInWrapper={false}
                 components={{
-                    FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, LabelBox, SliderBox, FieldView,
+                    FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, MenuIconBox, LabelBox, SliderBox, FieldView,
                     CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
                     PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, QueryBox,
                     ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, DocHolderBox, LinkBox, ScriptingBox,
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 3b91ac6b5..198a90225 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -198,8 +198,11 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
             // }))} 
             >
 
+                {/* {this.props.InMenu ? this.props.StartLink ? <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" /> :
+                    <FontAwesomeIcon className="documentdecorations-icon" icon="hand-paper" size="sm" /> : links.length} */}
+
                 {this.props.InMenu ? this.props.StartLink ? <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" /> :
-                    <FontAwesomeIcon className="documentdecorations-icon" icon="hand-paper" size="sm" /> : links.length}
+                    link : links.length}
 
             </div>
             {DocumentLinksButton.StartLink && this.props.InMenu && !!!this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index b3bfadf4f..22a2bb8fe 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -94,6 +94,8 @@ export interface DocumentViewProps {
     layoutKey?: string;
     radialMenu?: String[];
     display?: string;
+    relative?: boolean;
+    scriptContext?: any;
 }
 
 @observer
@@ -287,7 +289,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 
     onClick = action((e: React.MouseEvent | React.PointerEvent) => {
-        if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick &&
+        if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && this.props.renderDepth >= 0 &&
             (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) {
             let stopPropagate = true;
             let preventDefault = true;
@@ -319,10 +321,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 const func = () => this.onClickHandler.script.run({
                     this: this.layoutDoc,
                     self: this.rootDoc,
+                    scriptContext: this.props.scriptContext,
                     thisContainer: this.props.ContainingCollectionDoc,
                     shiftKey: e.shiftKey
                 }, console.log);
-                if (this.props.Document !== Doc.UserDoc()["dockedBtn-undo"] && this.props.Document !== Doc.UserDoc()["dockedBtn-redo"]) {
+                if (!Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()["dockedBtn-undo"] as Doc) && !Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()["dockedBtn-redo"] as Doc)) {
                     UndoManager.RunInBatch(func, "on click");
                 } else func();
             } else if (this.Document["onClick-rawScript"] && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) {// bcz: hack? don't edit a script if you're clicking on a scripting box itself
@@ -584,6 +587,18 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
     }
 
+
+    @undoBatch
+    noOnClick = (): void => {
+        this.Document.ignoreClick = false;
+        this.Document.isLinkButton = false;
+    }
+
+    @undoBatch
+    toggleDetail = (): void => {
+        this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`);
+    }
+
     @undoBatch @action
     drop = async (e: Event, de: DragManager.DropEvent) => {
         if (this.props.Document === Doc.UserDoc().activeWorkspace) {
@@ -660,6 +675,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
     }
 
+    @action
+    onCopy = () => {
+        const copy = Doc.MakeCopy(this.props.Document, true);
+        copy.x = NumCast(this.props.Document.x) + NumCast(this.props.Document._width);
+        copy.y = NumCast(this.props.Document.y) + 30;
+        this.props.addDocument?.(copy);
+    }
+
     @action
     onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => {
         // the touch onContextMenu is button 0, the pointer onContextMenu is button 2
@@ -704,14 +727,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const existingOnClick = cm.findByDescription("OnClick...");
         const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
         onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
-        onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "window-restore" });
+        onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "concierge-bell" });
         onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" });
-        onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "concierge-bell" });
-        !this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("onRight", false, false), icon: "concierge-bell" });
-        onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: () => this.toggleFollowLink(undefined, false, false), icon: "concierge-bell" });
-        onClicks.push({ description: (this.Document.isPushpin ? "Remove" : "Make") + " Pushpin", event: () => this.toggleFollowLink(undefined, false, true), icon: "snowflake" });
-        onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" });
-        !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, addDivider: true, subitems: onClicks, icon: "hand-point-right" });
+        onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "link" });
+        !this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("onRight", false, false), icon: "link" });
+        onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: () => this.toggleFollowLink(undefined, false, false), icon: "link" });
+        onClicks.push({ description: (this.Document.isPushpin ? "Remove" : "Make") + " Pushpin", event: () => this.toggleFollowLink(undefined, false, true), icon: "map-pin" });
+        onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "terminal" });
+        !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, addDivider: true, subitems: onClicks, icon: "mouse-pointer" });
 
         const funcs: ContextMenuProps[] = [];
         if (this.layoutDoc.onDragStart) {
@@ -724,6 +747,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const more = cm.findByDescription("More...");
         const moreItems = more && "subitems" in more ? more.subitems : [];
         moreItems.push({ description: "Download document", icon: "download", event: async () => Doc.Zip(this.props.Document) });
+        moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "users" });
+        //moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
+        moreItems.push({ description: "Create an Alias", event: () => this.onCopy(), icon: "copy" });
         if (!Doc.UserDoc().noviceMode) {
             moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
             moreItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
@@ -735,16 +761,18 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             }
             moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" });
         }
+        //GetEffectiveAcl(this.props.Document) === AclEdit && moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" });
+
         const effectiveAcl = GetEffectiveAcl(this.props.Document);
         (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) && moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" });
-        moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "external-link-alt" });
+
         !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
         cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!);
 
         const help = cm.findByDescription("Help...");
         const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : [];
+        !Doc.UserDoc().novice && helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" });
         helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" });
-        helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" });
         helpItems.push({ description: "Print Document in Console", event: () => console.log(this.props.Document), icon: "hand-point-right" });
         cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" });
 
@@ -786,8 +814,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling());
     @computed.struct get linkOffset() { return [-15, 0]; }
     @computed get contents() {
+        const pos = this.props.relative ? "relative " : "absolute";
         TraceMobx();
-        return (<div style={{ position: "absolute", width: "100%", height: "100%" }}>
+        return (<div style={{ width: "100%", height: "100%" }}>
             <DocumentContentsView key={1}
                 docFilters={this.props.docFilters}
                 ContainingCollectionView={this.props.ContainingCollectionView}
@@ -823,6 +852,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 ChromeHeight={this.chromeHeight}
                 isSelected={this.isSelected}
                 select={this.select}
+                scriptContext={this.props.scriptContext}
                 onClick={this.onClickFunc}
                 layoutKey={this.finalLayoutKey} />
             {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors}
@@ -877,8 +907,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
     @computed get innards() {
         TraceMobx();
+        const pos = this.props.relative ? "relative" : undefined;
         if (this.props.treeViewDoc && !this.props.LayoutTemplateString?.includes("LinkAnchorBox")) {  // this happens when the document is a tree view label (but not an anchor dot)
-            return <div className="documentView-treeView" style={{ maxWidth: this.props.PanelWidth() || undefined }}>
+            return <div className="documentView-treeView" style={{
+                maxWidth: this.props.PanelWidth() || undefined,
+                position: pos
+            }}>
                 {StrCast(this.props.Document.title)}
                 {this.allAnchors}
             </div>;
@@ -1003,7 +1037,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 background: finalColor,
                 opacity: finalOpacity,
                 fontFamily: StrCast(this.Document._fontFamily, "inherit"),
-                fontSize: Cast(this.Document._fontSize, "string", null)
+                fontSize: Cast(this.Document._fontSize, "string", null),
             }}>
             {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <>
                 {this.innards}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 5d5bc1d73..1b4151bd8 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -61,6 +61,7 @@ export interface FieldViewProps {
     color?: string;
     xMargin?: number;
     yMargin?: number;
+    scriptContext?: any;
 }
 
 @observer
diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss
index 5b85d8b0b..69c835318 100644
--- a/src/client/views/nodes/FontIconBox.scss
+++ b/src/client/views/nodes/FontIconBox.scss
@@ -16,7 +16,7 @@
         position: absolute;
         text-align: center;
         font-size: 8px;
-        margin-top:4px;
+        //margin-top:4px;
         letter-spacing: normal;
         left: 0;
         overflow: hidden;
diff --git a/src/client/views/nodes/MenuIconBox.scss b/src/client/views/nodes/MenuIconBox.scss
new file mode 100644
index 000000000..1b72f5a8f
--- /dev/null
+++ b/src/client/views/nodes/MenuIconBox.scss
@@ -0,0 +1,49 @@
+.menuButton {
+    //padding: 7px;
+    padding-left: 7px;
+    width: 100%;
+    width: 60px;
+    height: 70px;
+
+    .menuButton-wrap {
+        width: 45px;
+        /* padding: 5px; */
+        touch-action: none;
+        background: black;
+        transform-origin: top left;
+        /* margin-bottom: 5px; */
+        margin-top: 5px;
+        margin-right: 25px;
+        border-radius: 8px;
+
+        &:hover {
+            background: rgb(61, 61, 61);
+            cursor: pointer;
+        }
+    }
+
+    .menuButton-label {
+        color: white;
+        margin-right: 4px;
+        border-radius: 8px;
+        width: 42px;
+        position: relative;
+        text-align: center;
+        font-size: 8px;
+        margin-top: 1px;
+        letter-spacing: normal;
+        padding: 3px;
+        background-color: inherit;
+    }
+
+    .menuButton-icon {
+        width: auto;
+        height: 35px;
+        padding: 5px;
+    }
+
+    svg {
+        width: 95% !important;
+        height: 95%;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/MenuIconBox.tsx b/src/client/views/nodes/MenuIconBox.tsx
new file mode 100644
index 000000000..0aa7b327e
--- /dev/null
+++ b/src/client/views/nodes/MenuIconBox.tsx
@@ -0,0 +1,33 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { createSchema, makeInterface } from '../../../fields/Schema';
+import { StrCast } from '../../../fields/Types';
+import { DocComponent } from '../DocComponent';
+import { FieldView, FieldViewProps } from './FieldView';
+import './MenuIconBox.scss';
+const MenuIconSchema = createSchema({
+    icon: "string"
+});
+
+type MenuIconDocument = makeInterface<[typeof MenuIconSchema]>;
+const MenuIconDocument = makeInterface(MenuIconSchema);
+@observer
+export class MenuIconBox extends DocComponent<FieldViewProps, MenuIconDocument>(MenuIconDocument) {
+    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(MenuIconBox, fieldKey); }
+    _ref: React.RefObject<HTMLButtonElement> = React.createRef();
+
+    render() {
+
+        const color = this.props.backgroundColor?.(this.props.Document) === "lightgrey" ? "black" : "white";
+        const menuBTN = <div className="menuButton" style={{ backgroundColor: this.props.backgroundColor?.(this.props.Document) }}>
+            <div className="menuButton-wrap"
+                style={{ backgroundColor: this.props.backgroundColor?.(this.props.Document) }} >
+                <FontAwesomeIcon className="menuButton-icon" icon={StrCast(this.dataDoc.icon, "user") as any} color={color} size="lg" />
+                <div className="menuButton-label" style={{ color: color }}> {this.dataDoc.title} </div>
+            </div>
+        </div>;
+
+        return menuBTN;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index c04c6c409..97f223c02 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -32,6 +32,7 @@ import { conformsTo } from "lodash";
 import { translate } from "googleapis/build/src/apis/translate";
 import { DragManager, dropActionType } from "../../util/DragManager";
 import { actionAsync } from "mobx-utils";
+import { SelectionManager } from "../../util/SelectionManager";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -260,7 +261,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         const srcContext = await DocCastAsync(targetDoc.context);
         const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
-        const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined;
+        const collectionDocView = presCollection ? await DocumentManager.Instance.getDocumentView(presCollection) : undefined;
         if (this.itemIndex >= 0) {
             if (targetDoc) {
                 if (srcContext) this.layoutDoc.presCollection = srcContext;
@@ -496,6 +497,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     selectElement = (doc: Doc) => {
         // this._selectedArray = [];
         this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex));
+        const view = DocumentManager.Instance.getDocumentView(doc);
+        view && SelectionManager.SelectDoc(view, false);
         // this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
         // console.log(this._selectedArray);
     }
@@ -504,8 +507,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @action
     multiSelect = (doc: Doc, ref: HTMLElement) => {
         this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
-        const ele = ref.getElementsByClassName("stacking");
         this._eleArray.push(ref);
+        const view = DocumentManager.Instance.getDocumentView(doc);
+        view && SelectionManager.SelectDoc(view, true);
     }
 
     //Shift click
@@ -517,6 +521,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) {
                 this._selectedArray.push(this.childDocs[i]);
                 this._eleArray.push(ref);
+                const view = DocumentManager.Instance.getDocumentView(doc);
+                view && SelectionManager.SelectDoc(view, true);
             }
         }
     }
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 958a37568..8ae71c035 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -190,7 +190,7 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
             }
             list.map(c => c.heading).indexOf(this._fieldKey) === -1 && list.push(new SchemaHeaderField(this._fieldKey, "#f1efeb"));
             list.map(c => c.heading).indexOf("text") === -1 && list.push(new SchemaHeaderField("text", "#f1efeb"));
-            alias._pivotField = this._fieldKey;
+            alias._pivotField = this._fieldKey.startsWith("#") ? "#" : this._fieldKey;
             this.props.tbox.props.addDocTab(alias, "onRight");
         }
     }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 627c6e363..fc65f34eb 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1267,7 +1267,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         this.doLinkOnDeselect();
 
         // move the richtextmenu offscreen
-        if (!RichTextMenu.Instance.Pinned) RichTextMenu.Instance.delayHide();
+        //if (!RichTextMenu.Instance.Pinned) RichTextMenu.Instance.delayHide();
     }
 
     _lastTimedMark: Mark | undefined = undefined;
@@ -1346,7 +1346,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
     render() {
         TraceMobx();
-        const scale = this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
+        const scale = this.props.hideOnLeave ? 1 : this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
         const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
         const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground;
         setTimeout(() => this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props), this.props.isSelected() ? 10 : 0); // need to make sure that we update a text box that is selected after updating the one that was deselected
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 7ccbfa051..f76707a79 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -77,7 +77,8 @@ export default class RichTextMenu extends AntimodeMenu {
         super(props);
         RichTextMenu.Instance = this;
         this._canFade = false;
-        this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]);
+        //this.Pinned = BoolCast(Doc.UserDoc()["menuRichText-pinned"]);
+        this.Pinned = true;
 
         this.fontSizeOptions = [
             { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize },
@@ -529,7 +530,7 @@ export default class RichTextMenu extends AntimodeMenu {
 
     indentParagraph(state: EditorState<any>, dispatch: any) {
         var tr = state.tr;
-        let headin = false;
+        const heading = false;
         state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
             if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
                 const nodeval = node.attrs.indent ? Number(node.attrs.indent) : undefined;
@@ -539,7 +540,7 @@ export default class RichTextMenu extends AntimodeMenu {
             }
             return true;
         });
-        !headin && dispatch?.(tr);
+        !heading && dispatch?.(tr);
         return true;
     }
 
@@ -920,16 +921,22 @@ export default class RichTextMenu extends AntimodeMenu {
     render() {
         TraceMobx();
         const row1 = <div className="antimodeMenu-row" key="row 1" style={{ display: this.collapsed ? "none" : undefined }}>{[
-            !this.collapsed ? this.getDragger() : (null),
-            !this.Pinned ? (null) : <div key="frag1"> {[
-                this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)),
-                this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)),
-                this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)),
-                this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)),
-                this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)),
-                this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)),
-                <div className="richTextMenu-divider" key="divider" />
-            ]}</div>,
+            //!this.collapsed ? this.getDragger() : (null),
+            // !this.Pinned ? (null) : <div key="frag1"> {[
+            //     this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)),
+            //     this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)),
+            //     this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)),
+            //     this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)),
+            //     this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)),
+            //     this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)),
+            //     <div className="richTextMenu-divider" key="divider" />
+            // ]}</div>,
+            this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)),
+            this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)),
+            this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)),
+            this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)),
+            this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)),
+            this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)),
             this.createColorButton(),
             this.createHighlighterButton(),
             this.createLinkButton(),
@@ -957,16 +964,16 @@ export default class RichTextMenu extends AntimodeMenu {
                 this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule),
                 <div className="richTextMenu-divider" key="divider 5" />,]}
             </div>
-            <div key="collapser">
-                {/* <div key="collapser">
+            {/* <div key="collapser">
+                {<div key="collapser">
                     <button className="antimodeMenu-button" key="collapse menu" title="Collapse menu" onClick={this.toggleCollapse} style={{ backgroundColor: this.collapsed ? "#121212" : "", width: 25 }}>
                         <FontAwesomeIcon icon="chevron-left" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.3s", transform: `rotate(${this.collapsed ? 180 : 0}deg)` }} />
                     </button>
-                </div> */}
+                </div> }
                 <button className="antimodeMenu-button" key="pin menu" title="Pin menu" onClick={this.toggleMenuPin} style={{ backgroundColor: this.Pinned ? "#121212" : "", display: this.collapsed ? "none" : undefined }}>
                     <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
                 </button>
-            </div>
+            </div> */}
         </div>;
 
         return (
diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts
index 0eca6d753..1616500f6 100644
--- a/src/client/views/nodes/formattedText/nodes_rts.ts
+++ b/src/client/views/nodes/formattedText/nodes_rts.ts
@@ -79,14 +79,14 @@ export const nodes: { [index: string]: NodeSpec } = {
         { tag: "h5", attrs: { level: 5 } },
         { tag: "h6", attrs: { level: 6 } }],
         toDOM(node) {
-            var dom = toParagraphDOM(node) as any;
-            var level = node.attrs.level || 1;
+            const dom = toParagraphDOM(node) as any;
+            const level = node.attrs.level || 1;
             dom[0] = 'h' + level;
             return dom;
         },
         getAttrs(dom: any) {
-            var attrs = getParagraphNodeAttrs(dom) as any;
-            var level = Number(dom.nodeName.substring(1)) || 1;
+            const attrs = getParagraphNodeAttrs(dom) as any;
+            const level = Number(dom.nodeName.substring(1)) || 1;
             attrs.level = level;
             return attrs;
         }
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 43e74ff61..85fc63074 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -528,10 +528,10 @@ export namespace Doc {
             const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
             const field = ProxyField.WithoutProxy(() => doc[key]);
             const copyObjectField = async (field: ObjectField) => {
-                const list = await Cast(doc[key], listSpec(Doc));
+                const list = Cast(doc[key], listSpec(Doc));
                 const docs = list && (await DocListCastAsync(list))?.filter(d => d instanceof Doc);
                 if (docs !== undefined && docs.length) {
-                    const clones = await Promise.all(docs.map(async d => await Doc.makeClone(d as Doc, cloneMap, rtfs, exclusions, dontCreate)));
+                    const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, rtfs, exclusions, dontCreate)));
                     !dontCreate && assignKey(new List<Doc>(clones));
                 } else if (doc[key] instanceof Doc) {
                     assignKey(key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, rtfs, exclusions, dontCreate)); // reference documents except copy documents that are expanded teplate fields 
@@ -625,7 +625,7 @@ export namespace Doc {
         Array.from(map.entries()).forEach(f => docs[f[0]] = f[1]);
         const docString = JSON.stringify({ id: doc[Id], docs }, replacer);
 
-        var zip = new JSZip();
+        const zip = new JSZip();
 
         zip.file(doc.title + ".json", docString);
 
diff --git a/src/server/ActionUtilities.ts b/src/server/ActionUtilities.ts
index 60f66c878..fd9bc0c83 100644
--- a/src/server/ActionUtilities.ts
+++ b/src/server/ActionUtilities.ts
@@ -1,11 +1,11 @@
-import { readFile, writeFile, exists, mkdir, unlink, createWriteStream } from 'fs';
-import { ExecOptions } from 'shelljs';
 import { exec } from 'child_process';
-import * as path from 'path';
-import * as rimraf from "rimraf";
-import { yellow, Color } from 'colors';
+import { Color, yellow } from 'colors';
+import { createWriteStream, exists, mkdir, readFile, unlink, writeFile } from 'fs';
 import * as nodemailer from "nodemailer";
 import { MailOptions } from "nodemailer/lib/json-transport";
+import * as path from 'path';
+import * as rimraf from "rimraf";
+import { ExecOptions } from 'shelljs';
 import Mail = require('nodemailer/lib/mailer');
 
 const projectRoot = path.resolve(__dirname, "../../");
diff --git a/src/server/ApiManagers/UtilManager.ts b/src/server/ApiManagers/UtilManager.ts
index e2cd88726..e657866ce 100644
--- a/src/server/ApiManagers/UtilManager.ts
+++ b/src/server/ApiManagers/UtilManager.ts
@@ -6,7 +6,6 @@ import { exec } from 'child_process';
 
 // const recommender = new Recommender();
 // recommender.testModel();
-import executeImport from "../../scraping/buxton/final/BuxtonImporter";
 
 export default class UtilManager extends ApiManager {
 
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 2bf4c1956..890fb6f6d 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -1,23 +1,22 @@
-import { unlinkSync, createWriteStream, readFileSync, rename, writeFile, existsSync } from 'fs';
-import { Utils } from '../Utils';
-import * as path from 'path';
-import * as sharp from 'sharp';
-import request = require('request-promise');
+import { red } from 'colors';
 import { ExifImage } from 'exif';
-import { Opt } from '../fields/Doc';
-import { AcceptibleMedia, Upload } from './SharedMediaTypes';
-import { filesDirectory, publicDirectory } from '.';
 import { File } from 'formidable';
+import { createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs';
+import * as path from 'path';
 import { basename } from "path";
-import { createIfNotExists } from './ActionUtilities';
+import * as sharp from 'sharp';
+import { Stream } from 'stream';
+import { filesDirectory, publicDirectory } from '.';
+import { Opt } from '../fields/Doc';
 import { ParsedPDF } from "../server/PdfTypes";
+import { Utils } from '../Utils';
+import { createIfNotExists } from './ActionUtilities';
+import { clientPathToFile, Directory, pathToDirectory, serverPathToFile } from './ApiManagers/UploadManager';
+import { resolvedServerUrl } from "./server_Initialization";
+import { AcceptibleMedia, Upload } from './SharedMediaTypes';
+import request = require('request-promise');
 const parse = require('pdf-parse');
-import { Directory, serverPathToFile, clientPathToFile, pathToDirectory } from './ApiManagers/UploadManager';
-import { red } from 'colors';
-import { Stream } from 'stream';
-import { resolvedPorts } from './server_Initialization';
 const requestImageSize = require("../client/util/request-image-size");
-import { resolvedServerUrl } from "./server_Initialization";
 
 export enum SizeSuffix {
     Small = "_s",
diff --git a/src/server/GarbageCollector.ts b/src/server/GarbageCollector.ts
index 24745cbb4..a9a3b0481 100644
--- a/src/server/GarbageCollector.ts
+++ b/src/server/GarbageCollector.ts
@@ -1,9 +1,9 @@
-import { Database } from './database';
-
-import * as path from 'path';
 import * as fs from 'fs';
+import * as path from 'path';
+import { Database } from './database';
 import { Search } from './Search';
 
+
 function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) {
     for (const key in doc) {
         if (!doc.hasOwnProperty(key)) {
diff --git a/src/server/MemoryDatabase.ts b/src/server/MemoryDatabase.ts
index 1f1d702d9..7f477327e 100644
--- a/src/server/MemoryDatabase.ts
+++ b/src/server/MemoryDatabase.ts
@@ -1,6 +1,7 @@
-import { IDatabase, DocumentsCollection } from './IDatabase';
-import { Transferable } from './Message';
+import { DH_CHECK_P_NOT_SAFE_PRIME } from 'constants';
 import * as mongodb from 'mongodb';
+import { DocumentsCollection, IDatabase } from './IDatabase';
+import { Transferable } from './Message';
 
 export class MemoryDatabase implements IDatabase {
 
diff --git a/src/server/Message.ts b/src/server/Message.ts
index ff0381fd3..59b24cd82 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -1,6 +1,6 @@
-import { Utils } from "../Utils";
 import { Point } from "../pen-gestures/ndollar";
 import { AnalysisResult, ImportResults } from "../scraping/buxton/final/BuxtonImporter";
+import { Utils } from "../Utils";
 
 export class Message<T> {
     private _name: string;
diff --git a/src/server/ProcessFactory.ts b/src/server/ProcessFactory.ts
index acb8b3a99..63682368f 100644
--- a/src/server/ProcessFactory.ts
+++ b/src/server/ProcessFactory.ts
@@ -1,8 +1,8 @@
-import { existsSync, mkdirSync } from "fs";
-import { pathFromRoot, fileDescriptorFromStream } from './ActionUtilities';
-import rimraf = require("rimraf");
 import { ChildProcess, spawn, StdioOptions } from "child_process";
+import { existsSync, mkdirSync } from "fs";
 import { Stream } from "stream";
+import { fileDescriptorFromStream, pathFromRoot } from './ActionUtilities';
+import rimraf = require("rimraf");
 
 export namespace ProcessFactory {
 
diff --git a/src/server/Recommender.ts b/src/server/Recommender.ts
deleted file mode 100644
index 935ec3871..000000000
--- a/src/server/Recommender.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-// //import { Doc } from "../fields/Doc";
-// //import { StrCast } from "../fields/Types";
-// //import { List } from "../fields/List";
-// //import { CognitiveServices } from "../client/cognitive_services/CognitiveServices";
-
-// // var w2v = require('word2vec');
-// var assert = require('assert');
-// var arxivapi = require('arxiv-api-node');
-// import requestPromise = require("request-promise");
-// import * as use from '@tensorflow-models/universal-sentence-encoder';
-// import { Tensor } from "@tensorflow/tfjs-core/dist/tensor";
-// require('@tensorflow/tfjs-node');
-
-// //http://gnuwin32.sourceforge.net/packages/make.htm
-
-// export class Recommender {
-
-//     private _model: any;
-//     static Instance: Recommender;
-//     private dimension: number = 0;
-//     private choice: string = ""; // Tensorflow or Word2Vec
-
-//     constructor() {
-//         Recommender.Instance = this;
-//     }
-
-//     /***
-//      * Loads pre-trained model from TF
-//      */
-
-//     public async loadTFModel() {
-//         let self = this;
-//         return new Promise(res => {
-//             use.load().then(model => {
-//                 self.choice = "TF";
-//                 self._model = model;
-//                 self.dimension = 512;
-//                 res(model);
-//             });
-//         }
-
-//         );
-//     }
-
-//     /***
-//      * Loads pre-trained model from word2vec
-//      */
-
-//     // private loadModel(): Promise<any> {
-//     //     let self = this;
-//     //     return new Promise(res => {
-//     //         w2v.loadModel("./node_modules/word2vec/examples/fixtures/vectors.txt", function (err: any, model: any) {
-//     //             self.choice = "WV";
-//     //             self._model = model;
-//     //             self.dimension = model.size;
-//     //             res(model);
-//     //         });
-//     //     });
-//     // }
-
-//     /***
-//      * Testing
-//      */
-
-//     public async testModel() {
-//         if (!this._model) {
-//             await this.loadTFModel();
-//         }
-//         if (this._model) {
-//             if (this.choice === "WV") {
-//                 let similarity = this._model.similarity('father', 'mother');
-//             }
-//             else if (this.choice === "TF") {
-//                 const model = this._model as use.UniversalSentenceEncoder;
-//                 // Embed an array of sentences.
-//                 const sentences = [
-//                     'Hello.',
-//                     'How are you?'
-//                 ];
-//                 const embeddings = await this.vectorize(sentences);
-//                 if (embeddings) embeddings.print(true /*verbose*/);
-//                 // model.embed(sentences).then(embeddings => {
-//                 //     // `embeddings` is a 2D tensor consisting of the 512-dimensional embeddings for each sentence.
-//                 //     // So in this example `embeddings` has the shape [2, 512].
-//                 //     embeddings.print(true /* verbose */);
-//                 // });
-//             }
-//         }
-//         else {
-//             console.log("model not found :(");
-//         }
-//     }
-
-//     /***
-//      * Uses model to convert words to vectors
-//      */
-
-//     public async vectorize(text: string[]): Promise<Tensor | undefined> {
-//         if (!this._model) {
-//             await this.loadTFModel();
-//         }
-//         if (this._model) {
-//             if (this.choice === "WV") {
-//                 let word_vecs = this._model.getVectors(text);
-//                 return word_vecs;
-//             }
-//             else if (this.choice === "TF") {
-//                 const model = this._model as use.UniversalSentenceEncoder;
-//                 return new Promise<Tensor>(res => {
-//                     model.embed(text).then(embeddings => {
-//                         res(embeddings);
-//                     });
-//                 });
-
-//             }
-//         }
-//     }
-
-//     // public async trainModel() {
-//     //     w2v.word2vec("./node_modules/word2vec/examples/eng_news-typical_2016_1M-sentences.txt", './node_modules/word2vec/examples/my_phrases.txt', {
-//     //         cbow: 1,
-//     //         size: 200,
-//     //         window: 8,
-//     //         negative: 25,
-//     //         hs: 0,
-//     //         sample: 1e-4,
-//     //         threads: 20,
-//     //         iter: 200,
-//     //         minCount: 2
-//     //     });
-//     // }
-
-// }
diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts
index 1a2340afc..78b75d6be 100644
--- a/src/server/RouteManager.ts
+++ b/src/server/RouteManager.ts
@@ -1,8 +1,8 @@
-import RouteSubscriber from "./RouteSubscriber";
-import { DashUserModel } from "./authentication/DashUserModel";
-import { Request, Response, Express } from 'express';
-import { cyan, red, green } from 'colors';
+import { cyan, green, red } from 'colors';
+import { Express, Request, Response } from 'express';
 import { AdminPriviliges } from ".";
+import { DashUserModel } from "./authentication/DashUserModel";
+import RouteSubscriber from "./RouteSubscriber";
 
 export enum Method {
     GET,
diff --git a/src/server/Search.ts b/src/server/Search.ts
index 21064e520..decd1f5b1 100644
--- a/src/server/Search.ts
+++ b/src/server/Search.ts
@@ -1,5 +1,5 @@
-import * as rp from 'request-promise';
 import { red } from 'colors';
+import * as rp from 'request-promise';
 
 const pathTo = (relative: string) => `http://localhost:8983/solr/dash/${relative}`;
 
diff --git a/src/server/database.ts b/src/server/database.ts
index 2372cbcf2..b7aa77f5d 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -1,11 +1,11 @@
 import * as mongodb from 'mongodb';
-import { Transferable } from './Message';
+import * as mongoose from 'mongoose';
 import { Opt } from '../fields/Doc';
-import { Utils, emptyFunction } from '../Utils';
+import { emptyFunction, Utils } from '../Utils';
 import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils';
-import { IDatabase, DocumentsCollection } from './IDatabase';
+import { DocumentsCollection, IDatabase } from './IDatabase';
 import { MemoryDatabase } from './MemoryDatabase';
-import * as mongoose from 'mongoose';
+import { Transferable } from './Message';
 import { Upload } from './SharedMediaTypes';
 
 export namespace Database {
diff --git a/src/server/downsize.ts b/src/server/downsize.ts
index 5cd709fa3..382994e2d 100644
--- a/src/server/downsize.ts
+++ b/src/server/downsize.ts
@@ -1,5 +1,5 @@
-import * as sharp from 'sharp';
 import * as fs from 'fs';
+import * as sharp from 'sharp';
 
 const folder = "./src/server/public/files/";
 const pngTypes = ["png", "PNG"];
diff --git a/src/server/index.ts b/src/server/index.ts
index 9af4b00bc..9185e3c5e 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -1,29 +1,29 @@
 require('dotenv').config();
-import { GoogleApiServerUtils } from "./apis/google/GoogleApiServerUtils";
+import { yellow } from "colors";
 import * as mobileDetect from 'mobile-detect';
 import * as path from 'path';
-import { Database } from './database';
-import { DashUploadUtils } from './DashUploadUtils';
-import RouteSubscriber from './RouteSubscriber';
-import initializeServer, { resolvedPorts } from './server_Initialization';
-import RouteManager, { Method, _success, _permission_denied, _error, _invalid, PublicHandler } from './RouteManager';
 import * as qs from 'query-string';
-import UtilManager from './ApiManagers/UtilManager';
-import { SearchManager } from './ApiManagers/SearchManager';
-import UserManager from './ApiManagers/UserManager';
-import DownloadManager from './ApiManagers/DownloadManager';
-import { GoogleCredentialsLoader, SSL } from './apis/google/CredentialsLoader';
-import DeleteManager from "./ApiManagers/DeleteManager";
-import PDFManager from "./ApiManagers/PDFManager";
-import UploadManager from "./ApiManagers/UploadManager";
 import { log_execution } from "./ActionUtilities";
+import DeleteManager from "./ApiManagers/DeleteManager";
+import DownloadManager from './ApiManagers/DownloadManager';
 import GeneralGoogleManager from "./ApiManagers/GeneralGoogleManager";
-import HypothesisManager from "./ApiManagers/HypothesisManager";
 import GooglePhotosManager from "./ApiManagers/GooglePhotosManager";
-import { Logger } from "./ProcessFactory";
-import { yellow } from "colors";
+import HypothesisManager from "./ApiManagers/HypothesisManager";
+import PDFManager from "./ApiManagers/PDFManager";
+import { SearchManager } from './ApiManagers/SearchManager';
 import SessionManager from "./ApiManagers/SessionManager";
+import UploadManager from "./ApiManagers/UploadManager";
+import UserManager from './ApiManagers/UserManager';
+import UtilManager from './ApiManagers/UtilManager';
+import { GoogleCredentialsLoader, SSL } from './apis/google/CredentialsLoader';
+import { GoogleApiServerUtils } from "./apis/google/GoogleApiServerUtils";
 import { AppliedSessionAgent } from "./DashSession/Session/agents/applied_session_agent";
+import { DashUploadUtils } from './DashUploadUtils';
+import { Database } from './database';
+import { Logger } from "./ProcessFactory";
+import RouteManager, { Method, PublicHandler } from './RouteManager';
+import RouteSubscriber from './RouteSubscriber';
+import initializeServer, { resolvedPorts } from './server_Initialization';
 
 export const AdminPriviliges: Map<string, boolean> = new Map();
 export const onWindows = process.platform === "win32";
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index 744d4547b..e40f2b8e5 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -1,31 +1,31 @@
+import * as bodyParser from 'body-parser';
+import { blue, yellow } from 'colors';
+import * as cookieParser from 'cookie-parser';
+import * as cors from "cors";
 import * as express from 'express';
-import * as expressValidator from 'express-validator';
 import * as session from 'express-session';
+import * as expressValidator from 'express-validator';
+import * as fs from 'fs';
+import { Server as HttpServer } from "http";
+import { createServer, Server as HttpsServer } from "https";
 import * as passport from 'passport';
-import * as bodyParser from 'body-parser';
-import * as cookieParser from 'cookie-parser';
-import expressFlash = require('express-flash');
-import flash = require('connect-flash');
-import { Database } from './database';
-import { getForgot, getLogin, getLogout, getReset, getSignup, postForgot, postLogin, postReset, postSignup } from './authentication/AuthenticationManager';
-const MongoStore = require('connect-mongo')(session);
-import RouteManager from './RouteManager';
-import { WebSocket } from './websocket';
+import * as request from 'request';
 import * as webpack from 'webpack';
-const config = require('../../webpack.config');
-const compiler = webpack(config);
 import * as wdm from 'webpack-dev-middleware';
 import * as whm from 'webpack-hot-middleware';
-import * as fs from 'fs';
-import * as request from 'request';
-import RouteSubscriber from './RouteSubscriber';
 import { publicDirectory } from '.';
 import { logPort } from './ActionUtilities';
-import { blue, yellow } from 'colors';
-import * as cors from "cors";
-import { createServer, Server as HttpsServer } from "https";
-import { Server as HttpServer } from "http";
 import { SSL } from './apis/google/CredentialsLoader';
+import { getForgot, getLogin, getLogout, getReset, getSignup, postForgot, postLogin, postReset, postSignup } from './authentication/AuthenticationManager';
+import { Database } from './database';
+import RouteManager from './RouteManager';
+import RouteSubscriber from './RouteSubscriber';
+import { WebSocket } from './websocket';
+import expressFlash = require('express-flash');
+import flash = require('connect-flash');
+const MongoStore = require('connect-mongo')(session);
+const config = require('../../webpack.config');
+const compiler = webpack(config);
 
 /* RouteSetter is a wrapper around the server that prevents the server
    from being exposed. */
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index f63a35e43..d5f89a750 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -1,21 +1,20 @@
-import * as fs from 'fs';
-import { logPort } from './ActionUtilities';
-import { Utils } from "../Utils";
-import { MessageStore, Transferable, Types, Diff, YoutubeQueryInput, YoutubeQueryTypes, GestureContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, MobileDocumentUploadContent, RoomMessage } from "./Message";
-import { Client } from "./Client";
-import { Socket } from "socket.io";
-import { Database } from "./database";
-import { Search } from "./Search";
-import * as sio from 'socket.io';
-import YoutubeApi from "./apis/youtube/youtubeApiSample";
-import { GoogleCredentialsLoader, SSL } from "./apis/google/CredentialsLoader";
-import { timeMap } from "./ApiManagers/UserManager";
 import { green } from "colors";
+import * as express from "express";
+import { createServer, Server } from "https";
 import { networkInterfaces } from "os";
+import * as sio from 'socket.io';
+import { Socket } from "socket.io";
 import executeImport from "../scraping/buxton/final/BuxtonImporter";
+import { Utils } from "../Utils";
+import { logPort } from './ActionUtilities';
+import { timeMap } from "./ApiManagers/UserManager";
+import { GoogleCredentialsLoader, SSL } from "./apis/google/CredentialsLoader";
+import YoutubeApi from "./apis/youtube/youtubeApiSample";
+import { Client } from "./Client";
+import { Database } from "./database";
 import { DocumentsCollection } from "./IDatabase";
-import { createServer, Server } from "https";
-import * as express from "express";
+import { Diff, GestureContent, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, Transferable, Types, UpdateMobileInkOverlayPositionContent, YoutubeQueryInput, YoutubeQueryTypes } from "./Message";
+import { Search } from "./Search";
 import { resolvedPorts } from './server_Initialization';
 
 export namespace WebSocket {
-- 
cgit v1.2.3-70-g09d2


From f4c14a48f91ec95b900bb1e25452d18971ff21a8 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Mon, 3 Aug 2020 23:14:20 +0800
Subject: works with selection manager (PropertiesView)

---
 .../collectionFreeForm/PropertiesView.scss         | 42 +++++++++++-----------
 .../collectionFreeForm/PropertiesView.tsx          | 21 +++++++----
 src/client/views/nodes/PresBox.scss                |  2 +-
 src/client/views/nodes/PresBox.tsx                 |  2 +-
 .../views/presentationview/PresElementBox.tsx      |  2 +-
 5 files changed, 39 insertions(+), 30 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index 6283a6669..2cdaa25ee 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -543,6 +543,27 @@
     }
 }
 
+.propertiesView-presSelected {
+    border-top: solid 1px darkgrey;
+    width: 100%;
+    padding-top: 5px;
+    font-family: Roboto;
+    font-weight: 500;
+    display: inline-flex;
+
+    .propertiesView-selectedList {
+        border-left: solid 1px darkgrey;
+        margin-left: 10px;
+        padding-left: 5px;
+
+        .selectedList-items {
+            font-size: 12;
+            font-weight: 300;
+            margin-top: 1;
+        }
+    }
+}
+
 .widthAndDash {
 
     .width {
@@ -617,25 +638,4 @@
             margin-top: 2px;
         }
     }
-
-    .propertiesView-presSelected {
-        border-top: solid 1px darkgrey;
-        width: 100%;
-        padding-top: 5px;
-        font-family: Roboto;
-        font-weight: 500;
-        display: inline-flex;
-
-        .propertiesView-selectedList {
-            border-left: solid 1px darkgrey;
-            margin-left: 10px;
-            padding-left: 5px;
-
-            .selectedList-items {
-                font-size: 12;
-                font-weight: 300;
-                margin-top: 1;
-            }
-        }
-    }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index ce8baf559..88d585596 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -47,9 +47,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     @computed get selectedDocumentView() {
         if (SelectionManager.SelectedDocuments().length) {
             return SelectionManager.SelectedDocuments()[0];
-        } else { console.log(undefined); return undefined; }
+        } else if (PresBox.Instance._selectedArray.length >= 1) {
+            return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
+        } else { return undefined; }
+    }
+    @computed get isPres(): boolean {
+        if (this.selectedDoc?.type === DocumentType.PRES) return true;
+        return false;
     }
-    @computed get isPres() { return this.selectedDoc?.type === DocumentType.PRES }
     @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
     @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; }
 
@@ -748,10 +753,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     render() {
 
         if (!this.selectedDoc) {
-            return <div className="propertiesView" style={{ width: this.props.width }}>
-                <div className="propertiesView-title" style={{ width: this.props.width, paddingLeft: 6 }}>
-                    No Document Selected
-            </div> </div>;
+            console.log("!selectedDoc")
+            if (this.isPres === false) {
+                console.log("!isPres")
+                return <div className="propertiesView" style={{ width: this.props.width }}>
+                    <div className="propertiesView-title" style={{ width: this.props.width, paddingLeft: 6 }}>
+                        No Document Selected
+                </div> </div>;
+            }
         }
 
         const novice = Doc.UserDoc().noviceMode;
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index e5878708f..83e7152a8 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -143,7 +143,7 @@
         display: grid;
         justify-content: flex-start;
         align-items: center;
-        grid-template-columns: repeat(auto-fit, 50px);
+        grid-template-columns: repeat(auto-fit, 70px);
     }
 
     .ribbon-property {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 618161e97..496d4666e 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -832,7 +832,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             </div>
                         </div>
                         <div className="presBox-subheading" style={{ display: effect === 'None' ? "none" : "block" }}>Effect direction</div>
-                        <div className="presBox-reactiveGrid" style={{ display: effect === 'None' ? "none" : "grid", width: 40 }}>
+                        <div className="presBox-reactiveGrid" style={{ display: effect === 'None' ? "none" : "grid" }}>
                             <div className="effectDirection" style={{ display: "grid", width: 40 }}>
                                 <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "left" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'left'}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
                                 <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "right" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'right'}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 85949c5a8..ce7a43315 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -278,7 +278,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     } else if (e.shiftKey) {
                         PresBox.Instance.shiftSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!);
                     } else {
-                        this.props.focus(this.rootDoc);
+                        PresBox.Instance.selectElement(this.rootDoc);
                         PresBox.Instance._eleArray = [];
                         PresBox.Instance._eleArray.push(this._itemRef.current!);
                         PresBox.Instance._dragArray = [];
-- 
cgit v1.2.3-70-g09d2


From f848ef4d6f43f281618b511f8bf1815ef1c63ecc Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Tue, 4 Aug 2020 17:58:50 +0800
Subject: properties view for presentation

---
 .../collectionFreeForm/PropertiesView.scss         |  4 +-
 src/client/views/nodes/PresBox.scss                | 14 ++---
 src/client/views/nodes/PresBox.tsx                 | 59 +++++++++++-----------
 .../views/presentationview/PresElementBox.tsx      |  8 ++-
 4 files changed, 44 insertions(+), 41 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index 2cdaa25ee..f559b940c 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -5,8 +5,8 @@
     font-family: "Noto Sans";
     cursor: auto;
 
-    overflow-x: visible;
-    overflow-y: visible;
+    overflow-x: hidden;
+    overflow-y: scroll;
 
     .propertiesView-title {
         background-color: rgb(159, 159, 159);
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 83e7152a8..45c6d33b8 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -291,7 +291,7 @@
 
     .ribbon-textInput {
         border-radius: 2px;
-        height: 30px;
+        height: 20px;
         font-size: 11.5;
         font-weight: 100;
         align-self: center;
@@ -363,14 +363,14 @@
 
         .ribbon-final-button {
             position: relative;
-            font-size: 11.5;
+            font-size: 11;
             font-weight: normal;
             letter-spacing: normal;
             display: flex;
             justify-content: center;
             align-items: center;
             margin-bottom: 5px;
-            height: 30px;
+            height: 25px;
             color: white;
             width: 100%;
             max-width: 120;
@@ -382,14 +382,14 @@
 
         .ribbon-final-button-hidden {
             position: relative;
-            font-size: 11.5;
+            font-size: 11;
             font-weight: normal;
             letter-spacing: normal;
             display: flex;
             justify-content: center;
             align-items: center;
             margin-bottom: 5px;
-            height: 30px;
+            height: 25px;
             color: lightgrey;
             width: 100%;
             max-width: 120;
@@ -414,9 +414,9 @@
     }
 
     .ribbon-button {
-        font-size: 11;
+        font-size: 10.5;
         font-weight: 200;
-        height: 30;
+        height: 20;
         background-color: #dedede;
         border: solid 1px black;
         display: flex;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 496d4666e..0a73106a3 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -900,22 +900,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                         <div className="ribbon-box">
                             {this.stringType} options
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.VID ? "inline-flex" : "none" }}>
-                                <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Child documents</div>
-                                <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "flex" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Edit</div>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.AUDIO ? "inline-flex" : "none" }}>
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Start automatically</div>
+                                <div className="ribbon-button" style={{ display: "flex", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Start manually</div>
                             </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
-                                <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Internal zoom</div>
-                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Viewfinder</div>
-                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div>
-                            </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
-                                <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
-                                <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.editTextProgressivize ? "#aedef8" : "" }} onClick={this.editTextProgressivize}>Edit</div>
+                            <div className="ribbon-doubleButton" style={{ display: "flex" }}>
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Open document</div>
+                                <div className="ribbon-button" style={{ display: "flex", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Open parent collection</div>
                             </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.PDF ? "inline-flex" : "none" }}>
-                                <div className="ribbon-button" style={{ backgroundColor: activeItem.scrollProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeScroll}>Scroll progressivize</div>
-                                <div className="ribbon-button" style={{ display: activeItem.scrollProgressivize ? "flex" : "none", backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.WEB ? "inline-flex" : "none" }}>
+                                <div className="ribbon-button" onClick={this.progressivizeText}>Store original website</div>
                             </div>
                         </div>
                     </div>
@@ -928,28 +922,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return (
             <div>
                 <div className={'presBox-toolbar-dropdown'} style={{ display: this.newDocumentTools && this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-                    <div className="layout-container" style={{ height: this.openLayouts ? 'max-content' : '75px' }}>
-                        <div className="layout" style={{ border: this.layout === 'blank' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'blank' })} />
-                        <div className="layout" style={{ border: this.layout === 'title' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'title' })}>
+                    <div className="layout-container" style={{ height: 'max-content' }}>
+                        <div className="layout" style={{ border: this.layout === 'blank' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} />
+                        <div className="layout" style={{ border: this.layout === 'title' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}>
                             <div className="title">Title</div>
                             <div className="subtitle">Subtitle</div>
                         </div>
-                        <div className="layout" style={{ border: this.layout === 'header' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'header' })}>
+                        <div className="layout" style={{ border: this.layout === 'header' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}>
                             <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
                         </div>
-                        <div className="layout" style={{ border: this.layout === 'content' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'content' })}>
+                        <div className="layout" style={{ border: this.layout === 'content' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}>
                             <div className="title" style={{ alignSelf: 'center' }}>Title</div>
                             <div className="content">Text goes here</div>
                         </div>
-                        <div className="layout" style={{ border: this.layout === 'twoColumns' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'twoColumns' })}>
+                        <div className="layout" style={{ border: this.layout === 'twoColumns' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'twoColumns'; this.createNewSlide(this.layout); })}>
                             <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>Title</div>
                             <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>Column one text</div>
                             <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>Column two text</div>
                         </div>
                     </div>
-                    <div className="open-layout" onClick={() => runInAction(() => { this.openLayouts = !this.openLayouts })}>
-                        <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"caret-down"} size={"lg"} />
-                    </div>
                 </div>
             </div >
         );
@@ -1033,9 +1024,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
     createTemplate = (layout: string, input?: string) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        let x = 0;
+        let y = 0;
+        if (activeItem && targetDoc) {
+            x = NumCast(targetDoc._x);
+            y = NumCast(targetDoc._y) + NumCast(targetDoc._height) + 20;
+        }
         let doc = undefined;
         const title = Docs.Create.TextDocument("Click to change title", {
-            title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt"
+            title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt",
         });
         const subtitle = Docs.Create.TextDocument("Click to change subtitle", {
             title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt"
@@ -1058,27 +1057,27 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         switch (layout) {
             case 'blank':
                 doc = Docs.Create.FreeformDocument([], {
-                    title: input ? input : "Blank slide", _width: 400, _height: 225, _fitToBox: true
+                    title: input ? input : "Blank slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
                 });
                 break;
             case 'title':
                 doc = Docs.Create.FreeformDocument([title, subtitle], {
-                    title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true
+                    title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
                 });
                 break;
             case 'header':
                 doc = Docs.Create.FreeformDocument([header], {
-                    title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true
+                    title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
                 });
                 break;
             case 'content':
                 doc = Docs.Create.FreeformDocument([contentTitle, content], {
-                    title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true
+                    title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
                 });
                 break;
             case 'twoColumns':
                 doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], {
-                    title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true
+                    title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
                 });
                 break;
             default:
@@ -1218,7 +1217,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 <div className="ribbon-button" style={{ display: activeItem.scrollProgressivize ? "flex" : "none", backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div>
                             </div>
                         </div>
-                        <div className="ribbon-final-box" style={{ display: activeItem.zoomProgressivize || activeItem.scrollProgressivize || activeItem.presProgressivize || activeItem.textProgressivize ? "inline-flex" : "none" }}>
+                        <div className="ribbon-final-box" style={{ display: activeItem.zoomProgressivize || activeItem.scrollProgressivize || activeItem.presProgressivize || activeItem.textProgressivize ? "grid" : "none" }}>
                             Frames
                             <div className="ribbon-doubleButton">
                                 <div className="ribbon-frameSelector">
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index ce7a43315..90eb8580e 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -251,6 +251,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray().map(doc => doc));
         // let value = this.getValue(this._heading);
         // value = typeof value === "string" ? `"${value}"` : value;
+        PresBox.Instance._dragArray.map(ele => {
+            ele.style.backgroundColor = "#d5dce2";
+            ele.style.borderRadius = '5px';
+        });
         if (activeItem) {
             DragManager.StartDocumentDrag(PresBox.Instance._dragArray.map(ele => ele), dragData, e.clientX, e.clientY);
             activeItem.dragging = true;
@@ -295,10 +299,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                 onPointerDown={this.headerDown}
             >
                 <>
-                    <div ref={this._dragRef} className="presElementBox-number">
+                    <div className="presElementBox-number">
                         {`${this.indexInPres + 1}.`}
                     </div>
-                    <div className="presElementBox-name">
+                    <div ref={this._dragRef} className="presElementBox-name">
                         {`${this.targetDoc?.title}`}
                     </div>
                     <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.transition}</div></Tooltip>
-- 
cgit v1.2.3-70-g09d2


From 917deb0c0d73997f4ffa465e75ac05fdca7a8519 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Wed, 5 Aug 2020 01:21:44 +0800
Subject: pres elements

---
 .../collectionFreeForm/PropertiesView.tsx          | 260 ++++++++----
 src/client/views/nodes/AudioBox.tsx                |   9 +-
 src/client/views/nodes/PresBox.scss                |   1 +
 src/client/views/nodes/PresBox.tsx                 | 445 ++++++++-------------
 .../views/presentationview/PresElementBox.tsx      |  17 +-
 5 files changed, 365 insertions(+), 367 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 3e8404874..1f66d4144 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -27,6 +27,8 @@ import { ColorState, SketchPicker } from "react-color";
 import AntimodeMenu from "../../AntimodeMenu";
 import "./FormatShapePane.scss";
 import { discovery_v1 } from "googleapis";
+import { PresBox } from "../../nodes/PresBox";
+import { DocumentManager } from "../../../util/DocumentManager";
 
 
 interface PropertiesViewProps {
@@ -45,8 +47,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     @computed get selectedDocumentView() {
         if (SelectionManager.SelectedDocuments().length) {
             return SelectionManager.SelectedDocuments()[0];
+        } else if (PresBox.Instance._selectedArray.length >= 1) {
+            return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
         } else { return undefined; }
     }
+    @computed get isPres(): boolean {
+        if (this.selectedDoc?.type === DocumentType.PRES) return true;
+        return false;
+    }
     @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
     @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; }
 
@@ -58,6 +66,12 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     @observable openLayout: boolean = true;
     @observable openAppearance: boolean = true;
     @observable openTransform: boolean = true;
+    //Pres Trails booleans:
+    @observable openAddSlide: boolean = true;
+    @observable openPresentationTools: boolean = true;
+    @observable openPresTransitions: boolean = true;
+    @observable openPresProgressivize: boolean = true;
+    @observable openSlideOptions: boolean = true;
 
     @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; }
 
@@ -732,7 +746,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
 
     render() {
 
-        if (!this.selectedDoc) {
+        if (!this.selectedDoc && !this.isPres) {
             return <div className="propertiesView" style={{ width: this.props.width }}>
                 <div className="propertiesView-title" style={{ width: this.props.width }}>
                     No Document Selected
@@ -745,106 +759,192 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
 
         const novice = Doc.UserDoc().noviceMode;
 
-        return <div className="propertiesView" style={{ width: this.props.width }} >
-            <div className="propertiesView-title" style={{ width: this.props.width }}>
-                Properties
+        if (this.selectedDoc && !this.isPres) {
+            return <div className="propertiesView" style={{ width: this.props.width }} >
+                <div className="propertiesView-title" style={{ width: this.props.width }}>
+                    Properties
                 <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
-                    <FontAwesomeIcon icon="times" color="black" size="sm" />
+                        <FontAwesomeIcon icon="times" color="black" size="sm" />
+                    </div>
                 </div>
-            </div>
-            <div className="propertiesView-name">
-                {this.editableTitle}
-            </div>
-            <div className="propertiesView-settings">
-                <div className="propertiesView-settings-title"
-                    onPointerDown={() => runInAction(() => { this.openActions = !this.openActions; })}
-                    style={{ backgroundColor: this.openActions ? "black" : "" }}>
-                    Actions
+                <div className="propertiesView-name">
+                    {this.editableTitle}
+                </div>
+                <div className="propertiesView-settings">
+                    <div className="propertiesView-settings-title"
+                        onPointerDown={() => runInAction(() => { this.openActions = !this.openActions; })}
+                        style={{ backgroundColor: this.openActions ? "black" : "" }}>
+                        Actions
                     <div className="propertiesView-settings-title-icon">
-                        <FontAwesomeIcon icon={this.openActions ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            <FontAwesomeIcon icon={this.openActions ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
                     </div>
+                    {!this.openActions ? (null) :
+                        <div className="propertiesView-settings-content">
+                            <PropertiesButtons />
+                        </div>}
                 </div>
-                {!this.openActions ? (null) :
-                    <div className="propertiesView-settings-content">
-                        <PropertiesButtons />
-                    </div>}
-            </div>
-            <div className="propertiesView-sharing">
-                <div className="propertiesView-sharing-title"
-                    onPointerDown={() => runInAction(() => { this.openSharing = !this.openSharing; })}
-                    style={{ backgroundColor: this.openSharing ? "black" : "" }}>
-                    Sharing {"&"} Permissions
+                <div className="propertiesView-sharing">
+                    <div className="propertiesView-sharing-title"
+                        onPointerDown={() => runInAction(() => { this.openSharing = !this.openSharing; })}
+                        style={{ backgroundColor: this.openSharing ? "black" : "" }}>
+                        Sharing {"&"} Permissions
                     <div className="propertiesView-sharing-title-icon">
-                        <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
                     </div>
+                    {!this.openSharing ? (null) :
+                        <div className="propertiesView-sharing-content">
+                            {this.sharingTable}
+                        </div>}
                 </div>
-                {!this.openSharing ? (null) :
-                    <div className="propertiesView-sharing-content">
-                        {this.sharingTable}
-                    </div>}
-            </div>
 
-            {!this.isInk ? (null) :
-                <div className="propertiesView-appearance">
-                    <div className="propertiesView-appearance-title"
-                        onPointerDown={() => runInAction(() => { this.openAppearance = !this.openAppearance; })}
-                        style={{ backgroundColor: this.openAppearance ? "black" : "" }}>
-                        Appearance
+                {!this.isInk ? (null) :
+                    <div className="propertiesView-appearance">
+                        <div className="propertiesView-appearance-title"
+                            onPointerDown={() => runInAction(() => { this.openAppearance = !this.openAppearance; })}
+                            style={{ backgroundColor: this.openAppearance ? "black" : "" }}>
+                            Appearance
                         <div className="propertiesView-appearance-title-icon">
-                            <FontAwesomeIcon icon={this.openAppearance ? "caret-down" : "caret-right"} size="lg" color="white" />
+                                <FontAwesomeIcon icon={this.openAppearance ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
                         </div>
-                    </div>
-                    {!this.openAppearance ? (null) :
-                        <div className="propertiesView-appearance-content">
-                            {this.appearanceEditor}
-                        </div>}
-                </div>}
+                        {!this.openAppearance ? (null) :
+                            <div className="propertiesView-appearance-content">
+                                {this.appearanceEditor}
+                            </div>}
+                    </div>}
 
-            {this.isInk ? <div className="propertiesView-transform">
-                <div className="propertiesView-transform-title"
-                    onPointerDown={() => runInAction(() => { this.openTransform = !this.openTransform; })}
-                    style={{ backgroundColor: this.openTransform ? "black" : "" }}>
-                    Transform
+                {this.isInk ? <div className="propertiesView-transform">
+                    <div className="propertiesView-transform-title"
+                        onPointerDown={() => runInAction(() => { this.openTransform = !this.openTransform; })}
+                        style={{ backgroundColor: this.openTransform ? "black" : "" }}>
+                        Transform
                     <div className="propertiesView-transform-title-icon">
-                        <FontAwesomeIcon icon={this.openTransform ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            <FontAwesomeIcon icon={this.openTransform ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
                     </div>
-                </div>
-                {this.openTransform ? <div className="propertiesView-transform-content">
-                    {this.transformEditor}
+                    {this.openTransform ? <div className="propertiesView-transform-content">
+                        {this.transformEditor}
+                    </div> : null}
                 </div> : null}
-            </div> : null}
-
-            <div className="propertiesView-fields">
-                <div className="propertiesView-fields-title"
-                    onPointerDown={() => runInAction(() => { this.openFields = !this.openFields; })}
-                    style={{ backgroundColor: this.openFields ? "black" : "" }}>
-                    <div className="propertiesView-fields-title-name">
-                        Fields {"&"} Tags
+
+                <div className="propertiesView-fields">
+                    <div className="propertiesView-fields-title"
+                        onPointerDown={() => runInAction(() => { this.openFields = !this.openFields; })}
+                        style={{ backgroundColor: this.openFields ? "black" : "" }}>
+                        <div className="propertiesView-fields-title-name">
+                            Fields {"&"} Tags
                         <div className="propertiesView-fields-title-icon">
-                            <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
+                                <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
                         </div>
                     </div>
+                    {!novice && this.openFields ? <div className="propertiesView-fields-checkbox">
+                        {this.fieldsCheckbox}
+                        <div className="propertiesView-fields-checkbox-text">Layout</div>
+                    </div> : null}
+                    {!this.openFields ? (null) :
+                        <div className="propertiesView-fields-content">
+                            {novice ? this.noviceFields : this.expandedField}
+                        </div>}
                 </div>
-                {!novice && this.openFields ? <div className="propertiesView-fields-checkbox">
-                    {this.fieldsCheckbox}
-                    <div className="propertiesView-fields-checkbox-text">Layout</div>
-                </div> : null}
-                {!this.openFields ? (null) :
-                    <div className="propertiesView-fields-content">
-                        {novice ? this.noviceFields : this.expandedField}
-                    </div>}
-            </div>
-            <div className="propertiesView-layout">
-                <div className="propertiesView-layout-title"
-                    onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}
-                    style={{ backgroundColor: this.openLayout ? "black" : "" }}>
-                    Layout
+                <div className="propertiesView-layout">
+                    <div className="propertiesView-layout-title"
+                        onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}
+                        style={{ backgroundColor: this.openLayout ? "black" : "" }}>
+                        Layout
                     <div className="propertiesView-layout-title-icon" onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}>
-                        <FontAwesomeIcon icon={this.openLayout ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            <FontAwesomeIcon icon={this.openLayout ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
                     </div>
+                    {this.openLayout ? <div className="propertiesView-layout-content">{this.layoutPreview}</div> : null}
                 </div>
-                {this.openLayout ? <div className="propertiesView-layout-content">{this.layoutPreview}</div> : null}
-            </div>
-        </div>;
+            </div>;
+        }
+        if (this.isPres) {
+            return <div className="propertiesView" style={{ width: this.props.width }} >
+                <div className="propertiesView-title" style={{ width: this.props.width }}>
+                    Presentation Toolbar
+                <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
+                        <FontAwesomeIcon icon="times" color="black" size="sm" />
+                    </div>
+                </div>
+                <div className="propertiesView-name">
+                    {this.editableTitle}
+                    <div className="propertiesView-presSelected">
+                        {PresBox.Instance._selectedArray.length} selected
+                        <div className="propertiesView-selectedList">
+                            {PresBox.Instance.listOfSelected}
+                        </div>
+                    </div>
+                </div>
+                <div className="propertiesView-settings">
+                    <div className="propertiesView-settings-title"
+                        onPointerDown={() => runInAction(() => { this.openAddSlide = !this.openAddSlide; })}
+                        style={{ backgroundColor: this.openAddSlide ? "black" : "" }}>
+                        &nbsp; <FontAwesomeIcon icon={"plus"} /> &nbsp; Add new slide
+                    <div className="propertiesView-settings-title-icon">
+                            <FontAwesomeIcon icon={this.openAddSlide ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
+                    </div>
+                    {this.openAddSlide ? <div className="propertiesView-settings-content">
+                        {PresBox.Instance.newDocumentDropdown}
+                    </div> : null}
+                </div>
+                <div className="propertiesView-sharing">
+                    <div className="propertiesView-sharing-title"
+                        onPointerDown={() => runInAction(() => { this.openPresTransitions = !this.openPresTransitions; })}
+                        style={{ backgroundColor: this.openPresTransitions ? "black" : "" }}>
+                        &nbsp; <FontAwesomeIcon icon={"rocket"} /> &nbsp; Transitions
+                    <div className="propertiesView-sharing-title-icon">
+                            <FontAwesomeIcon icon={this.openPresTransitions ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
+                    </div>
+                    {this.openPresTransitions ? <div className="propertiesView-sharing-content">
+                        {PresBox.Instance.transitionDropdown}
+                    </div> : null}
+                </div>
+                <div className="propertiesView-sharing">
+                    <div className="propertiesView-sharing-title"
+                        onPointerDown={() => runInAction(() => { this.openPresProgressivize = !this.openPresProgressivize; })}
+                        style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}>
+                        &nbsp; <FontAwesomeIcon icon={"tasks"} /> &nbsp; Progressivize
+                    <div className="propertiesView-sharing-title-icon">
+                            <FontAwesomeIcon icon={this.openPresProgressivize ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
+                    </div>
+                    {this.openPresProgressivize ? <div className="propertiesView-sharing-content">
+                        {PresBox.Instance.progressivizeDropdown}
+                    </div> : null}
+                </div>
+                <div className="propertiesView-sharing">
+                    <div className="propertiesView-sharing-title"
+                        onPointerDown={() => runInAction(() => { this.openSlideOptions = !this.openSlideOptions; })}
+                        style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}>
+                        <FontAwesomeIcon icon={"cog"} /> &nbsp; {PresBox.Instance.stringType} options
+                    <div className="propertiesView-sharing-title-icon">
+                            <FontAwesomeIcon icon={this.openSlideOptions ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
+                    </div>
+                    {this.openSlideOptions ? <div className="propertiesView-sharing-content">
+                        {PresBox.Instance.optionsDropdown}
+                    </div> : null}
+                </div>
+                <div className="propertiesView-sharing">
+                    <div className="propertiesView-sharing-title"
+                        onPointerDown={() => runInAction(() => { this.openSharing = !this.openSharing; })}
+                        style={{ backgroundColor: this.openSharing ? "black" : "" }}>
+                        Sharing {"&"} Permissions
+                    <div className="propertiesView-sharing-title-icon">
+                            <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+                        </div>
+                    </div>
+                    {this.openSharing ? <div className="propertiesView-sharing-content">
+                        {this.sharingTable}
+                    </div> : null}
+                </div>
+            </div>;
+        }
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 5c921cea4..dba92faae 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -21,6 +21,7 @@ import { Docs, DocUtils } from "../../documents/Documents";
 import { ComputedField } from "../../../fields/ScriptField";
 import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
+import { signedCookie } from "cookie-parser";
 
 // testing testing 
 
@@ -43,7 +44,7 @@ const AudioDocument = makeInterface(documentSchema, audioSchema);
 export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument>(AudioDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(AudioBox, fieldKey); }
     public static Enabled = false;
-
+    static Instance: AudioBox;
     _linkPlayDisposer: IReactionDisposer | undefined;
     _reactionDisposer: IReactionDisposer | undefined;
     _scrubbingDisposer: IReactionDisposer | undefined;
@@ -51,12 +52,14 @@ export class AudioBox extends ViewBoxBaseComponent<FieldViewProps, AudioDocument
     _recorder: any;
     _recordStart = 0;
     _stream: MediaStream | undefined;
-
+    constructor(props: any) {
+        super(props);
+        AudioBox.Instance = this;
+    }
     @observable private static _scrubTime = 0;
     @computed get audioState(): undefined | "recording" | "paused" | "playing" { return this.dataDoc.audioState as (undefined | "recording" | "paused" | "playing"); }
     set audioState(value) { this.dataDoc.audioState = value; }
     public static SetScrubTime = (timeInMillisFrom1970: number) => { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); };
-
     @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); }
     async slideTemplate() { return (await Cast((await Cast(Doc.UserDoc().slidesBtn, Doc) as Doc).dragFactory, Doc) as Doc); }
 
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 45c6d33b8..089f69873 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -667,6 +667,7 @@
         height: 55px;
         min-width: 90px;
         width: 90px;
+        overflow: hidden;
         background-color: white;
         border: solid darkgrey 1px;
         display: grid;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 0a73106a3..2389d3875 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -33,6 +33,7 @@ import { translate } from "googleapis/build/src/apis/translate";
 import { DragManager, dropActionType } from "../../util/DragManager";
 import { actionAsync } from "mobx-utils";
 import { SelectionManager } from "../../util/SelectionManager";
+import { AudioBox } from "./AudioBox";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -90,6 +91,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         Doc.UserDoc().activePresentation = this.rootDoc;
     }
 
+    @observable _moveOnFromAudio: boolean = false;
+
     @undoBatch
     @action
     next = () => {
@@ -106,9 +109,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             presTargetDoc.currentFrame = curFrame + 1;
             if (presTargetDoc.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc);
             // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
+        } else if ((presTargetDoc.type === DocumentType.VID || presTargetDoc.type === DocumentType.AUDIO) && !this._moveOnFromAudio) {
+            if (presTargetDoc.type === DocumentType.AUDIO) {
+                AudioBox.Instance.playFrom(0);
+                this._moveOnFromAudio = true;
+            }
+            if (presTargetDoc.type === DocumentType.VID) {
+                this._moveOnFromAudio = true;
+            }
         } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
             const nextSelected = this.itemIndex + 1;
             this.gotoDocument(nextSelected, this.itemIndex);
+            this._moveOnFromAudio = false;
         }
     }
 
@@ -185,73 +197,100 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
 
     @action
-    onHideDocumentUntilPressClick = () => {
+    onHideDocument = () => {
         this.childDocs.forEach((doc, index) => {
             const curDoc = Cast(doc, Doc, null);
             const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
-            if (tagDoc.presEffect === 'None' || !tagDoc.presEffect) {
-                tagDoc.opacity = 1;
-            } else {
-                if (index <= this.itemIndex) {
+            if (tagDoc) tagDoc.opacity = 1;
+            if (curDoc.presHideTillShownButton) {
+                console.log("-------------hide before---------------");
+                console.log("this.itemIndex: " + this.itemIndex);
+                console.log("index: " + index)
+                if (index > this.itemIndex) {
+                    tagDoc.opacity = 0;
+                } else if (!curDoc.presHideAfterButton) {
                     tagDoc.opacity = 1;
-                } else {
+                }
+            }
+            if (curDoc.presHideAfterButton) {
+                console.log("-------------hide after---------------");
+                console.log("this.itemIndex: " + (this.itemIndex + 1));
+                console.log("index: " + (index + 1))
+                if (index < this.itemIndex) {
                     tagDoc.opacity = 0;
+                } else if (!curDoc.presHideTillShownButton) {
+                    tagDoc.opacity = 1;
                 }
             }
         });
     }
 
-    /**
-     * This is the method that checks for the actions that need to be performed
-     * before the document has been presented, which involves 3 button options:
-     * Hide Until Presented, Hide After Presented, Fade After Presented
-     */
     @action
-    hideDocumentInPres = () => {
-        this.updateCurrentPresentation();
-        this.childDocs.forEach((doc, i) => {
-            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            console.log("HB: " + doc.presHideTillShownButton);
-            console.log("HA: " + doc.presHideAfterButton);
-            if (doc.presHideTillShownButton) {
-                if (i < this.itemIndex) {
-                    console.log(i + 1 + "hide before");
-                    tagDoc.opacity = 0;
-                    console.log(tagDoc.opacity);
-                } else {
-                    tagDoc.opacity = 1;
-                }
-            }
-            if (doc.presHideAfterButton) {
-                if (i > this.itemIndex) {
-                    console.log(i + 1 + "hide after");
+    onHideAfterPresClick = () => {
+        this.childDocs.forEach((doc, index) => {
+            const curDoc = Cast(doc, Doc, null);
+            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
+            if (curDoc.presHideAfterButton) {
+                if (index < this.itemIndex) {
                     tagDoc.opacity = 0;
-                    console.log(tagDoc.opacity);
-                } else {
+                } else if (index = this.itemIndex) {
                     tagDoc.opacity = 1;
                 }
             }
         });
     }
 
+    /**
+     * This is the method that checks for the actions that need to be performed
+     * before the document has been presented, which involves 3 button options:
+     * Hide Until Presented, Hide After Presented, Fade After Presented
+     */
+    // @action
+    // hideDocumentInPres = () => {
+    //     this.updateCurrentPresentation();
+    //     this.childDocs.forEach((doc, i) => {
+    //         const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+    //         console.log("HB: " + doc.presHideTillShownButton);
+    //         console.log("HA: " + doc.presHideAfterButton);
+    //         if (doc.presHideTillShownButton) {
+    //             if (i < this.itemIndex) {
+    //                 console.log(i + 1 + "hide before");
+    //                 tagDoc.opacity = 0;
+    //                 console.log(tagDoc.opacity);
+    //             } else {
+    //                 tagDoc.opacity = 1;
+    //             }
+    //         }
+    //         if (doc.presHideAfterButton) {
+    //             if (i > this.itemIndex) {
+    //                 console.log(i + 1 + "hide after");
+    //                 tagDoc.opacity = 0;
+    //                 console.log(tagDoc.opacity);
+    //             } else {
+    //                 tagDoc.opacity = 1;
+    //             }
+    //         }
+    //     });
+    // }
+
     /**
      * This is the method that checks for the actions that need to be performed
      * after the document has been presented, which involves 3 button options:
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
-    showAfterPresented = (index: number) => {
-        this.updateCurrentPresentation();
-        this.childDocs.forEach((doc, ind) => {
-            const presTargetDoc = doc.presentationTargetDoc as Doc;
-            //the order of cases is aligned based on priority
-            if (doc.presHideTillShownButton && ind <= index) {
-                presTargetDoc.opacity = 1;
-            }
-            if (doc.presHideAfterButton && ind < index) {
-                presTargetDoc.opacity = 0;
-            }
-        });
-    }
+    // showAfterPresented = (index: number) => {
+    //     this.updateCurrentPresentation();
+    //     this.childDocs.forEach((doc, ind) => {
+    //         const presTargetDoc = doc.presentationTargetDoc as Doc;
+    //         //the order of cases is aligned based on priority
+    //         if (doc.presHideTillShownButton && ind <= index) {
+    //             presTargetDoc.opacity = 1;
+    //         }
+    //         if (doc.presHideAfterButton && ind < index) {
+    //             presTargetDoc.opacity = 0;
+    //         }
+    //     });
+    // }
 
     /**
      * This method makes sure that cursor navigates to the element that
@@ -264,6 +303,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const srcContext = await DocCastAsync(targetDoc.context);
         const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
         const collectionDocView = presCollection ? await DocumentManager.Instance.getDocumentView(presCollection) : undefined;
+        this.turnOffEdit();
+
         if (this.itemIndex >= 0) {
             if (targetDoc) {
                 if (srcContext) this.layoutDoc.presCollection = srcContext;
@@ -272,12 +313,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (srcContext) console.log("NC: " + srcContext.title);
         if (presCollection) console.log("PC: " + presCollection.title);
         if (collectionDocView) {
-            if (srcContext && srcContext !== presCollection) {
-                console.log("Case 1: new srcContext inside of current collection so add a new tab to the current pres collection");
-                console.log(collectionDocView);
-                collectionDocView.props.addDocTab(srcContext, "inPlace");
+            if (activeItem.openDocument) {
+                collectionDocView.props.addDocTab(activeItem, "inPlace");
+            } else if (srcContext && srcContext !== presCollection) {
+                if (activeItem.openDocument) {
+                    collectionDocView.props.addDocTab(activeItem, "inPlace");
+                } else {
+                    console.log("Case 1: new srcContext inside of current collection so add a new tab to the current pres collection");
+                    console.log(collectionDocView);
+                    collectionDocView.props.addDocTab(srcContext, "inPlace");
+                }
             }
         }
+        if (targetDoc.presWebsiteData) {
+            targetDoc.data = targetDoc.presWebsiteData;
+        }
         // else if (srcContext) {
         //     console.log("Case 2: srcContext - not open and collection containing this document exists, so open collection that contains it and then await zooming in on document");
         //     this.props.addDocTab(srcContext, "onRight");
@@ -290,7 +340,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const willZoom = false;
 
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
-        if (docToJump === curDoc) {
+        if (targetDoc.zoomProgressivize && this.rootDoc.presStatus !== 'edit') {
+            this.zoomProgressivizeNext(targetDoc);
+        } else if (docToJump === curDoc) {
             //checking if curDoc has navigation open
             if (curDoc.presNavButton && targetDoc) {
                 await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext);
@@ -320,7 +372,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             // this.hideIfNotPresented(index);
             // this.showAfterPresented(index);
             // this.hideDocumentInPres();
-            this.onHideDocumentUntilPressClick();
+            this.onHideDocument();
+            // this.onHideAfterPresClick();
         }
     });
 
@@ -371,14 +424,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             if (doc.presHideAfterButton && this.childDocs.indexOf(doc) < startIndex) {
                 presTargetDoc.opacity = 0;
             }
-            if (doc.presFadeButton && this.childDocs.indexOf(doc) < startIndex) {
-                presTargetDoc.opacity = 0.5;
-            }
         });
     }
 
     updateMinimize = () => {
         const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
+        this.turnOffEdit();
         if (srcContext) {
             if (srcContext.miniPres) {
                 document.removeEventListener("keydown", this.keyEvents, false);
@@ -461,7 +512,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
     childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement;
     removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc);
-    getTransform = () => this.props.ScreenToLocalTransform();// listBox padding-left and pres-box-cont minHeight - .translate(-5, -65)
+    getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
     panelHeight = () => this.props.PanelHeight() - 40;
     active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) &&
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
@@ -498,10 +549,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     //Regular click
     @action
     selectElement = (doc: Doc) => {
-        // this._selectedArray = [];
         this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex));
-        // this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
-        // console.log(this._selectedArray);
     }
 
     //Command click
@@ -526,8 +574,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
-
-
     //Esc click
     @action
     keyEvents = (e: KeyboardEvent) => {
@@ -566,69 +612,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @observable private pathBoolean: boolean = false;
     @observable private expandBoolean: boolean = false;
 
-    // For toggling transition toolbar
-    @action toggleTransitionTools = () => {
-        this.transitionTools = !this.transitionTools;
-        this.newDocumentTools = false;
-        this.progressivizeTools = false;
-        this.moreInfoTools = false;
-        this.playTools = false;
-    }
-    // For toggling the add new document dropdown
-    @action toggleNewDocument = () => {
-        this.newDocumentTools = !this.newDocumentTools;
-        this.transitionTools = false;
-        this.progressivizeTools = false;
-        this.moreInfoTools = false;
-        this.playTools = false;
-    }
-    // For toggling the tools for progressivize
-    @action toggleProgressivize = () => {
-        this.progressivizeTools = !this.progressivizeTools;
-        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        targetDoc.editZoomProgressivize = false;
-        targetDoc.editProgressivize = false;
-        this.transitionTools = false;
-        this.newDocumentTools = false;
-        this.moreInfoTools = false;
-        this.playTools = false;
-    }
-    // For toggling the tools for more info
-    @action toggleMoreInfo = () => {
-        this.moreInfoTools = !this.moreInfoTools;
-        this.transitionTools = false;
-        this.newDocumentTools = false;
-        this.progressivizeTools = false;
-        this.playTools = false;
-    }
-    // For toggling the options when the user wants to select play
-    @action togglePlay = () => {
-        this.playTools = !this.playTools;
-        this.transitionTools = false;
-        this.newDocumentTools = false;
-        this.progressivizeTools = false;
-        this.moreInfoTools = false;
-    }
-
-    // For toggling the options when the user wants to select play
-    @action togglePresent = () => {
-        this.presentTools = !this.presentTools;
-        this.playTools = false;
-        this.transitionTools = false;
-        this.newDocumentTools = false;
-        this.progressivizeTools = false;
-        this.moreInfoTools = false;
-    }
-
-    @action toggleAllDropdowns() {
-        this.transitionTools = false;
-        this.newDocumentTools = false;
-        this.progressivizeTools = false;
-        this.moreInfoTools = false;
-        this.playTools = false;
-    }
-
     @undoBatch
     @action
     viewPaths = async () => {
@@ -831,20 +814,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 <div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Roll'}>Roll</div>
                             </div>
                         </div>
-                        <div className="presBox-subheading" style={{ display: effect === 'None' ? "none" : "block" }}>Effect direction</div>
-                        <div className="presBox-reactiveGrid" style={{ display: effect === 'None' ? "none" : "grid" }}>
-                            <div className="effectDirection" style={{ display: "grid", width: 40 }}>
-                                <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "left" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'left'}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
-                                <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "right" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'right'}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
-                                <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === "top" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'top'}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
-                                <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: targetDoc.presEffectDirection === "bottom" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'bottom'}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip>
-                                <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: targetDoc.presEffectDirection ? "solid 2px black" : "solid 2px #5a9edd", borderRadius: "100%" }} onClick={() => targetDoc.presEffectDirection = false}></div></Tooltip>
-                            </div>
+                        <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? "none" : "inline-flex" }}>
+                            <div className="presBox-subheading" >Effect direction</div>
                             <div className="ribbon-property">
                                 {this.effectDirection}
                             </div>
                         </div>
-
+                        <div className="effectDirection" style={{ display: effect === 'None' ? "none" : "grid", width: 40 }}>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "left" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'left'}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === "right" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'right'}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === "top" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'top'}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: targetDoc.presEffectDirection === "bottom" ? "#5a9edd" : "black" }} onClick={() => targetDoc.presEffectDirection = 'bottom'}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: targetDoc.presEffectDirection ? "solid 2px black" : "solid 2px #5a9edd", borderRadius: "100%" }} onClick={() => targetDoc.presEffectDirection = false}></div></Tooltip>
+                        </div>
                     </div>
                     <div className="ribbon-final-box">
                         <div className={this._selectedArray.length === 0 ? "ribbon-final-button" : "ribbon-final-button-hidden"} onClick={() => this.applyTo(this._selectedArray)}>
@@ -887,9 +869,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         });
     }
 
-    public inputRef = React.createRef<HTMLInputElement>();
-
-
+    private inputRef = React.createRef<HTMLInputElement>();
 
     @computed get optionsDropdown() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
@@ -899,14 +879,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 <div>
                     <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                         <div className="ribbon-box">
-                            {this.stringType} options
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.AUDIO ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Start automatically</div>
                                 <div className="ribbon-button" style={{ display: "flex", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Start manually</div>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: "flex" }}>
-                                <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Open document</div>
-                                <div className="ribbon-button" style={{ display: "flex", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Open parent collection</div>
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.openDocument ? "#aedef8" : "" }} onClick={() => { activeItem.openDocument = !activeItem.openDocument }}>Open document</div>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.WEB ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Store original website</div>
@@ -935,11 +913,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="title" style={{ alignSelf: 'center' }}>Title</div>
                             <div className="content">Text goes here</div>
                         </div>
-                        <div className="layout" style={{ border: this.layout === 'twoColumns' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'twoColumns'; this.createNewSlide(this.layout); })}>
+                        {/* <div className="layout" style={{ border: this.layout === 'twoColumns' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'twoColumns'; this.createNewSlide(this.layout); })}>
                             <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>Title</div>
                             <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>Column one text</div>
                             <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>Column two text</div>
-                        </div>
+                        </div> */}
                     </div>
                 </div>
             </div >
@@ -1009,17 +987,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     createNewSlide = (layout?: string, title?: string, freeform?: boolean) => {
         console.log("whats going on?");
         let doc = undefined;
+        if (layout) doc = this.createTemplate(layout);
         if (freeform && layout) doc = this.createTemplate(layout, title);
-        if (!freeform) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title });
+        if (!freeform && !layout) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title });
         const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
         const data = Cast(presCollection.data, listSpec(Doc));
         const presData = Cast(this.rootDoc.data, listSpec(Doc));
-        console.log(data);
-        console.log(doc);
         if (data && doc && presData) {
-            console.log("data and doc");
             data.push(doc);
             DockedFrameRenderer.PinDoc(doc, false);
+            this.gotoDocument(this.childDocs.length, this.itemIndex);
         }
     }
 
@@ -1029,56 +1006,32 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         let x = 0;
         let y = 0;
         if (activeItem && targetDoc) {
-            x = NumCast(targetDoc._x);
-            y = NumCast(targetDoc._y) + NumCast(targetDoc._height) + 20;
+            x = NumCast(targetDoc.x);
+            y = NumCast(targetDoc.y) + NumCast(targetDoc._height) + 20;
         }
         let doc = undefined;
-        const title = Docs.Create.TextDocument("Click to change title", {
-            title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt",
-        });
-        const subtitle = Docs.Create.TextDocument("Click to change subtitle", {
-            title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt"
-        });
-        const header = Docs.Create.TextDocument("Click to change header", {
-            title: "Slide header", _width: 380, _height: 65, x: 10, y: 80, _fontSize: "20pt"
-        });
-        const contentTitle = Docs.Create.TextDocument("Click to change title", {
-            title: "Slide title", _width: 380, _height: 60, x: 10, y: 10, _fontSize: "24pt"
-        });
-        const content = Docs.Create.TextDocument("Click to change texte", {
-            title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt"
-        });
-        const content1 = Docs.Create.TextDocument("Click to change text", {
-            title: "Column 1", _width: 185, _height: 140, x: 10, y: 80, _fontSize: "14pt"
-        });
-        const content2 = Docs.Create.TextDocument("Click to change text", {
-            title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt"
-        });
+        const title = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt", });
+        const subtitle = Docs.Create.TextDocument("Click to change subtitle", { title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt" });
+        const header = Docs.Create.TextDocument("Click to change header", { title: "Slide header", _width: 380, _height: 65, x: 10, y: 80, _fontSize: "20pt" });
+        const contentTitle = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 10, _fontSize: "24pt" });
+        const content = Docs.Create.TextDocument("Click to change texte", { title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt" });
+        const content1 = Docs.Create.TextDocument("Click to change text", { title: "Column 1", _width: 185, _height: 140, x: 10, y: 80, _fontSize: "14pt" });
+        const content2 = Docs.Create.TextDocument("Click to change text", { title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt" });
         switch (layout) {
             case 'blank':
-                doc = Docs.Create.FreeformDocument([], {
-                    title: input ? input : "Blank slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
-                });
+                doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
                 break;
             case 'title':
-                doc = Docs.Create.FreeformDocument([title, subtitle], {
-                    title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
-                });
+                doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
                 break;
             case 'header':
-                doc = Docs.Create.FreeformDocument([header], {
-                    title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
-                });
+                doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
                 break;
             case 'content':
-                doc = Docs.Create.FreeformDocument([contentTitle, content], {
-                    title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
-                });
+                doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
                 break;
             case 'twoColumns':
-                doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], {
-                    title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y
-                });
+                doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
                 break;
             default:
                 break;
@@ -1086,6 +1039,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return doc;
     }
 
+    // Dropdown that appears for autoplay
     @computed get playDropdown() {
         return (
             <div className={`dropdown-play ${this.playTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
@@ -1099,30 +1053,27 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         );
     }
 
+    // Dropdown that appears when the user wants to begin presenting (either minimize or sidebar view)
     @computed get presentDropdown() {
         return (
             <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={this.updateMinimize}>
                     Minimize
                 </div>
-                <div className="dropdown-play-button" onClick={() => this.startOrResetPres(0)}>
+                <div className="dropdown-play-button" onClick={() => { this.startOrResetPres(0); this.turnOffEdit(); }}>
                     Sidebar view
                 </div>
             </div>
         );
     }
 
-    // progressivizeOptions = (viewType: string) => {
-    //     const buttons = [];
-    //     buttons.push(<div className="ribbon-button" onClick={this.progressivize}>Child documents</div>);
-    //     buttons.push(<div className="ribbon-button" onClick={() => console.log("hide after")}>Internal zoom</div>);
-    //     buttons.push(<div className="ribbon-button" onClick={() => console.log("hide after")}>Bullet points</div>);
-    //     if (viewType === "rtf") {
-    //         buttons.push(<div className="ribbon-button" title="Progressivize bullet points" onClick={() => console.log("hide after")}>Bullet points</div>);
-    //     }
-    //     return buttons;
-    // }
+    // For toggling the options when the user wants to select play
+    @action togglePlay = () => { this.playTools = !this.playTools; }
 
+    // For toggling the options when the user wants to select play
+    @action togglePresent = () => { this.presentTools = !this.presentTools; }
+
+    // Case in which the document has keyframes to navigate to next key frame
     @undoBatch
     @action
     nextKeyframe = (tagDoc: Doc): void => {
@@ -1178,13 +1129,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
         let type: string = '';
-        switch (targetDoc.type) {
-            case DocumentType.PDF: type = "PDF"; break;
-            case DocumentType.RTF: type = "Text node"; break;
-            case DocumentType.COL: type = "Collection"; break;
-            case DocumentType.AUDIO: type = "Audio"; break;
-            case DocumentType.VID: type = "Video"; break;
-            default: type = "Other node"; break;
+        if (activeItem) {
+            switch (targetDoc.type) {
+                case DocumentType.PDF: type = "PDF"; break;
+                case DocumentType.RTF: type = "Text node"; break;
+                case DocumentType.COL: type = "Collection"; break;
+                case DocumentType.AUDIO: type = "Audio"; break;
+                case DocumentType.VID: type = "Video"; break;
+                case DocumentType.IMG: type = "Image"; break;
+                default: type = "Other node"; break;
+            }
         }
         return type;
     }
@@ -1206,7 +1160,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Internal zoom</div>
                                 <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Viewfinder</div>
-                                <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div>
+                                {/* <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div> */}
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
@@ -1242,6 +1196,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    turnOffEdit = () => {
+        this.childDocs.forEach((doc, index) => {
+            const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            targetDoc.editSnapZoomProgressivize = false;
+            targetDoc.editZoomProgressivize = false;
+            targetDoc.editScrollProgressivize = false;
+            if (doc.type === DocumentType.WEB) {
+                doc.presWebsite = doc.data;
+            }
+        });
+    }
+
     //Toggle whether the user edits or not
     @action
     editSnapZoomProgressivize = (e: React.MouseEvent) => {
@@ -1703,13 +1669,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return width;
     }
 
-
     @computed get toolbar() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         if (activeItem) {
             return (
                 <>
-                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={this.toggleNewDocument}><FontAwesomeIcon icon={"plus"} />
+                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={() => runInAction(() => { this.newDocumentTools = !this.newDocumentTools; })}><FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
                     <div className="toolbar-divider" />
@@ -1735,7 +1700,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         <FontAwesomeIcon className={`dropdown ${this.progressivizeTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
                     <div className="toolbar-divider" /> */}
-                    <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
+                    {/* <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
                         <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
                     </div>
                     <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
@@ -1744,16 +1709,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="toolbar-moreInfoBall" />
                             <div className="toolbar-moreInfoBall" />
                         </div>
-                    </div>
+                    </div> */}
                 </>
             );
         } else {
             return (
                 <>
-                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={this.toggleNewDocument}><FontAwesomeIcon icon={"plus"} />
+                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={() => runInAction(() => { this.newDocumentTools = !this.newDocumentTools; })}>
+                        <FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
-                    <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
+                    {/* <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
                         <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
                     </div>
                     <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
@@ -1762,68 +1728,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="toolbar-moreInfoBall" />
                             <div className="toolbar-moreInfoBall" />
                         </div>
-                    </div>
+                    </div> */}
                 </>
             );
         }
     }
 
-    private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
-
-
-    // protected createPresDropTarget = (ele: HTMLDivElement) => {
-    //     console.log("created?");
-    //     this.treedropDisposer?.();
-    //     ele && (this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc, this.onInternalPreDrop.bind(this)));
-    //     if (ele) {
-    //         console.log("ele: " + ele.className)
-    //     }
-    // }
-
-    // protected onInternalPreDrop(e: Event, de: DragManager.DropEvent, targetAction: dropActionType) {
-    //     console.log("preDrop?")
-    //     if (de.complete.docDragData) {
-    //         // if targetDropAction is, say 'alias', but we're just dragging within a collection, we want to ignore the targetAction.
-    //         // otherwise, the targetAction should become the actual action (which can still be overridden by the userDropAction -eg, shift/ctrl keys)
-    //         if (targetAction && !de.complete.docDragData.draggedDocuments.some(d => d.context === this.props.Document && this.childDocs.includes(d))) {
-    //             de.complete.docDragData.dropAction = targetAction;
-    //         }
-    //         e.stopPropagation();
-    //     }
-    // }
-
-    // @action
-    // protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
-    //     console.log("drop in pres")
-    //     const docDragData = de.complete.docDragData;
-    //     ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData });
-    //     if (docDragData && this.props.addDocument) {
-    //         console.log("docDragData && this.props.addDocument");
-    //         let added = false;
-    //         const dropaction = docDragData.dropAction || docDragData.userDropAction;
-    //         if (dropaction && dropaction !== "move") {
-    //             console.log("dropaction && dropaction !== move");
-    //             added = this.props.addDocument(docDragData.droppedDocuments);
-    //         } else if (docDragData.moveDocument) {
-    //             console.log("docDragData.moveDocument");
-    //             const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d);
-    //             const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d);
-    //             const res = addedDocs.length ? this.props.addDocument(addedDocs) : true;
-    //             if (movedDocs.length) {
-    //                 const canAdd = this.props.Document._viewType === CollectionViewType.Pile || de.embedKey ||
-    //                     Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document);
-    //                 added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.props.addDocument : returnFalse);
-    //             } else added = res;
-    //         } else {
-    //             console.log("else");
-    //             added = this.props.addDocument(docDragData.droppedDocuments);
-    //         }
-    //         added && e.stopPropagation();
-    //         return added;
-    //     }
-    //     return false;
-    // }
-
     render() {
         this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields
         const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
@@ -1872,12 +1782,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             </div>
             <div id="toolbarContainer" className={`presBox-toolbar ${this.layoutDoc.presStatus === "edit" ? "active" : ""}`}> {this.toolbar} </div>
             {this.newDocumentToolbarDropdown}
-            {/* {this.newDocumentDropdown}
-            {this.moreInfoDropdown}
-            {this.transitionDropdown}
-            {this.progressivizeDropdown} */}
             <div className="presBox-listCont">
-                {/* ref={this.createPresDropTarget}> */}
                 {mode !== CollectionViewType.Invalid ?
                     <CollectionView {...this.props}
                         ContainingCollectionDoc={this.props.Document}
@@ -1890,8 +1795,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         removeDocument={returnFalse}
                         dontRegisterView={true}
                         focus={this.selectElement}
-                        // presMultiSelect={this.multiSelect}
-                        // ScreenToLocalTransform={Transform.Identity} />
                         ScreenToLocalTransform={this.getTransform} />
                     : (null)
                 }
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 90eb8580e..b3d8cca98 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -251,10 +251,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray().map(doc => doc));
         // let value = this.getValue(this._heading);
         // value = typeof value === "string" ? `"${value}"` : value;
-        PresBox.Instance._dragArray.map(ele => {
-            ele.style.backgroundColor = "#d5dce2";
-            ele.style.borderRadius = '5px';
-        });
         if (activeItem) {
             DragManager.StartDocumentDrag(PresBox.Instance._dragArray.map(ele => ele), dragData, e.clientX, e.clientY);
             activeItem.dragging = true;
@@ -276,26 +272,21 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                 onClick={e => {
                     e.stopPropagation();
                     e.preventDefault();
+                    // Command/ control click
                     if (e.ctrlKey || e.metaKey) {
                         PresBox.Instance.multiSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!);
-                        console.log("cmmd click");
+                        // Shift click
                     } else if (e.shiftKey) {
                         PresBox.Instance.shiftSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!);
+                        // Regular click
                     } else {
-                        PresBox.Instance.selectElement(this.rootDoc);
+                        this.props.focus(this.rootDoc);
                         PresBox.Instance._eleArray = [];
                         PresBox.Instance._eleArray.push(this._itemRef.current!);
                         PresBox.Instance._dragArray = [];
                         PresBox.Instance._dragArray.push(this._dragRef.current!);
-                        console.log("normal click");
                     }
                 }}
-                // onClick={e => {
-                //     if (this.props.active(true)) {
-                //         e.stopPropagation();
-                //         e.preventDefault();
-                //     }
-                // }}
                 onPointerDown={this.headerDown}
             >
                 <>
-- 
cgit v1.2.3-70-g09d2


From fa0b28c300416621dec25407484fc2606a736e2a Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Thu, 6 Aug 2020 05:11:18 +0800
Subject: automatic text progressivize, ui changes, bug fixes

---
 src/client/documents/Documents.ts                  |   2 +
 src/client/views/PropertiesButtons.tsx             |  37 ++-
 .../views/collections/CollectionDockingView.scss   |   8 +-
 .../views/collections/CollectionDockingView.tsx    |   2 +-
 .../views/collections/CollectionStackingView.tsx   |  12 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   4 +-
 .../collectionFreeForm/PropertiesView.tsx          |   4 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  20 +-
 src/client/views/nodes/PresBox.scss                |  56 +++-
 src/client/views/nodes/PresBox.tsx                 | 337 ++++++++-------------
 .../views/nodes/formattedText/FormattedTextBox.tsx |  65 ++++
 .../views/presentationview/PresElementBox.scss     |  35 ++-
 .../views/presentationview/PresElementBox.tsx      |  49 ++-
 13 files changed, 386 insertions(+), 245 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 539341b62..57fcf3a00 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -129,6 +129,7 @@ export interface DocumentOptions {
     isLinkButton?: boolean;
     _columnWidth?: number;
     _fontSize?: string;
+    _fontWeight?: number;
     _fontFamily?: string;
     curPage?: number;
     currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video)  value is in seconds
@@ -139,6 +140,7 @@ export interface DocumentOptions {
     appearFrame?: number; // the frame in which the document appears
     presTransition?: number; //the time taken for the transition TO a document
     presDuration?: number; //the duration of the slide in presentation view
+    presProgressivize?: boolean;
     // xArray?: number[];
     // yArray?: number[];
     borderRounding?: string;
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index d46c03470..7d8a75dda 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -30,6 +30,7 @@ import { undoBatch, UndoManager } from '../util/UndoManager';
 import { DocumentType } from '../documents/DocumentTypes';
 import { CollectionFreeFormView } from './collections/collectionFreeForm/CollectionFreeFormView';
 import { InkField } from '../../fields/InkField';
+import { PresBox } from './nodes/PresBox';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -209,13 +210,44 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
         return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}>
             <div className="propertiesButtons-linker"
-                style={{ backgroundColor: isPinned ? "white" : "", color: isPinned ? "black" : "white" }}
+                style={{ backgroundColor: isPinned ? "" : "white", color: isPinned ? "white" : "black" }}
                 onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
                 />
             </div></Tooltip>;
     }
 
+    @computed
+    get pinWithViewButton() {
+        const targetDoc = this.selectedDoc;
+        const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
+        if (targetDoc) {
+            const x = targetDoc._panX;
+            const y = targetDoc._panY;
+            const scale = targetDoc._viewScale;
+        }
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Pin with this view"}</div></>}>
+            <div className="propertiesButtons-linker"
+                style={{ backgroundColor: "white", color: "black" }}
+                onClick={e => {
+                    if (targetDoc) {
+                        DockedFrameRenderer.PinDoc(targetDoc, false);
+                        const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1];
+                        const x = targetDoc._panX;
+                        const y = targetDoc._panY;
+                        const scale = targetDoc._viewScale;
+                        activeDoc.presPinView = true;
+                        activeDoc.presPinViewX = x;
+                        activeDoc.presPinViewY = y;
+                        activeDoc.presPinViewScale = scale;
+                    }
+                }}>
+                <div style={{ position: 'absolute', fontSize: 25, fontWeight: 700, transform: 'translate(42%, -7px)', color: 'rgba(0,0,0,0.2)' }}>V</div>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
+            </div></Tooltip>;
+    }
+
+
     @computed
     get metadataButton() {
         //const view0 = this.view0;
@@ -607,6 +639,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             <div className="propertiesButtons-button">
                 {this.pinButton}
             </div>
+            <div className="propertiesButtons-button">
+                {this.pinWithViewButton}
+            </div>
             <div className="propertiesButtons-button">
                 {this.copyButton}
             </div>
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index 857f751d3..98babc3d2 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -45,7 +45,7 @@
 
         .miniPres-button-text {
             display: flex;
-            height: 30;
+            height: 20;
             font-weight: 400;
             min-width: 100%;
             border-radius: 5px;
@@ -55,15 +55,15 @@
         }
 
         .miniPres-divider {
-            width: 1px;
+            width: 0.5px;
             height: 80%;
             border-right: solid 2px #5a5a5a;
         }
 
         .miniPres-button {
             display: flex;
-            height: 30;
-            min-width: 30;
+            height: 20;
+            min-width: 20;
             border-radius: 100%;
             align-items: center;
             justify-content: center;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 9c85bd0a2..bc88236dd 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -871,7 +871,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     }
     renderMiniPres() {
         return <div className="miniPres" style={{
-            width: 400, height: 50, background: '#323232'
+            width: 250, height: 30, background: '#323232'
         }}>
             <div className="miniPresOverlay" >
                 <div className="miniPres-button" onClick={PresBox.Instance.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e00bdb065..fe3d57bdb 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -184,7 +184,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
         if (found) {
             const top = found.getBoundingClientRect().top;
             const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top);
-            smoothScroll(doc.presTransition ? Number(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
+            smoothScroll(doc.presTransition || doc.presTransition === 0 ? NumCast(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
         }
         afterFocus && setTimeout(() => {
             if (afterFocus?.()) { }
@@ -291,20 +291,19 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
                 const docs = this.childDocList;
                 if (docs) {
                     newDocs.map((doc, i) => {
+                        console.log(doc.title);
                         if (i === 0) {
                             if (targInd === -1) targInd = docs.length;
                             else targInd = docs.indexOf(this.filteredChildren[targInd]);
                             const srcInd = docs.indexOf(doc);
                             docs.splice(srcInd, 1);
                             docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
-                        } else {
+                        } else if (i < (newDocs.length / 2)) { //glr: for some reason dragged documents are duplicated
                             if (targInd === -1) targInd = docs.length;
-                            else targInd = docs.indexOf(this.filteredChildren[targInd]);
+                            else targInd = docs.indexOf(newDocs[0]) + 1;
                             const srcInd = docs.indexOf(doc);
-                            const firstInd = docs.indexOf(newDocs[0]);
                             docs.splice(srcInd, 1);
-                            // docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
-                            docs.splice(firstInd + 1, 0, doc);
+                            docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
                         }
                     });
                 }
@@ -312,6 +311,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
         }
         return false;
     }
+
     @undoBatch
     @action
     onExternalDrop = async (e: React.DragEvent): Promise<void> => {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 109808956..65cd28742 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -911,8 +911,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
             //     !doc.z && NumCast(this.layoutDoc.scale) < 1 && this.scaleAtPt(DocumentView._focusHack, 1); // [NumCast(doc.x), NumCast(doc.y)], 1);
             // } else {
             if (DocListCast(this.dataDoc[this.props.fieldKey]).includes(doc)) {
-                // glr: freeform transform speed can be set through user by adjusting for presentation transform
-                if (!doc.z) this.setPan(newPanX, newPanY, doc.presTransition ? `transform ${doc.presTransition}ms` : "transform 500ms", 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
+                // glr: freeform transform speed can be set by adjusting presTransition field - needs a way of knowing when presentation is not active...
+                if (!doc.z) this.setPan(newPanX, newPanY, doc.presTransition || doc.presTransition === 0 ? `transform ${doc.presTransition}ms` : "transform 500ms", 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
             }
             Doc.BrushDoc(this.props.Document);
             this.props.focus(this.props.Document);
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 1f66d4144..035cd938e 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -865,7 +865,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         if (this.isPres) {
             return <div className="propertiesView" style={{ width: this.props.width }} >
                 <div className="propertiesView-title" style={{ width: this.props.width }}>
-                    Presentation Toolbar
+                    Presentation
                 <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
                         <FontAwesomeIcon icon="times" color="black" size="sm" />
                     </div>
@@ -922,7 +922,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                     <div className="propertiesView-sharing-title"
                         onPointerDown={() => runInAction(() => { this.openSlideOptions = !this.openSlideOptions; })}
                         style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}>
-                        <FontAwesomeIcon icon={"cog"} /> &nbsp; {PresBox.Instance.stringType} options
+                        &nbsp; <FontAwesomeIcon icon={"cog"} /> &nbsp; {PresBox.Instance.stringType} options
                     <div className="propertiesView-sharing-title-icon">
                             <FontAwesomeIcon icon={this.openSlideOptions ? "caret-down" : "caret-right"} size="lg" color="white" />
                         </div>
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index c29547eac..35ed6c5a5 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -107,6 +107,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         d["w-indexed"] = new List<number>(windexed);
         d["opacity-indexed"] = new List<number>(oindexed);
         d["scroll-indexed"] = new List<number>(scrollIndexed);
+        if (d.appearFrame) {
+            if (d.appearFrame === timecode + 1) {
+                d["text-color"] = "red";
+            } else if (d.appearFrame < timecode + 1) {
+                d["text-color"] = "grey";
+            } else { d["text-color"] = "black"; }
+        } else if (d.appearFrame === 0) {
+            d["text-color"] = "black";
+        }
     }
 
     public static updateScrollframe(doc: Doc, time: number) {
@@ -139,6 +148,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number);
             yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number);
             opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
+            if (doc.appearFrame) {
+                if (doc.appearFrame === timecode + 1) {
+                    doc["text-color"] = "red";
+                } else if (doc.appearFrame < timecode + 1) {
+                    doc["text-color"] = "grey";
+                } else { doc["text-color"] = "black"; }
+            } else if (doc.appearFrame === 0) {
+                doc["text-color"] = "black";
+            }
             doc.dataTransition = "all 1s";
         });
         setTimeout(() => docs.forEach(doc => doc.dataTransition = "inherit"), 1010);
@@ -166,7 +184,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) {
         docs.forEach((doc, i) => {
-            if (!doc.appearFrame) doc.appearFrame = i;
+            if (doc.appearFrame === undefined) doc.appearFrame = i;
             const curTimecode = progressivize ? i : timecode;
             const xlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const ylist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 089f69873..16821f5bc 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -754,8 +754,6 @@
     }
 
     .presBox-button {
-        margin-right: 2.5px;
-        margin-left: 2.5px;
         height: 25px;
         border-radius: 5px;
         display: none;
@@ -787,13 +785,65 @@
         min-width: 100px;
         width: 100px;
         position: absolute;
-        right: 8px;
+        right: 10px;
 
         .present-icon {
             margin-right: 7px;
         }
     }
 
+        
+    .miniPresOverlay {
+        background-color: #323232;
+        color: white;
+        border-radius: 5px;
+        grid-template-rows: 100%;
+        height: 25;
+        width: 200;
+        justify-content: space-evenly;
+        align-items: center;
+        display: flex;
+        position: absolute;
+        right: 10px;
+
+        .miniPres-button-text {
+            display: flex;
+            height: 20;
+            width: max-content;
+            font-family: Roboto;
+            font-weight: 400;
+            letter-spacing: normal;
+            border-radius: 5px;
+            align-items: center;
+            justify-content: center;
+            transition: all 0.3s;
+        }
+
+        .miniPres-divider {
+            width: 0.5px;
+            height: 80%;
+            border-right: solid 1px #5a5a5a;
+        }
+
+        .miniPres-button {
+            display: flex;
+            height: 20;
+            min-width: 20;
+            border-radius: 100%;
+            align-items: center;
+            justify-content: center;
+            transition: all 0.3s;
+        }
+
+        .miniPres-button:hover {
+            background-color: #5a5a5a;
+        }
+
+        .miniPres-button-text:hover {
+            background-color: #5a5a5a;
+        }
+    }
+
 
 
     .collectionViewBaseChrome-viewPicker {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 2389d3875..1caefdc57 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -97,7 +97,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @action
     next = () => {
         this.updateCurrentPresentation();
+        const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null);
         const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
+        const childDocs = DocListCast(presTargetDoc[Doc.LayoutFieldKey(presTargetDoc)]);
+        const currentFrame = Cast(presTargetDoc.currentFrame, "number", null);
         const lastFrame = Cast(presTargetDoc.lastFrame, "number", null);
         const curFrame = NumCast(presTargetDoc.currentFrame);
         let internalFrames: boolean = false;
@@ -107,8 +110,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             presTargetDoc._viewTransition = "all 1s";
             setTimeout(() => presTargetDoc._viewTransition = undefined, 1010);
             presTargetDoc.currentFrame = curFrame + 1;
+            if (presTargetDoc.scrollProgressivize) CollectionFreeFormDocumentView.updateScrollframe(presTargetDoc, currentFrame);
+            if (presTargetDoc.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
             if (presTargetDoc.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc);
-            // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
+            // Case 2: Audio or video therefore wait to play the audio or video before moving on
         } else if ((presTargetDoc.type === DocumentType.VID || presTargetDoc.type === DocumentType.AUDIO) && !this._moveOnFromAudio) {
             if (presTargetDoc.type === DocumentType.AUDIO) {
                 AudioBox.Instance.playFrom(0);
@@ -117,7 +122,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             if (presTargetDoc.type === DocumentType.VID) {
                 this._moveOnFromAudio = true;
             }
-        } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
+            // Case 3: No more frames in current doc and next slide is defined, therefore move to next slide
+        } else if (activeNext !== undefined) {
+            if (!presTargetDoc.presProgressivize) {
+                const nextTagDoc = Cast(this.childDocs[this.itemIndex + 1].presentationTargetDoc, Doc, null);
+                const nextChildDocs = DocListCast(nextTagDoc[Doc.LayoutFieldKey(presTargetDoc)]);
+                nextChildDocs.forEach((doc, i) => {
+                    doc.opacity = 1;
+                })
+            }
             const nextSelected = this.itemIndex + 1;
             this.gotoDocument(nextSelected, this.itemIndex);
             this._moveOnFromAudio = false;
@@ -130,15 +143,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.updateCurrentPresentation();
         const docAtCurrent = this.childDocs[this.itemIndex];
         if (docAtCurrent) {
-            //check if any of the group members had used zooming in including the current document
-            //If so making sure to zoom out, which goes back to state before zooming action
             let prevSelected = this.itemIndex;
-            let didZoom = docAtCurrent.zoomButton;
-            // for (; !didZoom && prevSelected > 0 && this.childDocs[prevSelected].groupButton; prevSelected--) {
-            //     didZoom = this.childDocs[prevSelected].zoomButton;
-            // }
             prevSelected = Math.max(0, prevSelected - 1);
-
             this.gotoDocument(prevSelected, this.itemIndex);
         }
     }
@@ -159,19 +165,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 const panelWidth: number = srcDocView.props.PanelWidth();
                 const panelHeight: number = srcDocView.props.PanelHeight();
                 console.log("srcDocView: " + srcDocView.props.PanelWidth());
-                // console.log("layoutdoc._width: " + layoutdoc._width);
-                // console.log("srcContext._width: " + srcContext._width);
                 const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2;
                 const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2;
-                // const newPanX = NumCast(presTargetDoc.x) + panelWidth / 2;
-                // const newPanY = NumCast(presTargetDoc.y) + panelHeight / 2;
                 let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
-                // srcContext._panX = newPanX + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]) + NumCast(presTargetDoc._panX) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]) / 2));
-                // srcContext._panY = newPanY + (NumCast(presTargetDoc._viewScale) * this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]) + NumCast(presTargetDoc._panY) + (this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]) / 2));
                 srcContext._panX = newPanX + (vfLeft + (vfWidth / 2));
                 srcContext._panY = newPanY + (vfTop + (vfHeight / 2));
-                // srcContext._panX = newPanX
-                // srcContext._panY = newPanY
                 srcContext._viewScale = newScale;
                 console.log("X: " + srcContext._panX + ", Y: " + srcContext._panY + ", Scale: " + srcContext._viewScale);
             }
@@ -203,9 +201,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
             if (tagDoc) tagDoc.opacity = 1;
             if (curDoc.presHideTillShownButton) {
-                console.log("-------------hide before---------------");
-                console.log("this.itemIndex: " + this.itemIndex);
-                console.log("index: " + index)
                 if (index > this.itemIndex) {
                     tagDoc.opacity = 0;
                 } else if (!curDoc.presHideAfterButton) {
@@ -213,9 +208,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 }
             }
             if (curDoc.presHideAfterButton) {
-                console.log("-------------hide after---------------");
-                console.log("this.itemIndex: " + (this.itemIndex + 1));
-                console.log("index: " + (index + 1))
                 if (index < this.itemIndex) {
                     tagDoc.opacity = 0;
                 } else if (!curDoc.presHideTillShownButton) {
@@ -225,73 +217,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         });
     }
 
-    @action
-    onHideAfterPresClick = () => {
-        this.childDocs.forEach((doc, index) => {
-            const curDoc = Cast(doc, Doc, null);
-            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
-            if (curDoc.presHideAfterButton) {
-                if (index < this.itemIndex) {
-                    tagDoc.opacity = 0;
-                } else if (index = this.itemIndex) {
-                    tagDoc.opacity = 1;
-                }
-            }
-        });
-    }
-
-    /**
-     * This is the method that checks for the actions that need to be performed
-     * before the document has been presented, which involves 3 button options:
-     * Hide Until Presented, Hide After Presented, Fade After Presented
-     */
-    // @action
-    // hideDocumentInPres = () => {
-    //     this.updateCurrentPresentation();
-    //     this.childDocs.forEach((doc, i) => {
-    //         const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
-    //         console.log("HB: " + doc.presHideTillShownButton);
-    //         console.log("HA: " + doc.presHideAfterButton);
-    //         if (doc.presHideTillShownButton) {
-    //             if (i < this.itemIndex) {
-    //                 console.log(i + 1 + "hide before");
-    //                 tagDoc.opacity = 0;
-    //                 console.log(tagDoc.opacity);
-    //             } else {
-    //                 tagDoc.opacity = 1;
-    //             }
-    //         }
-    //         if (doc.presHideAfterButton) {
-    //             if (i > this.itemIndex) {
-    //                 console.log(i + 1 + "hide after");
-    //                 tagDoc.opacity = 0;
-    //                 console.log(tagDoc.opacity);
-    //             } else {
-    //                 tagDoc.opacity = 1;
-    //             }
-    //         }
-    //     });
-    // }
-
-    /**
-     * This is the method that checks for the actions that need to be performed
-     * after the document has been presented, which involves 3 button options:
-     * Hide Until Presented, Hide After Presented, Fade After Presented
-     */
-    // showAfterPresented = (index: number) => {
-    //     this.updateCurrentPresentation();
-    //     this.childDocs.forEach((doc, ind) => {
-    //         const presTargetDoc = doc.presentationTargetDoc as Doc;
-    //         //the order of cases is aligned based on priority
-    //         if (doc.presHideTillShownButton && ind <= index) {
-    //             presTargetDoc.opacity = 1;
-    //         }
-    //         if (doc.presHideAfterButton && ind < index) {
-    //             presTargetDoc.opacity = 0;
-    //         }
-    //     });
-    // }
-
     /**
      * This method makes sure that cursor navigates to the element that
      * has the option open and last in the group. If not in the group, and it has
@@ -310,24 +235,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 if (srcContext) this.layoutDoc.presCollection = srcContext;
             } else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
         }
-        if (srcContext) console.log("NC: " + srcContext.title);
-        if (presCollection) console.log("PC: " + presCollection.title);
         if (collectionDocView) {
-            if (activeItem.openDocument) {
-                collectionDocView.props.addDocTab(activeItem, "inPlace");
-            } else if (srcContext && srcContext !== presCollection) {
-                if (activeItem.openDocument) {
-                    collectionDocView.props.addDocTab(activeItem, "inPlace");
-                } else {
-                    console.log("Case 1: new srcContext inside of current collection so add a new tab to the current pres collection");
-                    console.log(collectionDocView);
-                    collectionDocView.props.addDocTab(srcContext, "inPlace");
-                }
+            if (srcContext && srcContext !== presCollection) {
+                // Case 1: new srcContext inside of current collection so add a new tab to the current pres collection
+                collectionDocView.props.addDocTab(srcContext, "inPlace");
             }
         }
-        if (targetDoc.presWebsiteData) {
-            targetDoc.data = targetDoc.presWebsiteData;
-        }
         // else if (srcContext) {
         //     console.log("Case 2: srcContext - not open and collection containing this document exists, so open collection that contains it and then await zooming in on document");
         //     this.props.addDocTab(srcContext, "onRight");
@@ -354,6 +267,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             //awaiting jump so that new scale can be found, since jumping is async
             targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext);
         }
+        if (activeItem.presPinView) {
+            targetDoc._panX = activeItem.presPinViewX;
+            targetDoc._panY = activeItem.presPinViewY;
+            targetDoc._viewScale = activeItem.presPinViewScale;
+        }
+        if (collectionDocView && activeItem.openDocument) {
+            collectionDocView.props.addDocTab(activeItem, "inPlace");
+        }
+        if (targetDoc.presWebsiteData) {
+            targetDoc.data = targetDoc.presWebsiteData;
+        }
     }
 
     //The function that is called when a document is clicked or reached through next or back.
@@ -381,6 +305,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @observable _presTimer!: NodeJS.Timeout;
 
     //The function that starts or resets presentaton functionally, depending on status flag.
+    @undoBatch
     @action
     startOrResetPres = (startSlide: number) => {
         this.updateCurrentPresentation();
@@ -432,31 +357,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.turnOffEdit();
         if (srcContext) {
             if (srcContext.miniPres) {
-                document.removeEventListener("keydown", this.keyEvents, false);
+                document.removeEventListener("keydown", this.minimizeEvents, false);
                 srcContext.miniPres = false;
-                // Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
                 CollectionDockingView.AddRightSplit(this.rootDoc);
-                // this.layoutDoc.inOverlay = false;
             } else {
-                document.addEventListener("keydown", this.keyEvents, false);
+                document.addEventListener("keydown", this.minimizeEvents, false);
                 srcContext.miniPres = true;
                 this.props.addDocTab?.(this.rootDoc, "close");
-                // Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
             }
         }
-        // if (srcContext) {
-        //     Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
-        //     CollectionDockingView.AddRightSplit(this.rootDoc);
-        //     this.layoutDoc.inOverlay = false;
-        // }
-        // else {
-        //         const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
-        //         this.rootDoc.x = pt[0];// 500;//e.clientX + 25;
-        //         this.rootDoc.y = pt[1];////e.clientY - 25;
-        //         this.props.addDocTab?.(this.rootDoc, "close");
-        //         Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
-        //     }
-        // }
     }
 
     @undoBatch
@@ -464,7 +373,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         //@ts-ignore
         const viewType = e.target.selectedOptions[0].value as CollectionViewType;
         viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
-        // this.updateMinimize(this.rootDoc._viewType = viewType);
+        this.rootDoc._viewType = viewType;
         if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 5;
     });
 
@@ -485,7 +394,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         } else if (movement === 'switch') {
             targetDoc.presTransition = 0;
             activeItem.presSwitchButton = !activeItem.presSwitchButton;
-            if (activeItem.presSwitchButton) activeItem.presMovement = 'Switch';
+            if (activeItem.presSwitchButton) activeItem.presMovement = 'Jump cut';
             else activeItem.presMovement = 'None';
         } else {
             activeItem.presMovement = 'None';
@@ -496,12 +405,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     });
 
     whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
+    // For dragging documents into the presentation trail
     addDocumentFilter = (doc: Doc | Doc[]) => {
         const docs = doc instanceof Doc ? [doc] : doc;
         docs.forEach((doc, i) => {
             if (this.childDocs.includes(doc)) {
-                console.log(docs.length);
-                console.log(i + 1);
                 if (docs.length === i + 1) return false;
             } else {
                 doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
@@ -574,33 +482,45 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    @action
+    minimizeEvents = (e: KeyboardEvent) => {
+        e.stopPropagation();
+        e.preventDefault();
+        if (e.keyCode === 27) { // Escape key
+            this.layoutDoc.presStatus = "edit";
+        } if (e.keyCode === 37) { // left(37) / a(65) / up(38) to go back
+            this.back();
+        } if (e.keyCode === 39) { // right (39) / d(68) / down(40) to go to next
+            this.next();
+        }
+    }
+
     //Esc click
     @action
     keyEvents = (e: KeyboardEvent) => {
         e.stopPropagation();
         e.preventDefault();
-        // switch(e.keyCode) {
-        //     case 27: console.log("escape");
-        //     case 65 && (e.metaKey || e.altKey):
-        // }
-        // Escape key
-        if (e.keyCode === 27) {
+
+        if (e.keyCode === 27) { // Escape key
             if (this.layoutDoc.presStatus === "edit") this._selectedArray = [];
             else this.layoutDoc.presStatus = "edit";
-            // Ctrl-A to select all
-        } if ((e.metaKey || e.altKey) && e.keyCode === 65) {
+        } if ((e.metaKey || e.altKey) && e.keyCode === 65) { // Ctrl-A to select all
             if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs;
-            // left(37) / a(65) / up(38) to go back
-        } if (e.keyCode === 37) {
+        } if (e.keyCode === 37) { // left(37) / a(65) / up(38) to go back
             if (this.layoutDoc.presStatus !== "edit") this.back();
-            // right (39) / d(68) / down(40) to go to next
-        } if (e.keyCode === 39) {
-            if (this.layoutDoc.presStatus !== "edit") this.next();
-            // spacebar to 'present' or go to next slide
-        } if (e.keyCode === 32) {
+        } if (e.keyCode === 39) { // right (39) / d(68) / down(40) to go to next
             if (this.layoutDoc.presStatus !== "edit") this.next();
+        } if (e.keyCode === 32) { // spacebar to 'present' or autoplay
+            if (this.layoutDoc.presStatus !== "edit") this.startOrResetPres(0);
             else this.layoutDoc.presStatus = "manual";
         }
+        if (e.keyCode === 8) { // delete selected items
+            if (this.layoutDoc.presStatus === "edit") {
+                this._selectedArray.forEach((doc, i) => {
+                    this.removeDocument(doc);
+                });
+            }
+        }
     }
 
     @observable private transitionTools: boolean = false;
@@ -617,7 +537,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     viewPaths = async () => {
         const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
         if (this.pathBoolean) {
-            console.log("true");
             if (srcContext) {
                 this.togglePath();
                 srcContext._fitToBox = false;
@@ -625,7 +544,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 srcContext.presPathView = false;
             }
         } else {
-            console.log("false");
             if (srcContext) {
                 this.togglePath();
                 srcContext._fitToBox = true;
@@ -633,13 +551,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 srcContext.presPathView = true;
             }
         }
-        console.log("view paths");
         const viewType = srcContext?._viewType;
         const fit = srcContext?._fitToBox;
-
-        // if (!DocumentManager.Instance.getDocumentView(curPres)) {
-        //     CollectionDockingView.AddRightSplit(curPres);
-        // }
     }
 
     @computed get order() {
@@ -664,7 +577,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     @computed get paths() {
         let pathPoints = "";
-        console.log(this.childDocs.length - 1);
         this.childDocs.forEach((doc, index) => {
             const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
             const srcContext = Cast(targetDoc.context, Doc, null);
@@ -678,7 +590,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 else pathPoints = pathPoints + " " + 0 + "," + 0;
             }
         });
-        console.log(pathPoints);
         return (<polyline
             points={pathPoints}
             style={{
@@ -720,12 +631,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    // WHAT IS THIS?
     @action
     dropdownToggle = (menu: string) => {
-        console.log('presBox' + menu + 'Dropdown');
         const dropMenu = document.getElementById('presBox' + menu + 'Dropdown');
-        console.log(dropMenu);
-        console.log(dropMenu?.style.display);
         if (dropMenu) dropMenu.style.display === 'none' ? dropMenu.style.display = 'block' : dropMenu.style.display = 'none';
     }
 
@@ -749,8 +658,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (activeItem && targetDoc) {
             const transitionSpeed = targetDoc.presTransition ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
             const duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2;
-            const transitionThumbLocation = String(-9.48 * Number(transitionSpeed) + 93);
-            const durationThumbLocation = String(9.48 * Number(duration));
             const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
             activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
             return (
@@ -767,7 +674,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 <div className={`presBox-dropdownOption ${activeItem.presMovement === 'None' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div>
                                 <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Zoom' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom</div>
                                 <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Pan' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Switch' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Switch</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Jump cut' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Jump cut</div>
                             </div>
                         </div>
                         <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === 'Pan' || activeItem.presMovement === 'Zoom' ? "inline-flex" : "none" }}>
@@ -985,7 +892,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
     createNewSlide = (layout?: string, title?: string, freeform?: boolean) => {
-        console.log("whats going on?");
         let doc = undefined;
         if (layout) doc = this.createTemplate(layout);
         if (freeform && layout) doc = this.createTemplate(layout, title);
@@ -1019,7 +925,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const content2 = Docs.Create.TextDocument("Click to change text", { title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt" });
         switch (layout) {
             case 'blank':
-                doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, x: x, y: y });
                 break;
             case 'title':
                 doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
@@ -1084,14 +990,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             CollectionFreeFormDocumentView.setupScroll(tagDoc, 0);
             CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
         }
-        let lastFrame: number = 0;
-        childDocs.forEach((doc) => {
-            if (NumCast(doc.appearFrame) > lastFrame) lastFrame = NumCast(doc.appearFrame);
-        });
+        // let lastFrame: number = 0;
+        // childDocs.forEach((doc) => {
+        //     if (NumCast(doc.appearFrame) > lastFrame) lastFrame = NumCast(doc.appearFrame);
+        // });
         CollectionFreeFormDocumentView.updateScrollframe(tagDoc, currentFrame);
         CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
         tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1);
-        tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), lastFrame);
+        tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), NumCast(tagDoc.lastFrame));
         if (tagDoc.zoomProgressivize) {
             const resize = document.getElementById('resizable');
             if (resize) {
@@ -1153,20 +1059,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                         <div className="ribbon-box">
                             {this.stringType} selected
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL ? "inline-flex" : "none" }}>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Child documents</div>
                                 <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "flex" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Edit</div>
                             </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
+                            <div className="ribbon-doubleButton" style={{ display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Internal zoom</div>
                                 <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Viewfinder</div>
                                 {/* <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div> */}
                             </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
                                 <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.editTextProgressivize ? "#aedef8" : "" }} onClick={this.editTextProgressivize}>Edit</div>
                             </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.PDF ? "inline-flex" : "none" }}>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.scrollProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeScroll}>Scroll progressivize</div>
                                 <div className="ribbon-button" style={{ display: activeItem.scrollProgressivize ? "flex" : "none", backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div>
                             </div>
@@ -1188,7 +1094,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 </div>
                                 <Tooltip title={<><div className="dash-tooltip">{"Last frame"}</div></>}><div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div></Tooltip>
                             </div>
-                            <div className="ribbon-button" style={{ height: 20, backgroundColor: "#5a9edd" }} onClick={() => console.log("play frames")}>Play</div>
+                            <div className="ribbon-button" style={{ height: 20, backgroundColor: "#5a9edd" }} onClick={() => console.log(" TODO: play frames")}>Play</div>
                         </div>
                     </div>
                 </div>
@@ -1298,9 +1204,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
         targetDoc.presProgressivize = !targetDoc.presProgressivize;
-        console.log(targetDoc.presProgressivize);
         if (activeItem.presProgressivize) {
-            console.log("progressivize");
             targetDoc.currentFrame = 0;
             CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
             targetDoc.lastFrame = docs.length - 1;
@@ -1350,9 +1254,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const y: List<number> = ylist;
         const tags: JSX.Element[] = [];
         let pathPoints = ""; //List of all of the pathpoints that need to be added
-        // console.log(x);
-        // console.log(x.length);
-        // console.log(x[0]);
         for (let i = 0; i < x.length - 1; i++) {
             if (y[i] || x[i]) {
                 if (i === 0) pathPoints = (x[i] - 11) + "," + (y[i] + 33);
@@ -1630,7 +1531,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @undoBatch
     @action
     nextAppearFrame = (doc: Doc, i: number): void => {
-        console.log("next");
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
         const appearFrame = Cast(doc.appearFrame, "number", null);
@@ -1638,9 +1538,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             doc.appearFrame = 0;
         }
         doc.appearFrame = appearFrame + 1;
-        const olist = new List<number>(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1));
-        doc["opacity-indexed"] = olist;
-        console.log(doc.appearFrame);
+        this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame));
     }
 
     @undoBatch
@@ -1654,9 +1552,32 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             doc.appearFrame = 0;
         }
         doc.appearFrame = Math.max(0, appearFrame - 1);
-        const olist = new List<number>(numberRange(NumCast(targetDoc.lastFrame)).map(t => targetDoc.presProgressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1));
-        doc["opacity-indexed"] = olist;
-        console.log(doc.appearFrame);
+        this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame));
+    }
+
+    @action
+    updateOpacityList = (list: any, frame: number) => {
+        const x: List<number> = list;
+        if (x && x.length >= frame) {
+            for (let i = 0; i < x.length; i++) {
+                if (i < frame) {
+                    x[i] = 0;
+                } else if (i >= frame) {
+                    x[i] = 1;
+                }
+            }
+            list = x;
+        } else {
+            x.length = frame + 1;
+            for (let i = 0; i < x.length; i++) {
+                if (i < frame) {
+                    x[i] = 0;
+                } else if (i >= frame) {
+                    x[i] = 1;
+                }
+            }
+            list = x;
+        }
     }
 
     @computed get moreInfoDropdown() {
@@ -1746,37 +1667,37 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     onPointerDown={e => e.stopPropagation()}
                     onChange={this.viewChanged}
                     value={mode}>
-                    {/* <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Invalid}>Min</option> */}
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>List</option>
-                    {/* <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Time}>Time</option> */}
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel}>Slides</option>
                 </select>
                 <div className="presBox-presentPanel">
-                    <span className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title={"Reset Presentation" + this.layoutDoc.presStatus ? "" : " From Start"} style={{ minWidth: 60, gridColumn: 2 }}>
-                        <div className="presBox-button-left" onClick={() => this.startOrResetPres(0)}>
-                            <FontAwesomeIcon icon={"clock"} /> &nbsp;
-                            <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
-                        </div>
-                        <div className={`presBox-button-right ${this.playTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePlay(); }}>
-                            <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.playTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
-                            {this.playDropdown}
-                        </div>
-                    </span>
-                    <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`} title="Present">
+                    <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
                         <div className="presBox-button-left" onClick={() => this.layoutDoc.presStatus = "manual"}><FontAwesomeIcon icon={"play-circle"} /> &nbsp; Present </div>
                         <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePresent(); }}>
                             <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
                             {this.presentDropdown}
                         </div>
                     </span>
-                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title="Back" onClick={this.back}>
-                        <FontAwesomeIcon icon={"arrow-left"} />
-                    </div>
-                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`} title="Next" onClick={this.next}>
-                        <FontAwesomeIcon icon={"arrow-right"} />
-                    </div>
-                    <div className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "edit" : ""}`} title="Next" onClick={() => this.layoutDoc.presStatus = "edit"}>
-                        <FontAwesomeIcon icon={"times"} />
+                    <div className="miniPresOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
+                        {/* <span className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`}>
+                            <div className="presBox-button-left" onClick={() => this.startOrResetPres(0)}>
+                                <FontAwesomeIcon icon={"clock"} /> &nbsp;
+                                <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
+                            </div>
+                            <div className={`presBox-button-right ${this.playTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePlay(); }}>
+                                <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.playTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
+                                {this.playDropdown}
+                            </div>
+                        </span> */}
+                        <div className="miniPres-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
+                        <div className="miniPres-button" onClick={() => this.startOrResetPres(this.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
+                        <div className="miniPres-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
+                        <div className="miniPres-divider"></div>
+                        <div className="miniPres-button-text">Slide {this.itemIndex + 1} / {this.childDocs.length}</div>
+                        <div className="miniPres-divider"></div>
+                        <div className="miniPres-button" onClick={() => this.layoutDoc.presStatus = "edit"}>
+                            <FontAwesomeIcon icon={"times"} />
+                        </div>
                     </div>
                 </div>
             </div>
@@ -1809,14 +1730,4 @@ Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, d
     if (field === '_itemIndex') return container._itemIndex;
     if (field === 'presBox') return container;
     return undefined;
-});
-
-
-
-// console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus);
-// const presOrderedDocs = DocListCast(activeItem.presOrderedDocs);
-// if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) {
-//     this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice());
-// }
-
-
+});
\ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index fc65f34eb..76d23ddfe 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -536,6 +536,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 Doc.AddDocToList(Cast(Doc.UserDoc()["template-notes"], Doc, null), "data", this.rootDoc);
             }, icon: "eye"
         });
+        appearanceItems.push({ description: "Create progressivized slide...", event: this.progressivizeText, icon: "desktop" });
         cm.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" });
 
         const options = cm.findByDescription("Options...");
@@ -547,6 +548,69 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         this._downX = this._downY = Number.NaN;
     }
 
+    progressivizeText = () => {
+        const list = this.ProseRef?.getElementsByTagName("li");
+        const mainBulletText: string[] = [];
+        const mainBulletList: Doc[] = [];
+        if (list) {
+            const newBullets: Doc[] = this.recursiveProgressivize(1, list);
+            mainBulletList.push.apply(mainBulletList, newBullets);
+        }
+        console.log(mainBulletList.length);
+        const title = Docs.Create.TextDocument(StrCast(this.rootDoc.title), { title: "Title", _width: 800, _height: 70, x: 20, y: -10, _fontSize: '20pt', backgroundColor: "rgba(0,0,0,0)", appearFrame: 0, _fontWeight: 700 });
+        mainBulletList.push(title);
+        const doc = Docs.Create.FreeformDocument(mainBulletList, {
+            title: StrCast(this.rootDoc.title),
+            x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y) + NumCast(this.props.Document._height) + 10,
+            _width: 400, _height: 225, _fitToBox: true,
+        });
+        this.props.addDocument?.(doc);
+    }
+
+    recursiveProgressivize = (nestDepth: number, list: HTMLCollectionOf<HTMLLIElement>, d?: number, y?: number, before?: string): Doc[] => {
+        const mainBulletList: Doc[] = [];
+        let b = d ? d : 0;
+        let yLoc = y ? y : 0;
+        let nestCount = 0;
+        let count: string = before ? before : '';
+        const fontSize: string = (16 - (nestDepth * 2)) + 'pt';
+        const xLoc: number = (nestDepth * 20);
+        const width: number = 390 - xLoc;
+        const height: number = 55 - (nestDepth * 5);
+        for (let i = 0; i < list.length; i++) {
+            const mainBullets: number = Number(list[i].getAttribute("data-bulletstyle"));
+            if (mainBullets === nestDepth) {
+                if (list[i].childElementCount > 1) {
+                    b++;
+                    nestCount++;
+                    count = before ? count + nestCount + "." : nestCount + ".";
+                    yLoc += height;
+                    const text = list[i].getElementsByTagName("p")[0].innerText;
+                    const length = text.length;
+                    console.log(yLoc);
+                    const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b });
+                    mainBulletList.push(bullet1);
+                    const newList = this.recursiveProgressivize(nestDepth + 1, list[i].getElementsByTagName("li"), b, yLoc, count);
+                    mainBulletList.push.apply(mainBulletList, newList);
+                    b += newList.length;
+                    yLoc += newList.length * (55 - ((nestDepth + 1) * 5));
+                } else {
+                    b++;
+                    nestCount++;
+                    count = before ? count + nestCount + "." : nestCount + ".";
+                    yLoc += height;
+                    const text = list[i].innerText;
+                    const length = text.length;
+                    console.log(yLoc);
+                    const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b });
+                    mainBulletList.push(bullet1);
+                }
+            }
+        }
+        console.log("b: " + b);
+        return mainBulletList;
+    }
+
     recordDictation = () => {
         DictationManager.Controls.listen({
             interimHandler: this.setCurrentBulletContent,
@@ -1374,6 +1438,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                         color: this.props.color ? this.props.color : StrCast(this.layoutDoc[this.props.fieldKey + "-color"], this.props.hideOnLeave ? "white" : "inherit"),
                         pointerEvents: interactive ? undefined : "none",
                         fontSize: Cast(this.layoutDoc._fontSize, "string", null),
+                        fontWeight: Cast(this.layoutDoc._fontWeight, "number", null),
                         fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"),
                         transition: "opacity 1s"
                     }}
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 159cb5f8a..fa70b2a41 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -2,7 +2,8 @@
     display: grid;
     grid-template-columns: max-content max-content max-content;
     background-color: #d5dce2;
-    // box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.25);
+    font-family: Roboto;
+    letter-spacing: normal;
     position: relative;
     pointer-events: all;
     width: 100%;
@@ -21,13 +22,30 @@
 
     .presElementBox-highlight {
         position: absolute;
-        transform: translate(-100px, -6px);
+        transform: translate(-100px, -4px);
         z-index: -1;
         width: calc(100% + 200px);
-        height: calc(100% + 12px);
+        height: calc(100% + 8px);
         background-color: #AEDDF8;
     }
 
+    .presElementBox-highlightTop {
+        position: absolute;
+        transform: translate(-100px, -4px);
+        z-index: -1;
+        width: calc(100% + 200px);
+        height: calc(50% + 4px);
+    }
+
+    .presElementBox-highlightBottom {
+        position: absolute;
+        transform: translate(-100px, 0px);
+        z-index: -1;
+        top: 50%;
+        width: calc(100% + 200px);
+        height: calc(50% + 4px);
+    }
+
     .documentView-node {
         position: absolute;
         z-index: 1;
@@ -79,8 +97,12 @@
 
 .presElementBox-number {
     font-size: 12px;
+    width: 20;
     font-weight: 700;
-    left: -15;
+    text-align: right;
+    justify-content: center;
+    align-content: center;
+    left: -20;
     position: absolute;
     display: inline-block;
     overflow: hidden;
@@ -110,9 +132,8 @@
     font-size: 10;
     font-weight: 300;
     font-family: Roboto;
-    /* font-style: italic; */
+    z-index: 300;
     letter-spacing: normal;
-    /* left: 10px; */
 }
 
 .presElementBox-embedded {
@@ -174,7 +195,7 @@
     bottom: 3px;
     width: 20px;
     height: 20px;
-    z-index: 200;
+    z-index: 300;
     display: flex;
     background-color: black;
     color: white;
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index b3d8cca98..e035ed0b8 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -220,7 +220,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         let durationInS: number;
         if (this.targetDoc.presDuration) durationInS = NumCast(this.targetDoc.presDuration) / 1000;
         else durationInS = 2;
-        return "V: " + durationInS + "s";
+        return "D: " + durationInS + "s";
     }
 
     @computed get transition() {
@@ -245,25 +245,61 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         }
     }
 
+    headerUp = (e: React.PointerEvent<HTMLDivElement>) => {
+        e.stopPropagation();
+        e.preventDefault();
+        DragManager.docsBeingDragged = [];
+        this._highlightTopRef.current!.style.borderBottom = "0px";
+        this._highlightBottomRef.current!.style.borderBottom = "0px";
+    }
+
     startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
         // const ele: HTMLElement[] = PresBox.Instance._eleArray.map(doc => doc);
         const activeItem = this.rootDoc;
         const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray().map(doc => doc));
         // let value = this.getValue(this._heading);
         // value = typeof value === "string" ? `"${value}"` : value;
+        let dragItem: HTMLElement[] = [];
+        PresBox.Instance._dragArray.map(ele => {
+            const drag = ele;
+            drag.style.backgroundColor = "#d5dce2";
+            drag.style.borderRadius = '5px';
+            dragItem.push(drag);
+        });
         if (activeItem) {
-            DragManager.StartDocumentDrag(PresBox.Instance._dragArray.map(ele => ele), dragData, e.clientX, e.clientY);
+            DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY);
             activeItem.dragging = true;
             return true;
         }
         return false;
     }
 
+    private _highlightTopRef: React.RefObject<HTMLDivElement> = React.createRef();
+    private _highlightBottomRef: React.RefObject<HTMLDivElement> = React.createRef();
 
 
+    onPointerTop = (e: React.PointerEvent<HTMLDivElement>) => {
+        if (DragManager.docsBeingDragged.length > 0) {
+            this._highlightTopRef.current!.style.borderTop = "solid 2px #5B9FDD";
+        }
+    }
+
+    onPointerBottom = (e: React.PointerEvent<HTMLDivElement>) => {
+        if (DragManager.docsBeingDragged.length > 0) {
+            this._highlightBottomRef.current!.style.borderBottom = "solid 2px #5B9FDD";
+        }
+    }
+
+    onPointerLeave = (e: React.PointerEvent<HTMLDivElement>) => {
+        if (DragManager.docsBeingDragged.length > 0) {
+            this._highlightBottomRef.current!.style.borderBottom = "0px";
+            this._highlightTopRef.current!.style.borderTop = "0px";
+        }
+    }
+
     render() {
         const treecontainer = this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Tree;
-        const className = "presElementBox-item" + (this.itemIndex === this.indexInPres ? " presElementBox-active" : "");
+        const className = "presElementBox-item" + (PresBox.Instance._selectedArray.includes(this.rootDoc) ? " presElementBox-active" : "");
         const pbi = "presElementBox-interaction";
         return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : (
             <div className={className} key={this.props.Document[Id] + this.indexInPres}
@@ -288,6 +324,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     }
                 }}
                 onPointerDown={this.headerDown}
+                onPointerUp={this.headerUp}
             >
                 <>
                     <div className="presElementBox-number">
@@ -297,7 +334,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                         {`${this.targetDoc?.title}`}
                     </div>
                     <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.transition}</div></Tooltip>
-                    <Tooltip title={<><div className="dash-tooltip">{"Duration of visibility"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.duration}</div></Tooltip>
+                    <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.duration}</div></Tooltip>
                     <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><div
                         className="presElementBox-closeIcon"
                         // onPointerDown={e => e.stopPropagation()}
@@ -311,7 +348,9 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                         <FontAwesomeIcon icon={(this.rootDoc.presExpandInlineButton ? "angle-up" : "angle-down")} onPointerDown={e => e.stopPropagation()} />
                     </div></Tooltip>
                 </>
-                <div className="presElementBox-highlight" style={{ display: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "block" : "none" }} />
+                <div ref={this._highlightTopRef} onPointerOver={this.onPointerTop} onPointerLeave={this.onPointerLeave} className="presElementBox-highlightTop" style={{ zIndex: 299, backgroundColor: "rgba(0,0,0,0)" }} />
+                <div ref={this._highlightBottomRef} onPointerOver={this.onPointerBottom} onPointerLeave={this.onPointerLeave} className="presElementBox-highlightBottom" style={{ zIndex: 299, backgroundColor: "rgba(0,0,0,0)" }} />
+                <div className="presElementBox-highlight" style={{ backgroundColor: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "#AEDDF8" : "rgba(0,0,0,0)" }} />
                 <div className="presElementBox-buttons" style={{ display: this.rootDoc.presExpandInlineButton ? "grid" : "none" }}>
                     <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} onPointerDown={e => e.stopPropagation()} /></button>
                     <button title="Navigate" className={pbi + (this.rootDoc.presNavButton ? "-selected" : "")} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} /></button>
-- 
cgit v1.2.3-70-g09d2


From cc905d329c88d7bdf9b7324a4f02ab92906ba7c8 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 5 Aug 2020 22:20:49 -0400
Subject: cleanup of presentation code pre-merge.

---
 src/client/documents/Documents.ts                  |  4 --
 src/client/util/CurrentUserUtils.ts                |  8 ++--
 src/client/views/InkingStroke.tsx                  |  6 +--
 src/client/views/MainView.tsx                      |  2 +-
 .../CollectionStackingViewFieldColumn.tsx          |  3 +-
 .../views/collections/CollectionTreeView.tsx       |  1 -
 .../collectionFreeForm/PropertiesView.tsx          |  4 +-
 src/client/views/nodes/AudioBox.tsx                |  1 -
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 11 +----
 src/client/views/nodes/DocumentLinksButton.tsx     |  2 +-
 src/client/views/nodes/PresBox.tsx                 | 49 ++++++++++------------
 .../views/nodes/formattedText/FormattedTextBox.tsx | 17 ++++----
 .../views/nodes/formattedText/RichTextMenu.tsx     |  3 +-
 .../views/presentationview/PresElementBox.tsx      |  2 +-
 14 files changed, 46 insertions(+), 67 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 57fcf3a00..959aeac41 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -801,10 +801,6 @@ export namespace Docs {
             return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { hideLinkButton: true, ...(options || {}) });
         }
 
-        export function MenuIconDocument(options?: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.MENUICON), undefined, { hideLinkButton: true, ...(options || {}) });
-        }
-
         export function PresElementBoxDocument(options?: DocumentOptions) {
             return InstanceFromProto(Prototypes.get(DocumentType.PRESELEMENT), undefined, { ...(options || {}) });
         }
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 8023df8b4..4e59434b5 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -546,7 +546,7 @@ export class CurrentUserUtils {
                     btn.color = "white";
                     btn._backgroundColor = "";
                 }));
-            })
+            });
         });
         return doc.menuStack as Doc;
     }
@@ -763,13 +763,13 @@ export class CurrentUserUtils {
     }
 
     static setupSidebarContainer(doc: Doc) {
-        if (doc["sidebar"] === undefined) {
+        if (doc.sidebar === undefined) {
             const sidebarContainer = new Doc();
             sidebarContainer._chromeStatus = "disabled";
             sidebarContainer.onClick = ScriptField.MakeScript("freezeSidebar()");
-            doc["sidebar"] = new PrefetchProxy(sidebarContainer);
+            doc.sidebar = new PrefetchProxy(sidebarContainer);
         }
-        return doc["sidebar"] as Doc;
+        return doc.sidebar as Doc;
     }
 
     // setup the list of sidebar mode buttons which determine what is displayed in the sidebar
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 6c5eda256..4a77728b6 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -115,9 +115,9 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
             StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
             "none", "none", "0", scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true);
 
-        var controlPoints: { X: number, Y: number, I: number }[] = [];
-        var handlePoints: { X: number, Y: number, I: number, dot1: number, dot2: number }[] = [];
-        var handleLine: { X1: number, Y1: number, X2: number, Y2: number, X3: number, Y3: number, dot1: number, dot2: number }[] = [];
+        const controlPoints: { X: number, Y: number, I: number }[] = [];
+        const handlePoints: { X: number, Y: number, I: number, dot1: number, dot2: number }[] = [];
+        const handleLine: { X1: number, Y1: number, X2: number, Y2: number, X3: number, Y3: number, dot1: number, dot2: number }[] = [];
         if (data.length >= 4) {
             for (var i = 0; i <= data.length - 4; i += 4) {
                 controlPoints.push({ X: data[i].X, Y: data[i].Y, I: i });
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 138ff226f..7f50dda72 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -80,7 +80,7 @@ export class MainView extends React.Component {
     @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; }
     @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs && docs.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
 
-    @observable public sidebarContent: any = this.userDoc?.["sidebar"];
+    @observable public sidebarContent: any = this.userDoc?.sidebar;
     @observable public panelContent: string = "none";
     @observable public showProperties: boolean = false;
     public isPointerDown = false;
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 68c233a16..fbc4e1552 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -12,6 +12,7 @@ import { NumCast, StrCast, Cast } from "../../../fields/Types";
 import { ImageField } from "../../../fields/URLField";
 import { TraceMobx } from "../../../fields/util";
 import { Docs, DocUtils } from "../../documents/Documents";
+import { DocumentType } from "../../documents/DocumentTypes";
 import { DragManager } from "../../util/DragManager";
 import { Transform } from "../../util/Transform";
 import { undoBatch } from "../../util/UndoManager";
@@ -366,7 +367,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                             {this.props.parent.children(this.props.docList, uniqueHeadings.length)}
                             {singleColumn ? (null) : this.props.parent.columnDragger}
                         </div>
-                        {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled' && type !== 'presentation') ?
+                        {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled' && type !== DocumentType.PRES) ?
                             <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
                                 style={{ width: style.columnWidth / style.numGroupColumns }}>
                                 <EditableView {...newEditableViewProps} menuCallback={this.menuCallback} />
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 8ec855c7c..3c7471d7c 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -133,7 +133,6 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
-        console.log("ele");
         this._treedropDisposer?.();
         ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), undefined, this.preTreeDrop.bind(this)), this.doc);
     }
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 2b0a00498..dcbf8e989 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -552,7 +552,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
 
     getField(key: string) {
         //if (this.selectedDoc) {
-        return Field.toString(this.selectedDoc[key] as Field);
+        return Field.toString(this?.[key] as Field);
         // } else {
         //     return undefined as Opt<string>;
         // }
@@ -698,7 +698,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 <input className="width-range" type="range"
                     defaultValue={Number(this.widthStk)} min={1} max={100}
                     onChange={(action((e) => this.widthStk = e.target.value))}
-                    onMouseDown={(e) => { this._widthUndo = UndoManager.StartBatch("width undo");; }}
+                    onMouseDown={(e) => { this._widthUndo = UndoManager.StartBatch("width undo"); }}
                     onMouseUp={(e) => { this._widthUndo?.end(); this._widthUndo = undefined; }}
                 />
             </div>
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index dba92faae..2396e6973 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -21,7 +21,6 @@ import { Docs, DocUtils } from "../../documents/Documents";
 import { ComputedField } from "../../../fields/ScriptField";
 import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
-import { signedCookie } from "cookie-parser";
 
 // testing testing 
 
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 35ed6c5a5..42a42ddf1 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -18,8 +18,6 @@ import { DocumentType } from "../../documents/DocumentTypes";
 import { Zoom, Fade, Flip, Rotate, Bounce, Roll, LightSpeed } from 'react-reveal';
 import { PresBox } from "./PresBox";
 import { InkingStroke } from "../InkingStroke";
-import { PDFViewer } from "../pdf/PDFViewer";
-import { PDFBox } from "./PDFBox";
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -119,7 +117,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     }
 
     public static updateScrollframe(doc: Doc, time: number) {
-        let _pdfViewer: PDFViewer | undefined;
         const timecode = Math.round(time);
         const scrollIndexed = Cast(doc['scroll-indexed'], listSpec("number"), null);
         scrollIndexed?.length <= timecode + 1 && scrollIndexed.push(undefined as any as number);
@@ -191,15 +188,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             const wlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const hlist = new List<number>(numberRange(timecode + 1).map(i => undefined) as any as number[]);
             const olist = new List<number>(numberRange(timecode + 1).map(t => progressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1));
-            let oarray: List<number>;
-            console.log(doc.title + "AF: " + doc.appearFrame);
-            console.log("timecode: " + timecode);
-            oarray = olist;
+            const oarray = olist;
             oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
             oarray.fill(1, NumCast(doc.appearFrame), timecode);
             // oarray.fill(0, 0, NumCast(doc.appearFrame) - 1);
-            // oarray.fill(1, NumCast(doc.appearFrame), timecode);
-            // console.log(oarray);
+            // oarray.fill(1, NumCast(doc.appearFrame), timecode);\
             wlist[curTimecode] = NumCast(doc._width);
             hlist[curTimecode] = NumCast(doc._height);
             xlist[curTimecode] = NumCast(doc.x);
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 4713ce447..025669b41 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -125,7 +125,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
         } else if (this.props.InMenu && !this.props.StartLink && DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) {
             const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
             // this notifies any of the subviews that a document is made so that they can make finer-grained hyperlinks ().  see note above in onLInkButtonMoved
-            DocumentLinksButton.StartLink!._link = this.props.View._link = linkDoc;
+            DocumentLinksButton.StartLink._link = this.props.View._link = linkDoc;
             setTimeout(action(() => DocumentLinksButton.StartLink!._link = this.props.View._link = undefined), 0);
             LinkManager.currentLink = linkDoc;
             if (linkDoc) {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 1caefdc57..ccf1fb8e3 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -129,7 +129,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 const nextChildDocs = DocListCast(nextTagDoc[Doc.LayoutFieldKey(presTargetDoc)]);
                 nextChildDocs.forEach((doc, i) => {
                     doc.opacity = 1;
-                })
+                });
             }
             const nextSelected = this.itemIndex + 1;
             this.gotoDocument(nextSelected, this.itemIndex);
@@ -158,28 +158,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const vfHeight: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]);
         // Case 1: document that is not a Golden Layout tab
         if (srcContext) {
-            console.log("CASE 1");
             const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
             if (srcDocView) {
                 const layoutdoc = Doc.Layout(presTargetDoc);
                 const panelWidth: number = srcDocView.props.PanelWidth();
                 const panelHeight: number = srcDocView.props.PanelHeight();
-                console.log("srcDocView: " + srcDocView.props.PanelWidth());
                 const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2;
                 const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2;
-                let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
+                const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
                 srcContext._panX = newPanX + (vfLeft + (vfWidth / 2));
                 srcContext._panY = newPanY + (vfTop + (vfHeight / 2));
                 srcContext._viewScale = newScale;
-                console.log("X: " + srcContext._panX + ", Y: " + srcContext._panY + ", Scale: " + srcContext._viewScale);
             }
         }
         // Case 2: document is the containing collection
         if (docView && !srcContext) {
-            console.log("CASE 2");
             const panelWidth: number = docView.props.PanelWidth();
             const panelHeight: number = docView.props.PanelHeight();
-            let newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
+            const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
             presTargetDoc._panX = vfLeft + (vfWidth / 2);
             presTargetDoc._panY = vfTop + (vfWidth / 2);
             presTargetDoc._viewScale = newScale;
@@ -791,7 +787,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 <div className="ribbon-button" style={{ display: "flex", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Start manually</div>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: "flex" }}>
-                                <div className="ribbon-button" style={{ backgroundColor: activeItem.openDocument ? "#aedef8" : "" }} onClick={() => { activeItem.openDocument = !activeItem.openDocument }}>Open document</div>
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.openDocument ? "#aedef8" : "" }} onClick={() => activeItem.openDocument = !activeItem.openDocument}>Open document</div>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.WEB ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Store original website</div>
@@ -808,15 +804,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             <div>
                 <div className={'presBox-toolbar-dropdown'} style={{ display: this.newDocumentTools && this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                     <div className="layout-container" style={{ height: 'max-content' }}>
-                        <div className="layout" style={{ border: this.layout === 'blank' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} />
-                        <div className="layout" style={{ border: this.layout === 'title' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}>
+                        <div className="layout" style={{ border: this.layout === 'blank' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} />
+                        <div className="layout" style={{ border: this.layout === 'title' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}>
                             <div className="title">Title</div>
                             <div className="subtitle">Subtitle</div>
                         </div>
-                        <div className="layout" style={{ border: this.layout === 'header' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}>
+                        <div className="layout" style={{ border: this.layout === 'header' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}>
                             <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
                         </div>
-                        <div className="layout" style={{ border: this.layout === 'content' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}>
+                        <div className="layout" style={{ border: this.layout === 'content' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}>
                             <div className="title" style={{ alignSelf: 'center' }}>Title</div>
                             <div className="content">Text goes here</div>
                         </div>
@@ -845,39 +841,39 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         {/* <div className="dropdown-textInput"> */}
                         <input className="ribbon-textInput" placeholder="..." type="text" name="fname" ref={this.inputRef} onChange={(e) => {
                             e.stopPropagation();
-                            runInAction(() => { (this.title = e.target.value) });
+                            runInAction(() => this.title = e.target.value);
                         }}></input>
                         {/* </div> */}
                     </div>
                     <div className="ribbon-box">
                         Choose type:
                         <div className="ribbon-doubleButton">
-                            <div title="Text" className={'ribbon-button'} style={{ background: this.addFreeform ? "" : "#aedef8" }} onClick={() => runInAction(() => { this.addFreeform = !this.addFreeform })}>Text</div>
-                            <div title="Freeform" className={'ribbon-button'} style={{ background: this.addFreeform ? "#aedef8" : "" }} onClick={() => runInAction(() => { this.addFreeform = !this.addFreeform })}>Freeform</div>
+                            <div title="Text" className={'ribbon-button'} style={{ background: this.addFreeform ? "" : "#aedef8" }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Text</div>
+                            <div title="Freeform" className={'ribbon-button'} style={{ background: this.addFreeform ? "#aedef8" : "" }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Freeform</div>
                         </div>
                     </div>
                     <div className="ribbon-box" style={{ display: this.addFreeform ? "grid" : "none" }}>
                         Preset layouts:
                         <div className="layout-container" style={{ height: this.openLayouts ? 'max-content' : '75px' }}>
-                            <div className="layout" style={{ border: this.layout === 'blank' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'blank' })} />
-                            <div className="layout" style={{ border: this.layout === 'title' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'title' })}>
+                            <div className="layout" style={{ border: this.layout === 'blank' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => this.layout = 'blank')} />
+                            <div className="layout" style={{ border: this.layout === 'title' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => this.layout = 'title')}>
                                 <div className="title">Title</div>
                                 <div className="subtitle">Subtitle</div>
                             </div>
-                            <div className="layout" style={{ border: this.layout === 'header' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'header' })}>
+                            <div className="layout" style={{ border: this.layout === 'header' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => this.layout = 'header')}>
                                 <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
                             </div>
-                            <div className="layout" style={{ border: this.layout === 'content' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'content' })}>
+                            <div className="layout" style={{ border: this.layout === 'content' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => this.layout = 'content')}>
                                 <div className="title" style={{ alignSelf: 'center' }}>Title</div>
                                 <div className="content">Text goes here</div>
                             </div>
-                            <div className="layout" style={{ border: this.layout === 'twoColumns' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'twoColumns' })}>
+                            <div className="layout" style={{ border: this.layout === 'twoColumns' ? 'solid 2px #5b9ddd' : '' }} onClick={action(() => this.layout = 'twoColumns')}>
                                 <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>Title</div>
                                 <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>Column one text</div>
                                 <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>Column two text</div>
                             </div>
                         </div>
-                        <div className="open-layout" onClick={() => runInAction(() => { this.openLayouts = !this.openLayouts })}>
+                        <div className="open-layout" onClick={action(() => this.openLayouts = !this.openLayouts)}>
                             <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"caret-down"} size={"lg"} />
                         </div>
                     </div>
@@ -974,10 +970,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
     // For toggling the options when the user wants to select play
-    @action togglePlay = () => { this.playTools = !this.playTools; }
+    @action togglePlay = () => { this.playTools = !this.playTools; };
 
     // For toggling the options when the user wants to select play
-    @action togglePresent = () => { this.presentTools = !this.presentTools; }
+    @action togglePresent = () => { this.presentTools = !this.presentTools; };
 
     // Case in which the document has keyframes to navigate to next key frame
     @undoBatch
@@ -1381,9 +1377,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (doc && tagDocView) {
 
             const scale = tagDocView.childScaling();
-            console.log("childScaling: " + scale);
             const scale2 = tagDocView.props.ScreenToLocalTransform().Scale;
-            console.log("ScreenToLocal...Scale: " + scale2);
             let height = doc.offsetHeight;
             let width = doc.offsetWidth;
             let top = doc.offsetTop;
@@ -1544,7 +1538,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @undoBatch
     @action
     prevAppearFrame = (doc: Doc, i: number): void => {
-        console.log("prev");
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
         const appearFrame = Cast(doc.appearFrame, "number", null);
@@ -1595,7 +1588,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (activeItem) {
             return (
                 <>
-                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={() => runInAction(() => { this.newDocumentTools = !this.newDocumentTools; })}><FontAwesomeIcon icon={"plus"} />
+                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}><FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
                     <div className="toolbar-divider" />
@@ -1636,7 +1629,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         } else {
             return (
                 <>
-                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={() => runInAction(() => { this.newDocumentTools = !this.newDocumentTools; })}>
+                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
                         <FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 76d23ddfe..ab1de5529 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -577,20 +577,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         const xLoc: number = (nestDepth * 20);
         const width: number = 390 - xLoc;
         const height: number = 55 - (nestDepth * 5);
-        for (let i = 0; i < list.length; i++) {
-            const mainBullets: number = Number(list[i].getAttribute("data-bulletstyle"));
+        Array.from(list).forEach(listItem => {
+            const mainBullets: number = Number(listItem.getAttribute("data-bulletstyle"));
             if (mainBullets === nestDepth) {
-                if (list[i].childElementCount > 1) {
+                if (listItem.childElementCount > 1) {
                     b++;
                     nestCount++;
                     count = before ? count + nestCount + "." : nestCount + ".";
                     yLoc += height;
-                    const text = list[i].getElementsByTagName("p")[0].innerText;
+                    const text = listItem.getElementsByTagName("p")[0].innerText;
                     const length = text.length;
-                    console.log(yLoc);
                     const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b });
                     mainBulletList.push(bullet1);
-                    const newList = this.recursiveProgressivize(nestDepth + 1, list[i].getElementsByTagName("li"), b, yLoc, count);
+                    const newList = this.recursiveProgressivize(nestDepth + 1, listItem.getElementsByTagName("li"), b, yLoc, count);
                     mainBulletList.push.apply(mainBulletList, newList);
                     b += newList.length;
                     yLoc += newList.length * (55 - ((nestDepth + 1) * 5));
@@ -599,15 +598,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     nestCount++;
                     count = before ? count + nestCount + "." : nestCount + ".";
                     yLoc += height;
-                    const text = list[i].innerText;
+                    const text = listItem.innerText;
                     const length = text.length;
-                    console.log(yLoc);
                     const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b });
                     mainBulletList.push(bullet1);
                 }
             }
-        }
-        console.log("b: " + b);
+        });
         return mainBulletList;
     }
 
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 6e268be48..5af07c15d 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -903,8 +903,9 @@ export default class RichTextMenu extends AntimodeMenu {
             ref_node = pos.nodeBefore;
         }
         if (pos.nodeAfter !== null && pos.nodeAfter !== undefined) {
-            if (!pos.nodeBefore || this.view.state.selection.$from.pos !== this.view.state.selection.$to.pos)
+            if (!pos.nodeBefore || this.view.state.selection.$from.pos !== this.view.state.selection.$to.pos) {
                 ref_node = pos.nodeAfter;
+            }
         }
         if (!ref_node && pos.pos > 0) {
             let skip = false;
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index e035ed0b8..11ffde9dd 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -259,7 +259,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray().map(doc => doc));
         // let value = this.getValue(this._heading);
         // value = typeof value === "string" ? `"${value}"` : value;
-        let dragItem: HTMLElement[] = [];
+        const dragItem: HTMLElement[] = [];
         PresBox.Instance._dragArray.map(ele => {
             const drag = ele;
             drag.style.backgroundColor = "#d5dce2";
-- 
cgit v1.2.3-70-g09d2


From 0bd77219c2f470f5b2a8680cf9712f5947f22bd1 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Thu, 6 Aug 2020 15:13:43 +0800
Subject: pin with view button UI and other small changes

---
 src/client/views/PropertiesButtons.tsx | 46 ++++++++++++++++------------------
 src/client/views/nodes/PresBox.scss    | 10 +++++---
 src/client/views/nodes/PresBox.tsx     |  7 +++---
 3 files changed, 33 insertions(+), 30 deletions(-)

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

diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 642476bc3..002abc5a3 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -237,36 +237,34 @@ export class PropertiesButtons extends React.Component<{}, {}> {
     @computed
     get pinWithViewButton() {
         const targetDoc = this.selectedDoc;
-        const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
         if (targetDoc) {
             const x = targetDoc._panX;
             const y = targetDoc._panY;
             const scale = targetDoc._viewScale;
         }
         return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Pin with this view"}</div></>}>
-            <div className="propertiesButtons-linker"
-                style={{ backgroundColor: "black", color: "white" }}
-                onClick={e => {
-                    if (targetDoc) {
-                        DockedFrameRenderer.PinDoc(targetDoc, false);
-                        const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1];
-                        const x = targetDoc._panX;
-                        const y = targetDoc._panY;
-                        const scale = targetDoc._viewScale;
-                        activeDoc.presPinView = true;
-                        activeDoc.presPinViewX = x;
-                        activeDoc.presPinViewY = y;
-                        activeDoc.presPinViewScale = scale;
-                    }
-                }}>
-                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
-                <div style={{ position: 'relative', fontSize: 25, fontWeight: 700, transform: 'translate(42%, -7px)', color: 'rgba(0,0,0,0.2)' }}>V</div>
-                <div className="propertiesButtons-title" style={{
-                    backgroundColor: "black",
-                    color: "white"
-                }}
-                >{"Pin with view"}</div>
-            </div></Tooltip>;
+            <>
+                <div className="propertiesButtons-linker"
+                    style={{ backgroundColor: "black", color: "white" }}
+                    onClick={e => {
+                        if (targetDoc) {
+                            DockedFrameRenderer.PinDoc(targetDoc, false);
+                            const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1];
+                            const x = targetDoc._panX;
+                            const y = targetDoc._panY;
+                            const scale = targetDoc._viewScale;
+                            activeDoc.presPinView = true;
+                            activeDoc.presPinViewX = x;
+                            activeDoc.presPinViewY = y;
+                            activeDoc.presPinViewScale = scale;
+                        }
+                    }}>
+                    <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
+                    <div style={{ position: 'relative', fontSize: 25, fontWeight: 700, transform: 'translate(0, -20px)', color: 'rgba(250,250,250,0.5)' }}>V</div>
+                </div>
+                <div className="propertiesButtons-title" style={{ backgroundColor: "black", color: "white" }}>{"View"}</div>
+            </>
+        </Tooltip>;
     }
 
 
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 16821f5bc..8ce71935c 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -30,7 +30,7 @@
         transform: translate(8px, -5px);
         box-shadow: 1px 1px 4px 4px rgba(0, 0, 0, 0.25);
         z-index: 1000;
-        width: 315;
+        width: calc(100% - 50px);
         height: max-content;
         justify-self: center;
         letter-spacing: normal;
@@ -583,6 +583,8 @@
     align-items: center;
     justify-content: center;
     border-radius: 4px;
+    padding-left: 7px;
+    padding-right: 7px;
     border-bottom-right-radius: 0;
     border-top-right-radius: 0;
 }
@@ -597,6 +599,8 @@
     align-items: center;
     justify-content: center;
     border-radius: 4px;
+    padding-left: 7px;
+    padding-right: 7px;
     border-bottom-left-radius: 0;
     border-top-left-radius: 0;
 }
@@ -722,6 +726,7 @@
     position: relative;
     width: 100%;
     background: gray;
+    min-height: 35px;
     padding-top: 5px;
     padding-bottom: 5px;
     display: grid;
@@ -782,8 +787,7 @@
 
     .presBox-button.present {
         display: flex;
-        min-width: 100px;
-        width: 100px;
+        width: max-content;
         position: absolute;
         right: 10px;
 
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index ccf1fb8e3..c3b920b26 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -1064,10 +1064,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                                 <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Viewfinder</div>
                                 {/* <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div> */}
                             </div>
-                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}>
+                            {/* <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
                                 <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.editTextProgressivize ? "#aedef8" : "" }} onClick={this.editTextProgressivize}>Edit</div>
-                            </div>
+                            </div> */}
                             <div className="ribbon-doubleButton" style={{ display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.scrollProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeScroll}>Scroll progressivize</div>
                                 <div className="ribbon-button" style={{ display: activeItem.scrollProgressivize ? "flex" : "none", backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div>
@@ -1657,6 +1657,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return <div onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
             <div className="presBox-buttons" style={{ display: this.rootDoc._chromeStatus === "disabled" ? "none" : undefined }}>
                 <select className="presBox-viewPicker"
+                    style={{ display: this.layoutDoc.presStatus === "edit" ? "block" : "none" }}
                     onPointerDown={e => e.stopPropagation()}
                     onChange={this.viewChanged}
                     value={mode}>
@@ -1665,7 +1666,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 </select>
                 <div className="presBox-presentPanel">
                     <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
-                        <div className="presBox-button-left" onClick={() => this.layoutDoc.presStatus = "manual"}><FontAwesomeIcon icon={"play-circle"} /> &nbsp; Present </div>
+                        <div className="presBox-button-left" onClick={() => this.layoutDoc.presStatus = "manual"}><FontAwesomeIcon icon={"play-circle"} /> <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present </div></div>
                         <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePresent(); }}>
                             <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
                             {this.presentDropdown}
-- 
cgit v1.2.3-70-g09d2


From 557bcff59aaec470b045a01600b0c2a6e785c730 Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Thu, 6 Aug 2020 18:05:24 +0800
Subject: ui changes and commenting code

also removed _viewTransition and backgroundColor...
---
 src/client/util/DocumentManager.ts                 |   6 +-
 src/client/views/.DS_Store                         | Bin 6148 -> 6148 bytes
 src/client/views/PropertiesButtons.tsx             |   4 +-
 src/client/views/nodes/PresBox.scss                |  47 +-
 src/client/views/nodes/PresBox.tsx                 | 485 +++++++++++----------
 .../views/presentationview/PresElementBox.scss     |   8 +-
 .../views/presentationview/PresElementBox.tsx      |  10 +-
 7 files changed, 292 insertions(+), 268 deletions(-)

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

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index d18eac374..523dbfca0 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -127,10 +127,6 @@ export class DocumentManager {
         CollectionDockingView.AddRightSplit(doc);
         finished?.();
     }
-    // static openInPlace = (doc: Doc, finished?: () => void) => {
-    //     CollectionDockingView.AddTab(doc);
-    //     finished?.();
-    // }
     public jumpToDocument = async (
         targetDoc: Doc,        // document to display
         willZoom: boolean,     // whether to zoom doc to take up most of screen
@@ -180,7 +176,7 @@ export class DocumentManager {
                 const targetDocContextView = getFirstDocView(targetDocContext);
                 targetDocContext._scrollY = 0;  // this will force PDFs to activate and load their annotations / allow scrolling
                 if (targetDocContextView) { // we found a context view and aren't forced to create a new one ... focus on the context first..
-                    targetDocContext._viewTransition = "transform 10000ms";
+                    targetDocContext._viewTransition = "transform 500ms";
                     targetDocContextView.props.focus(targetDocContextView.props.Document, willZoom);
 
                     // now find the target document within the context
diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store
index 3ce88292c..7a8c419ee 100644
Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 002abc5a3..3392371de 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -242,7 +242,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             const y = targetDoc._panY;
             const scale = targetDoc._viewScale;
         }
-        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Pin with this view"}</div></>}>
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Pin with this view"}</div></>} placement="top">
             <>
                 <div className="propertiesButtons-linker"
                     style={{ backgroundColor: "black", color: "white" }}
@@ -259,7 +259,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                             activeDoc.presPinViewScale = scale;
                         }
                     }}>
-                    <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
+                    <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon="map-pin" />
                     <div style={{ position: 'relative', fontSize: 25, fontWeight: 700, transform: 'translate(0, -20px)', color: 'rgba(250,250,250,0.5)' }}>V</div>
                 </div>
                 <div className="propertiesButtons-title" style={{ backgroundColor: "black", color: "white" }}>{"View"}</div>
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 8ce71935c..d5389da35 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -1,3 +1,7 @@
+$light-blue: #AEDDF8;
+$dark-blue: #5B9FDD;
+$light-background: #ececec;
+
 .presBox-cont {
     position: absolute;
     display: block;
@@ -20,10 +24,6 @@
         margin-top: 3px;
     }
 
-    .presBox-toolbar {
-        display: none;
-    }
-
     .presBox-toolbar-dropdown {
         border-radius: 5px;
         background-color: white;
@@ -40,7 +40,7 @@
         font-size: 13;
     }
 
-    .presBox-toolbar.active {
+    .presBox-toolbar {
         position: relative;
         display: inline-flex;
         align-items: center;
@@ -59,7 +59,7 @@
         }
 
         .toolbar-button.active {
-            color: #AEDDF8;
+            color: $light-blue;
         }
 
         .toolbar-transitionButtons {
@@ -85,7 +85,6 @@
         display: flex;
         width: max-content;
         height: 25px;
-        /* background-color: pink; */
         justify-content: center;
         transform: rotate(90deg);
         align-items: center;
@@ -120,7 +119,7 @@
 
 .dropdown.active {
     transform: rotate(180deg);
-    color: #AEDDF8;
+    color: $light-blue;
     opacity: 0.8;
 }
 
@@ -128,10 +127,7 @@
     position: relative;
     display: inline;
     font-family: Roboto;
-    /* background-color: white; */
     color: black;
-    width: 100%;
-    height: max-content;
     z-index: 100;
     transition: 0.7s;
 
@@ -157,7 +153,6 @@
         margin-left: 5px;
         margin-top: 5px;
         margin-bottom: 5px;
-        /* border-radius: 5px; */
         margin-right: 5px;
         width: max-content;
         justify-content: center;
@@ -176,7 +171,7 @@
     //     margin-top: 5px;
     //     width: 100%;
     //     max-width: 200px;
-        
+
     // }
 
     // .toolbar-slider:focus {
@@ -235,20 +230,20 @@
         .toolbar-slider:focus {
             outline: none;
         }
-        
+
         .toolbar-slider::-webkit-slider-runnable-track {
-          height: 10px;
-          -webkit-appearance: none;
-          margin-top: -1px;
+            height: 10px;
+            -webkit-appearance: none;
+            margin-top: -1px;
         }
-        
+
         .toolbar-slider::-webkit-slider-thumb {
-          width: 10px;
-          -webkit-appearance: none;
-          height: 10px;
-          cursor: ew-resize;
-          background: #5b9ddd;
-          box-shadow: -100vw 0 0 100vw #aedef8;
+            width: 10px;
+            -webkit-appearance: none;
+            height: 10px;
+            cursor: ew-resize;
+            background: #5b9ddd;
+            box-shadow: -100vw 0 0 100vw #aedef8;
         }
     }
 
@@ -751,7 +746,7 @@
         min-width: 150px;
     }
 
-    
+
 
     select {
         background: #323232;
@@ -796,7 +791,7 @@
         }
     }
 
-        
+
     .miniPresOverlay {
         background-color: #323232;
         color: white;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index c3b920b26..5d4cde382 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -20,17 +20,10 @@ import { Docs, DocUtils } from "../../documents/Documents";
 import { PrefetchProxy } from "../../../fields/Proxy";
 import { ScriptField } from "../../../fields/ScriptField";
 import { Scripting } from "../../util/Scripting";
-import { InkingStroke } from "../InkingStroke";
-import { HighlightSpanKind } from "typescript";
-import { SearchUtil } from "../../util/SearchUtil";
 import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
-import { child } from "serializr";
 import { List } from "../../../fields/List";
 import { Tooltip } from "@material-ui/core";
 import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
-import { conformsTo } from "lodash";
-import { translate } from "googleapis/build/src/apis/translate";
-import { DragManager, dropActionType } from "../../util/DragManager";
 import { actionAsync } from "mobx-utils";
 import { SelectionManager } from "../../util/SelectionManager";
 import { AudioBox } from "./AudioBox";
@@ -41,9 +34,26 @@ const PresBoxDocument = makeInterface(documentSchema);
 @observer
 export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>(PresBoxDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
-    private treedropDisposer?: DragManager.DragDropDisposer;
     static Instance: PresBox;
+
     @observable _isChildActive = false;
+    @observable _moveOnFromAudio: boolean = false;
+    @observable _presTimer!: NodeJS.Timeout;
+
+    @observable _selectedArray: Doc[] = [];
+    @observable _sortedSelectedArray: Doc[] = [];
+    @observable _eleArray: HTMLElement[] = [];
+    @observable _dragArray: HTMLElement[] = [];
+
+    @observable private transitionTools: boolean = false;
+    @observable private newDocumentTools: boolean = false;
+    @observable private progressivizeTools: boolean = false;
+    @observable private moreInfoTools: boolean = false;
+    @observable private playTools: boolean = false;
+    @observable private presentTools: boolean = false;
+    @observable private pathBoolean: boolean = false;
+    @observable private expandBoolean: boolean = false;
+
     @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); }
     @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); }
     @computed get presElement() { return Cast(Doc.UserDoc().presElement, Doc, null); }
@@ -65,18 +75,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
 
-
     componentDidMount() {
         this.rootDoc.presBox = this.rootDoc;
         this.rootDoc._forceRenderEngine = "timeline";
         this.rootDoc._replacedChrome = "replaced";
         this.layoutDoc.presStatus = "edit";
         this.layoutDoc._gridGap = 5;
-        // document.addEventListener("keydown", this.keyEvents, false);
-    }
-
-    componentWillUnmount() {
-        this.treedropDisposer?.();
     }
 
     onPointerOver = () => {
@@ -91,8 +95,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         Doc.UserDoc().activePresentation = this.rootDoc;
     }
 
-    @observable _moveOnFromAudio: boolean = false;
-
+    /**
+     * Called when the user moves to the next slide in the presentation trail.
+     */
     @undoBatch
     @action
     next = () => {
@@ -137,6 +142,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    /**
+     * Called when the user moves back
+     * Design choice: If there are frames within the presentation, moving back will not
+     * got back through the frames but instead directly to the next point in the presentation.
+     */
     @undoBatch
     @action
     back = () => {
@@ -149,6 +159,93 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    //The function that is called when a document is clicked or reached through next or back.
+    //it'll also execute the necessary actions if presentation is playing.
+    public gotoDocument = action((index: number, fromDoc: number) => {
+        this.updateCurrentPresentation();
+        Doc.UnBrushAllDocs();
+        if (index >= 0 && index < this.childDocs.length) {
+            this.rootDoc._itemIndex = index;
+            const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
+            if (presTargetDoc?.lastFrame !== undefined) {
+                presTargetDoc.currentFrame = 0;
+            }
+            this.navigateToElement(this.childDocs[index]); //Handles movement to element
+            this._selectedArray = [this.childDocs[index]]; //Update selected array
+            this.onHideDocument(); //Handles hide after/before
+        }
+    });
+
+    /**
+     * This method makes sure that cursor navigates to the element that
+     * has the option open and last in the group. 
+     * Design choice: If the next document is not in presCollection or 
+     * presCollection itself then if there is a presCollection it will add
+     * a new tab. If presCollection is undefined it will open the document
+     * on the right. 
+     */
+    navigateToElement = async (curDoc: Doc) => {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+        const srcContext = await DocCastAsync(targetDoc.context);
+        const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
+        const collectionDocView = presCollection ? await DocumentManager.Instance.getDocumentView(presCollection) : undefined;
+        this.turnOffEdit();
+
+        if (this.itemIndex >= 0) {
+            if (targetDoc) {
+                if (srcContext) this.layoutDoc.presCollection = srcContext;
+            } else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
+        }
+        if (collectionDocView) {
+            if (srcContext && srcContext !== presCollection) {
+                // Case 1: new srcContext inside of current collection so add a new tab to the current pres collection
+                collectionDocView.props.addDocTab(srcContext, "inPlace");
+            }
+        }
+        this.updateCurrentPresentation();
+        const docToJump = curDoc;
+        const willZoom = false;
+
+        //docToJump stayed same meaning, it was not in the group or was the last element in the group
+        if (targetDoc.zoomProgressivize && this.rootDoc.presStatus !== 'edit') {
+            this.zoomProgressivizeNext(targetDoc);
+        } else if (docToJump === curDoc) {
+            //checking if curDoc has navigation open
+            if (curDoc.presNavButton && targetDoc) {
+                await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext);
+            } else if (curDoc.presZoomButton && targetDoc) {
+                //awaiting jump so that new scale can be found, since jumping is async
+                await DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext);
+            }
+        } else {
+            //awaiting jump so that new scale can be found, since jumping is async
+            targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext);
+        }
+        // After navigating to the document, if it is added as a presPinView then it will
+        // adjust the pan and scale to that of the pinView when it was added.
+        // TODO: Add option to remove presPinView 
+        if (activeItem.presPinView) {
+            targetDoc._panX = activeItem.presPinViewX;
+            targetDoc._panY = activeItem.presPinViewY;
+            targetDoc._viewScale = activeItem.presPinViewScale;
+        }
+        // If openDocument is selected then it should open the document for the user
+        if (collectionDocView && activeItem.openDocument) {
+            collectionDocView.props.addDocTab(activeItem, "inPlace");
+        }
+        // If website and has presWebsite data associated then on click it should
+        // go back to that specific website
+        // TODO: Add progressivize for navigating web (storing websites for given frames)
+        if (targetDoc.presWebsiteData) {
+            targetDoc.data = targetDoc.presWebsiteData;
+        }
+    }
+
+    /**
+     * Uses the viewfinder to progressivize through the different views of a single collection.
+     * @param presTargetDoc: document for which internal zoom is used
+     */
     zoomProgressivizeNext = (presTargetDoc: Doc) => {
         const srcContext = Cast(presTargetDoc.context, Doc, null);
         const docView = DocumentManager.Instance.getDocumentView(presTargetDoc);
@@ -190,6 +287,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
 
+    /**
+     * For 'Hide Before' and 'Hide After' buttons making sure that
+     * they are hidden each time the presentation is updated.
+     */
     @action
     onHideDocument = () => {
         this.childDocs.forEach((doc, index) => {
@@ -213,97 +314,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         });
     }
 
-    /**
-     * This method makes sure that cursor navigates to the element that
-     * has the option open and last in the group. If not in the group, and it has
-     * the option open, navigates to that element.
-     */
-    navigateToElement = async (curDoc: Doc) => {
-        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        const srcContext = await DocCastAsync(targetDoc.context);
-        const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
-        const collectionDocView = presCollection ? await DocumentManager.Instance.getDocumentView(presCollection) : undefined;
-        this.turnOffEdit();
-
-        if (this.itemIndex >= 0) {
-            if (targetDoc) {
-                if (srcContext) this.layoutDoc.presCollection = srcContext;
-            } else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
-        }
-        if (collectionDocView) {
-            if (srcContext && srcContext !== presCollection) {
-                // Case 1: new srcContext inside of current collection so add a new tab to the current pres collection
-                collectionDocView.props.addDocTab(srcContext, "inPlace");
-            }
-        }
-        // else if (srcContext) {
-        //     console.log("Case 2: srcContext - not open and collection containing this document exists, so open collection that contains it and then await zooming in on document");
-        //     this.props.addDocTab(srcContext, "onRight");
-        // } else if (!srcContext) {
-        //     console.log("Case 3: !srcContext - no collection containing this document, therefore open document itself on right");
-        //     this.props.addDocTab(targetDoc, "onRight");
-        // }
-        this.updateCurrentPresentation();
-        const docToJump = curDoc;
-        const willZoom = false;
-
-        //docToJump stayed same meaning, it was not in the group or was the last element in the group
-        if (targetDoc.zoomProgressivize && this.rootDoc.presStatus !== 'edit') {
-            this.zoomProgressivizeNext(targetDoc);
-        } else if (docToJump === curDoc) {
-            //checking if curDoc has navigation open
-            if (curDoc.presNavButton && targetDoc) {
-                await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext);
-            } else if (curDoc.presZoomButton && targetDoc) {
-                //awaiting jump so that new scale can be found, since jumping is async
-                await DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext);
-            }
-        } else {
-            //awaiting jump so that new scale can be found, since jumping is async
-            targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext);
-        }
-        if (activeItem.presPinView) {
-            targetDoc._panX = activeItem.presPinViewX;
-            targetDoc._panY = activeItem.presPinViewY;
-            targetDoc._viewScale = activeItem.presPinViewScale;
-        }
-        if (collectionDocView && activeItem.openDocument) {
-            collectionDocView.props.addDocTab(activeItem, "inPlace");
-        }
-        if (targetDoc.presWebsiteData) {
-            targetDoc.data = targetDoc.presWebsiteData;
-        }
-    }
-
-    //The function that is called when a document is clicked or reached through next or back.
-    //it'll also execute the necessary actions if presentation is playing.
-    public gotoDocument = action((index: number, fromDoc: number) => {
-        this.updateCurrentPresentation();
-        Doc.UnBrushAllDocs();
-        if (index >= 0 && index < this.childDocs.length) {
-            this.rootDoc._itemIndex = index;
-            const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
-            if (presTargetDoc?.lastFrame !== undefined) {
-                presTargetDoc.currentFrame = 0;
-            }
-            this.navigateToElement(this.childDocs[index]);
-            this._selectedArray = [this.childDocs[index]];
-            // this.hideIfNotPresented(index);
-            // this.showAfterPresented(index);
-            // this.hideDocumentInPres();
-            this.onHideDocument();
-            // this.onHideAfterPresClick();
-        }
-    });
-
-
-    @observable _presTimer!: NodeJS.Timeout;
 
-    //The function that starts or resets presentaton functionally, depending on status flag.
+    //The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
     @undoBatch
     @action
-    startOrResetPres = (startSlide: number) => {
+    startPres = (startSlide: number) => {
         this.updateCurrentPresentation();
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
@@ -326,15 +341,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     //The function that resets the presentation by removing every action done by it. It also
     //stops the presentaton.
+    // TODO: Ensure resetPresentation is called when the presentation is closed
     resetPresentation = () => {
         this.updateCurrentPresentation();
-        this.childDocs.forEach(doc => (doc.presentationTargetDoc as Doc).opacity = 1);
         this.rootDoc._itemIndex = 0;
-        // this.layoutDoc.presStatus = false;
     }
 
-    //The function that starts the presentation, also checking if actions should be applied
-    //directly at start.
+    @action togglePath = () => this.pathBoolean = !this.pathBoolean;
+    @action toggleExpand = () => this.expandBoolean = !this.expandBoolean;
+
+    /**
+     * The function that starts the presentation at the given index, also checking if actions should be applied
+     * directly at start.
+     * @param startIndex: index that the presentation will start at
+     */
     startPresentation = (startIndex: number) => {
         this.updateCurrentPresentation();
         this.childDocs.map(doc => {
@@ -348,6 +368,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         });
     }
 
+    /**
+     * The method called to open the presentation as a minimized view
+     * TODO: Look at old updateMinimize and compare...
+     */
     updateMinimize = () => {
         const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
         this.turnOffEdit();
@@ -364,39 +388,52 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    /**
+     * Called when the user changes the view type
+     * Either 'List' (stacking) or 'Slides' (carousel)
+     */
     @undoBatch
     viewChanged = action((e: React.ChangeEvent) => {
         //@ts-ignore
         const viewType = e.target.selectedOptions[0].value as CollectionViewType;
-        viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined); // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
+        // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
+        viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined);
         this.rootDoc._viewType = viewType;
         if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 5;
     });
 
+    /**
+     * When the movement dropdown is changes
+     */
     @undoBatch
     movementChanged = action((movement: string) => {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-        if (movement === 'zoom') {
-            activeItem.presZoomButton = !activeItem.presZoomButton;
-            if (activeItem.presZoomButton) activeItem.presMovement = 'Zoom';
-            else activeItem.presMovement = 'None';
-            activeItem.presNavButton = false;
-        } else if (movement === 'nav') {
-            activeItem.presZoomButton = false;
-            activeItem.presNavButton = !activeItem.presNavButton;
-            if (activeItem.presNavButton) activeItem.presMovement = 'Pan';
-            else activeItem.presMovement = 'None';
-        } else if (movement === 'switch') {
-            targetDoc.presTransition = 0;
-            activeItem.presSwitchButton = !activeItem.presSwitchButton;
-            if (activeItem.presSwitchButton) activeItem.presMovement = 'Jump cut';
-            else activeItem.presMovement = 'None';
-        } else {
-            activeItem.presMovement = 'None';
-            activeItem.presZoomButton = false;
-            activeItem.presNavButton = false;
-            activeItem.presSwitchButton = false;
+        switch (movement) {
+            case 'zoom': //Pan and zoom
+                activeItem.presZoomButton = !activeItem.presZoomButton;
+                if (activeItem.presZoomButton) activeItem.presMovement = 'Zoom';
+                else activeItem.presMovement = 'None';
+                activeItem.presNavButton = false;
+                break;
+            case 'pan': //Pan
+                activeItem.presZoomButton = false;
+                activeItem.presNavButton = !activeItem.presNavButton;
+                if (activeItem.presNavButton) activeItem.presMovement = 'Pan';
+                else activeItem.presMovement = 'None';
+                break;
+            case 'jump': //Jump Cut
+                targetDoc.presTransition = 0;
+                activeItem.presSwitchButton = !activeItem.presSwitchButton;
+                if (activeItem.presSwitchButton) activeItem.presMovement = 'Jump cut';
+                else activeItem.presMovement = 'None';
+                break;
+            case 'none': default:
+                activeItem.presMovement = 'None';
+                activeItem.presZoomButton = false;
+                activeItem.presNavButton = false;
+                activeItem.presSwitchButton = false;
+                break;
         }
     });
 
@@ -421,13 +458,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) &&
         (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
 
-    // KEYS
-    @observable _selectedArray: Doc[] = [];
-    @observable _sortedSelectedArray: Doc[] = [];
-    @observable _eleArray: HTMLElement[] = [];
-    @observable _dragArray: HTMLElement[] = [];
-
-    //TODO: Update to radix / quick sort
+    /**
+     * For sorting the array so that the order is maintained when it is dropped.
+     */
     @action
     sortArray = (): Doc[] => {
         const sort: Doc[] = this._selectedArray;
@@ -439,6 +472,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return sort;
     }
 
+    /**
+     * Method to get the list of selected items in the order in which they have been selected
+     */
     @computed get listOfSelected() {
         const list = this._selectedArray.map((doc: Doc, index: any) => {
             const activeItem = Cast(doc, Doc, null);
@@ -478,6 +514,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    // Key events when the minimized player is active
     @action
     minimizeEvents = (e: KeyboardEvent) => {
         e.stopPropagation();
@@ -491,7 +528,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
-    //Esc click
+    // Key for when the presentaiton is active (according to Selection Manager)
     @action
     keyEvents = (e: KeyboardEvent) => {
         e.stopPropagation();
@@ -507,7 +544,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         } if (e.keyCode === 39) { // right (39) / d(68) / down(40) to go to next
             if (this.layoutDoc.presStatus !== "edit") this.next();
         } if (e.keyCode === 32) { // spacebar to 'present' or autoplay
-            if (this.layoutDoc.presStatus !== "edit") this.startOrResetPres(0);
+            if (this.layoutDoc.presStatus !== "edit") this.startPres(0);
             else this.layoutDoc.presStatus = "manual";
         }
         if (e.keyCode === 8) { // delete selected items
@@ -519,15 +556,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
-    @observable private transitionTools: boolean = false;
-    @observable private newDocumentTools: boolean = false;
-    @observable private progressivizeTools: boolean = false;
-    @observable private moreInfoTools: boolean = false;
-    @observable private playTools: boolean = false;
-    @observable private presentTools: boolean = false;
-    @observable private pathBoolean: boolean = false;
-    @observable private expandBoolean: boolean = false;
-
+    /**
+     * 
+     */
     @undoBatch
     @action
     viewPaths = async () => {
@@ -551,16 +582,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const fit = srcContext?._fitToBox;
     }
 
+    // Adds the index in the pres path graphically
     @computed get order() {
         const order: JSX.Element[] = [];
         this.childDocs.forEach((doc, index) => {
             const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
             const srcContext = Cast(targetDoc.context, Doc, null);
+            // Case A: Document is contained within the colleciton
             if (this.rootDoc.presCollection === srcContext) {
                 order.push(
                     <div className="pathOrder" style={{ top: NumCast(targetDoc.y), left: NumCast(targetDoc.x) }}>
                         <div className="pathOrder-frame">{index + 1}</div>
                     </div>);
+                // Case B: Document is not inside of the collection
             } else {
                 order.push(
                     <div className="pathOrder" style={{ top: 0, left: 0 }}>
@@ -571,6 +605,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return order;
     }
 
+    /**
+     * Method called for viewing paths which adds a single line with
+     * points at the center of each document added.
+     * Design choice: When this is called it sets _fitToBox as true so the
+     * user can have an overview of all of the documents in the collection.
+     * (Design needed for when documents in presentation trail are in another
+     * collection)
+     */
     @computed get paths() {
         let pathPoints = "";
         this.childDocs.forEach((doc, index) => {
@@ -601,9 +643,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         />);
     }
 
-    @action togglePath = () => this.pathBoolean = !this.pathBoolean;
-    @action toggleExpand = () => this.expandBoolean = !this.expandBoolean;
-
     /**
      * The function that is called on click to turn fading document after presented option on/off.
      * It also makes sure that the option swithches from hide-after to this one, since both
@@ -627,13 +666,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
-    // WHAT IS THIS?
-    @action
-    dropdownToggle = (menu: string) => {
-        const dropMenu = document.getElementById('presBox' + menu + 'Dropdown');
-        if (dropMenu) dropMenu.style.display === 'none' ? dropMenu.style.display = 'block' : dropMenu.style.display = 'none';
-    }
-
+    // Converts seconds to ms and updates presTransition
     setTransitionTime = (number: String) => {
         const timeInMS = Number(number) * 1000;
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
@@ -641,6 +674,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (targetDoc) targetDoc.presTransition = timeInMS;
     }
 
+    // Converts seconds to ms and updates presDuration
     setDurationTime = (number: String) => {
         const timeInMS = Number(number) * 1000;
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
@@ -648,6 +682,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (targetDoc) targetDoc.presDuration = timeInMS;
     }
 
+
     @computed get transitionDropdown() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
@@ -660,17 +695,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                     <div className="ribbon-box">
                         Movement
-                        <div className="presBox-dropdown"
-                            onPointerDown={e => e.stopPropagation()}
-                        // onClick={() => this.dropdownToggle('Movement')}
-                        >
+                        <div className="presBox-dropdown" onPointerDown={e => e.stopPropagation()}>
                             {activeItem.presMovement}
                             <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
                             <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
                                 <div className={`presBox-dropdownOption ${activeItem.presMovement === 'None' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div>
                                 <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Zoom' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Pan' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('nav')}>Pan</div>
-                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Jump cut' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('switch')}>Jump cut</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Pan' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('pan')}>Pan</div>
+                                <div className={`presBox-dropdownOption ${activeItem.presMovement === 'Jump cut' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('jump')}>Jump cut</div>
                             </div>
                         </div>
                         <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === 'Pan' || activeItem.presMovement === 'Zoom' ? "inline-flex" : "none" }}>
@@ -783,8 +815,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                         <div className="ribbon-box">
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.AUDIO ? "inline-flex" : "none" }}>
-                                <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Start automatically</div>
-                                <div className="ribbon-button" style={{ display: "flex", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Start manually</div>
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.playAuto ? "#aedef8" : "" }} onClick={() => activeItem.playAuto = !activeItem.playAuto}>Play automatically</div>
+                                <div className="ribbon-button" style={{ display: "flex", backgroundColor: targetDoc.playAuto ? "" : "#aedef8" }} onClick={() => activeItem.playAuto = !activeItem.playAuto}>Play on next</div>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: "flex" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.openDocument ? "#aedef8" : "" }} onClick={() => activeItem.openDocument = !activeItem.openDocument}>Open document</div>
@@ -838,12 +870,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 <div className={"presBox-ribbon"} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
                     <div className="ribbon-box">
                         Slide Title: <br></br>
-                        {/* <div className="dropdown-textInput"> */}
                         <input className="ribbon-textInput" placeholder="..." type="text" name="fname" ref={this.inputRef} onChange={(e) => {
                             e.stopPropagation();
                             runInAction(() => this.title = e.target.value);
                         }}></input>
-                        {/* </div> */}
                     </div>
                     <div className="ribbon-box">
                         Choose type:
@@ -941,40 +971,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         return doc;
     }
 
-    // Dropdown that appears for autoplay
-    @computed get playDropdown() {
-        return (
-            <div className={`dropdown-play ${this.playTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-                <div className="dropdown-play-button" onClick={() => this.startOrResetPres(this.itemIndex)}>
-                    Present from current slide
-                </div>
-                <div className="dropdown-play-button" onClick={() => this.startOrResetPres(0)}>
-                    Present from first slide
-                </div>
-            </div>
-        );
-    }
-
     // Dropdown that appears when the user wants to begin presenting (either minimize or sidebar view)
     @computed get presentDropdown() {
         return (
             <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={this.updateMinimize}>
+                <div className="dropdown-play-button" onClick={(action(() => { this.updateMinimize; this.layoutDoc.presStatus = "manual"; this.turnOffEdit(); }))}>
                     Minimize
                 </div>
-                <div className="dropdown-play-button" onClick={() => { this.startOrResetPres(0); this.turnOffEdit(); }}>
+                <div className="dropdown-play-button" onClick={(action(() => { this.layoutDoc.presStatus = "manual"; this.turnOffEdit(); }))}>
                     Sidebar view
                 </div>
             </div>
         );
     }
 
-    // For toggling the options when the user wants to select play
-    @action togglePlay = () => { this.playTools = !this.playTools; };
-
-    // For toggling the options when the user wants to select play
-    @action togglePresent = () => { this.presentTools = !this.presentTools; };
-
     // Case in which the document has keyframes to navigate to next key frame
     @undoBatch
     @action
@@ -986,10 +996,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             CollectionFreeFormDocumentView.setupScroll(tagDoc, 0);
             CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
         }
-        // let lastFrame: number = 0;
-        // childDocs.forEach((doc) => {
-        //     if (NumCast(doc.appearFrame) > lastFrame) lastFrame = NumCast(doc.appearFrame);
-        // });
         CollectionFreeFormDocumentView.updateScrollframe(tagDoc, currentFrame);
         CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
         tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1);
@@ -1027,6 +1033,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
+    /**
+     * Returns the collection type as a string for headers
+     */
     @computed get stringType(): string {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
@@ -1587,7 +1596,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         if (activeItem) {
             return (
-                <>
+                <div id="toolbarContainer" className={'presBox-toolbar'} style={{ display: this.layoutDoc.presStatus !== 'auto' && this.layoutDoc.presStatus !== 'manual' ? "inline-flex" : "none" }}>
                     <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}><FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
@@ -1624,7 +1633,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="toolbar-moreInfoBall" />
                         </div>
                     </div> */}
-                </>
+                </div>
             );
         } else {
             return (
@@ -1648,13 +1657,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
-    render() {
-        this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields
+    /**
+     * Top panel containes:
+     * viewPicker: The option to choose between List and Slides view for the presentaiton trail
+     * presentPanel: The button to start the presentation / open minimized view of the presentation
+     */
+    @computed get topPanel() {
         const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
-        // const addDocument = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => {
-        //     return add(doc, relativeTo ? relativeTo : docs[i], before !== undefined ? before : false);
-        // };
-        return <div onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
+        return (
             <div className="presBox-buttons" style={{ display: this.rootDoc._chromeStatus === "disabled" ? "none" : undefined }}>
                 <select className="presBox-viewPicker"
                     style={{ display: this.layoutDoc.presStatus === "edit" ? "block" : "none" }}
@@ -1666,36 +1676,61 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 </select>
                 <div className="presBox-presentPanel">
                     <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
-                        <div className="presBox-button-left" onClick={() => this.layoutDoc.presStatus = "manual"}><FontAwesomeIcon icon={"play-circle"} /> <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present </div></div>
-                        <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePresent(); }}>
+                        <div className="presBox-button-left" onClick={() => this.layoutDoc.presStatus = "manual"}>
+                            <FontAwesomeIcon icon={"play-circle"} />
+                            <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present</div>
+                        </div>
+                        <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.presentTools = !this.presentTools; }}>
                             <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
                             {this.presentDropdown}
                         </div>
                     </span>
-                    <div className="miniPresOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
-                        {/* <span className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`}>
-                            <div className="presBox-button-left" onClick={() => this.startOrResetPres(0)}>
-                                <FontAwesomeIcon icon={"clock"} /> &nbsp;
-                                <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
-                            </div>
-                            <div className={`presBox-button-right ${this.playTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePlay(); }}>
-                                <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.playTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
-                                {this.playDropdown}
-                            </div>
-                        </span> */}
-                        <div className="miniPres-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
-                        <div className="miniPres-button" onClick={() => this.startOrResetPres(this.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
-                        <div className="miniPres-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
-                        <div className="miniPres-divider"></div>
-                        <div className="miniPres-button-text">Slide {this.itemIndex + 1} / {this.childDocs.length}</div>
-                        <div className="miniPres-divider"></div>
-                        <div className="miniPres-button" onClick={() => this.layoutDoc.presStatus = "edit"}>
-                            <FontAwesomeIcon icon={"times"} />
-                        </div>
-                    </div>
+                    {this.playButtons}
+                </div>
+            </div>
+        );
+    }
+
+    @computed get playButtons() {
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        // Case 1: There are still other frames and should go through all frames before going to next slide
+        return (<div className="miniPresOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
+            {/* <span className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`}>
+                <div className="presBox-button-left" onClick={() => this.startPres(0)}>
+                    <FontAwesomeIcon icon={"clock"} /> &nbsp;
+                    <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
+                </div>
+                <div className={`presBox-button-right ${this.playTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePlay(); }}>
+                    <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.playTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
+                    {this.playDropdown}
                 </div>
+            </span> */}
+            <div className="miniPres-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
+            <div className="miniPres-button" onClick={() => this.startPres(this.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
+            <div className="miniPres-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
+            <div className="miniPres-divider"></div>
+            <div className="miniPres-button-text" style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
+                Slide {this.itemIndex + 1} / {this.childDocs.length}
+                {targetDoc ? <div className="miniPres-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? "inline-flex" : "none" }}>
+                    <div>{targetDoc.currentFrame}</div>
+                    <div>{targetDoc.lastFrame}</div>
+                </div> : null}
             </div>
-            <div id="toolbarContainer" className={`presBox-toolbar ${this.layoutDoc.presStatus === "edit" ? "active" : ""}`}> {this.toolbar} </div>
+            <div className="miniPres-divider"></div>
+            <div className="miniPres-button" onClick={() => this.layoutDoc.presStatus = "edit"}>
+                <FontAwesomeIcon icon={"times"} />
+            </div>
+        </div>);
+    }
+
+    render() {
+        // needed to insure that the childDocs are loaded for looking up fields
+        this.childDocs.slice();
+        const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
+        return <div onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
+            {this.topPanel}
+            {this.toolbar}
             {this.newDocumentToolbarDropdown}
             <div className="presBox-listCont">
                 {mode !== CollectionViewType.Invalid ?
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index fa70b2a41..3d730d7ac 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -1,3 +1,7 @@
+$light-blue: #AEDDF8;
+$dark-blue: #5B9FDD;
+$light-background: #ececec;
+
 .presElementBox-item {
     display: grid;
     grid-template-columns: max-content max-content max-content;
@@ -26,7 +30,7 @@
         z-index: -1;
         width: calc(100% + 200px);
         height: calc(100% + 8px);
-        background-color: #AEDDF8;
+        background-color: $light-blue;
     }
 
     .presElementBox-highlightTop {
@@ -69,7 +73,7 @@
 .presElementBox-active {
     color: black;
     border-radius: 6px;
-    border: solid 2px #5B9FDD;
+    border: solid 2px $dark-blue;
 }
 
 .presElementBox-buttons {
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 11ffde9dd..092fd1fd3 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -189,7 +189,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
                     LibraryPath={emptyPath}
                     fitToBox={true}
-                    backgroundColor={() => "darkgrey"}
+                    backgroundColor={this.props.backgroundColor}
                     rootSelected={returnTrue}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
@@ -254,11 +254,8 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
     }
 
     startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
-        // const ele: HTMLElement[] = PresBox.Instance._eleArray.map(doc => doc);
         const activeItem = this.rootDoc;
         const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray().map(doc => doc));
-        // let value = this.getValue(this._heading);
-        // value = typeof value === "string" ? `"${value}"` : value;
         const dragItem: HTMLElement[] = [];
         PresBox.Instance._dragArray.map(ele => {
             const drag = ele;
@@ -337,7 +334,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.duration}</div></Tooltip>
                     <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><div
                         className="presElementBox-closeIcon"
-                        // onPointerDown={e => e.stopPropagation()}
                         onClick={e => {
                             this.props.removeDocument?.(this.rootDoc);
                             e.stopPropagation();
@@ -363,6 +359,4 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
             </div>
         );
     }
-}
-
-// this.layoutDoc.title !== "pres element template"
\ No newline at end of file
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 142011ffd5c9ca5aeed85ed8a74e5919e0e5a6dd Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Thu, 6 Aug 2020 20:38:31 +0800
Subject: audio auto play bug fix && some more commenting

---
 src/client/views/.DS_Store                         | Bin 6148 -> 10244 bytes
 src/client/views/MainView.tsx                      |   6 +-
 src/client/views/PropertiesButtons.tsx             |   8 +-
 .../views/collections/CollectionDockingView.scss   |  15 ++
 .../views/collections/CollectionDockingView.tsx    |  30 ++--
 src/client/views/nodes/PresBox.scss                |  79 ++++-------
 src/client/views/nodes/PresBox.tsx                 | 151 ++++++++-------------
 7 files changed, 127 insertions(+), 162 deletions(-)

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

diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store
index 7a8c419ee..c379549d0 100644
Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 007d531c8..51137a080 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -175,10 +175,8 @@ export class MainView extends React.Component {
             fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faChevronLeft, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript,
             fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper,
             fa.faDesktop, fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle,
-            fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand, fa.faUndo, fa.faSlidersH, fa.faAngleDoubleLeft);
-        //Pres trail icons (just for the sake of merging)
-        library.add(fa.faAngleUp, fa.faAngleDown, fa.faPlayCircle, fa.faClock,
-            fa.faRocket, fa.faExchangeAlt, faBuffer);
+            fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand, fa.faUndo, fa.faSlidersH, fa.faAngleDoubleLeft, fa.faAngleUp,
+            fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, faBuffer);
         this.initEventListeners();
         this.initAuthenticationRouters();
     }
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 3392371de..55eb6c028 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -243,9 +243,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             const scale = targetDoc._viewScale;
         }
         return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Pin with this view"}</div></>} placement="top">
-            <>
+            <div>
                 <div className="propertiesButtons-linker"
-                    style={{ backgroundColor: "black", color: "white" }}
                     onClick={e => {
                         if (targetDoc) {
                             DockedFrameRenderer.PinDoc(targetDoc, false);
@@ -262,8 +261,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                     <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon="map-pin" />
                     <div style={{ position: 'relative', fontSize: 25, fontWeight: 700, transform: 'translate(0, -20px)', color: 'rgba(250,250,250,0.5)' }}>V</div>
                 </div>
-                <div className="propertiesButtons-title" style={{ backgroundColor: "black", color: "white" }}>{"View"}</div>
-            </>
+
+                <div className="propertiesButtons-title">{"View"}</div>
+            </div>
         </Tooltip>;
     }
 
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index 98babc3d2..4204ef5bb 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -54,6 +54,21 @@
             transition: all 0.3s;
         }
 
+        .miniPres-button-frame {
+            justify-self: center;
+            align-self: center;
+            align-items: center;
+            display: grid;
+            grid-template-columns: auto auto auto;
+            justify-content: space-around;
+            font-size: 11;
+            margin-left: 7;
+            width: 30;
+            height: 85%;
+            background-color: rgba(91, 157, 221, 0.4);
+            border-radius: 5px;
+        }
+
         .miniPres-divider {
             width: 0.5px;
             height: 80%;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index af701bfdd..7bd79b2ef 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -870,19 +870,25 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         return currentFrame;
     }
     renderMiniPres() {
-        return <div className="miniPres" style={{
-            width: 250, height: 30, background: '#323232'
-        }}>
-            <div className="miniPresOverlay" onClick={() => document.addEventListener("keydown", PresBox.Instance.minimizeEvents, false)}>
-                <div className="miniPres-button" onClick={PresBox.Instance.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
-                <div className="miniPres-button" onClick={() => PresBox.Instance.startOrResetPres(PresBox.Instance.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
-                <div className="miniPres-button" onClick={PresBox.Instance.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
-                <div className="miniPres-divider"></div>
-                <div className="miniPres-button-text">Slide {PresBox.Instance.itemIndex + 1} / {PresBox.Instance.childDocs.length}</div>
-                <div className="miniPres-divider"></div>
-                <div className="miniPres-button-text" onClick={PresBox.Instance.updateMinimize}>EXIT</div>
+        return (
+            <div className="miniPres"
+                style={{ width: 250, height: 30, background: '#323232' }}
+                onClick={() => document.addEventListener("keydown", PresBox.Instance.minimizeEvents, false)}
+            >
+                {<div className="miniPresOverlay" onClick={() => document.addEventListener("keydown", PresBox.Instance.minimizeEvents, false)}>
+                    <div className="miniPres-button" onClick={PresBox.Instance.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
+                    <div className="miniPres-button" onClick={() => PresBox.Instance.startAutoPres(PresBox.Instance.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
+                    <div className="miniPres-button" onClick={PresBox.Instance.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
+                    <div className="miniPres-divider"></div>
+                    <div className="miniPres-button-text">
+                        Slide {PresBox.Instance.itemIndex + 1} / {PresBox.Instance.childDocs.length}
+                        {PresBox.Instance.playButtonFrames}
+                    </div>
+                    <div className="miniPres-divider"></div>
+                    <div className="miniPres-button-text" onClick={PresBox.Instance.updateMinimize}>EXIT</div>
+                </div>}
             </div>
-        </div>;
+        );
     }
     renderMiniMap() {
         return <div className="miniMap" style={{
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index d5389da35..77e7924dd 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -161,52 +161,6 @@ $light-background: #ececec;
         padding-left: 10px;
     }
 
-    // .toolbar-slider {
-    //     position: relative;
-    //     align-self: center;
-    //     justify-self: left;
-    //     -webkit-appearance: none;
-    //     background-color: #5b9ddd;
-    //     overflow: hidden;
-    //     margin-top: 5px;
-    //     width: 100%;
-    //     max-width: 200px;
-
-    // }
-
-    // .toolbar-slider:focus {
-    //     outline: none;
-    // }
-
-    // .effectDirection {
-    //     justify-self: center;
-    //     align-self: center;
-    //     align-items: center;
-    //     justify-content: center;
-    //     grid-template-columns: 13px 13px 13px;
-    //     display: grid;
-    // }
-
-    // .toolbar-slider::-webkit-slider-thumb {
-    //     -webkit-appearance: none;
-    //     background-color: #5b9ddd;
-    //     box-shadow: -100 vw 0 0 100vw pink;
-    //     width: 12px;
-    //     height: 12px;
-    // }
-
-    // .toolbar-slider::-webkit-slider-runnable-track {
-    //     position: relative;
-    //     align-self: center;
-    //     justify-self: left;
-    //     -webkit-appearance: none;
-    //     background-color: #5b9ddd;
-    //     margin-top: 5px;
-    //     border: solid 1px black;
-    //     border-radius: 10px;
-    //     height: 5px;
-    //     left: 0px;
-    // }
     .presBox-subheading {
         font-size: 11;
         font-weight: 400;
@@ -412,7 +366,7 @@ $light-background: #ececec;
         font-size: 10.5;
         font-weight: 200;
         height: 20;
-        background-color: #dedede;
+        background-color: $light-background;
         border: solid 1px black;
         display: flex;
         margin-top: 5px;
@@ -504,7 +458,7 @@ $light-background: #ececec;
             grid-template-columns: auto 20%;
             position: relative;
             border: solid 1px black;
-            background-color: #dedede;
+            background-color: $light-background;
             border-radius: 5px;
             font-size: 10;
             height: 30;
@@ -632,7 +586,7 @@ $light-background: #ececec;
     align-items: center;
     justify-content: center;
     transform: translate(0px, -1px);
-    background-color: #dedede;
+    background-color: $light-background;
     width: 40px;
     height: 15px;
     align-self: center;
@@ -646,7 +600,7 @@ $light-background: #ececec;
 .layout-container {
     padding: 5px;
     display: grid;
-    background-color: #dedede;
+    background-color: $light-background;
     grid-template-columns: repeat(auto-fit, minmax(90px, 100px));
     width: 100%;
     border: solid 1px black;
@@ -798,12 +752,14 @@ $light-background: #ececec;
         border-radius: 5px;
         grid-template-rows: 100%;
         height: 25;
-        width: 200;
+        width: max-content;
+        min-width: max-content;
         justify-content: space-evenly;
         align-items: center;
         display: flex;
         position: absolute;
         right: 10px;
+        transition: all 0.2s;
 
         .miniPres-button-text {
             display: flex;
@@ -811,6 +767,10 @@ $light-background: #ececec;
             width: max-content;
             font-family: Roboto;
             font-weight: 400;
+            margin-left: 3px;
+            margin-right: 3px;
+            padding-right: 3px;
+            padding-left: 3px;
             letter-spacing: normal;
             border-radius: 5px;
             align-items: center;
@@ -824,10 +784,27 @@ $light-background: #ececec;
             border-right: solid 1px #5a5a5a;
         }
 
+        .miniPres-button-frame {
+            justify-self: center;
+            align-self: center;
+            align-items: center;
+            display: grid;
+            grid-template-columns: auto auto auto;
+            justify-content: space-around;
+            font-size: 11;
+            margin-left: 7;
+            width: 30;
+            height: 85%;
+            background-color: rgba(91, 157, 221, 0.4);
+            border-radius: 5px;
+        }
+
         .miniPres-button {
             display: flex;
             height: 20;
             min-width: 20;
+            margin-left: 3px;
+            margin-right: 3px;
             border-radius: 100%;
             align-items: center;
             justify-content: center;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 5d4cde382..24918098f 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -27,6 +27,7 @@ import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
 import { actionAsync } from "mobx-utils";
 import { SelectionManager } from "../../util/SelectionManager";
 import { AudioBox } from "./AudioBox";
+import { white } from "colors";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -37,7 +38,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     static Instance: PresBox;
 
     @observable _isChildActive = false;
-    @observable _moveOnFromAudio: boolean = false;
+    @observable _moveOnFromAudio: boolean = true;
     @observable _presTimer!: NodeJS.Timeout;
 
     @observable _selectedArray: Doc[] = [];
@@ -103,7 +104,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     next = () => {
         this.updateCurrentPresentation();
         const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null);
-        const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null);
+        const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        const presTargetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
         const childDocs = DocListCast(presTargetDoc[Doc.LayoutFieldKey(presTargetDoc)]);
         const currentFrame = Cast(presTargetDoc.currentFrame, "number", null);
         const lastFrame = Cast(presTargetDoc.lastFrame, "number", null);
@@ -119,26 +121,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             if (presTargetDoc.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
             if (presTargetDoc.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc);
             // Case 2: Audio or video therefore wait to play the audio or video before moving on
-        } else if ((presTargetDoc.type === DocumentType.VID || presTargetDoc.type === DocumentType.AUDIO) && !this._moveOnFromAudio) {
-            if (presTargetDoc.type === DocumentType.AUDIO) {
-                AudioBox.Instance.playFrom(0);
-                this._moveOnFromAudio = true;
-            }
-            if (presTargetDoc.type === DocumentType.VID) {
-                this._moveOnFromAudio = true;
-            }
+        } else if ((presTargetDoc.type === DocumentType.AUDIO) && !this._moveOnFromAudio) {
+            AudioBox.Instance.playFrom(0);
+            this._moveOnFromAudio = true;
             // Case 3: No more frames in current doc and next slide is defined, therefore move to next slide
-        } else if (activeNext !== undefined) {
-            if (!presTargetDoc.presProgressivize) {
-                const nextTagDoc = Cast(this.childDocs[this.itemIndex + 1].presentationTargetDoc, Doc, null);
-                const nextChildDocs = DocListCast(nextTagDoc[Doc.LayoutFieldKey(presTargetDoc)]);
-                nextChildDocs.forEach((doc, i) => {
-                    doc.opacity = 1;
-                });
-            }
+        } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
             const nextSelected = this.itemIndex + 1;
             this.gotoDocument(nextSelected, this.itemIndex);
-            this._moveOnFromAudio = false;
+            const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
+            if (activeNext && targetNext.type === DocumentType.AUDIO && activeNext.playAuto) {
+            } else { this._moveOnFromAudio = false };
         }
     }
 
@@ -318,7 +310,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     //The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
     @undoBatch
     @action
-    startPres = (startSlide: number) => {
+    startAutoPres = (startSlide: number) => {
         this.updateCurrentPresentation();
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
@@ -377,13 +369,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.turnOffEdit();
         if (srcContext) {
             if (srcContext.miniPres) {
-                document.removeEventListener("keydown", this.minimizeEvents, false);
                 srcContext.miniPres = false;
                 CollectionDockingView.AddRightSplit(this.rootDoc);
+                document.removeEventListener("keydown", this.minimizeEvents, false);
             } else {
-                document.addEventListener("keydown", this.minimizeEvents, false);
                 srcContext.miniPres = true;
                 this.props.addDocTab?.(this.rootDoc, "close");
+                document.addEventListener("keydown", this.minimizeEvents, false);
             }
         }
     }
@@ -544,7 +536,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         } if (e.keyCode === 39) { // right (39) / d(68) / down(40) to go to next
             if (this.layoutDoc.presStatus !== "edit") this.next();
         } if (e.keyCode === 32) { // spacebar to 'present' or autoplay
-            if (this.layoutDoc.presStatus !== "edit") this.startPres(0);
+            if (this.layoutDoc.presStatus !== "edit") this.startAutoPres(0);
             else this.layoutDoc.presStatus = "manual";
         }
         if (e.keyCode === 8) { // delete selected items
@@ -688,7 +680,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
         if (activeItem && targetDoc) {
             const transitionSpeed = targetDoc.presTransition ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
-            const duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2;
+            let duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2;
+            if (targetDoc.type === DocumentType.AUDIO) duration = NumCast(targetDoc.duration);
             const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
             activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
             return (
@@ -726,8 +719,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="presBox-subheading">Slide Duration</div>
                             <div className="ribbon-property"> {duration} s </div>
                         </div>
-                        <input type="range" step="0.1" min="0.1" max="10" value={duration} style={{ transform: 'rotate(0deg)' }} className={"toolbar-slider"} id="duration-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
-                        <div className={"slider-headers"}>
+                        <input type="range" step="0.1" min="0.1" max="10" value={duration} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }} className={"toolbar-slider"} id="duration-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
+                        <div className={"slider-headers"} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }}>
                             <div className="slider-text">Short</div>
                             <div className="slider-text">Medium</div>
                             <div className="slider-text">Long</div>
@@ -816,7 +809,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                         <div className="ribbon-box">
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.AUDIO ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.playAuto ? "#aedef8" : "" }} onClick={() => activeItem.playAuto = !activeItem.playAuto}>Play automatically</div>
-                                <div className="ribbon-button" style={{ display: "flex", backgroundColor: targetDoc.playAuto ? "" : "#aedef8" }} onClick={() => activeItem.playAuto = !activeItem.playAuto}>Play on next</div>
+                                <div className="ribbon-button" style={{ display: "flex", backgroundColor: activeItem.playAuto ? "" : "#aedef8" }} onClick={() => activeItem.playAuto = !activeItem.playAuto}>Play on next</div>
                             </div>
                             <div className="ribbon-doubleButton" style={{ display: "flex" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.openDocument ? "#aedef8" : "" }} onClick={() => activeItem.openDocument = !activeItem.openDocument}>Open document</div>
@@ -923,12 +916,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         if (freeform && layout) doc = this.createTemplate(layout, title);
         if (!freeform && !layout) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title });
         const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
-        const data = Cast(presCollection.data, listSpec(Doc));
+        const data = Cast(presCollection?.data, listSpec(Doc));
         const presData = Cast(this.rootDoc.data, listSpec(Doc));
         if (data && doc && presData) {
             data.push(doc);
             DockedFrameRenderer.PinDoc(doc, false);
             this.gotoDocument(this.childDocs.length, this.itemIndex);
+        } else {
+            this.props.addDocTab(doc as Doc, "onRight");
         }
     }
 
@@ -975,7 +970,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @computed get presentDropdown() {
         return (
             <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={(action(() => { this.updateMinimize; this.layoutDoc.presStatus = "manual"; this.turnOffEdit(); }))}>
+                <div className="dropdown-play-button" onClick={this.updateMinimize}>
                     Minimize
                 </div>
                 <div className="dropdown-play-button" onClick={(action(() => { this.layoutDoc.presStatus = "manual"; this.turnOffEdit(); }))}>
@@ -1108,7 +1103,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
     turnOffEdit = () => {
-        this.childDocs.forEach((doc, index) => {
+        this.childDocs.forEach((doc) => {
+            doc.editSnapZoomProgressivize = false;
+            doc.editZoomProgressivize = false;
+            doc.editScrollProgressivize = false;
             const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
             targetDoc.editSnapZoomProgressivize = false;
             targetDoc.editZoomProgressivize = false;
@@ -1596,63 +1594,31 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         if (activeItem) {
             return (
-                <div id="toolbarContainer" className={'presBox-toolbar'} style={{ display: this.layoutDoc.presStatus !== 'auto' && this.layoutDoc.presStatus !== 'manual' ? "inline-flex" : "none" }}>
-                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}><FontAwesomeIcon icon={"plus"} />
+                <div id="toolbarContainer" className={'presBox-toolbar'} style={{ display: this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }}>
+                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
+                        <FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
                     <div className="toolbar-divider" />
                     <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}><div className={`toolbar-button ${this.pathBoolean ? "active" : ""}`}>
-                        <FontAwesomeIcon icon={"exchange-alt"} onClick={this.viewPaths} />
+                        <FontAwesomeIcon icon={"exchange-alt"} onClick={this.childDocs.length > 1 ? this.viewPaths : undefined} />
                     </div></Tooltip>
                     <Tooltip title={<><div className="dash-tooltip">{this.expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
                         <div className={`toolbar-button ${this.expandBoolean ? "active" : ""}`} onClick={() => { this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = true; else doc.presExpandInlineButton = false; }); }}>
                             <FontAwesomeIcon icon={"eye"} />
                         </div>
                     </Tooltip>
-                    {/* <div className="toolbar-button"><FontAwesomeIcon title={"Portal"} icon={"eye"} onClick={this.toolbarTest} /></div> */}
-                    <div className="toolbar-divider" />
-                    {/* <Tooltip title={<><div className="dash-tooltip">{"Transitions"}</div></>}><div className={`toolbar-button ${this.transitionTools ? "active" : ""}`} onClick={this.toggleTransitionTools}>
-                        <FontAwesomeIcon icon={"rocket"} />
-                        <div style={{ display: this.props.PanelWidth() > 430 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Transitions</div>
-                        <FontAwesomeIcon className={`dropdown ${this.transitionTools ? "active" : ""}`} icon={"angle-down"} />
-                    </div></Tooltip>
                     <div className="toolbar-divider" />
-                    <Tooltip title={<><div className="dash-tooltip">{"Progressivize"}</div></>}><div className={`toolbar-button ${this.progressivizeTools ? "active" : ""}`} onClick={this.toggleProgressivize}>
-                        <FontAwesomeIcon icon={"tasks"} />
-                        <div style={{ display: this.props.PanelWidth() > 430 ? "block" : "none" }} className="toolbar-buttonText">&nbsp; Progressivize</div>
-                        <FontAwesomeIcon className={`dropdown ${this.progressivizeTools ? "active" : ""}`} icon={"angle-down"} />
-                    </div></Tooltip>
-                    <div className="toolbar-divider" /> */}
-                    {/* <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
-                        <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
-                    </div>
-                    <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
-                        <div className={`toolbar-moreInfo ${this.moreInfoTools ? "active" : ""}`}>
-                            <div className="toolbar-moreInfoBall" />
-                            <div className="toolbar-moreInfoBall" />
-                            <div className="toolbar-moreInfoBall" />
-                        </div>
-                    </div> */}
                 </div>
             );
         } else {
             return (
-                <>
+                <div id="toolbarContainer" className={'presBox-toolbar'}>
                     <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
                         <FontAwesomeIcon icon={"plus"} />
                         <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
                     </div></Tooltip>
-                    {/* <div className="toolbar-button" style={{ position: 'absolute', right: 23, transform: 'rotate(45deg)', fontSize: 16 }}>
-                        <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"thumbtack"} />
-                    </div>
-                    <div className={`toolbar-button ${this.moreInfoTools ? "active" : ""}`} onClick={this.toggleMoreInfo}>
-                        <div className={`toolbar-moreInfo ${this.moreInfoTools ? "active" : ""}`}>
-                            <div className="toolbar-moreInfoBall" />
-                            <div className="toolbar-moreInfoBall" />
-                            <div className="toolbar-moreInfoBall" />
-                        </div>
-                    </div> */}
-                </>
+                </div>
             );
         }
     }
@@ -1674,13 +1640,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>List</option>
                     <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel}>Slides</option>
                 </select>
-                <div className="presBox-presentPanel">
+                <div className="presBox-presentPanel" style={{ opacity: this.childDocs.length > 0 ? 1 : 0.3 }}>
                     <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
-                        <div className="presBox-button-left" onClick={() => this.layoutDoc.presStatus = "manual"}>
+                        <div className="presBox-button-left" onClick={() => { if (this.childDocs.length > 0) this.layoutDoc.presStatus = "manual" }}>
                             <FontAwesomeIcon icon={"play-circle"} />
                             <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present</div>
                         </div>
-                        <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.presentTools = !this.presentTools; }}>
+                        <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`}
+                            onClick={(action(() => {
+                                if (this.childDocs.length > 0) this.presentTools = !this.presentTools;
+                            }))}>
                             <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
                             {this.presentDropdown}
                         </div>
@@ -1691,41 +1660,41 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         );
     }
 
-    @computed get playButtons() {
+    @computed get playButtonFrames() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        return (
+            <>
+                {targetDoc ? <div className="miniPres-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? "inline-flex" : "none" }}>
+                    <div>{targetDoc.currentFrame}</div>
+                    <div className="miniPres-divider" style={{ border: 'solid 0.5px white', height: '60%' }}></div>
+                    <div>{targetDoc.lastFrame}</div>
+                </div> : null}
+            </>
+        );
+    }
+
+    @computed get playButtons() {
         // Case 1: There are still other frames and should go through all frames before going to next slide
         return (<div className="miniPresOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
-            {/* <span className={`presBox-button ${this.layoutDoc.presStatus !== "edit" ? "active" : ""}`}>
-                <div className="presBox-button-left" onClick={() => this.startPres(0)}>
-                    <FontAwesomeIcon icon={"clock"} /> &nbsp;
-                    <FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} />
-                </div>
-                <div className={`presBox-button-right ${this.playTools ? "active" : ""}`} onClick={e => { e.stopPropagation; this.togglePlay(); }}>
-                    <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.playTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
-                    {this.playDropdown}
-                </div>
-            </span> */}
             <div className="miniPres-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
-            <div className="miniPres-button" onClick={() => this.startPres(this.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
+            <div className="miniPres-button" onClick={() => this.startAutoPres(this.itemIndex)}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
             <div className="miniPres-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
             <div className="miniPres-divider"></div>
             <div className="miniPres-button-text" style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
                 Slide {this.itemIndex + 1} / {this.childDocs.length}
-                {targetDoc ? <div className="miniPres-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? "inline-flex" : "none" }}>
-                    <div>{targetDoc.currentFrame}</div>
-                    <div>{targetDoc.lastFrame}</div>
-                </div> : null}
+                {this.playButtonFrames}
             </div>
             <div className="miniPres-divider"></div>
-            <div className="miniPres-button" onClick={() => this.layoutDoc.presStatus = "edit"}>
-                <FontAwesomeIcon icon={"times"} />
-            </div>
+            {this.props.PanelWidth() > 250 ? <div className="miniPres-button-text" onClick={() => this.layoutDoc.presStatus = "edit"}>EXIT</div>
+                : <div className="miniPres-button" onClick={() => this.layoutDoc.presStatus = "edit"}>
+                    <FontAwesomeIcon icon={"times"} />
+                </div>}
         </div>);
     }
 
     render() {
-        // needed to insure that the childDocs are loaded for looking up fields
+        // needed to ensure that the childDocs are loaded for looking up fields
         this.childDocs.slice();
         const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
         return <div onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
-- 
cgit v1.2.3-70-g09d2


From 649ce72e3c30bca38e452c87d7f15453745c0785 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Thu, 6 Aug 2020 20:50:28 +0800
Subject: remove console log and texte -> text :basecamp:

---
 src/client/views/nodes/PresBox.tsx                   | 2 +-
 src/client/views/presentationview/PresElementBox.tsx | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

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

diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 24918098f..efcea832d 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -941,7 +941,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const subtitle = Docs.Create.TextDocument("Click to change subtitle", { title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt" });
         const header = Docs.Create.TextDocument("Click to change header", { title: "Slide header", _width: 380, _height: 65, x: 10, y: 80, _fontSize: "20pt" });
         const contentTitle = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 10, _fontSize: "24pt" });
-        const content = Docs.Create.TextDocument("Click to change texte", { title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt" });
+        const content = Docs.Create.TextDocument("Click to change text", { title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt" });
         const content1 = Docs.Create.TextDocument("Click to change text", { title: "Column 1", _width: 185, _height: 140, x: 10, y: 80, _fontSize: "14pt" });
         const content2 = Docs.Create.TextDocument("Click to change text", { title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt" });
         switch (layout) {
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 092fd1fd3..816577847 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -238,7 +238,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
         e.stopPropagation();
         e.preventDefault();
         if (element) {
-            console.log(element.className);
             if (PresBox.Instance._eleArray.includes(element)) {
                 setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
             }
-- 
cgit v1.2.3-70-g09d2


From 33487aa34fd455acf5216cfee7913d6e36f390ed Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Fri, 7 Aug 2020 01:35:46 +0800
Subject: presentaiton options slightly reformatted :pear:

---
 src/client/views/PropertiesButtons.tsx             |  3 +-
 .../views/collections/CollectionDockingView.tsx    |  3 +-
 .../collectionFreeForm/PropertiesView.scss         | 37 +++++++++
 .../collectionFreeForm/PropertiesView.tsx          | 64 ++++++++--------
 src/client/views/nodes/PresBox.scss                |  8 +-
 src/client/views/nodes/PresBox.tsx                 | 89 ++++++++++------------
 .../views/nodes/formattedText/FormattedTextBox.tsx | 19 ++---
 .../views/presentationview/PresElementBox.scss     |  4 +-
 .../views/presentationview/PresElementBox.tsx      |  3 +-
 9 files changed, 128 insertions(+), 102 deletions(-)

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

diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 55eb6c028..5c584d270 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -221,8 +221,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                 <div className="propertiesButtons-linker"
                     style={{ backgroundColor: isPinned ? "white" : "", color: isPinned ? "black" : "white" }}
                     onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
-                    <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon="map-pin"
-                    />
+                    <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon="map-pin" />
                 </div>
 
                 <div className="propertiesButtons-title" style={{
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 7bd79b2ef..7e096fa37 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -873,9 +873,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         return (
             <div className="miniPres"
                 style={{ width: 250, height: 30, background: '#323232' }}
-                onClick={() => document.addEventListener("keydown", PresBox.Instance.minimizeEvents, false)}
             >
-                {<div className="miniPresOverlay" onClick={() => document.addEventListener("keydown", PresBox.Instance.minimizeEvents, false)}>
+                {<div className="miniPresOverlay">
                     <div className="miniPres-button" onClick={PresBox.Instance.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
                     <div className="miniPres-button" onClick={() => PresBox.Instance.startAutoPres(PresBox.Instance.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
                     <div className="miniPres-button" onClick={PresBox.Instance.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index 5b41db90e..3ae94efb7 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -405,6 +405,43 @@
         }
 
     }
+
+    .propertiesView-presTrails {
+        border-bottom: 1px solid black;
+        //padding: 8.5px;
+
+        .propertiesView-presTrails-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding: 4px;
+            display: flex;
+            color: white;
+            padding-left: 8px;
+            background-color: rgb(51, 51, 51);
+
+            &:hover {
+                cursor: pointer;
+            }
+
+            .propertiesView-presTrails-title-icon {
+                float: right;
+                right: 0;
+                position: absolute;
+                margin-left: 2px;
+                margin-right: 9px;
+
+                &:hover {
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .propertiesView-presTrails-content {
+            font-size: 10px;
+            padding: 10px;
+            margin-left: 5px;
+        }
+    }
 }
 
 .inking-button {
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 89f48fc65..cef2241c9 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -71,11 +71,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     @observable openAppearance: boolean = true;
     @observable openTransform: boolean = true;
     //Pres Trails booleans:
-    @observable openAddSlide: boolean = true;
-    @observable openPresentationTools: boolean = true;
-    @observable openPresTransitions: boolean = true;
-    @observable openPresProgressivize: boolean = true;
-    @observable openSlideOptions: boolean = true;
+    @observable openPresTransitions: boolean = false;
+    @observable openPresProgressivize: boolean = false;
+    @observable openAddSlide: boolean = false;
+    @observable openSlideOptions: boolean = false;
 
     @observable inActions: boolean = false;
     @observable _controlBtn: boolean = false;
@@ -874,6 +873,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 </div>;
             }
             if (this.isPres) {
+                const selectedItem: boolean = PresBox.Instance._selectedArray.length > 0;
                 return <div className="propertiesView" style={{ width: this.props.width }} >
                     <div className="propertiesView-title" style={{ width: this.props.width }}>
                         Presentation
@@ -890,57 +890,57 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                             </div>
                         </div>
                     </div>
-                    <div className="propertiesView-settings">
-                        <div className="propertiesView-settings-title"
-                            onPointerDown={() => runInAction(() => { this.openAddSlide = !this.openAddSlide; })}
-                            style={{ backgroundColor: this.openAddSlide ? "black" : "" }}>
-                            &nbsp; <FontAwesomeIcon icon={"plus"} /> &nbsp; Add new slide
-                        <div className="propertiesView-settings-title-icon">
-                                <FontAwesomeIcon icon={this.openAddSlide ? "caret-down" : "caret-right"} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {this.openAddSlide ? <div className="propertiesView-settings-content">
-                            {PresBox.Instance.newDocumentDropdown}
-                        </div> : null}
-                    </div>
-                    <div className="propertiesView-sharing">
-                        <div className="propertiesView-sharing-title"
+                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+                        <div className="propertiesView-presTrails-title"
                             onPointerDown={() => runInAction(() => { this.openPresTransitions = !this.openPresTransitions; })}
                             style={{ backgroundColor: this.openPresTransitions ? "black" : "" }}>
                             &nbsp; <FontAwesomeIcon icon={"rocket"} /> &nbsp; Transitions
-                        <div className="propertiesView-sharing-title-icon">
+                        <div className="propertiesView-presTrails-title-icon">
                                 <FontAwesomeIcon icon={this.openPresTransitions ? "caret-down" : "caret-right"} size="lg" color="white" />
                             </div>
                         </div>
-                        {this.openPresTransitions ? <div className="propertiesView-sharing-content">
+                        {this.openPresTransitions ? <div className="propertiesView-presTrails-content">
                             {PresBox.Instance.transitionDropdown}
                         </div> : null}
-                    </div>
-                    <div className="propertiesView-sharing">
-                        <div className="propertiesView-sharing-title"
+                    </div>}
+                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+                        <div className="propertiesView-presTrails-title"
                             onPointerDown={() => runInAction(() => { this.openPresProgressivize = !this.openPresProgressivize; })}
                             style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}>
                             &nbsp; <FontAwesomeIcon icon={"tasks"} /> &nbsp; Progressivize
-                        <div className="propertiesView-sharing-title-icon">
+                        <div className="propertiesView-presTrails-title-icon">
                                 <FontAwesomeIcon icon={this.openPresProgressivize ? "caret-down" : "caret-right"} size="lg" color="white" />
                             </div>
                         </div>
-                        {this.openPresProgressivize ? <div className="propertiesView-sharing-content">
+                        {this.openPresProgressivize ? <div className="propertiesView-presTrails-content">
                             {PresBox.Instance.progressivizeDropdown}
                         </div> : null}
-                    </div>
-                    <div className="propertiesView-sharing">
-                        <div className="propertiesView-sharing-title"
+                    </div>}
+                    {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+                        <div className="propertiesView-presTrails-title"
                             onPointerDown={() => runInAction(() => { this.openSlideOptions = !this.openSlideOptions; })}
                             style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}>
                             &nbsp; <FontAwesomeIcon icon={"cog"} /> &nbsp; {PresBox.Instance.stringType} options
-                        <div className="propertiesView-sharing-title-icon">
+                        <div className="propertiesView-presTrails-title-icon">
                                 <FontAwesomeIcon icon={this.openSlideOptions ? "caret-down" : "caret-right"} size="lg" color="white" />
                             </div>
                         </div>
-                        {this.openSlideOptions ? <div className="propertiesView-sharing-content">
+                        {this.openSlideOptions ? <div className="propertiesView-presTrails-content">
                             {PresBox.Instance.optionsDropdown}
                         </div> : null}
+                    </div>}
+                    <div className="propertiesView-presTrails">
+                        <div className="propertiesView-presTrails-title"
+                            onPointerDown={() => runInAction(() => { this.openAddSlide = !this.openAddSlide; })}
+                            style={{ backgroundColor: this.openAddSlide ? "black" : "" }}>
+                            &nbsp; <FontAwesomeIcon icon={"plus"} /> &nbsp; Add new slide
+                        <div className="propertiesView-presTrails-title-icon">
+                                <FontAwesomeIcon icon={this.openAddSlide ? "caret-down" : "caret-right"} size="lg" color="white" />
+                            </div>
+                        </div>
+                        {this.openAddSlide ? <div className="propertiesView-presTrails-content">
+                            {PresBox.Instance.newDocumentDropdown}
+                        </div> : null}
                     </div>
                     <div className="propertiesView-sharing">
                         <div className="propertiesView-sharing-title"
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 77e7924dd..a87b0e466 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -247,7 +247,7 @@ $light-background: #ececec;
         justify-self: left;
         margin-top: 5px;
         padding-left: 10px;
-        background-color: rgb(222, 222, 222);
+        background-color: $light-background;
         border: solid 1px black;
         min-width: 80px;
         max-width: 200px;
@@ -272,7 +272,7 @@ $light-background: #ececec;
             cursor: pointer;
             position: relative;
             height: 100%;
-            background: #d5dce2;
+            background: $light-background;
             display: flex;
             align-items: center;
             justify-content: center;
@@ -436,7 +436,7 @@ $light-background: #ececec;
 
             .presBox-dropdownOptions {
                 position: absolute;
-                top: 29px;
+                top: 24px;
                 left: -1px;
                 z-index: 200;
                 width: 85%;
@@ -461,7 +461,7 @@ $light-background: #ececec;
             background-color: $light-background;
             border-radius: 5px;
             font-size: 10;
-            height: 30;
+            height: 25;
             padding-left: 5px;
             align-items: center;
             margin-top: 5px;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index efcea832d..a9daba675 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -371,11 +371,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             if (srcContext.miniPres) {
                 srcContext.miniPres = false;
                 CollectionDockingView.AddRightSplit(this.rootDoc);
-                document.removeEventListener("keydown", this.minimizeEvents, false);
             } else {
                 srcContext.miniPres = true;
                 this.props.addDocTab?.(this.rootDoc, "close");
-                document.addEventListener("keydown", this.minimizeEvents, false);
             }
         }
     }
@@ -506,20 +504,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
     }
 
-    // Key events when the minimized player is active
-    @action
-    minimizeEvents = (e: KeyboardEvent) => {
-        e.stopPropagation();
-        e.preventDefault();
-        if (e.keyCode === 27) { // Escape key
-            this.layoutDoc.presStatus = "edit";
-        } if (e.keyCode === 37) { // left(37) / a(65) / up(38) to go back
-            this.back();
-        } if (e.keyCode === 39) { // right (39) / d(68) / down(40) to go to next
-            this.next();
-        }
-    }
-
     // Key for when the presentaiton is active (according to Selection Manager)
     @action
     keyEvents = (e: KeyboardEvent) => {
@@ -531,10 +515,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             else this.layoutDoc.presStatus = "edit";
         } if ((e.metaKey || e.altKey) && e.keyCode === 65) { // Ctrl-A to select all
             if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs;
-        } if (e.keyCode === 37) { // left(37) / a(65) / up(38) to go back
-            if (this.layoutDoc.presStatus !== "edit") this.back();
-        } if (e.keyCode === 39) { // right (39) / d(68) / down(40) to go to next
-            if (this.layoutDoc.presStatus !== "edit") this.next();
+        } if (e.keyCode === 37 || e.keyCode === 38) { // left(37) / a(65) / up(38) to go back
+            this.back();
+        } if (e.keyCode === 39 || e.keyCode === 40) { // right (39) / d(68) / down(40) to go to next
+            this.next();
         } if (e.keyCode === 32) { // spacebar to 'present' or autoplay
             if (this.layoutDoc.presStatus !== "edit") this.startAutoPres(0);
             else this.layoutDoc.presStatus = "manual";
@@ -720,7 +704,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="ribbon-property"> {duration} s </div>
                         </div>
                         <input type="range" step="0.1" min="0.1" max="10" value={duration} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }} className={"toolbar-slider"} id="duration-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
-                        <div className={"slider-headers"} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }}>
+                        <div className={"slider-headers"} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "grid" }}>
                             <div className="slider-text">Short</div>
                             <div className="slider-text">Medium</div>
                             <div className="slider-text">Long</div>
@@ -814,6 +798,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                             <div className="ribbon-doubleButton" style={{ display: "flex" }}>
                                 <div className="ribbon-button" style={{ backgroundColor: activeItem.openDocument ? "#aedef8" : "" }} onClick={() => activeItem.openDocument = !activeItem.openDocument}>Open document</div>
                             </div>
+                            <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL ? "inline-flex" : "none" }}>
+                                <div className="ribbon-button" style={{ backgroundColor: activeItem.presPinView ? "#aedef8" : "" }}
+                                    onClick={() => {
+                                        activeItem.presPinView = !activeItem.presPinView;
+                                        if (activeItem.presPinView) {
+                                            const x = targetDoc._panX;
+                                            const y = targetDoc._panY;
+                                            const scale = targetDoc._viewScale;
+                                            activeItem.presPinViewX = x;
+                                            activeItem.presPinViewY = y;
+                                            activeItem.presPinViewScale = scale;
+                                        }
+                                    }}>Presentation pin view</div>
+                            </div>
                             <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.WEB ? "inline-flex" : "none" }}>
                                 <div className="ribbon-button" onClick={this.progressivizeText}>Store original website</div>
                             </div>
@@ -1592,35 +1590,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
 
     @computed get toolbar() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        if (activeItem) {
-            return (
-                <div id="toolbarContainer" className={'presBox-toolbar'} style={{ display: this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }}>
-                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
-                        <FontAwesomeIcon icon={"plus"} />
-                        <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
-                    </div></Tooltip>
-                    <div className="toolbar-divider" />
-                    <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}><div className={`toolbar-button ${this.pathBoolean ? "active" : ""}`}>
-                        <FontAwesomeIcon icon={"exchange-alt"} onClick={this.childDocs.length > 1 ? this.viewPaths : undefined} />
-                    </div></Tooltip>
-                    <Tooltip title={<><div className="dash-tooltip">{this.expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
-                        <div className={`toolbar-button ${this.expandBoolean ? "active" : ""}`} onClick={() => { this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = true; else doc.presExpandInlineButton = false; }); }}>
-                            <FontAwesomeIcon icon={"eye"} />
-                        </div>
-                    </Tooltip>
-                    <div className="toolbar-divider" />
-                </div>
-            );
-        } else {
-            return (
-                <div id="toolbarContainer" className={'presBox-toolbar'}>
-                    <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
-                        <FontAwesomeIcon icon={"plus"} />
-                        <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
-                    </div></Tooltip>
-                </div>
-            );
-        }
+        return (
+            <div id="toolbarContainer" className={'presBox-toolbar'} style={{ display: this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }}>
+                <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
+                    <FontAwesomeIcon icon={"plus"} />
+                    <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
+                </div></Tooltip>
+                <div className="toolbar-divider" />
+                <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}>
+                    <div style={{ opacity: this.childDocs.length > 1 ? 1 : 0.3 }} className={`toolbar-button ${this.pathBoolean ? "active" : ""}`} onClick={this.childDocs.length > 1 ? this.viewPaths : undefined}>
+                        <FontAwesomeIcon icon={"exchange-alt"} />
+                    </div>
+                </Tooltip>
+                <Tooltip title={<><div className="dash-tooltip">{this.expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
+                    <div style={{ opacity: this.childDocs.length > 0 ? 1 : 0.3 }} className={`toolbar-button ${this.expandBoolean ? "active" : ""}`} onClick={() => { if (this.childDocs.length > 0) this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = true; else doc.presExpandInlineButton = false; }); }}>
+                        <FontAwesomeIcon icon={"eye"} />
+                    </div>
+                </Tooltip>
+                <div className="toolbar-divider" />
+            </div>
+        );
     }
 
     /**
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index af4bd77c7..cc37cf586 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -577,7 +577,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         const mainBulletText: string[] = [];
         const mainBulletList: Doc[] = [];
         if (list) {
-            const newBullets: Doc[] = this.recursiveProgressivize(1, list);
+            const newBullets: Doc[] = this.recursiveProgressivize(1, list)[0];
             mainBulletList.push.apply(mainBulletList, newBullets);
         }
         console.log(mainBulletList.length);
@@ -591,7 +591,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         this.props.addDocument?.(doc);
     }
 
-    recursiveProgressivize = (nestDepth: number, list: HTMLCollectionOf<HTMLLIElement>, d?: number, y?: number, before?: string): Doc[] => {
+    recursiveProgressivize = (nestDepth: number, list: HTMLCollectionOf<HTMLLIElement>, d?: number, y?: number, before?: string): [Doc[], number] => {
         const mainBulletList: Doc[] = [];
         let b = d ? d : 0;
         let yLoc = y ? y : 0;
@@ -607,29 +607,30 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 if (listItem.childElementCount > 1) {
                     b++;
                     nestCount++;
-                    count = before ? count + nestCount + "." : nestCount + ".";
                     yLoc += height;
+                    count = before ? count + nestCount + "." : nestCount + ".";
                     const text = listItem.getElementsByTagName("p")[0].innerText;
                     const length = text.length;
-                    const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b });
+                    const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _autoHeight: true, x: xLoc, y: (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b });
+                    // yLoc += NumCast(bullet1._height);
                     mainBulletList.push(bullet1);
                     const newList = this.recursiveProgressivize(nestDepth + 1, listItem.getElementsByTagName("li"), b, yLoc, count);
-                    mainBulletList.push.apply(mainBulletList, newList);
-                    b += newList.length;
+                    mainBulletList.push.apply(mainBulletList, newList[0]);
                     yLoc += newList.length * (55 - ((nestDepth + 1) * 5));
                 } else {
                     b++;
                     nestCount++;
-                    count = before ? count + nestCount + "." : nestCount + ".";
                     yLoc += height;
+                    count = before ? count + nestCount + "." : nestCount + ".";
                     const text = listItem.innerText;
                     const length = text.length;
-                    const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _height: height, x: xLoc, y: 10 + (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b });
+                    const bullet1 = Docs.Create.TextDocument(count + " " + text, { title: "Slide text", _width: width, _autoHeight: true, x: xLoc, y: (yLoc), _fontSize: fontSize, backgroundColor: "rgba(0,0,0,0)", appearFrame: d ? d : b });
+                    // yLoc += NumCast(bullet1._height);
                     mainBulletList.push(bullet1);
                 }
             }
         });
-        return mainBulletList;
+        return [mainBulletList, yLoc];
     }
 
     recordDictation = () => {
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 3d730d7ac..1e776384a 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -4,7 +4,7 @@ $light-background: #ececec;
 
 .presElementBox-item {
     display: grid;
-    grid-template-columns: max-content max-content max-content;
+    grid-template-columns: max-content max-content max-content max-content;
     background-color: #d5dce2;
     font-family: Roboto;
     letter-spacing: normal;
@@ -122,7 +122,7 @@ $light-background: #ececec;
     padding-left: 10px;
     padding-right: 10px;
     letter-spacing: normal;
-    max-width: max-content;
+    width: max-content;
     text-overflow: ellipsis;
     overflow: hidden;
     white-space: pre;
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 816577847..a6dbb76ef 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -326,11 +326,12 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     <div className="presElementBox-number">
                         {`${this.indexInPres + 1}.`}
                     </div>
-                    <div ref={this._dragRef} className="presElementBox-name">
+                    <div ref={this._dragRef} className="presElementBox-name" style={{ maxWidth: (PresBox.Instance.toolbarWidth - 70) }}>
                         {`${this.targetDoc?.title}`}
                     </div>
                     <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.transition}</div></Tooltip>
                     <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presElementBox-time" style={{ display: PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>{this.duration}</div></Tooltip>
+                    <Tooltip title={<><div className="dash-tooltip">{"Presentation pin view"}</div></>}><div className="presElementBox-time" style={{ fontWeight: 700, display: this.rootDoc.presPinView && PresBox.Instance.toolbarWidth > 300 ? "block" : "none" }}>V</div></Tooltip>
                     <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><div
                         className="presElementBox-closeIcon"
                         onClick={e => {
-- 
cgit v1.2.3-70-g09d2


From 985c4eb599859d946833ee4ca42a5743b7d6caf8 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Fri, 7 Aug 2020 02:15:04 +0800
Subject: keyEvent changes :key: :point_down:

---
 .../collectionFreeForm/PropertiesView.tsx          |  2 +-
 src/client/views/nodes/PresBox.tsx                 | 39 ++++++++++++++--------
 2 files changed, 26 insertions(+), 15 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index cef2241c9..9c1cbec99 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -51,7 +51,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     @computed get selectedDocumentView() {
         if (SelectionManager.SelectedDocuments().length) {
             return SelectionManager.SelectedDocuments()[0];
-        } else if (PresBox.Instance._selectedArray.length >= 1) {
+        } else if (PresBox.Instance._selectedArray.length) {
             return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
         } else { return undefined; }
     }
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index a9daba675..7b370e89b 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -27,7 +27,6 @@ import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
 import { actionAsync } from "mobx-utils";
 import { SelectionManager } from "../../util/SelectionManager";
 import { AudioBox } from "./AudioBox";
-import { white } from "colors";
 
 type PresBoxSchema = makeInterface<[typeof documentSchema]>;
 const PresBoxDocument = makeInterface(documentSchema);
@@ -74,7 +73,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         }
         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.SelectedDocuments().length) {
+            return SelectionManager.SelectedDocuments()[0];
+        } else if (PresBox.Instance._selectedArray.length) {
+            return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
+        } else { return undefined; }
+    }
+    @computed get isPres(): boolean {
+        if (this.selectedDoc?.type === DocumentType.PRES) {
+            document.addEventListener("keydown", this.keyEvents, true);
+            return true;
+        } else {
+            document.removeEventListener("keydown", this.keyEvents, true);
+            return false;
+        }
+    }
+    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
 
     componentDidMount() {
         this.rootDoc.presBox = this.rootDoc;
@@ -84,14 +99,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         this.layoutDoc._gridGap = 5;
     }
 
-    onPointerOver = () => {
-        document.addEventListener("keydown", this.keyEvents, true);
-    }
-
-    onPointerLeave = () => {
-        document.removeEventListener("keydown", this.keyEvents, true);
-    }
-
     updateCurrentPresentation = () => {
         Doc.UserDoc().activePresentation = this.rootDoc;
     }
@@ -485,9 +492,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     //Command click
     @action
     multiSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
-        this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
-        this._eleArray.push(ref);
-        this._dragArray.push(drag);
+        if (!this._selectedArray.includes(doc)) {
+            this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
+            this._eleArray.push(ref);
+            this._dragArray.push(drag);
+        }
     }
 
     //Shift click
@@ -1683,10 +1692,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     }
 
     render() {
+        // calling this method for keyEvents
+        this.isPres;
         // needed to ensure that the childDocs are loaded for looking up fields
         this.childDocs.slice();
         const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
-        return <div onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
+        return <div className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
             {this.topPanel}
             {this.toolbar}
             {this.newDocumentToolbarDropdown}
-- 
cgit v1.2.3-70-g09d2


From 002eb8c7cd45bf4ad3e4e1e99ccb70675029678b Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Fri, 7 Aug 2020 03:46:21 +0800
Subject: viewfinder updates (bug fixes) :eyes:

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 40 +++++++++-------------
 src/client/views/nodes/PresBox.tsx                 | 40 +++++++++++++---------
 2 files changed, 39 insertions(+), 41 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ffeb3024d..192335abb 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1495,33 +1495,26 @@ interface CollectionFreeFormViewPannableContentsProps {
 @observer
 class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
     @computed get zoomProgressivize() {
-        if (this.props.zoomProgressivize) {
-            console.log("should render");
-            return (
-                <>
-                    {PresBox.Instance.zoomProgressivizeContainer}
-                </>
-            );
-        }
+        if (PresBox.Instance) return (
+            <>
+                {this.props.zoomProgressivize ? PresBox.Instance.zoomProgressivizeContainer : (null)}
+            </>
+        );
     }
 
     @computed get progressivize() {
-        if (this.props.progressivize) {
-            console.log("should render");
-            return (
-                <>
-                    {PresBox.Instance.progressivizeChildDocs}
-                </>
-            );
-        }
+        if (PresBox.Instance) return (
+            <>
+                {this.props.progressivize ? PresBox.Instance.progressivizeChildDocs : (null)}
+            </>
+        );
     }
 
     @computed get presPaths() {
         const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden");
-        if (this.props.presPaths) {
-            return (
-                <>
-                    <div>{PresBox.Instance.order}</div>
+        if (PresBox.Instance) return (
+            <>
+                {!this.props.presPaths ? (null) : <><div>{PresBox.Instance.order}</div>
                     <svg className={presPaths}>
                         <defs>
                             <marker id="arrow" markerWidth="3" overflow="visible" markerHeight="3" refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
@@ -1542,10 +1535,9 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
                             </marker>
                         </defs>;
                     {PresBox.Instance.paths}
-                    </svg>
-                </>
-            );
-        }
+                    </svg></>}
+            </>
+        );
     }
 
     render() {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 7b370e89b..230137584 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -1390,8 +1390,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         const doc = document.getElementById('resizable');
         if (doc && tagDocView) {
 
-            const scale = tagDocView.childScaling();
-            const scale2 = tagDocView.props.ScreenToLocalTransform().Scale;
+            const scale2 = tagDocView.childScaling();
+            const scale3 = tagDocView.props.ScreenToLocalTransform().Scale;
+            const scale = NumCast(targetDoc._viewScale);
+            console.log("scale: " + NumCast(targetDoc._viewScale));
             let height = doc.offsetHeight;
             let width = doc.offsetWidth;
             let top = doc.offsetTop;
@@ -1428,9 +1430,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             // }
             //Bottom right
             if (this._isDraggingBR) {
-                const newHeight = height += (e.movementY * scale2);
+                const newHeight = height += (e.movementY * scale);
                 doc.style.height = newHeight + 'px';
-                const newWidth = width += (e.movementX * scale2);
+                const newWidth = width += (e.movementX * scale);
                 doc.style.width = newWidth + 'px';
                 // Bottom left
             } else if (this._isDraggingBL) {
@@ -1442,26 +1444,26 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 doc.style.left = newLeft + 'px';
                 // Top right
             } else if (this._isDraggingTR) {
-                const newWidth = width += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newWidth = width += (e.movementX * scale);
                 doc.style.width = newWidth + 'px';
-                const newHeight = height -= (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newHeight = height -= (e.movementY * scale);
                 doc.style.height = newHeight + 'px';
-                const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newTop = top += (e.movementY * scale);
                 doc.style.top = newTop + 'px';
                 // Top left
             } else if (this._isDraggingTL) {
-                const newWidth = width -= (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newWidth = width -= (e.movementX * scale);
                 doc.style.width = newWidth + 'px';
-                const newHeight = height -= (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newHeight = height -= (e.movementY * scale);
                 doc.style.height = newHeight + 'px';
-                const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newTop = top += (e.movementY * scale);
                 doc.style.top = newTop + 'px';
-                const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newLeft = left += (e.movementX * scale);
                 doc.style.left = newLeft + 'px';
             } else if (this._isDragging) {
-                const newTop = top += (e.movementY * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newTop = top += (e.movementY * scale);
                 doc.style.top = newTop + 'px';
-                const newLeft = left += (e.movementX * tagDocView.props.ScreenToLocalTransform().Scale);
+                const newLeft = left += (e.movementX * scale);
                 doc.style.left = newLeft + 'px';
             }
             this.updateList(targetDoc, targetDoc["viewfinder-width-indexed"], width);
@@ -1501,20 +1503,24 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @computed get zoomProgressivizeContainer() {
         const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
         const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
-        if (targetDoc.editZoomProgressivize) {
+        if (targetDoc) {
+            const vfLeft: number = this.checkList(targetDoc, targetDoc["viewfinder-left-indexed"]);
+            const vfWidth: number = this.checkList(targetDoc, targetDoc["viewfinder-width-indexed"]);
+            const vfTop: number = this.checkList(targetDoc, targetDoc["viewfinder-top-indexed"]);
+            const vfHeight: number = this.checkList(targetDoc, targetDoc["viewfinder-height-indexed"]);
             return (
                 <>
-                    <div id="resizable" className="resizable" onPointerDown={this.onPointerMid} style={{ width: this.checkList(targetDoc, targetDoc["viewfinder-width-indexed"]), height: this.checkList(targetDoc, targetDoc["viewfinder-height-indexed"]), top: this.checkList(targetDoc, targetDoc["viewfinder-top-indexed"]), left: this.checkList(targetDoc, targetDoc["viewfinder-left-indexed"]), position: 'absolute' }}>
+                    {!targetDoc.editZoomProgressivize ? (null) : <div id="resizable" className="resizable" onPointerDown={this.onPointerMid} style={{ width: vfWidth, height: vfHeight, top: vfTop, left: vfLeft, position: 'absolute' }}>
                         <div className='resizers'>
                             <div id="resizer-tl" className='resizer top-left' onPointerDown={this.onPointerTL}></div>
                             <div id="resizer-tr" className='resizer top-right' onPointerDown={this.onPointerTR}></div>
                             <div id="resizer-bl" className='resizer bottom-left' onPointerDown={this.onPointerBL}></div>
                             <div id="resizer-br" className='resizer bottom-right' onPointerDown={this.onPointerBR}></div>
                         </div>
-                    </div>
+                    </div>}
                 </>
             );
-        } else return null;
+        }
     }
 
     @computed get progressivizeChildDocs() {
-- 
cgit v1.2.3-70-g09d2


From 301b10ba693dc76ebcd42d3fa4020410f2092bee Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 6 Aug 2020 23:13:50 -0400
Subject: fixed lint warnings

---
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 48 +++++++-------
 src/client/views/nodes/AudioBox.tsx                | 75 ++++++++++++----------
 src/client/views/nodes/PresBox.tsx                 |  4 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  3 +-
 4 files changed, 67 insertions(+), 63 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 5b1f3c01c..ef4b7b9d2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1504,32 +1504,30 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
 
     @computed get presPaths() {
         const presPaths = "presPaths" + (this.props.presPaths ? "" : "-hidden");
-        if (PresBox.Instance) return (
-            <>
-                {!this.props.presPaths ? (null) : <><div>{PresBox.Instance.order}</div>
-                    <svg className={presPaths}>
-                        <defs>
-                            <marker id="arrow" markerWidth="3" overflow="visible" markerHeight="3" refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
-                                <path d="M0,0 L0,6 L9,3 z" fill="#69a6db" />
-                            </marker>
-                            <marker id="square" markerWidth="3" markerHeight="3" overflow="visible"
-                                refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
-                                <path d="M 5,1 L 9,5 5,9 1,5 z" fill="#69a6db" />
-                            </marker>
-                            <marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4"
-                                orient="auto" overflow="visible">
-                                <rect x="1" y="1" width="5" height="5" fill="#69a6db" />
-                            </marker>
-
-                            <marker id="markerArrow" markerWidth="5" markerHeight="5" refX="2" refY="7"
-                                orient="auto" overflow="visible">
-                                <path d="M2,2 L2,13 L8,7 L2,2" fill="#69a6db" />
-                            </marker>
-                        </defs>;
+        return !(PresBox.Instance) ? (null) : (<>
+            {!this.props.presPaths ? (null) : <><div>{PresBox.Instance.order}</div>
+                <svg className={presPaths}>
+                    <defs>
+                        <marker id="arrow" markerWidth="3" overflow="visible" markerHeight="3" refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
+                            <path d="M0,0 L0,6 L9,3 z" fill="#69a6db" />
+                        </marker>
+                        <marker id="square" markerWidth="3" markerHeight="3" overflow="visible"
+                            refX="5" refY="5" orient="auto" markerUnits="strokeWidth">
+                            <path d="M 5,1 L 9,5 5,9 1,5 z" fill="#69a6db" />
+                        </marker>
+                        <marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4"
+                            orient="auto" overflow="visible">
+                            <rect x="1" y="1" width="5" height="5" fill="#69a6db" />
+                        </marker>
+
+                        <marker id="markerArrow" markerWidth="5" markerHeight="5" refX="2" refY="7"
+                            orient="auto" overflow="visible">
+                            <path d="M2,2 L2,13 L8,7 L2,2" fill="#69a6db" />
+                        </marker>
+                    </defs>;
                     {PresBox.Instance.paths}
-                    </svg></>}
-            </>
-        );
+                </svg></>}
+        </>);
     }
 
     render() {
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 11fecc0c2..eba1046b2 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -23,8 +23,8 @@ import { Networking } from "../../Network";
 import { LinkAnchorBox } from "./LinkAnchorBox";
 import { List } from "../../../fields/List";
 import { Scripting } from "../../util/Scripting";
-import Waveform from "react-audio-waveform"
-import axios from "axios"
+import Waveform from "react-audio-waveform";
+import axios from "axios";
 const _global = (window /* browser */ || global /* node */) as any;
 
 declare class MediaRecorder {
@@ -375,7 +375,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     @action
     end(marker: number) {
         this._hold = false;
-        let newMarker = Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
+        const newMarker = Docs.Create.LabelDocument({ title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, useLinkSmallAnchor: true, hideLinkButton: true, audioStart: this._start, audioEnd: marker, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document });
         newMarker.data = "";
         if (this.dataDoc[this.annotationKey]) {
             this.dataDoc[this.annotationKey].push(newMarker);
@@ -429,7 +429,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
 
         const rect = await (e.target as any).getBoundingClientRect();
 
-        let newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+        const newTime = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
 
         this.changeMarker(this._currMarker, newTime);
     }
@@ -437,11 +437,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     // updates the marker with the new time
     @action
     changeMarker = (m: any, time: any) => {
-        for (let i = 0; i < this.dataDoc[this.annotationKey].length; i++) {
-            if (this.isSame(this.dataDoc[this.annotationKey][i], m)) {
-                this._left ? this.dataDoc[this.annotationKey][i].audioStart = time : this.dataDoc[this.annotationKey][i].audioEnd = time;
+        DocListCast(this.dataDoc[this.annotationKey]).forEach((marker: Doc) => {
+            if (this.isSame(marker, m)) {
+                this._left ? marker.audioStart = time : marker.audioEnd = time;
             }
-        }
+        });
     }
 
     // checks if the two markers are the same with start and end time
@@ -457,7 +457,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         const increment = NumCast(this.layoutDoc.duration) / 500;
         this._count = [];
         for (let i = 0; i < 500; i++) {
-            this._count.push([increment * i, 0])
+            this._count.push([increment * i, 0]);
         }
 
     }
@@ -468,7 +468,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
             this._first = false;
             this.markers();
         }
-        let max = 0
+        let max = 0;
 
         for (let i = 0; i < 500; i++) {
             if (this._count[i][0] >= m.audioStart && this._count[i][0] <= m.audioEnd) {
@@ -490,7 +490,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
         if (this.dataDoc.markerAmount < max) {
             this.dataDoc.markerAmount = max;
         }
-        return max - 1
+        return max - 1;
     }
 
     // returns the audio waveform
@@ -509,27 +509,27 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     // decodes the audio file into peaks for generating the waveform
     @action
     buckets = async () => {
-        let audioCtx = new (window.AudioContext)();
+        const audioCtx = new (window.AudioContext)();
 
         axios({ url: this.path, responseType: "arraybuffer" })
             .then(response => {
-                let audioData = response.data;
+                const audioData = response.data;
 
                 audioCtx.decodeAudioData(audioData, action(buffer => {
-                    let decodedAudioData = buffer.getChannelData(0);
+                    const decodedAudioData = buffer.getChannelData(0);
                     const NUMBER_OF_BUCKETS = 100;
-                    let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
+                    const bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS);
 
                     for (let i = 0; i < NUMBER_OF_BUCKETS; i++) {
-                        let startingPoint = i * bucketDataSize;
-                        let endingPoint = i * bucketDataSize + bucketDataSize;
+                        const startingPoint = i * bucketDataSize;
+                        const endingPoint = i * bucketDataSize + bucketDataSize;
                         let max = 0;
                         for (let j = startingPoint; j < endingPoint; j++) {
                             if (decodedAudioData[j] > max) {
                                 max = decodedAudioData[j];
                             }
                         }
-                        let size = Math.abs(max);
+                        const size = Math.abs(max);
                         this._buckets.push(size / 2);
                     }
 
@@ -560,36 +560,36 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
     update = (width: number, height: number) => {
         if (height) {
             this._height = 0.8 * NumCast(this.layoutDoc._height);
-            let canvas2 = document.getElementsByTagName("canvas")[0];
+            const canvas2 = document.getElementsByTagName("canvas")[0];
             if (canvas2) {
-                let oldWidth = canvas2.width;
-                let oldHeight = canvas2.height;
+                const oldWidth = canvas2.width;
+                const oldHeight = canvas2.height;
                 canvas2.style.height = `${this._height}`;
                 canvas2.style.width = `${width}`;
 
-                let ratio1 = oldWidth / window.innerWidth;
-                let ratio2 = oldHeight / window.innerHeight;
-                let context = canvas2.getContext('2d');
+                const ratio1 = oldWidth / window.innerWidth;
+                const ratio2 = oldHeight / window.innerHeight;
+                const context = canvas2.getContext('2d');
                 if (context) {
-                    context.scale(ratio1, ratio2)
+                    context.scale(ratio1, ratio2);
                 }
             }
 
-            let canvas1 = document.getElementsByTagName("canvas")[1];
+            const canvas1 = document.getElementsByTagName("canvas")[1];
             if (canvas1) {
-                let oldWidth = canvas1.width;
-                let oldHeight = canvas1.height;
+                const oldWidth = canvas1.width;
+                const oldHeight = canvas1.height;
                 canvas1.style.height = `${this._height}`;
                 canvas1.style.width = `${width}`;
 
-                let ratio1 = oldWidth / window.innerWidth;
-                let ratio2 = oldHeight / window.innerHeight;
-                let context = canvas1.getContext('2d');
+                const ratio1 = oldWidth / window.innerWidth;
+                const ratio2 = oldHeight / window.innerHeight;
+                const context = canvas1.getContext('2d');
                 if (context) {
-                    context.scale(ratio1, ratio2)
+                    context.scale(ratio1, ratio2);
                 }
 
-                let parent = canvas1.parentElement;
+                const parent = canvas1.parentElement;
                 if (parent) {
                     parent.style.width = `${width}`;
                     parent.style.height = `${this._height}`;
@@ -665,7 +665,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
                                 (!m.isLabel) ?
                                     (this.layoutDoc.hideMarkers) ? (null) :
                                         rect =
-                                        <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"} title={`${formatTime(Math.round(NumCast(m.audioStart)))}` + " - " + `${formatTime(Math.round(NumCast(m.audioEnd)))}`} key={i} id={"audiobox-marker-container1"} style={{ left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%`, width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / (this.dataDoc.markerAmount + 1) * 100}%`, top: `${this.isOverlap(m) * 1 / (this.dataDoc.markerAmount + 1) * 100}%` }} onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} >
+                                        <div key={i} id={"audiobox-marker-container1"} className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container1"}
+                                            title={`${formatTime(Math.round(NumCast(m.audioStart)))}` + " - " + `${formatTime(Math.round(NumCast(m.audioEnd)))}`}
+                                            style={{
+                                                left: `${NumCast(m.audioStart) / NumCast(this.dataDoc.duration, 1) * 100}%`,
+                                                width: `${(NumCast(m.audioEnd) - NumCast(m.audioStart)) / NumCast(this.dataDoc.duration, 1) * 100}%`, height: `${1 / (this.dataDoc.markerAmount + 1) * 100}%`,
+                                                top: `${this.isOverlap(m) * 1 / (this.dataDoc.markerAmount + 1) * 100}%`
+                                            }}
+                                            onClick={e => { this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} >
                                             <div className="left-resizer" onPointerDown={e => this.onPointerDown(e, m, true)}></div>
                                             <DocumentView {...this.props}
                                                 Document={m}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 230137584..502fd51f3 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -137,7 +137,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             this.gotoDocument(nextSelected, this.itemIndex);
             const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
             if (activeNext && targetNext.type === DocumentType.AUDIO && activeNext.playAuto) {
-            } else { this._moveOnFromAudio = false };
+            } else this._moveOnFromAudio = false;
         }
     }
 
@@ -1646,7 +1646,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
                 </select>
                 <div className="presBox-presentPanel" style={{ opacity: this.childDocs.length > 0 ? 1 : 0.3 }}>
                     <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
-                        <div className="presBox-button-left" onClick={() => { if (this.childDocs.length > 0) this.layoutDoc.presStatus = "manual" }}>
+                        <div className="presBox-button-left" onClick={() => (this.childDocs.length > 0) && (this.layoutDoc.presStatus = "manual")}>
                             <FontAwesomeIcon icon={"play-circle"} />
                             <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present</div>
                         </div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 4b06f2800..b0bf54be6 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -305,7 +305,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     // for inserting timestamps 
     insertTime = () => {
-        let linkTime;
         if (this._first) {
             this._first = false;
             DocListCast(this.dataDoc.links).map((l, i) => {
@@ -318,7 +317,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     this._linkTime = NumCast(l.anchor1_timecode);
                 }
 
-            })
+            });
         }
         this._currentTime = Date.now();
         let time;
-- 
cgit v1.2.3-70-g09d2

