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

---
 src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

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

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;
-- 
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/CollectionFreeFormDocumentView.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/CollectionFreeFormDocumentView.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/CollectionFreeFormDocumentView.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 b83a38a3a92c0149562da460ad9c35eaaf3054ec Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Sun, 26 Jul 2020 17:41:01 +0800
Subject: download name update

**not part of pres trails**
---
 src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 10 +++++-----
 src/fields/Doc.ts                                         |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

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

diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index ba9385514..480abdaed 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -114,10 +114,10 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     }
 
     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>();
+        const width = new List<number>();
+        const height = new List<number>();
+        const top = new List<number>();
+        const left = new List<number>();
         width.push(NumCast(doc.width));
         height.push(NumCast(doc.height));
         top.push(NumCast(doc.height) / -2);
@@ -176,7 +176,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             NativeWidth={this.NativeWidth}
             PanelWidth={this.panelWidth}
             PanelHeight={this.panelHeight} />;
-        if (this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc) {
+        if (PresBox.Instance && this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc) {
             const effectProps = {
                 left: this.layoutDoc.presEffectDirection === 'left',
                 right: this.layoutDoc.presEffectDirection === 'right',
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index e28f6b7d2..cc90574a2 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -595,7 +595,7 @@ export namespace Doc {
 
         var zip = new JSZip();
 
-        zip.file("doc.json", docString);
+        zip.file(doc.title + ".json", docString);
 
         // // Generate a directory within the Zip file structure
         // var img = zip.folder("images");
@@ -607,7 +607,7 @@ export namespace Doc {
         zip.generateAsync({ type: "blob" })
             .then((content: any) => {
                 // Force down of the Zip file
-                saveAs(content, "download.zip");
+                saveAs(content, doc.title + ".zip"); // glr: Possibly change the name of the document to match the title?
             });
     }
     //
-- 
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/CollectionFreeFormDocumentView.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/CollectionFreeFormDocumentView.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 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/CollectionFreeFormDocumentView.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/CollectionFreeFormDocumentView.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

