From b69106994f5450e2ac2c515f28dacceb2e13b78b Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 25 Sep 2019 00:16:55 -0400
Subject: refactored collection view to be cleaner and more modular for
 supporting things like PivotView. fixed pivot view selection bug.

---
 src/client/views/nodes/PresBox.tsx | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index e376fbddb..5afd85430 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -161,10 +161,8 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
             if (zoomOut || this.presElementsMappings.get(docAtCurrent)!.showButton) {
                 let prevScale = NumCast(this.childrenDocs[prevSelected].viewScale, null);
                 let curScale = DocumentManager.Instance.getScaleOfDocView(this.childrenDocs[current]);
-                if (prevScale !== undefined) {
-                    if (prevScale !== curScale) {
-                        DocumentManager.Instance.zoomIntoScale(docAtCurrent, prevScale);
-                    }
+                if (prevScale !== undefined && prevScale !== curScale) {
+                    DocumentManager.Instance.zoomIntoScale(docAtCurrent, prevScale);
                 }
             }
         }
-- 
cgit v1.2.3-70-g09d2


From d49e573d62fb9caee0568b454cb3555775a887ff Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 30 Sep 2019 11:14:52 -0400
Subject: start of presentationview cleanup

---
 src/client/views/MainView.tsx                      |  43 +--
 src/client/views/nodes/PresBox.tsx                 | 410 ++++++++-------------
 .../presentationview/PresentationModeMenu.tsx      |   4 -
 3 files changed, 161 insertions(+), 296 deletions(-)

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

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index cf09bd2d0..dadff21a7 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,5 @@
 import { IconName, library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faClone, faCloudUploadAlt, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, faMusic, faObjectGroup, faPause, faPenNib, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faUndoAlt, faTv } from '@fortawesome/free-solid-svg-icons';
+import { faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faClone, faCloudUploadAlt, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, faMusic, faObjectGroup, faPause, faPenNib, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faTv, faUndoAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, configure, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -7,23 +7,24 @@ import "normalize.css";
 import * as React from 'react';
 import { SketchPicker } from 'react-color';
 import Measure from 'react-measure';
-import { List } from '../../new_fields/List';
-import { Doc, DocListCast, Opt, HeightSym, FieldResult, Field } from '../../new_fields/Doc';
+import { Doc, DocListCast, Field, FieldResult, HeightSym, Opt } from '../../new_fields/Doc';
 import { Id } from '../../new_fields/FieldSymbols';
 import { InkTool } from '../../new_fields/InkField';
+import { List } from '../../new_fields/List';
 import { listSpec } from '../../new_fields/Schema';
-import { BoolCast, Cast, FieldValue, StrCast, NumCast } from '../../new_fields/Types';
+import { BoolCast, Cast, FieldValue, StrCast } from '../../new_fields/Types';
 import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
 import { RouteStore } from '../../server/RouteStore';
-import { emptyFunction, returnOne, returnTrue, Utils, returnEmptyString } from '../../Utils';
+import { emptyFunction, returnEmptyString, returnOne, returnTrue, Utils } from '../../Utils';
 import { DocServer } from '../DocServer';
+import { Docs, DocumentOptions } from '../documents/Documents';
 import { ClientUtils } from '../util/ClientUtils';
 import { DictationManager } from '../util/DictationManager';
 import { SetupDrag } from '../util/DragManager';
-import { Transform } from '../util/Transform';
-import { UndoManager, undoBatch } from '../util/UndoManager';
-import { Docs, DocumentOptions } from '../documents/Documents';
 import { HistoryUtil } from '../util/History';
+import SharingManager from '../util/SharingManager';
+import { Transform } from '../util/Transform';
+import { UndoManager } from '../util/UndoManager';
 import { CollectionBaseView, CollectionViewType } from './collections/CollectionBaseView';
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import { CollectionTreeView } from './collections/CollectionTreeView';
@@ -33,20 +34,13 @@ import KeyManager from './GlobalKeyHandler';
 import { InkingControl } from './InkingControl';
 import "./Main.scss";
 import { MainOverlayTextBox } from './MainOverlayTextBox';
+import MainViewModal from './MainViewModal';
 import { DocumentView } from './nodes/DocumentView';
+import { PresBox } from './nodes/PresBox';
 import { OverlayView } from './OverlayView';
 import PDFMenu from './pdf/PDFMenu';
 import { PreviewCursor } from './PreviewCursor';
 import { FilterBox } from './search/FilterBox';
-import PresModeMenu from './presentationview/PresentationModeMenu';
-import { PresBox } from './nodes/PresBox';
-import { GooglePhotos } from '../apis/google_docs/GooglePhotosClientUtils';
-import { ImageField } from '../../new_fields/URLField';
-import { LinkFollowBox } from './linking/LinkFollowBox';
-import { DocumentManager } from '../util/DocumentManager';
-import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField';
-import MainViewModal from './MainViewModal';
-import SharingManager from '../util/SharingManager';
 
 @observer
 export class MainView extends React.Component {
@@ -185,9 +179,8 @@ export class MainView extends React.Component {
                     CurrentUserUtils.MainDocId = pathname[1];
                     if (!this.userDoc) {
                         runInAction(() => this.flyoutWidth = 0);
-                        DocServer.GetRefField(CurrentUserUtils.MainDocId).then(action(field => {
-                            field instanceof Doc && (CurrentUserUtils.GuestTarget = field);
-                        }));
+                        DocServer.GetRefField(CurrentUserUtils.MainDocId).then(action((field: Opt<Field>) =>
+                            field instanceof Doc && (CurrentUserUtils.GuestTarget = field)));
                     }
                 }
             }
@@ -634,14 +627,6 @@ export class MainView extends React.Component {
         );
     }
 
-    @computed get miniPresentation() {
-        let next = () => PresBox.CurrentPresentation.next();
-        let back = () => PresBox.CurrentPresentation.back();
-        let startOrResetPres = () => PresBox.CurrentPresentation.startOrResetPres();
-        let closePresMode = action(() => { PresBox.CurrentPresentation.presMode = false; this.addDocTabFunc(PresBox.CurrentPresentation.props.Document, undefined, "onRight"); });
-        return !PresBox.CurrentPresentation || !PresBox.CurrentPresentation.presMode ? (null) : <PresModeMenu next={next} back={back} presStatus={PresBox.CurrentPresentation.presStatus} startOrResetPres={startOrResetPres} closePresMode={closePresMode} > </PresModeMenu>;
-    }
-
     render() {
         return (
             <div id="main-div">
@@ -649,7 +634,7 @@ export class MainView extends React.Component {
                 <SharingManager />
                 <DocumentDecorations />
                 {this.mainContent}
-                {this.miniPresentation}
+                {PresBox.miniPresentation}
                 <PreviewCursor />
                 <ContextMenu />
                 {this.nodesMenu()}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 5afd85430..d246da87a 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -2,21 +2,20 @@ import React = require("react");
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faArrowLeft, faArrowRight, faEdit, faMinus, faPlay, faPlus, faStop, faTimes } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, runInAction } from "mobx";
+import { action, observable, runInAction, computed } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { List } from "../../../new_fields/List";
+import { Doc, DocListCast } from "../../../new_fields/Doc";
 import { listSpec } from "../../../new_fields/Schema";
-import { BoolCast, Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types";
-import { Utils } from "../../../Utils";
+import { BoolCast, Cast, FieldValue, NumCast } from "../../../new_fields/Types";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
+import { ContextMenu } from "../ContextMenu";
 import PresentationElement from "../presentationview/PresentationElement";
 import PresentationViewList from "../presentationview/PresentationList";
 import "../presentationview/PresentationView.scss";
 import { FieldView, FieldViewProps } from './FieldView';
-import { ContextMenu } from "../ContextMenu";
+import PresModeMenu from "../presentationview/PresentationModeMenu";
+import { CollectionDockingView } from "../collections/CollectionDockingView";
 
 library.add(faArrowLeft);
 library.add(faArrowRight);
@@ -27,147 +26,99 @@ library.add(faTimes);
 library.add(faMinus);
 library.add(faEdit);
 
-
-export interface PresViewProps {
-    Documents: List<Doc>;
-}
-
-const expandedWidth = 450;
-
 @observer
-export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
-
-
+export class PresBox extends React.Component<FieldViewProps> {
     public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(PresBox, fieldKey); }
 
     public static Instance: PresBox;
-
-    //Keeping track of the doc for the current presentation -- bcz: keeping a list of current presentations shouldn't be needed.  Let users create them, store them, as they see fit.
-    @computed get curPresentation() { return this.props.Document; }
-
     //mapping from docs to their rendered component
-    @observable presElementsMappings: Map<Doc, PresentationElement> = new Map();
+    @observable _presElementsMappings: Map<Doc, PresentationElement> = new Map();
     //variable that holds all the docs in the presentation
-    @observable childrenDocs: Doc[] = [];
-    //variable to hold if presentation is started
-    @observable presStatus: boolean = false;
-    //Mapping of guids to presentations.
-    @observable presentationsMapping: Map<String, Doc> = new Map();
-    //Mapping of presentations to guid, so that select option values can be given.
-    @observable presentationsKeyMapping: Map<Doc, String> = new Map();
-    //Variable to keep track of guid of the current presentation
-    @observable currentSelectedPresValue: string | undefined;
-    //A flag to keep track if title input is open, which is used in rendering.
-    @observable PresTitleInputOpen: boolean = false;
-    //Variable that holds reference to title input, so that new presentations get titles assigned.
-    @observable titleInputElement: HTMLInputElement | undefined;
-    @observable PresTitleChangeOpen: boolean = false;
-
-    @observable opacity = 1;
-    @observable persistOpacity = true;
-    @observable labelOpacity = 0;
-    @observable presMode = false;
+    @observable _childrenDocs: Doc[] = [];
 
+    @observable _opacity = 1;
+    @observable _persistOpacity = true;
+    @observable _labelOpacity = 0;
+    // whether presentation view has been minimized
+    @observable _presMode = false;
     @observable public static CurrentPresentation: PresBox;
 
+    @computed static get miniPresentation() {
+        let next = () => PresBox.CurrentPresentation.next();
+        let back = () => PresBox.CurrentPresentation.back();
+        let startOrResetPres = () => PresBox.CurrentPresentation.startOrResetPres();
+        let closePresMode = action(() => {
+            PresBox.CurrentPresentation._presMode = false;
+            CollectionDockingView.AddRightSplit(PresBox.CurrentPresentation.props.Document, undefined);
+        });
+        return !PresBox.CurrentPresentation || !PresBox.CurrentPresentation._presMode ? (null) :
+            <PresModeMenu next={next} back={back} presStatus={BoolCast(PresBox.CurrentPresentation.props.Document.presStatus)}
+                startOrResetPres={startOrResetPres} closePresMode={closePresMode} />;
+    }
+
     //initilize class variables
     constructor(props: FieldViewProps) {
         super(props);
         runInAction(() => PresBox.CurrentPresentation = this);
     }
 
-    @action
-    toggle = (forcedValue: boolean | undefined) => {
-        if (forcedValue !== undefined) {
-            this.curPresentation.width = forcedValue ? expandedWidth : 0;
-        } else {
-            this.curPresentation.width = this.curPresentation.width === expandedWidth ? 0 : expandedWidth;
-        }
-    }
-
-    //Second lifecycle function that gets called when component mounts. It makes sure toS
-    //get the back-up information from previous session for the current presentation.
-    async componentDidMount() {
-        this.setPresentationBackUps();
-    }
-
-
-    /**
-     * The function that retrieves the backUps for the current Presentation if present,
-     * otherwise initializes.
-     */
-    setPresentationBackUps = async () => {
-        //storing the presentation status,ie. whether it was stopped or playing
-        let presStatusBackUp = BoolCast(this.curPresentation.presStatus);
-        runInAction(() => this.presStatus = presStatusBackUp);
-    }
-
-    //observable means render is re-called every time variable is changed
-    @observable
-    collapsed: boolean = false;
     next = async () => {
-        const current = NumCast(this.curPresentation.selectedDoc);
+        const current = NumCast(this.props.Document.selectedDoc);
         //asking to get document at current index
         let docAtCurrentNext = await this.getDocAtIndex(current + 1);
-        if (docAtCurrentNext === undefined) {
-            return;
-        }
-        let nextSelected = current + 1;
+        if (docAtCurrentNext !== undefined) {
+            let presDocs = DocListCast(this.props.Document.data);
+            let nextSelected = current + 1;
 
-        let presDocs = DocListCast(this.curPresentation.data);
-        for (; nextSelected < presDocs.length - 1; nextSelected++) {
-            if (!this.presElementsMappings.get(presDocs[nextSelected + 1])!.props.document.groupButton) {
-                break;
+            for (; nextSelected < presDocs.length - 1; nextSelected++) {
+                if (!this._presElementsMappings.get(presDocs[nextSelected + 1])!.props.document.groupButton) {
+                    break;
+                }
             }
-        }
-
-        this.gotoDocument(nextSelected, current);
 
+            this.gotoDocument(nextSelected, current);
+        }
     }
     back = async () => {
-        const current = NumCast(this.curPresentation.selectedDoc);
+        const current = NumCast(this.props.Document.selectedDoc);
         //requesting for the doc at current index
         let docAtCurrent = await this.getDocAtIndex(current);
-        if (docAtCurrent === undefined) {
-            return;
-        }
+        if (docAtCurrent !== undefined) {
 
-        //asking for its presentation id.
-        let curPresId = StrCast(docAtCurrent.presentId);
-        let prevSelected = current;
-        let zoomOut: boolean = false;
+            //asking for its presentation id.
+            let prevSelected = current;
+            let zoomOut: boolean = false;
 
-        //checking if this presentation id is mapped to a group, if so chosing the first element in group
-        let presDocs = DocListCast(this.curPresentation.data);
-        let currentsArray: Doc[] = [];
-        for (; prevSelected > 0 && presDocs[prevSelected].groupButton; prevSelected--) {
-            currentsArray.push(presDocs[prevSelected]);
-        }
-        prevSelected = Math.max(0, prevSelected - 1);
-
-        //checking if any of the group members had used zooming in
-        currentsArray.forEach((doc: Doc) => {
-            //let presElem: PresentationElement | undefined = this.presElementsMappings.get(doc);
-            if (this.presElementsMappings.get(doc)!.props.document.showButton) {
-                zoomOut = true;
-                return;
+            //checking if this presentation id is mapped to a group, if so chosing the first element in group
+            let presDocs = DocListCast(this.props.Document.data);
+            let currentsArray: Doc[] = [];
+            for (; prevSelected > 0 && presDocs[prevSelected].groupButton; prevSelected--) {
+                currentsArray.push(presDocs[prevSelected]);
             }
-        });
-
-
-        // if a group set that flag to zero or a single element
-        //If so making sure to zoom out, which goes back to state before zooming action
-        if (current > 0) {
-            if (zoomOut || this.presElementsMappings.get(docAtCurrent)!.showButton) {
-                let prevScale = NumCast(this.childrenDocs[prevSelected].viewScale, null);
-                let curScale = DocumentManager.Instance.getScaleOfDocView(this.childrenDocs[current]);
-                if (prevScale !== undefined && prevScale !== curScale) {
-                    DocumentManager.Instance.zoomIntoScale(docAtCurrent, prevScale);
+            prevSelected = Math.max(0, prevSelected - 1);
+
+            //checking if any of the group members had used zooming in
+            currentsArray.forEach((doc: Doc) => {
+                //let presElem: PresentationElement | undefined = this.presElementsMappings.get(doc);
+                if (this._presElementsMappings.get(doc)!.props.document.showButton) {
+                    zoomOut = true;
+                    return;
+                }
+            });
+
+            // if a group set that flag to zero or a single element
+            //If so making sure to zoom out, which goes back to state before zooming action
+            if (current > 0) {
+                if (zoomOut || this._presElementsMappings.get(docAtCurrent)!.showButton) {
+                    let prevScale = NumCast(this._childrenDocs[prevSelected].viewScale, null);
+                    let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[current]);
+                    if (prevScale !== undefined && prevScale !== curScale) {
+                        DocumentManager.Instance.zoomIntoScale(docAtCurrent, prevScale);
+                    }
                 }
             }
+            this.gotoDocument(prevSelected, current);
         }
-        this.gotoDocument(prevSelected, current);
-
     }
 
     /**
@@ -176,21 +127,21 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
     showAfterPresented = (index: number) => {
-        this.presElementsMappings.forEach((presElem: PresentationElement, key: Doc) => {
+        this._presElementsMappings.forEach((presElem, doc) => {
             //the order of cases is aligned based on priority
             if (presElem.props.document.hideTillShownButton) {
-                if (this.childrenDocs.indexOf(key) <= index) {
-                    key.opacity = 1;
+                if (this._childrenDocs.indexOf(doc) <= index) {
+                    doc.opacity = 1;
                 }
             }
             if (presElem.props.document.hideAfterButton) {
-                if (this.childrenDocs.indexOf(key) < index) {
-                    key.opacity = 0;
+                if (this._childrenDocs.indexOf(doc) < index) {
+                    doc.opacity = 0;
                 }
             }
             if (presElem.props.document.fadeButton) {
-                if (this.childrenDocs.indexOf(key) < index) {
-                    key.opacity = 0.5;
+                if (this._childrenDocs.indexOf(doc) < index) {
+                    doc.opacity = 0.5;
                 }
             }
         });
@@ -202,21 +153,21 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
     hideIfNotPresented = (index: number) => {
-        this.presElementsMappings.forEach((presElem: PresentationElement, key: Doc) => {
+        this._presElementsMappings.forEach((presElem, key) => {
             //the order of cases is aligned based on priority
 
             if (presElem.props.document.hideAfterButton) {
-                if (this.childrenDocs.indexOf(key) >= index) {
+                if (this._childrenDocs.indexOf(key) >= index) {
                     key.opacity = 1;
                 }
             }
             if (presElem.props.document.fadeButton) {
-                if (this.childrenDocs.indexOf(key) >= index) {
+                if (this._childrenDocs.indexOf(key) >= index) {
                     key.opacity = 1;
                 }
             }
             if (presElem.props.document.hideTillShownButton) {
-                if (this.childrenDocs.indexOf(key) > index) {
+                if (this._childrenDocs.indexOf(key) > index) {
                     key.opacity = 0;
                 }
             }
@@ -229,26 +180,25 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
      * te option open, navigates to that element.
      */
     navigateToElement = async (curDoc: Doc, fromDoc: number) => {
-        let docToJump: Doc = curDoc;
-        let willZoom: boolean = false;
-
+        let docToJump = curDoc;
+        let willZoom = false;
 
-        let presDocs = DocListCast(this.curPresentation.data);
+        let presDocs = DocListCast(this.props.Document.data);
         let nextSelected = presDocs.indexOf(curDoc);
         let currentDocGroups: Doc[] = [];
         for (; nextSelected < presDocs.length - 1; nextSelected++) {
-            if (!this.presElementsMappings.get(presDocs[nextSelected + 1])!.props.document.groupButton) {
+            if (!this._presElementsMappings.get(presDocs[nextSelected + 1])!.props.document.groupButton) {
                 break;
             }
             currentDocGroups.push(presDocs[nextSelected]);
         }
 
         currentDocGroups.forEach((doc: Doc, index: number) => {
-            if (this.presElementsMappings.get(doc)!.navButton) {
+            if (this._presElementsMappings.get(doc)!.navButton) {
                 docToJump = doc;
                 willZoom = false;
             }
-            if (this.presElementsMappings.get(doc)!.showButton) {
+            if (this._presElementsMappings.get(doc)!.showButton) {
                 docToJump = doc;
                 willZoom = true;
             }
@@ -257,24 +207,23 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
         if (docToJump === curDoc) {
             //checking if curDoc has navigation open
-            if (this.presElementsMappings.get(curDoc)!.navButton) {
+            if (this._presElementsMappings.get(curDoc)!.navButton) {
                 DocumentManager.Instance.jumpToDocument(curDoc, false);
-            } else if (this.presElementsMappings.get(curDoc)!.showButton) {
-                let curScale = DocumentManager.Instance.getScaleOfDocView(this.childrenDocs[fromDoc]);
+            } else if (this._presElementsMappings.get(curDoc)!.showButton) {
+                let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[fromDoc]);
                 //awaiting jump so that new scale can be found, since jumping is async
                 await DocumentManager.Instance.jumpToDocument(curDoc, true);
-                let newScale = DocumentManager.Instance.getScaleOfDocView(curDoc);
-                curDoc.viewScale = newScale;
+                curDoc.viewScale = DocumentManager.Instance.getScaleOfDocView(curDoc);
 
                 //saving the scale user was on before zooming in
                 if (curScale !== 1) {
-                    this.childrenDocs[fromDoc].viewScale = curScale;
+                    this._childrenDocs[fromDoc].viewScale = curScale;
                 }
 
             }
             return;
         }
-        let curScale = DocumentManager.Instance.getScaleOfDocView(this.childrenDocs[fromDoc]);
+        let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[fromDoc]);
 
         //awaiting jump so that new scale can be found, since jumping is async
         await DocumentManager.Instance.jumpToDocument(docToJump, willZoom);
@@ -282,7 +231,7 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
         curDoc.viewScale = newScale;
         //saving the scale that user was on
         if (curScale !== 1) {
-            this.childrenDocs[fromDoc].viewScale = curScale;
+            this._childrenDocs[fromDoc].viewScale = curScale;
         }
 
     }
@@ -291,18 +240,13 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
      * Async function that supposedly return the doc that is located at given index.
      */
     getDocAtIndex = async (index: number) => {
-        const list = FieldValue(Cast(this.curPresentation.data, listSpec(Doc)));
-        if (!list) {
-            return undefined;
-        }
-        if (index < 0 || index >= list.length) {
-            return undefined;
+        const list = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+        if (list && index >= 0 && index < list.length) {
+            this.props.Document.selectedDoc = index;
+            //awaiting async call to finish to get Doc instance
+            return await list[index];
         }
-
-        this.curPresentation.selectedDoc = index;
-        //awaiting async call to finish to get Doc instance
-        const doc = await list[index];
-        return doc;
+        return undefined
     }
 
     /**
@@ -311,23 +255,19 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
      */
     @action
     public RemoveDoc = async (index: number) => {
-        const value = FieldValue(Cast(this.curPresentation.data, listSpec(Doc)));
+        const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc))); // don't replace with DocListCast -- we need to modify the document's actual stored list
         if (value) {
-            let removedDoc = await value.splice(index, 1)[0];
-
-            //removing the Presentation Element stored for it
-            this.presElementsMappings.delete(removedDoc);
-
+            //removing the Presentation Element from the document and update mappings
+            this._presElementsMappings.delete(await value.splice(index, 1)[0]);
         }
     }
 
     public removeDocByRef = (doc: Doc) => {
-        let indexOfDoc = this.childrenDocs.indexOf(doc);
-        const value = FieldValue(Cast(this.curPresentation.data, listSpec(Doc)));
+        let indexOfDoc = this._childrenDocs.indexOf(doc);
+        const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
         if (value) {
             value.splice(indexOfDoc, 1)[0];
         }
-        //this.RemoveDoc(indexOfDoc, true);
         if (indexOfDoc !== - 1) {
             return true;
         }
@@ -339,144 +279,92 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
     @action
     public gotoDocument = async (index: number, fromDoc: number) => {
         Doc.UnBrushAllDocs();
-        const list = FieldValue(Cast(this.curPresentation.data, listSpec(Doc)));
-        if (!list) {
-            return;
-        }
-        if (index < 0 || index >= list.length) {
-            return;
-        }
-        this.curPresentation.selectedDoc = index;
+        const list = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+        if (list && index >= 0 && index < list.length) {
+            this.props.Document.selectedDoc = index;
 
-        if (!this.presStatus) {
-            this.presStatus = true;
-            this.startPresentation(index);
-        }
+            if (!this.props.Document.presStatus) {
+                this.props.Document.presStatus = true;
+                this.startPresentation(index);
+            }
 
-        const doc = await list[index];
-        if (this.presStatus) {
-            this.navigateToElement(doc, fromDoc);
-            this.hideIfNotPresented(index);
-            this.showAfterPresented(index);
+            const doc = await list[index];
+            if (this.props.Document.presStatus) {
+                this.navigateToElement(doc, fromDoc);
+                this.hideIfNotPresented(index);
+                this.showAfterPresented(index);
+            }
         }
     }
     //Function that sets the store of the children docs.
     @action
     setChildrenDocs = (docList: Doc[]) => {
-        this.childrenDocs = docList;
+        this._childrenDocs = docList;
     }
 
     //The function that is called to render the play or pause button depending on
     //if presentation is running or not.
     renderPlayPauseButton = () => {
-        if (this.presStatus) {
-            return <button title="Reset Presentation" className="presentation-button" onClick={this.startOrResetPres}><FontAwesomeIcon icon="stop" /></button>;
-        } else {
-            return <button title="Start Presentation From Start" className="presentation-button" onClick={this.startOrResetPres}><FontAwesomeIcon icon="play" /></button>;
-        }
+        return <button title={"Reset Presentation" + this.props.Document.presStatus ? "" : " From Start"} className="presentation-button" onClick={this.startOrResetPres}>
+            <FontAwesomeIcon icon={this.props.Document.presStatus ? "stop" : "play"} />
+        </button>;
     }
 
     //The function that starts or resets presentaton functionally, depending on status flag.
     @action
     startOrResetPres = () => {
-        if (this.presStatus) {
+        if (this.props.Document.presStatus) {
             this.resetPresentation();
         } else {
-            this.presStatus = true;
+            this.props.Document.presStatus = true;
             this.startPresentation(0);
-            const current = NumCast(this.curPresentation.selectedDoc);
-            this.gotoDocument(0, current);
+            this.gotoDocument(0, NumCast(this.props.Document.selectedDoc));
         }
-        this.curPresentation.presStatus = this.presStatus;
     }
 
     //The function that resets the presentation by removing every action done by it. It also
     //stops the presentaton.
     @action
     resetPresentation = () => {
-        this.childrenDocs.forEach((doc: Doc) => {
+        this._childrenDocs.forEach((doc: Doc) => {
             doc.opacity = 1;
             doc.viewScale = 1;
         });
-        this.curPresentation.selectedDoc = 0;
-        this.presStatus = false;
-        this.curPresentation.presStatus = this.presStatus;
-        if (this.childrenDocs.length === 0) {
-            return;
+        this.props.Document.selectedDoc = 0;
+        this.props.Document.presStatus = false;
+        if (this._childrenDocs.length !== 0) {
+            DocumentManager.Instance.zoomIntoScale(this._childrenDocs[0], 1);
         }
-        DocumentManager.Instance.zoomIntoScale(this.childrenDocs[0], 1);
     }
 
-
     //The function that starts the presentation, also checking if actions should be applied
     //directly at start.
     startPresentation = (startIndex: number) => {
-        this.presElementsMappings.forEach((component: PresentationElement, doc: Doc) => {
+        this._presElementsMappings.forEach((component, doc) => {
             if (component.props.document.hideTillShownButton) {
-                if (this.childrenDocs.indexOf(doc) > startIndex) {
+                if (this._childrenDocs.indexOf(doc) > startIndex) {
                     doc.opacity = 0;
                 }
-
             }
             if (component.props.document.hideAfterButton) {
-                if (this.childrenDocs.indexOf(doc) < startIndex) {
+                if (this._childrenDocs.indexOf(doc) < startIndex) {
                     doc.opacity = 0;
                 }
             }
             if (component.props.document.fadeButton) {
-                if (this.childrenDocs.indexOf(doc) < startIndex) {
+                if (this._childrenDocs.indexOf(doc) < startIndex) {
                     doc.opacity = 0.5;
                 }
             }
-
         });
-
-    }
-
-
-    /**
-     * The function that is called to render either select for presentations, or title inputting.
-     */
-    renderSelectOrPresSelection = () => {
-        if (this.PresTitleInputOpen || this.PresTitleChangeOpen) {
-            return <input ref={(e) => this.titleInputElement = e!} type="text" className="presentationView-title" placeholder="Enter Name!" onKeyDown={this.submitPresentationTitle} />;
-        } else {
-            return (null);
-        }
-    }
-
-    /**
-     * The function that is called on enter press of title input. It gives the
-     * new presentation the title user entered. If nothing is entered, gives a default title.
-     */
-    @action
-    submitPresentationTitle = (e: React.KeyboardEvent) => {
-        if (e.keyCode === 13) {
-            let presTitle = this.titleInputElement!.value;
-            this.titleInputElement!.value = "";
-            if (this.PresTitleChangeOpen) {
-                this.PresTitleChangeOpen = false;
-                this.changePresentationTitle(presTitle);
-            }
-        }
-    }
-    /**
-     * The function that is called to change title of presentation to what user entered.
-     */
-    @undoBatch
-    changePresentationTitle = (newTitle: string) => {
-        if (newTitle === "") {
-            return;
-        }
-        this.curPresentation.title = newTitle;
     }
 
     addPressElem = (keyDoc: Doc, elem: PresentationElement) => {
-        this.presElementsMappings.set(keyDoc, elem);
+        this._presElementsMappings.set(keyDoc, elem);
     }
 
     minimize = undoBatch(action(() => {
-        this.presMode = true;
+        this._presMode = true;
         this.props.addDocTab && this.props.addDocTab(this.props.Document, this.props.DataDoc, "close");
     }));
 
@@ -485,12 +373,10 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
     }
 
     render() {
-
-        let width = "100%"; //NumCast(this.curPresentation.width)
         return (
-            <div className="presentationView-cont" onPointerEnter={action(() => !this.persistOpacity && (this.opacity = 1))} onContextMenu={this.specificContextMenu}
-                onPointerLeave={action(() => !this.persistOpacity && (this.opacity = 0.4))}
-                style={{ width: width, opacity: this.opacity, }}>
+            <div className="presentationView-cont" onPointerEnter={action(() => !this._persistOpacity && (this._opacity = 1))} onContextMenu={this.specificContextMenu}
+                onPointerLeave={action(() => !this._persistOpacity && (this._opacity = 0.4))}
+                style={{ width: "100%", opacity: this._opacity, }}>
                 <div className="presentation-buttons">
                     <button title="Back" className="presentation-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
                     {this.renderPlayPauseButton()}
@@ -500,28 +386,26 @@ export class PresBox extends React.Component<FieldViewProps> { //FieldViewProps?
                 <input
                     type="checkbox"
                     onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
-                        this.persistOpacity = e.target.checked;
-                        this.opacity = this.persistOpacity ? 1 : 0.4;
+                        this._persistOpacity = e.target.checked;
+                        this._opacity = this._persistOpacity ? 1 : 0.4;
                     })}
-                    checked={this.persistOpacity}
+                    checked={this._persistOpacity}
                     style={{ position: "absolute", bottom: 5, left: 5 }}
-                    onPointerEnter={action(() => this.labelOpacity = 1)}
-                    onPointerLeave={action(() => this.labelOpacity = 0)}
+                    onPointerEnter={action(() => this._labelOpacity = 1)}
+                    onPointerLeave={action(() => this._labelOpacity = 0)}
                 />
-                <p style={{ position: "absolute", bottom: 1, left: 22, opacity: this.labelOpacity, transition: "0.7s opacity ease" }}>opacity {this.persistOpacity ? "persistent" : "on focus"}</p>
+                <p style={{ position: "absolute", bottom: 1, left: 22, opacity: this._labelOpacity, transition: "0.7s opacity ease" }}>opacity {this._persistOpacity ? "persistent" : "on focus"}</p>
                 <PresentationViewList
-                    mainDocument={this.curPresentation}
+                    mainDocument={this.props.Document}
                     deleteDocument={this.RemoveDoc}
                     gotoDocument={this.gotoDocument}
-                    PresElementsMappings={this.presElementsMappings}
+                    PresElementsMappings={this._presElementsMappings}
                     setChildrenDocs={this.setChildrenDocs}
-                    presStatus={this.presStatus}
+                    presStatus={BoolCast(this.props.Document.presStatus)}
                     removeDocByRef={this.removeDocByRef}
-                    clearElemMap={() => this.presElementsMappings.clear()}
+                    clearElemMap={() => this._presElementsMappings.clear()}
                 />
             </div>
         );
     }
-
-
 }
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresentationModeMenu.tsx b/src/client/views/presentationview/PresentationModeMenu.tsx
index 0dd2b7731..e4123a1fe 100644
--- a/src/client/views/presentationview/PresentationModeMenu.tsx
+++ b/src/client/views/presentationview/PresentationModeMenu.tsx
@@ -98,8 +98,4 @@ export default class PresModeMenu extends React.Component<PresModeMenuProps> {
             </div >
         );
     }
-
-
-
-
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From d7f515f32de780884774e7bbdcc1cfe78733af45 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 30 Sep 2019 14:01:59 -0400
Subject: a bunch of changes to presentation view ... more coming.

---
 src/client/documents/DocumentTypes.ts              |   2 +-
 src/client/documents/Documents.ts                  |   5 +-
 src/client/views/MainView.tsx                      |   1 -
 src/client/views/nodes/DocumentContentsView.tsx    |  31 ++--
 src/client/views/nodes/PresBox.tsx                 | 165 ++++++++-------------
 .../views/presentationview/PresentationElement.tsx |  19 +--
 .../views/presentationview/PresentationList.tsx    |   9 --
 .../presentationview/PresentationModeMenu.scss     |  30 ----
 .../presentationview/PresentationModeMenu.tsx      | 101 -------------
 src/new_fields/Doc.ts                              |  22 ++-
 10 files changed, 105 insertions(+), 280 deletions(-)
 delete mode 100644 src/client/views/presentationview/PresentationModeMenu.scss
 delete mode 100644 src/client/views/presentationview/PresentationModeMenu.tsx

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

diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 381981e1b..8ec6e9642 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -19,5 +19,5 @@ export enum DocumentType {
     YOUTUBE = "youtube",
     DRAGBOX = "dragbox",
     PRES = "presentation",
-    LINKFOLLOW = "linkfollow",
+    LINKFOLLOW = "linkfollow"
 }
\ No newline at end of file
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index d1ec2ac39..01c36182f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -46,8 +46,6 @@ import { ComputedField } from "../../new_fields/ScriptField";
 import { ProxyField } from "../../new_fields/Proxy";
 import { DocumentType } from "./DocumentTypes";
 import { LinkFollowBox } from "../views/linking/LinkFollowBox";
-//import { PresBox } from "../views/nodes/PresBox";
-//import { PresField } from "../../new_fields/PresField";
 var requestImageSize = require('../util/request-image-size');
 var path = require('path');
 
@@ -176,7 +174,7 @@ export namespace Docs {
             }],
             [DocumentType.LINKFOLLOW, {
                 layout: { view: LinkFollowBox }
-            }]
+            }],
         ]);
 
         // All document prototypes are initialized with at least these values
@@ -459,7 +457,6 @@ export namespace Docs {
         export function LinkFollowBoxDocument(options?: DocumentOptions) {
             return InstanceFromProto(Prototypes.get(DocumentType.LINKFOLLOW), undefined, { ...(options || {}) });
         }
-
         export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id);
         }
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index dadff21a7..35d527c91 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -634,7 +634,6 @@ export class MainView extends React.Component {
                 <SharingManager />
                 <DocumentDecorations />
                 {this.mainContent}
-                {PresBox.miniPresentation}
                 <PreviewCursor />
                 <ContextMenu />
                 {this.nodesMenu()}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 3c3cc0d91..d035cbe18 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,37 +1,34 @@
-import { computed, trace } from "mobx";
+import { computed } from "mobx";
 import { observer } from "mobx-react";
+import { Doc } from "../../../new_fields/Doc";
+import { ScriptField } from "../../../new_fields/ScriptField";
+import { Cast } from "../../../new_fields/Types";
+import { OmitKeys, Without } from "../../../Utils";
+import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox";
+import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
 import { CollectionPDFView } from "../collections/CollectionPDFView";
 import { CollectionSchemaView } from "../collections/CollectionSchemaView";
 import { CollectionVideoView } from "../collections/CollectionVideoView";
 import { CollectionView } from "../collections/CollectionView";
+import { LinkFollowBox } from "../linking/LinkFollowBox";
+import { YoutubeBox } from "./../../apis/youtube/YoutubeBox";
 import { AudioBox } from "./AudioBox";
+import { ButtonBox } from "./ButtonBox";
 import { DocumentViewProps } from "./DocumentView";
 import "./DocumentView.scss";
-import { FormattedTextBox } from "./FormattedTextBox";
-import { ImageBox } from "./ImageBox";
 import { DragBox } from "./DragBox";
-import { ButtonBox } from "./ButtonBox";
-import { PresBox } from "./PresBox";
-import { LinkFollowBox } from "../linking/LinkFollowBox";
+import { FieldView, FieldViewProps } from "./FieldView";
+import { FormattedTextBox } from "./FormattedTextBox";
 import { IconBox } from "./IconBox";
+import { ImageBox } from "./ImageBox";
 import { KeyValueBox } from "./KeyValueBox";
 import { PDFBox } from "./PDFBox";
+import { PresBox } from "./PresBox";
 import { VideoBox } from "./VideoBox";
-import { FieldView } from "./FieldView";
 import { WebBox } from "./WebBox";
-import { YoutubeBox } from "./../../apis/youtube/YoutubeBox";
-import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox";
 import React = require("react");
-import { FieldViewProps } from "./FieldView";
-import { Without, OmitKeys } from "../../../Utils";
-import { Cast, StrCast, NumCast } from "../../../new_fields/Types";
-import { List } from "../../../new_fields/List";
-import { Doc } from "../../../new_fields/Doc";
-import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox";
-import { ScriptField } from "../../../new_fields/ScriptField";
-import { fromPromise } from "mobx-utils";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 type BindingProps = Without<FieldViewProps, 'fieldKey'>;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index d246da87a..e2dac4fd3 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -2,20 +2,19 @@ import React = require("react");
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faArrowLeft, faArrowRight, faEdit, faMinus, faPlay, faPlus, faStop, faTimes } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, observable, runInAction, computed } from "mobx";
+import { action, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
+import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
 import { listSpec } from "../../../new_fields/Schema";
 import { BoolCast, Cast, FieldValue, NumCast } from "../../../new_fields/Types";
+import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
+import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { ContextMenu } from "../ContextMenu";
-import PresentationElement from "../presentationview/PresentationElement";
 import PresentationViewList from "../presentationview/PresentationList";
 import "../presentationview/PresentationView.scss";
 import { FieldView, FieldViewProps } from './FieldView';
-import PresModeMenu from "../presentationview/PresentationModeMenu";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
 
 library.add(faArrowLeft);
 library.add(faArrowRight);
@@ -31,31 +30,13 @@ export class PresBox extends React.Component<FieldViewProps> {
     public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(PresBox, fieldKey); }
 
     public static Instance: PresBox;
-    //mapping from docs to their rendered component
-    @observable _presElementsMappings: Map<Doc, PresentationElement> = new Map();
     //variable that holds all the docs in the presentation
     @observable _childrenDocs: Doc[] = [];
 
-    @observable _opacity = 1;
-    @observable _persistOpacity = true;
-    @observable _labelOpacity = 0;
     // whether presentation view has been minimized
     @observable _presMode = false;
     @observable public static CurrentPresentation: PresBox;
 
-    @computed static get miniPresentation() {
-        let next = () => PresBox.CurrentPresentation.next();
-        let back = () => PresBox.CurrentPresentation.back();
-        let startOrResetPres = () => PresBox.CurrentPresentation.startOrResetPres();
-        let closePresMode = action(() => {
-            PresBox.CurrentPresentation._presMode = false;
-            CollectionDockingView.AddRightSplit(PresBox.CurrentPresentation.props.Document, undefined);
-        });
-        return !PresBox.CurrentPresentation || !PresBox.CurrentPresentation._presMode ? (null) :
-            <PresModeMenu next={next} back={back} presStatus={BoolCast(PresBox.CurrentPresentation.props.Document.presStatus)}
-                startOrResetPres={startOrResetPres} closePresMode={closePresMode} />;
-    }
-
     //initilize class variables
     constructor(props: FieldViewProps) {
         super(props);
@@ -71,7 +52,7 @@ export class PresBox extends React.Component<FieldViewProps> {
             let nextSelected = current + 1;
 
             for (; nextSelected < presDocs.length - 1; nextSelected++) {
-                if (!this._presElementsMappings.get(presDocs[nextSelected + 1])!.props.document.groupButton) {
+                if (!presDocs[nextSelected + 1].groupButton) {
                     break;
                 }
             }
@@ -89,18 +70,16 @@ export class PresBox extends React.Component<FieldViewProps> {
             let prevSelected = current;
             let zoomOut: boolean = false;
 
-            //checking if this presentation id is mapped to a group, if so chosing the first element in group
-            let presDocs = DocListCast(this.props.Document.data);
+            let presDocs = await DocListCastAsync(this.props.Document[this.props.fieldKey]);
             let currentsArray: Doc[] = [];
-            for (; prevSelected > 0 && presDocs[prevSelected].groupButton; prevSelected--) {
+            for (; presDocs && prevSelected > 0 && presDocs[prevSelected].groupButton; prevSelected--) {
                 currentsArray.push(presDocs[prevSelected]);
             }
             prevSelected = Math.max(0, prevSelected - 1);
 
             //checking if any of the group members had used zooming in
             currentsArray.forEach((doc: Doc) => {
-                //let presElem: PresentationElement | undefined = this.presElementsMappings.get(doc);
-                if (this._presElementsMappings.get(doc)!.props.document.showButton) {
+                if (doc.showButton) {
                     zoomOut = true;
                     return;
                 }
@@ -109,7 +88,7 @@ export class PresBox extends React.Component<FieldViewProps> {
             // if a group set that flag to zero or a single element
             //If so making sure to zoom out, which goes back to state before zooming action
             if (current > 0) {
-                if (zoomOut || this._presElementsMappings.get(docAtCurrent)!.showButton) {
+                if (zoomOut || docAtCurrent.showButton) {
                     let prevScale = NumCast(this._childrenDocs[prevSelected].viewScale, null);
                     let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[current]);
                     if (prevScale !== undefined && prevScale !== curScale) {
@@ -127,20 +106,20 @@ export class PresBox extends React.Component<FieldViewProps> {
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
     showAfterPresented = (index: number) => {
-        this._presElementsMappings.forEach((presElem, doc) => {
+        this._childrenDocs.forEach((doc, ind) => {
             //the order of cases is aligned based on priority
-            if (presElem.props.document.hideTillShownButton) {
-                if (this._childrenDocs.indexOf(doc) <= index) {
+            if (doc.hideTillShownButton) {
+                if (ind <= index) {
                     doc.opacity = 1;
                 }
             }
-            if (presElem.props.document.hideAfterButton) {
-                if (this._childrenDocs.indexOf(doc) < index) {
+            if (doc.hideAfterButton) {
+                if (ind < index) {
                     doc.opacity = 0;
                 }
             }
-            if (presElem.props.document.fadeButton) {
-                if (this._childrenDocs.indexOf(doc) < index) {
+            if (doc.fadeButton) {
+                if (ind < index) {
                     doc.opacity = 0.5;
                 }
             }
@@ -153,21 +132,21 @@ export class PresBox extends React.Component<FieldViewProps> {
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
     hideIfNotPresented = (index: number) => {
-        this._presElementsMappings.forEach((presElem, key) => {
+        this._childrenDocs.forEach((key, ind) => {
             //the order of cases is aligned based on priority
 
-            if (presElem.props.document.hideAfterButton) {
-                if (this._childrenDocs.indexOf(key) >= index) {
+            if (key.hideAfterButton) {
+                if (ind >= index) {
                     key.opacity = 1;
                 }
             }
-            if (presElem.props.document.fadeButton) {
-                if (this._childrenDocs.indexOf(key) >= index) {
+            if (key.fadeButton) {
+                if (ind >= index) {
                     key.opacity = 1;
                 }
             }
-            if (presElem.props.document.hideTillShownButton) {
-                if (this._childrenDocs.indexOf(key) > index) {
+            if (key.hideTillShownButton) {
+                if (ind > index) {
                     key.opacity = 0;
                 }
             }
@@ -187,18 +166,18 @@ export class PresBox extends React.Component<FieldViewProps> {
         let nextSelected = presDocs.indexOf(curDoc);
         let currentDocGroups: Doc[] = [];
         for (; nextSelected < presDocs.length - 1; nextSelected++) {
-            if (!this._presElementsMappings.get(presDocs[nextSelected + 1])!.props.document.groupButton) {
+            if (!presDocs[nextSelected + 1].groupButton) {
                 break;
             }
             currentDocGroups.push(presDocs[nextSelected]);
         }
 
         currentDocGroups.forEach((doc: Doc, index: number) => {
-            if (this._presElementsMappings.get(doc)!.navButton) {
+            if (doc.navButton) {
                 docToJump = doc;
                 willZoom = false;
             }
-            if (this._presElementsMappings.get(doc)!.showButton) {
+            if (doc.showButton) {
                 docToJump = doc;
                 willZoom = true;
             }
@@ -207,9 +186,9 @@ export class PresBox extends React.Component<FieldViewProps> {
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
         if (docToJump === curDoc) {
             //checking if curDoc has navigation open
-            if (this._presElementsMappings.get(curDoc)!.navButton) {
+            if (curDoc.navButton) {
                 DocumentManager.Instance.jumpToDocument(curDoc, false);
-            } else if (this._presElementsMappings.get(curDoc)!.showButton) {
+            } else if (curDoc.showButton) {
                 let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[fromDoc]);
                 //awaiting jump so that new scale can be found, since jumping is async
                 await DocumentManager.Instance.jumpToDocument(curDoc, true);
@@ -250,15 +229,13 @@ export class PresBox extends React.Component<FieldViewProps> {
     }
 
     /**
-     * The function that removes a doc from a presentation. It also makes sure to
-     * do necessary updates to backUps and mappings stored locally.
+     * The function that removes a doc from a presentation. 
      */
     @action
     public RemoveDoc = async (index: number) => {
         const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc))); // don't replace with DocListCast -- we need to modify the document's actual stored list
         if (value) {
-            //removing the Presentation Element from the document and update mappings
-            this._presElementsMappings.delete(await value.splice(index, 1)[0]);
+            value.splice(index, 1);
         }
     }
 
@@ -302,14 +279,6 @@ export class PresBox extends React.Component<FieldViewProps> {
         this._childrenDocs = docList;
     }
 
-    //The function that is called to render the play or pause button depending on
-    //if presentation is running or not.
-    renderPlayPauseButton = () => {
-        return <button title={"Reset Presentation" + this.props.Document.presStatus ? "" : " From Start"} className="presentation-button" onClick={this.startOrResetPres}>
-            <FontAwesomeIcon icon={this.props.Document.presStatus ? "stop" : "play"} />
-        </button>;
-    }
-
     //The function that starts or resets presentaton functionally, depending on status flag.
     @action
     startOrResetPres = () => {
@@ -340,18 +309,18 @@ export class PresBox extends React.Component<FieldViewProps> {
     //The function that starts the presentation, also checking if actions should be applied
     //directly at start.
     startPresentation = (startIndex: number) => {
-        this._presElementsMappings.forEach((component, doc) => {
-            if (component.props.document.hideTillShownButton) {
+        this._childrenDocs.map(doc => {
+            if (doc.hideTillShownButton) {
                 if (this._childrenDocs.indexOf(doc) > startIndex) {
                     doc.opacity = 0;
                 }
             }
-            if (component.props.document.hideAfterButton) {
+            if (doc.hideAfterButton) {
                 if (this._childrenDocs.indexOf(doc) < startIndex) {
                     doc.opacity = 0;
                 }
             }
-            if (component.props.document.fadeButton) {
+            if (doc.fadeButton) {
                 if (this._childrenDocs.indexOf(doc) < startIndex) {
                     doc.opacity = 0.5;
                 }
@@ -359,13 +328,18 @@ export class PresBox extends React.Component<FieldViewProps> {
         });
     }
 
-    addPressElem = (keyDoc: Doc, elem: PresentationElement) => {
-        this._presElementsMappings.set(keyDoc, elem);
-    }
-
-    minimize = undoBatch(action(() => {
-        this._presMode = true;
-        this.props.addDocTab && this.props.addDocTab(this.props.Document, this.props.DataDoc, "close");
+    toggleMinimize = undoBatch(action((e: React.PointerEvent) => {
+        if (this.props.Document.minimizedView) {
+            this.props.Document.minimizedView = false;
+            Doc.RemoveDocFromList((CurrentUserUtils.UserDocument.overlays as Doc), "data", this.props.Document);
+            CollectionDockingView.AddRightSplit(this.props.Document, this.props.DataDoc);
+        } else {
+            this.props.Document.minimizedView = true;
+            this.props.Document.x = e.clientX + 25;
+            this.props.Document.y = e.clientY - 25;
+            this.props.addDocTab && this.props.addDocTab(this.props.Document, this.props.DataDoc, "close");
+            Doc.AddDocToList((CurrentUserUtils.UserDocument.overlays as Doc), "data", this.props.Document);
+        }
     }));
 
     specificContextMenu = (e: React.MouseEvent): void => {
@@ -374,37 +348,24 @@ export class PresBox extends React.Component<FieldViewProps> {
 
     render() {
         return (
-            <div className="presentationView-cont" onPointerEnter={action(() => !this._persistOpacity && (this._opacity = 1))} onContextMenu={this.specificContextMenu}
-                onPointerLeave={action(() => !this._persistOpacity && (this._opacity = 0.4))}
-                style={{ width: "100%", opacity: this._opacity, }}>
-                <div className="presentation-buttons">
-                    <button title="Back" className="presentation-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
-                    {this.renderPlayPauseButton()}
-                    <button title="Next" className="presentation-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
-                    <button title="Minimize" className="presentation-button" onClick={this.minimize}><FontAwesomeIcon icon={"eye"} /></button>
+            <div className="presentationView-cont" onContextMenu={this.specificContextMenu} style={{ width: "100%", minWidth: "200px", height: "100%", minHeight: "50px" }}>
+                <div className="presentation-buttons" style={{ width: "100%" }}>
+                    <button className="presentation-button" title="Back" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
+                    <button className="presentation-button" title={"Reset Presentation" + this.props.Document.presStatus ? "" : " From Start"} onClick={this.startOrResetPres}>
+                        <FontAwesomeIcon icon={this.props.Document.presStatus ? "stop" : "play"} />
+                    </button>
+                    <button className="presentation-button" title="Next" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
+                    <button className="presentation-button" title={this.props.Document.minimizedView ? "Expand" : "Minimize"} onClick={this.toggleMinimize}><FontAwesomeIcon icon={"eye"} /></button>
                 </div>
-                <input
-                    type="checkbox"
-                    onChange={action((e: React.ChangeEvent<HTMLInputElement>) => {
-                        this._persistOpacity = e.target.checked;
-                        this._opacity = this._persistOpacity ? 1 : 0.4;
-                    })}
-                    checked={this._persistOpacity}
-                    style={{ position: "absolute", bottom: 5, left: 5 }}
-                    onPointerEnter={action(() => this._labelOpacity = 1)}
-                    onPointerLeave={action(() => this._labelOpacity = 0)}
-                />
-                <p style={{ position: "absolute", bottom: 1, left: 22, opacity: this._labelOpacity, transition: "0.7s opacity ease" }}>opacity {this._persistOpacity ? "persistent" : "on focus"}</p>
-                <PresentationViewList
-                    mainDocument={this.props.Document}
-                    deleteDocument={this.RemoveDoc}
-                    gotoDocument={this.gotoDocument}
-                    PresElementsMappings={this._presElementsMappings}
-                    setChildrenDocs={this.setChildrenDocs}
-                    presStatus={BoolCast(this.props.Document.presStatus)}
-                    removeDocByRef={this.removeDocByRef}
-                    clearElemMap={() => this._presElementsMappings.clear()}
-                />
+                {this.props.Document.minimizedView ? (null) :
+                    <PresentationViewList
+                        mainDocument={this.props.Document}
+                        deleteDocument={this.RemoveDoc}
+                        gotoDocument={this.gotoDocument}
+                        setChildrenDocs={this.setChildrenDocs}
+                        presStatus={BoolCast(this.props.Document.presStatus)}
+                        removeDocByRef={this.removeDocByRef}
+                    />}
             </div>
         );
     }
diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx
index 126d62c52..6e8c28d34 100644
--- a/src/client/views/presentationview/PresentationElement.tsx
+++ b/src/client/views/presentationview/PresentationElement.tsx
@@ -1,6 +1,6 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faFile as fileRegular } from '@fortawesome/free-regular-svg-icons';
-import { faArrowRight, faArrowUp, faFile as fileSolid, faFileDownload, faLocationArrow, faSearch } from '@fortawesome/free-solid-svg-icons';
+import { faArrowDown, faArrowUp, faFile as fileSolid, faFileDownload, faLocationArrow, faSearch } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed } from "mobx";
 import { observer } from "mobx-react";
@@ -22,7 +22,7 @@ library.add(fileSolid);
 library.add(faLocationArrow);
 library.add(fileRegular as any);
 library.add(faSearch);
-library.add(faArrowRight);
+library.add(faArrowDown);
 
 interface PresentationElementProps {
     mainDocument: Doc;
@@ -33,7 +33,6 @@ interface PresentationElementProps {
     allListElements: Doc[];
     presStatus: boolean;
     removeDocByRef(doc: Doc): boolean;
-    PresElementsMappings: Map<Doc, PresentationElement>;
 }
 
 /**
@@ -59,14 +58,14 @@ export default class PresentationElement extends React.Component<PresentationEle
     @computed get fadeButton() { return BoolCast(this.props.document.fadeButton); }
     @computed get hideAfterButton() { return BoolCast(this.props.document.hideAfterButton); }
     @computed get groupButton() { return BoolCast(this.props.document.groupButton); }
-    @computed get openRightButton() { return BoolCast(this.props.document.openRightButton); }
+    @computed get expandInlineButton() { return BoolCast(this.props.document.expandInlineButton); }
     set showButton(val: boolean) { this.props.document.showButton = val; }
     set navButton(val: boolean) { this.props.document.navButton = val; }
     set hideTillShownButton(val: boolean) { this.props.document.hideTillShownButton = val; }
     set fadeButton(val: boolean) { this.props.document.fadeButton = val; }
     set hideAfterButton(val: boolean) { this.props.document.hideAfterButton = val; }
     set groupButton(val: boolean) { this.props.document.groupButton = val; }
-    set openRightButton(val: boolean) { this.props.document.openRightButton = val; }
+    set expandInlineButton(val: boolean) { this.props.document.expandInlineButton = val; }
 
     //Lifecycle function that makes sure that button BackUp is received when mounted.
     async componentDidMount() {
@@ -190,14 +189,12 @@ export default class PresentationElement extends React.Component<PresentationEle
     }
 
     /**
-     * Function that opens up the option to open a element on right when navigated,
-     * instead of openening it as tab as default.
+     * Function that expands the target inline
      */
     @action
-    onRightTabClick = (e: React.MouseEvent) => {
+    onExpandTabClick = (e: React.MouseEvent) => {
         e.stopPropagation();
-
-        this.openRightButton = !this.openRightButton;
+        this.embedInline = !this.embedInline
     }
 
     /**
@@ -416,7 +413,7 @@ export default class PresentationElement extends React.Component<PresentationEle
                 <button title="Fade Document After Presented" className={this.fadeButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
                 <button title="Hide Document After Presented" className={this.hideAfterButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
                 <button title="Group With Up" className={this.groupButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onGroupClick}> <FontAwesomeIcon icon={"arrow-up"} /> </button>
-                <button title="Open Right" className={this.openRightButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onRightTabClick}><FontAwesomeIcon icon={"arrow-right"} /></button>
+                <button title="Expand Inline" className={this.expandInlineButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onExpandTabClick}><FontAwesomeIcon icon={"arrow-down"} /></button>
 
                 <br />
                 {this.renderEmbeddedInline()}
diff --git a/src/client/views/presentationview/PresentationList.tsx b/src/client/views/presentationview/PresentationList.tsx
index da48a856a..483461e5a 100644
--- a/src/client/views/presentationview/PresentationList.tsx
+++ b/src/client/views/presentationview/PresentationList.tsx
@@ -12,11 +12,9 @@ interface PresListProps {
     mainDocument: Doc;
     deleteDocument(index: number): void;
     gotoDocument(index: number, fromDoc: number): Promise<void>;
-    PresElementsMappings: Map<Doc, PresentationElement>;
     setChildrenDocs: (docList: Doc[]) => void;
     presStatus: boolean;
     removeDocByRef(doc: Doc): boolean;
-    clearElemMap(): void;
 }
 
 
@@ -45,16 +43,10 @@ export default class PresentationViewList extends React.Component<PresListProps>
         const children = DocListCast(this.props.mainDocument.data);
         this.initializeScaleViews(children);
         this.props.setChildrenDocs(children);
-        this.props.clearElemMap();
         return (
             <div className="presentationView-listCont" >
                 {children.map((doc: Doc, index: number) =>
                     <PresentationElement
-                        ref={(e) => {
-                            if (e && e !== null) {
-                                this.props.PresElementsMappings.set(doc, e);
-                            }
-                        }}
                         key={doc[Id]}
                         mainDocument={this.props.mainDocument}
                         document={doc}
@@ -64,7 +56,6 @@ export default class PresentationViewList extends React.Component<PresListProps>
                         allListElements={children}
                         presStatus={this.props.presStatus}
                         removeDocByRef={this.props.removeDocByRef}
-                        PresElementsMappings={this.props.PresElementsMappings}
                     />
                 )}
             </div>
diff --git a/src/client/views/presentationview/PresentationModeMenu.scss b/src/client/views/presentationview/PresentationModeMenu.scss
deleted file mode 100644
index 336f43d20..000000000
--- a/src/client/views/presentationview/PresentationModeMenu.scss
+++ /dev/null
@@ -1,30 +0,0 @@
-.presMenu-cont {
-    position: fixed;
-    z-index: 10000;
-    height: 35px;
-    background: #323232;
-    box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
-    border-radius: 0px 6px 6px 6px;
-    overflow: hidden;
-    display: flex;
-
-    .presMenu-button {
-        background-color: transparent;
-        width: 35px;
-        height: 35px;
-    }
-
-    .presMenu-button:hover {
-        background-color: #121212;
-    }
-
-    .presMenu-dragger {
-        height: 100%;
-        transition: width .2s;
-        background-image: url("https://logodix.com/logo/1020374.png");
-        background-size: 90% 100%;
-        background-repeat: no-repeat;
-        background-position: left center;
-    }
-
-}
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresentationModeMenu.tsx b/src/client/views/presentationview/PresentationModeMenu.tsx
deleted file mode 100644
index e4123a1fe..000000000
--- a/src/client/views/presentationview/PresentationModeMenu.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-import React = require("react");
-import { observable, action, runInAction } from "mobx";
-import "./PresentationModeMenu.scss";
-import { observer } from "mobx-react";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-
-
-export interface PresModeMenuProps {
-    next: () => void;
-    back: () => void;
-    presStatus: boolean;
-    startOrResetPres: () => void;
-    closePresMode: () => void;
-}
-
-/**
- * This class is responsible for modeling of the Presentation Mode Menu. The menu allows
- * user to navigate through presentation elements, and start/stop the presentation.
- */
-@observer
-export default class PresModeMenu extends React.Component<PresModeMenuProps> {
-
-    @observable private _top: number = 20;
-    @observable private _left: number = window.innerWidth - 160;
-    @observable private _opacity: number = 1;
-    @observable private _transition: string = "opacity 0.5s";
-    @observable private _transitionDelay: string = "";
-    private _offsetY: number = 0;
-    private _offsetX: number = 0;
-
-
-    private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
-
-    /**
-     * The function that changes the coordinates of the menu, depending on the
-     * movement of the mouse when it's being dragged.
-     */
-    @action
-    dragging = (e: PointerEvent) => {
-        this._left = e.pageX - this._offsetX;
-        this._top = e.pageY - this._offsetY;
-
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    /**
-     * The function that removes the event listeners that are responsible for
-     * dragging of the menu.
-     */
-    dragEnd = (e: PointerEvent) => {
-        document.removeEventListener("pointermove", this.dragging);
-        document.removeEventListener("pointerup", this.dragEnd);
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    /**
-     * The function that starts the dragging of the presentation mode menu. When
-     * the lines on further right are clicked on.
-     */
-    dragStart = (e: React.PointerEvent) => {
-        document.removeEventListener("pointermove", this.dragging);
-        document.addEventListener("pointermove", this.dragging);
-        document.removeEventListener("pointerup", this.dragEnd);
-        document.addEventListener("pointerup", this.dragEnd);
-
-        this._offsetX = this._mainCont.current!.getBoundingClientRect().width - e.nativeEvent.offsetX;
-        this._offsetY = e.nativeEvent.offsetY;
-
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    /**
-     * The function that is responsible for rendering the play or pause button, depending on the
-     * status of the presentation.
-     */
-    renderPlayPauseButton = () => {
-        if (this.props.presStatus) {
-            return <button title="Reset Presentation" className="presMenu-button" onClick={this.props.startOrResetPres}><FontAwesomeIcon icon="stop" /></button>;
-        } else {
-            return <button title="Start Presentation From Start" className="presMenu-button" onClick={this.props.startOrResetPres}><FontAwesomeIcon icon="play" /></button>;
-        }
-    }
-
-    render() {
-        return (
-            <div className="presMenu-cont" ref={this._mainCont}
-                style={{ left: this._left, top: this._top, opacity: this._opacity, transition: this._transition, transitionDelay: this._transitionDelay }}>
-                <button title="Back" className="presMenu-button" onClick={this.props.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
-                {this.renderPlayPauseButton()}
-                <button title="Next" className="presMenu-button" onClick={this.props.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
-                <button className="presMenu-button" title="Close Presentation Menu" onClick={this.props.closePresMode}>
-                    <FontAwesomeIcon icon="times" size="lg" />
-                </button>
-                <div className="presMenu-dragger" onPointerDown={this.dragStart} style={{ width: "20px" }} />
-            </div >
-        );
-    }
-}
\ No newline at end of file
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 79b73aba8..4a03fed08 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -337,11 +337,25 @@ export namespace Doc {
     export function IndexOf(toFind: Doc, list: Doc[]) {
         return list.findIndex(doc => doc === toFind || Doc.AreProtosEqual(doc, toFind));
     }
-    export function AddDocToList(target: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean) {
-        if (target[key] === undefined) {
-            Doc.GetProto(target)[key] = new List<Doc>();
+    export function RemoveDocFromList(listDoc: Doc, key: string, doc: Doc) {
+        if (listDoc[key] === undefined) {
+            Doc.GetProto(listDoc)[key] = new List<Doc>();
         }
-        let list = Cast(target[key], listSpec(Doc));
+        let list = Cast(listDoc[key], listSpec(Doc));
+        if (list) {
+            let ind = list.indexOf(doc);
+            if (ind !== -1) {
+                list.splice(ind, 1);
+                return true;
+            }
+        }
+        return false;
+    }
+    export function AddDocToList(listDoc: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean, reversed?: boolean) {
+        if (listDoc[key] === undefined) {
+            Doc.GetProto(listDoc)[key] = new List<Doc>();
+        }
+        let list = Cast(listDoc[key], listSpec(Doc));
         if (list) {
             if (allowDuplicates !== true) {
                 let pind = list.reduce((l, d, i) => d instanceof Doc && d[Id] === doc[Id] ? i : l, -1);
-- 
cgit v1.2.3-70-g09d2


From 65d9b92bcadbecb6e7dd55930f96f228c6a2f4f7 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 30 Sep 2019 17:12:28 -0400
Subject: simpliified presentations to be a PresBox with PresElementBoxes.

---
 src/client/documents/DocumentTypes.ts              |   3 +-
 src/client/documents/Documents.ts                  |  10 +-
 .../views/collections/CollectionDockingView.tsx    |   9 +-
 src/client/views/linking/LinkMenuItem.tsx          |   2 +-
 src/client/views/nodes/DocumentContentsView.tsx    |   3 +-
 src/client/views/nodes/PresBox.scss                |  33 ++
 src/client/views/nodes/PresBox.tsx                 | 189 +++++----
 .../views/presentationview/PresElementBox.scss     |  75 ++++
 .../views/presentationview/PresElementBox.tsx      | 329 ++++++++++++++++
 .../views/presentationview/PresentationElement.tsx | 423 ---------------------
 .../views/presentationview/PresentationList.tsx    |  64 ----
 .../views/presentationview/PresentationView.scss   | 113 ------
 12 files changed, 545 insertions(+), 708 deletions(-)
 create mode 100644 src/client/views/nodes/PresBox.scss
 create mode 100644 src/client/views/presentationview/PresElementBox.scss
 create mode 100644 src/client/views/presentationview/PresElementBox.tsx
 delete mode 100644 src/client/views/presentationview/PresentationElement.tsx
 delete mode 100644 src/client/views/presentationview/PresentationList.tsx
 delete mode 100644 src/client/views/presentationview/PresentationView.scss

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

diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 8ec6e9642..e5d5885cd 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -19,5 +19,6 @@ export enum DocumentType {
     YOUTUBE = "youtube",
     DRAGBOX = "dragbox",
     PRES = "presentation",
-    LINKFOLLOW = "linkfollow"
+    LINKFOLLOW = "linkfollow",
+    PRESELEMENT = "preselement"
 }
\ No newline at end of file
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 01c36182f..0d04d044e 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,7 +1,6 @@
 import { HistogramField } from "../northstar/dash-fields/HistogramField";
 import { HistogramBox } from "../northstar/dash-nodes/HistogramBox";
 import { HistogramOperation } from "../northstar/operations/HistogramOperation";
-import { CollectionPDFView } from "../views/collections/CollectionPDFView";
 import { CollectionVideoView } from "../views/collections/CollectionVideoView";
 import { CollectionView } from "../views/collections/CollectionView";
 import { CollectionViewType } from "../views/collections/CollectionBaseView";
@@ -46,6 +45,7 @@ import { ComputedField } from "../../new_fields/ScriptField";
 import { ProxyField } from "../../new_fields/Proxy";
 import { DocumentType } from "./DocumentTypes";
 import { LinkFollowBox } from "../views/linking/LinkFollowBox";
+import { PresElementBox } from "../views/presentationview/PresElementBox";
 var requestImageSize = require('../util/request-image-size');
 var path = require('path');
 
@@ -175,6 +175,9 @@ export namespace Docs {
             [DocumentType.LINKFOLLOW, {
                 layout: { view: LinkFollowBox }
             }],
+            [DocumentType.PRESELEMENT, {
+                layout: { view: PresElementBox }
+            }],
         ]);
 
         // All document prototypes are initialized with at least these values
@@ -457,6 +460,11 @@ export namespace Docs {
         export function LinkFollowBoxDocument(options?: DocumentOptions) {
             return InstanceFromProto(Prototypes.get(DocumentType.LINKFOLLOW), undefined, { ...(options || {}) });
         }
+
+        export function PresElementBoxDocument(options?: DocumentOptions) {
+            return InstanceFromProto(Prototypes.get(DocumentType.PRESELEMENT), undefined, { ...(options || {}) });
+        }
+
         export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id);
         }
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 963851a12..d83530d4f 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -31,6 +31,8 @@ import { SubCollectionViewProps } from "./CollectionSubView";
 import React = require("react");
 import { ButtonSelector } from './ParentDocumentSelector';
 import { DocumentType } from '../../documents/DocumentTypes';
+import { compileFunction } from 'vm';
+import { ComputedField } from '../../../new_fields/ScriptField';
 library.add(faFile);
 const _global = (window /* browser */ || global /* node */) as any;
 
@@ -571,11 +573,14 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         //add this new doc to props.Document
         let curPres = Cast(CurrentUserUtils.UserDocument.curPresentation, Doc) as Doc;
         if (curPres) {
+            let pinDoc = Docs.Create.PresElementBoxDocument();
+            Doc.GetProto(pinDoc).target = doc;
+            Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
             const data = Cast(curPres.data, listSpec(Doc));
             if (data) {
-                data.push(doc);
+                data.push(pinDoc);
             } else {
-                curPres.data = new List([doc]);
+                curPres.data = new List([pinDoc]);
             }
             if (!DocumentManager.Instance.getDocumentView(curPres)) {
                 this.addDocTab(curPres, undefined, "onRight");
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index e5a4a68bf..a6ee9c2c6 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -95,7 +95,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
     @action.bound
     async followDefault() {
         if (LinkFollowBox.Instance !== undefined) {
-            LinkFollowBox.setAddDocTab(this.props.addDocTab);;
+            LinkFollowBox.setAddDocTab(this.props.addDocTab);
             LinkFollowBox.Instance.setLinkDocs(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc);
             LinkFollowBox.Instance.defaultLinkBehavior();
         }
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index d035cbe18..75dd27f46 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -26,6 +26,7 @@ import { ImageBox } from "./ImageBox";
 import { KeyValueBox } from "./KeyValueBox";
 import { PDFBox } from "./PDFBox";
 import { PresBox } from "./PresBox";
+import { PresElementBox } from "../presentationview/PresElementBox";
 import { VideoBox } from "./VideoBox";
 import { WebBox } from "./WebBox";
 import React = require("react");
@@ -100,7 +101,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
         if (!this.layout && this.props.layoutKey !== "overlayLayout") return (null);
         return <ObserverJsxParser
             blacklistedAttrs={[]}
-            components={{ FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, DragBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox, LinkFollowBox }}
+            components={{ FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, DragBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox, LinkFollowBox, PresElementBox }}
             bindings={this.CreateBindings()}
             jsx={this.finalLayout}
             showWarnings={true}
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
new file mode 100644
index 000000000..2aadd77aa
--- /dev/null
+++ b/src/client/views/nodes/PresBox.scss
@@ -0,0 +1,33 @@
+.presBox-cont {
+    position: absolute;
+    z-index: 2;
+    box-shadow: #AAAAAA .2vw .2vw .4vw;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    width: 100%;
+    min-width: 200px;
+    height: 100%;
+    min-height: 50px;
+    letter-spacing: 2px;
+    overflow: hidden;
+    transition: 0.7s opacity ease;
+    pointer-events: all;
+
+    .presBox-listCont {
+        padding-left: 10px;
+        padding-right: 10px;
+    }
+
+    .presBox-buttons {
+        padding: 10px;
+        width: 100%;
+        .presBox-button {
+            margin-right: 2.5%;
+            margin-left: 2.5%;
+            width: 20%;
+            border-radius: 5px;
+        }
+    }
+}
+
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index e2dac4fd3..526416e57 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -2,19 +2,20 @@ import React = require("react");
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faArrowLeft, faArrowRight, faEdit, faMinus, faPlay, faPlus, faStop, faTimes } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, observable, runInAction } from "mobx";
+import { action, observable, runInAction, computed } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
 import { listSpec } from "../../../new_fields/Schema";
-import { BoolCast, Cast, FieldValue, NumCast } from "../../../new_fields/Types";
+import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
 import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { ContextMenu } from "../ContextMenu";
-import PresentationViewList from "../presentationview/PresentationList";
-import "../presentationview/PresentationView.scss";
+import "./PresBox.scss";
 import { FieldView, FieldViewProps } from './FieldView';
+import { PresElementBox } from "../presentationview/PresElementBox";
+import { Id } from "../../../new_fields/FieldSymbols";
 
 library.add(faArrowLeft);
 library.add(faArrowRight);
@@ -29,19 +30,7 @@ library.add(faEdit);
 export class PresBox extends React.Component<FieldViewProps> {
     public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(PresBox, fieldKey); }
 
-    public static Instance: PresBox;
-    //variable that holds all the docs in the presentation
-    @observable _childrenDocs: Doc[] = [];
-
-    // whether presentation view has been minimized
-    @observable _presMode = false;
-    @observable public static CurrentPresentation: PresBox;
-
-    //initilize class variables
-    constructor(props: FieldViewProps) {
-        super(props);
-        runInAction(() => PresBox.CurrentPresentation = this);
-    }
+    @computed get childDocs() { return DocListCast(this.props.Document[this.props.fieldKey]); }
 
     next = async () => {
         const current = NumCast(this.props.Document.selectedDoc);
@@ -89,8 +78,8 @@ export class PresBox extends React.Component<FieldViewProps> {
             //If so making sure to zoom out, which goes back to state before zooming action
             if (current > 0) {
                 if (zoomOut || docAtCurrent.showButton) {
-                    let prevScale = NumCast(this._childrenDocs[prevSelected].viewScale, null);
-                    let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[current]);
+                    let prevScale = NumCast(this.childDocs[prevSelected].viewScale, null);
+                    let curScale = DocumentManager.Instance.getScaleOfDocView(this.childDocs[current]);
                     if (prevScale !== undefined && prevScale !== curScale) {
                         DocumentManager.Instance.zoomIntoScale(docAtCurrent, prevScale);
                     }
@@ -106,22 +95,16 @@ export class PresBox extends React.Component<FieldViewProps> {
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
     showAfterPresented = (index: number) => {
-        this._childrenDocs.forEach((doc, ind) => {
+        this.childDocs.forEach((doc, ind) => {
             //the order of cases is aligned based on priority
-            if (doc.hideTillShownButton) {
-                if (ind <= index) {
-                    doc.opacity = 1;
-                }
+            if (doc.hideTillShownButton && ind <= index) {
+                (doc.target as Doc).opacity = 1;
             }
-            if (doc.hideAfterButton) {
-                if (ind < index) {
-                    doc.opacity = 0;
-                }
+            if (doc.hideAfterButton && ind < index) {
+                (doc.target as Doc).opacity = 0;
             }
-            if (doc.fadeButton) {
-                if (ind < index) {
-                    doc.opacity = 0.5;
-                }
+            if (doc.fadeButton && ind < index) {
+                (doc.target as Doc).opacity = 0.5;
             }
         });
     }
@@ -132,23 +115,17 @@ export class PresBox extends React.Component<FieldViewProps> {
      * Hide Until Presented, Hide After Presented, Fade After Presented
      */
     hideIfNotPresented = (index: number) => {
-        this._childrenDocs.forEach((key, ind) => {
+        this.childDocs.forEach((key, ind) => {
             //the order of cases is aligned based on priority
 
-            if (key.hideAfterButton) {
-                if (ind >= index) {
-                    key.opacity = 1;
-                }
+            if (key.hideAfterButton && ind >= index) {
+                (key.target as Doc).opacity = 1;
             }
-            if (key.fadeButton) {
-                if (ind >= index) {
-                    key.opacity = 1;
-                }
+            if (key.fadeButton && ind >= index) {
+                (key.target as Doc).opacity = 1;
             }
-            if (key.hideTillShownButton) {
-                if (ind > index) {
-                    key.opacity = 0;
-                }
+            if (key.hideTillShownButton && ind > index) {
+                (key.target as Doc).opacity = 0;
             }
         });
     }
@@ -158,11 +135,12 @@ export class PresBox extends React.Component<FieldViewProps> {
      * has the option open and last in the group. If not in the group, and it has
      * te option open, navigates to that element.
      */
-    navigateToElement = async (curDoc: Doc, fromDoc: number) => {
+    navigateToElement = async (curDoc: Doc, fromDocIndex: number) => {
+        let fromDoc = this.childDocs[fromDocIndex].target as Doc;
         let docToJump = curDoc;
         let willZoom = false;
 
-        let presDocs = DocListCast(this.props.Document.data);
+        let presDocs = DocListCast(this.props.Document[this.props.fieldKey]);
         let nextSelected = presDocs.indexOf(curDoc);
         let currentDocGroups: Doc[] = [];
         for (; nextSelected < presDocs.length - 1; nextSelected++) {
@@ -186,31 +164,32 @@ export class PresBox extends React.Component<FieldViewProps> {
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
         if (docToJump === curDoc) {
             //checking if curDoc has navigation open
+            let target = await curDoc.target as Doc;
             if (curDoc.navButton) {
-                DocumentManager.Instance.jumpToDocument(curDoc, false);
+                DocumentManager.Instance.jumpToDocument(target, false);
             } else if (curDoc.showButton) {
-                let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[fromDoc]);
+                let curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
                 //awaiting jump so that new scale can be found, since jumping is async
-                await DocumentManager.Instance.jumpToDocument(curDoc, true);
-                curDoc.viewScale = DocumentManager.Instance.getScaleOfDocView(curDoc);
+                await DocumentManager.Instance.jumpToDocument(target, true);
+                curDoc.viewScale = DocumentManager.Instance.getScaleOfDocView(target);
 
                 //saving the scale user was on before zooming in
                 if (curScale !== 1) {
-                    this._childrenDocs[fromDoc].viewScale = curScale;
+                    fromDoc.viewScale = curScale;
                 }
 
             }
             return;
         }
-        let curScale = DocumentManager.Instance.getScaleOfDocView(this._childrenDocs[fromDoc]);
+        let curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
 
         //awaiting jump so that new scale can be found, since jumping is async
-        await DocumentManager.Instance.jumpToDocument(docToJump, willZoom);
-        let newScale = DocumentManager.Instance.getScaleOfDocView(curDoc);
+        await DocumentManager.Instance.jumpToDocument(await docToJump.target as Doc, willZoom);
+        let newScale = DocumentManager.Instance.getScaleOfDocView(await curDoc.target as Doc);
         curDoc.viewScale = newScale;
         //saving the scale that user was on
         if (curScale !== 1) {
-            this._childrenDocs[fromDoc].viewScale = curScale;
+            fromDoc.viewScale = curScale;
         }
 
     }
@@ -219,34 +198,25 @@ export class PresBox extends React.Component<FieldViewProps> {
      * Async function that supposedly return the doc that is located at given index.
      */
     getDocAtIndex = async (index: number) => {
-        const list = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+        const list = FieldValue(Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)));
         if (list && index >= 0 && index < list.length) {
             this.props.Document.selectedDoc = index;
             //awaiting async call to finish to get Doc instance
-            return await list[index];
+            return list[index];
         }
-        return undefined
+        return undefined;
     }
 
-    /**
-     * The function that removes a doc from a presentation. 
-     */
-    @action
-    public RemoveDoc = async (index: number) => {
-        const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc))); // don't replace with DocListCast -- we need to modify the document's actual stored list
-        if (value) {
-            value.splice(index, 1);
-        }
-    }
 
-    public removeDocByRef = (doc: Doc) => {
-        let indexOfDoc = this._childrenDocs.indexOf(doc);
+    @undoBatch
+    public removeDocument = (doc: Doc) => {
         const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
         if (value) {
-            value.splice(indexOfDoc, 1)[0];
-        }
-        if (indexOfDoc !== - 1) {
-            return true;
+            let indexOfDoc = value.indexOf(doc);
+            if (indexOfDoc !== - 1) {
+                value.splice(indexOfDoc, 1)[0];
+                return true;
+            }
         }
         return false;
     }
@@ -256,7 +226,7 @@ export class PresBox extends React.Component<FieldViewProps> {
     @action
     public gotoDocument = async (index: number, fromDoc: number) => {
         Doc.UnBrushAllDocs();
-        const list = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+        const list = FieldValue(Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)));
         if (list && index >= 0 && index < list.length) {
             this.props.Document.selectedDoc = index;
 
@@ -273,11 +243,6 @@ export class PresBox extends React.Component<FieldViewProps> {
             }
         }
     }
-    //Function that sets the store of the children docs.
-    @action
-    setChildrenDocs = (docList: Doc[]) => {
-        this._childrenDocs = docList;
-    }
 
     //The function that starts or resets presentaton functionally, depending on status flag.
     @action
@@ -295,33 +260,33 @@ export class PresBox extends React.Component<FieldViewProps> {
     //stops the presentaton.
     @action
     resetPresentation = () => {
-        this._childrenDocs.forEach((doc: Doc) => {
+        this.childDocs.forEach((doc: Doc) => {
             doc.opacity = 1;
             doc.viewScale = 1;
         });
         this.props.Document.selectedDoc = 0;
         this.props.Document.presStatus = false;
-        if (this._childrenDocs.length !== 0) {
-            DocumentManager.Instance.zoomIntoScale(this._childrenDocs[0], 1);
+        if (this.childDocs.length !== 0) {
+            DocumentManager.Instance.zoomIntoScale(this.childDocs[0], 1);
         }
     }
 
     //The function that starts the presentation, also checking if actions should be applied
     //directly at start.
     startPresentation = (startIndex: number) => {
-        this._childrenDocs.map(doc => {
+        this.childDocs.map(doc => {
             if (doc.hideTillShownButton) {
-                if (this._childrenDocs.indexOf(doc) > startIndex) {
+                if (this.childDocs.indexOf(doc) > startIndex) {
                     doc.opacity = 0;
                 }
             }
             if (doc.hideAfterButton) {
-                if (this._childrenDocs.indexOf(doc) < startIndex) {
+                if (this.childDocs.indexOf(doc) < startIndex) {
                     doc.opacity = 0;
                 }
             }
             if (doc.fadeButton) {
-                if (this._childrenDocs.indexOf(doc) < startIndex) {
+                if (this.childDocs.indexOf(doc) < startIndex) {
                     doc.opacity = 0.5;
                 }
             }
@@ -346,26 +311,46 @@ export class PresBox extends React.Component<FieldViewProps> {
         ContextMenu.Instance.addItem({ description: "Make Current Presentation", event: action(() => Doc.UserDoc().curPresentation = this.props.Document), icon: "asterisk" });
     }
 
+    /**
+     * Initially every document starts with a viewScale 1, which means
+     * that they will be displayed in a canvas with scale 1.
+     */
+    @action
+    initializeScaleViews = (docList: Doc[]) => {
+        docList.forEach((doc: Doc) => {
+            let curScale = NumCast(doc.viewScale, null);
+            if (curScale === undefined) {
+                doc.viewScale = 1;
+            }
+        });
+    }
+
     render() {
+        this.initializeScaleViews(this.childDocs);
         return (
-            <div className="presentationView-cont" onContextMenu={this.specificContextMenu} style={{ width: "100%", minWidth: "200px", height: "100%", minHeight: "50px" }}>
-                <div className="presentation-buttons" style={{ width: "100%" }}>
-                    <button className="presentation-button" title="Back" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
-                    <button className="presentation-button" title={"Reset Presentation" + this.props.Document.presStatus ? "" : " From Start"} onClick={this.startOrResetPres}>
+            <div className="presBox-cont" onContextMenu={this.specificContextMenu}>
+                <div className="presBox-buttons">
+                    <button className="presBox-button" title="Back" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></button>
+                    <button className="presBox-button" title={"Reset Presentation" + this.props.Document.presStatus ? "" : " From Start"} onClick={this.startOrResetPres}>
                         <FontAwesomeIcon icon={this.props.Document.presStatus ? "stop" : "play"} />
                     </button>
-                    <button className="presentation-button" title="Next" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
-                    <button className="presentation-button" title={this.props.Document.minimizedView ? "Expand" : "Minimize"} onClick={this.toggleMinimize}><FontAwesomeIcon icon={"eye"} /></button>
+                    <button className="presBox-button" title="Next" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
+                    <button className="presBox-button" title={this.props.Document.minimizedView ? "Expand" : "Minimize"} onClick={this.toggleMinimize}><FontAwesomeIcon icon={"eye"} /></button>
                 </div>
                 {this.props.Document.minimizedView ? (null) :
-                    <PresentationViewList
-                        mainDocument={this.props.Document}
-                        deleteDocument={this.RemoveDoc}
-                        gotoDocument={this.gotoDocument}
-                        setChildrenDocs={this.setChildrenDocs}
-                        presStatus={BoolCast(this.props.Document.presStatus)}
-                        removeDocByRef={this.removeDocByRef}
-                    />}
+                    <div className="presBox-listCont" >
+                        {this.childDocs.map((doc, index) =>
+                            <PresElementBox
+                                {... this.props}
+                                key={doc[Id]}
+                                index={index}
+                                presentationDoc={this.props.Document}
+                                Document={doc}
+                                gotoDocument={this.gotoDocument}
+                                removeDocument={this.removeDocument}
+                            />
+                        )}
+                    </div>}
             </div>
         );
     }
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
new file mode 100644
index 000000000..c7d846718
--- /dev/null
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -0,0 +1,75 @@
+.presElementBox-item {
+    padding: 10px;
+    display: inline-block;
+    width: 100%;
+    outline-color: maroon;
+    outline-style: dashed;
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    transition: all .1s;
+
+    .documentView-node {
+        position: absolute;
+        z-index: 1;
+    }
+}
+
+.presElementBox-item-above {
+    border-top: black 2px solid;
+}
+
+.presElementBox-item-below {
+    border-bottom: black 2px solid;
+}
+
+.presElementBox-item:hover {
+    transition: all .1s;
+    background: #AAAAAA;
+    border-radius: 12px;
+}
+
+.presElementBox-selected {
+    background: gray;
+    color: black;
+    border-radius: 12px;
+    box-shadow: black 2px 2px 5px;
+}
+
+
+.presElementBox-icon {
+    float: right;
+}
+
+.presElementBox-interaction {
+    color: gray;
+    float: left;
+}
+
+.presElementBox-interaction-selected {
+    color: white;
+    float: left;
+}
+
+.presElementBox-name {
+    font-size: 15px;
+    display: inline-block;
+}
+
+.presElementBox-embedded {
+    position: relative;
+    margin-top: 15;
+}
+
+.presElementBox-embeddedMask {
+    width:100%;
+    height:100%;
+    position: absolute;
+    left:0;
+    top:0;
+    background: transparent;
+    z-index:2;
+}
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
new file mode 100644
index 000000000..fe2aea27b
--- /dev/null
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -0,0 +1,329 @@
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faFile as fileRegular } from '@fortawesome/free-regular-svg-icons';
+import { faArrowDown, faArrowUp, faFile as fileSolid, faFileDownload, faLocationArrow, faSearch } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, computed } from "mobx";
+import { observer } from "mobx-react";
+import { Doc } from "../../../new_fields/Doc";
+import { Id } from "../../../new_fields/FieldSymbols";
+import { BoolCast, NumCast, StrCast } from "../../../new_fields/Types";
+import { emptyFunction, returnEmptyString, returnFalse, returnOne } from "../../../Utils";
+import { DocumentType } from "../../documents/DocumentTypes";
+import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager";
+import { SelectionManager } from "../../util/SelectionManager";
+import { Transform } from "../../util/Transform";
+import { DocumentView } from "../nodes/DocumentView";
+import React = require("react");
+import "./PresElementBox.scss";
+import { FieldViewProps, FieldView } from '../nodes/FieldView';
+
+
+library.add(faArrowUp);
+library.add(fileSolid);
+library.add(faLocationArrow);
+library.add(fileRegular as any);
+library.add(faSearch);
+library.add(faArrowDown);
+
+interface PresElementProps {
+    presentationDoc: Doc;
+    index: number;
+    gotoDocument(index: number, fromDoc: number): Promise<void>;
+}
+
+/**
+ * This class models the view a document added to presentation will have in the presentation.
+ * It involves some functionality for its buttons and options.
+ */
+@observer
+export class PresElementBox extends React.Component<PresElementProps & FieldViewProps> {
+
+    public static LayoutString() { return FieldView.LayoutString(PresElementBox); }
+    private header?: HTMLDivElement | undefined;
+    private listdropDisposer?: DragManager.DragDropDisposer;
+    private presElRef: React.RefObject<HTMLDivElement> = React.createRef();
+
+    @computed get currentIndex() { return NumCast(this.props.presentationDoc.selectedDoc); }
+    @computed get showButton() { return BoolCast(this.props.Document.showButton); }
+    @computed get navButton() { return BoolCast(this.props.Document.navButton); }
+    @computed get hideTillShownButton() { return BoolCast(this.props.Document.hideTillShownButton); }
+    @computed get fadeButton() { return BoolCast(this.props.Document.fadeButton); }
+    @computed get hideAfterButton() { return BoolCast(this.props.Document.hideAfterButton); }
+    @computed get groupButton() { return BoolCast(this.props.Document.groupButton); }
+    @computed get embedInline() { return BoolCast(this.props.Document.embedOpen); }
+
+    set embedInline(value: boolean) { this.props.Document.embedOpen = value; }
+    set showButton(val: boolean) { this.props.Document.showButton = val; }
+    set navButton(val: boolean) { this.props.Document.navButton = val; }
+    set hideTillShownButton(val: boolean) { this.props.Document.hideTillShownButton = val; }
+    set fadeButton(val: boolean) { this.props.Document.fadeButton = val; }
+    set hideAfterButton(val: boolean) { this.props.Document.hideAfterButton = val; }
+    set groupButton(val: boolean) { this.props.Document.groupButton = val; }
+
+    //Lifecycle function that makes sure that button BackUp is received when mounted.
+    componentDidMount() {
+        if (this.presElRef.current) {
+            this.header = this.presElRef.current;
+            this.createListDropTarget(this.presElRef.current);
+        }
+    }
+
+    componentWillUnmount() {
+        this.listdropDisposer && this.listdropDisposer();
+    }
+    /**
+     * The function that is called on click to turn Hiding document till press option on/off.
+     * It also sets the beginning and end opacitys.
+     */
+    @action
+    onHideDocumentUntilPressClick = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        this.hideTillShownButton = !this.hideTillShownButton;
+        if (!this.hideTillShownButton) {
+            if (this.props.index >= this.currentIndex) {
+                (this.props.Document.target as Doc).opacity = 1;
+            }
+        } else {
+            if (this.props.presentationDoc.presStatus) {
+                if (this.props.index > this.currentIndex) {
+                    (this.props.Document.target as Doc).opacity = 0;
+                }
+            }
+        }
+    }
+
+    /**
+     * The function that is called on click to turn Hiding document after presented option on/off.
+     * It also makes sure that the option swithches from fade-after to this one, since both
+     * can't coexist.
+     */
+    @action
+    onHideDocumentAfterPresentedClick = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        this.hideAfterButton = !this.hideAfterButton;
+        if (!this.hideAfterButton) {
+            if (this.props.index <= this.currentIndex) {
+                (this.props.Document.target as Doc).opacity = 1;
+            }
+        } else {
+            if (this.fadeButton) this.fadeButton = false;
+            if (this.props.presentationDoc.presStatus) {
+                if (this.props.index < this.currentIndex) {
+                    (this.props.Document.target as Doc).opacity = 0;
+                }
+            }
+        }
+    }
+
+    /**
+     * The function that is called on click to turn fading document after presented option on/off.
+     * It also makes sure that the option swithches from hide-after to this one, since both
+     * can't coexist.
+     */
+    @action
+    onFadeDocumentAfterPresentedClick = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        this.fadeButton = !this.fadeButton;
+        if (!this.fadeButton) {
+            if (this.props.index <= this.currentIndex) {
+                (this.props.Document.target as Doc).opacity = 1;
+            }
+        } else {
+            this.hideAfterButton = false;
+            if (this.props.presentationDoc.presStatus) {
+                if (this.props.index < this.currentIndex) {
+                    (this.props.Document.target as Doc).opacity = 0.5;
+                }
+            }
+        }
+    }
+
+    /**
+     * The function that is called on click to turn navigation option of docs on/off.
+     */
+    @action
+    onNavigateDocumentClick = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        this.navButton = !this.navButton;
+        if (this.navButton) {
+            this.showButton = false;
+            if (this.currentIndex === this.props.index) {
+                this.props.gotoDocument(this.props.index, this.props.index);
+            }
+        }
+    }
+
+    /**
+    * The function that is called on click to turn zoom option of docs on/off.
+    */
+    @action
+    onZoomDocumentClick = (e: React.MouseEvent) => {
+        e.stopPropagation();
+
+        this.showButton = !this.showButton;
+        if (!this.showButton) {
+            this.props.Document.viewScale = 1;
+        } else {
+            this.navButton = false;
+            if (this.currentIndex === this.props.index) {
+                this.props.gotoDocument(this.props.index, this.props.index);
+            }
+        }
+    }
+
+    /**
+     * Creating a drop target for drag and drop when called.
+     */
+    protected createListDropTarget = (ele: HTMLDivElement) => {
+        this.listdropDisposer && this.listdropDisposer();
+        ele && (this.listdropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.listDrop.bind(this) } }));
+    }
+
+    /**
+     * Returns a local transformed coordinate array for given coordinates.
+     */
+    ScreenToLocalListTransform = (xCord: number, yCord: number) => [xCord, yCord];
+
+    /**
+     * This method is called when a element is dropped on a already esstablished target.
+     * It makes sure to do appropirate action depending on if the item is dropped before
+     * or after the target.
+     */
+    listDrop = async (e: Event, de: DragManager.DropEvent) => {
+        let x = this.ScreenToLocalListTransform(de.x, de.y);
+        let rect = this.header!.getBoundingClientRect();
+        let bounds = this.ScreenToLocalListTransform(rect.left, rect.top + rect.height / 2);
+        let before = x[1] < bounds[1];
+        if (de.data instanceof DragManager.DocumentDragData) {
+            let addDoc = (doc: Doc) => Doc.AddDocToList(this.props.presentationDoc, "data", doc, this.props.Document, before);
+            e.stopPropagation();
+            //where does treeViewId come from
+            let movedDocs = (de.data.options === this.props.presentationDoc[Id] ? de.data.draggedDocuments : de.data.droppedDocuments);
+            //console.log("How is this causing an issue");
+            document.removeEventListener("pointermove", this.onDragMove, true);
+            return (de.data.dropAction || de.data.userDropAction) ?
+                de.data.droppedDocuments.reduce((added: boolean, d: Doc) => Doc.AddDocToList(this.props.presentationDoc, "data", d, this.props.Document, before) || added, false)
+                : (de.data.moveDocument) ?
+                    movedDocs.reduce((added: boolean, d: Doc) => de.data.moveDocument(d, this.props.Document, addDoc) || added, false)
+                    : de.data.droppedDocuments.reduce((added: boolean, d: Doc) => Doc.AddDocToList(this.props.presentationDoc, "data", d, this.props.Document, before), false);
+        }
+        document.removeEventListener("pointermove", this.onDragMove, true);
+
+        return false;
+    }
+
+    //This is used to add dragging as an event.
+    onPointerEnter = (e: React.PointerEvent): void => {
+        if (e.buttons === 1 && SelectionManager.GetIsDragging()) {
+            this.header!.className = "presElementBox-item" + (this.currentIndex === this.props.index ? "presElementBox-selected" : "");
+
+            document.addEventListener("pointermove", this.onDragMove, true);
+        }
+    }
+
+    //This is used to remove the dragging when dropped.
+    onPointerLeave = (e: React.PointerEvent): void => {
+        this.header!.className = "presElementBox-item" + (this.currentIndex === this.props.index ? " presElementBox-selected" : "");
+
+        document.removeEventListener("pointermove", this.onDragMove, true);
+    }
+
+    /**
+     * This method is passed in to be used when dragging a document.
+     * It makes it possible to show dropping lines on drop targets.
+     */
+    onDragMove = (e: PointerEvent): void => {
+        Doc.UnBrushDoc(this.props.Document);
+        let x = this.ScreenToLocalListTransform(e.clientX, e.clientY);
+        let rect = this.header!.getBoundingClientRect();
+        let bounds = this.ScreenToLocalListTransform(rect.left, rect.top + rect.height / 2);
+        this.header!.className = "presElementBox-item presElementBox-item-" + (x[1] < bounds[1] ? "above" : "below");
+        e.stopPropagation();
+    }
+
+    /**
+     * This method is passed in to on down event of presElement, so that drag and
+     * drop can be completed with DragManager functionality.
+     */
+    @action
+    move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
+        return this.props.Document !== target && (this.props.removeDocument ? this.props.removeDocument(doc) : false) && addDoc(doc);
+    }
+
+    /**
+     * The function that is responsible for rendering the a preview or not for this
+     * presentation element.
+     */
+    renderEmbeddedInline = () => {
+        if (!this.embedInline || !(this.props.Document.target instanceof Doc)) {
+            return (null);
+        }
+
+        let propDocWidth = NumCast(this.props.Document.nativeWidth);
+        let propDocHeight = NumCast(this.props.Document.nativeHeight);
+        let scale = () => 175 / NumCast(this.props.Document.nativeWidth, 175);
+        return (
+            <div className="presElementBox-embedded" style={{
+                height: propDocHeight === 0 ? 100 : propDocHeight * scale(),
+                width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
+            }}>
+                <DocumentView
+                    fitToBox={StrCast(this.props.Document.type).indexOf(DocumentType.COL) !== -1}
+                    Document={this.props.Document.target as Doc}
+                    addDocument={returnFalse}
+                    removeDocument={returnFalse}
+                    ruleProvider={undefined}
+                    ScreenToLocalTransform={Transform.Identity}
+                    addDocTab={returnFalse}
+                    pinToPres={returnFalse}
+                    renderDepth={1}
+                    PanelWidth={() => 350}
+                    PanelHeight={() => 90}
+                    focus={emptyFunction}
+                    backgroundColor={returnEmptyString}
+                    parentActive={returnFalse}
+                    whenActiveChanged={returnFalse}
+                    bringToFront={emptyFunction}
+                    zoomToScale={emptyFunction}
+                    getScale={returnOne}
+                    ContainingCollectionView={undefined}
+                    ContainingCollectionDoc={undefined}
+                    ContentScaling={scale}
+                />
+                <div className="presElementBox-embeddedMask" />
+            </div>
+        );
+    }
+
+    render() {
+        let p = this.props;
+
+        let className = "presElementBox-item" + (this.currentIndex === p.index ? " presElementBox-selected" : "");
+        let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
+        let onItemDown = SetupDrag(this.presElRef, () => p.Document, this.move, dropAction, this.props.presentationDoc[Id], true);
+        return (
+            <div className={className} key={p.Document[Id] + p.index}
+                ref={this.presElRef}
+                onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}
+                onPointerDown={onItemDown}
+                style={{ outlineWidth: Doc.IsBrushed(p.Document) ? `1px` : "0px", }}
+                onClick={e => p.gotoDocument(p.index, this.currentIndex)}>
+                <strong className="presElementBox-name">
+                    {`${p.index + 1}. ${p.Document.title}`}
+                </strong>
+                <button className="presElementBox-icon" onPointerDown={e => e.stopPropagation()} onClick={e => this.props.removeDocument && this.props.removeDocument(p.Document)}>X</button>
+                <br />
+                <button title="Zoom" className={"presElementBox-interaction" + (this.showButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} /></button>
+                <button title="Navigate" className={"presElementBox-interaction" + (this.navButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} /></button>
+                <button title="Hide Til Presented" className={"presElementBox-interaction" + (this.hideTillShownButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={fileSolid} /></button>
+                <button title="Fade After Presented" className={"presElementBox-interaction" + (this.fadeButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
+                <button title="Hide After Presented" className={"presElementBox-interaction" + (this.hideAfterButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
+                <button title="Group With Up" className={"presElementBox-interaction" + (this.groupButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action(() => this.groupButton = !this.groupButton)}> <FontAwesomeIcon icon={"arrow-up"} /> </button>
+                <button title="Expand Inline" className={"presElementBox-interaction" + (this.embedInline ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action(() => this.embedInline = !this.embedInline)}><FontAwesomeIcon icon={"arrow-down"} /></button>
+
+                <br />
+                {this.renderEmbeddedInline()}
+            </div>
+        );
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx
deleted file mode 100644
index 6e8c28d34..000000000
--- a/src/client/views/presentationview/PresentationElement.tsx
+++ /dev/null
@@ -1,423 +0,0 @@
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { faFile as fileRegular } from '@fortawesome/free-regular-svg-icons';
-import { faArrowDown, faArrowUp, faFile as fileSolid, faFileDownload, faLocationArrow, faSearch } from '@fortawesome/free-solid-svg-icons';
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed } from "mobx";
-import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { BoolCast, NumCast, StrCast } from "../../../new_fields/Types";
-import { emptyFunction, returnEmptyString, returnFalse, returnOne } from "../../../Utils";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager";
-import { SelectionManager } from "../../util/SelectionManager";
-import { Transform } from "../../util/Transform";
-import { ContextMenu } from "../ContextMenu";
-import { DocumentView } from "../nodes/DocumentView";
-import React = require("react");
-
-
-library.add(faArrowUp);
-library.add(fileSolid);
-library.add(faLocationArrow);
-library.add(fileRegular as any);
-library.add(faSearch);
-library.add(faArrowDown);
-
-interface PresentationElementProps {
-    mainDocument: Doc;
-    document: Doc;
-    index: number;
-    deleteDocument(index: number): void;
-    gotoDocument(index: number, fromDoc: number): Promise<void>;
-    allListElements: Doc[];
-    presStatus: boolean;
-    removeDocByRef(doc: Doc): boolean;
-}
-
-/**
- * This class models the view a document added to presentation will have in the presentation.
- * It involves some functionality for its buttons and options.
- */
-@observer
-export default class PresentationElement extends React.Component<PresentationElementProps> {
-
-    private header?: HTMLDivElement | undefined;
-    private listdropDisposer?: DragManager.DragDropDisposer;
-    private presElRef: React.RefObject<HTMLDivElement> = React.createRef();
-
-    componentWillUnmount() {
-        this.listdropDisposer && this.listdropDisposer();
-    }
-
-    @computed get currentIndex() { return NumCast(this.props.mainDocument.selectedDoc); }
-
-    @computed get showButton() { return BoolCast(this.props.document.showButton); }
-    @computed get navButton() { return BoolCast(this.props.document.navButton); }
-    @computed get hideTillShownButton() { return BoolCast(this.props.document.hideTillShownButton); }
-    @computed get fadeButton() { return BoolCast(this.props.document.fadeButton); }
-    @computed get hideAfterButton() { return BoolCast(this.props.document.hideAfterButton); }
-    @computed get groupButton() { return BoolCast(this.props.document.groupButton); }
-    @computed get expandInlineButton() { return BoolCast(this.props.document.expandInlineButton); }
-    set showButton(val: boolean) { this.props.document.showButton = val; }
-    set navButton(val: boolean) { this.props.document.navButton = val; }
-    set hideTillShownButton(val: boolean) { this.props.document.hideTillShownButton = val; }
-    set fadeButton(val: boolean) { this.props.document.fadeButton = val; }
-    set hideAfterButton(val: boolean) { this.props.document.hideAfterButton = val; }
-    set groupButton(val: boolean) { this.props.document.groupButton = val; }
-    set expandInlineButton(val: boolean) { this.props.document.expandInlineButton = val; }
-
-    //Lifecycle function that makes sure that button BackUp is received when mounted.
-    async componentDidMount() {
-        if (this.presElRef.current) {
-            this.header = this.presElRef.current;
-            this.createListDropTarget(this.presElRef.current);
-        }
-    }
-
-    //Lifecycle function that makes sure button BackUp is received when not re-mounted bu re-rendered.
-    async componentDidUpdate() {
-        if (this.presElRef.current) {
-            this.header = this.presElRef.current;
-            this.createListDropTarget(this.presElRef.current);
-        }
-    }
-
-    @action
-    onGroupClick = (e: React.MouseEvent) => {
-        this.groupButton = !this.groupButton;
-    }
-
-    /**
-     * The function that is called on click to turn Hiding document till press option on/off.
-     * It also sets the beginning and end opacitys.
-     */
-    @action
-    onHideDocumentUntilPressClick = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        this.hideTillShownButton = !this.hideTillShownButton;
-        if (!this.hideTillShownButton) {
-            if (this.props.index >= this.currentIndex) {
-                this.props.document.opacity = 1;
-            }
-        } else {
-            if (this.props.presStatus) {
-                if (this.props.index > this.currentIndex) {
-                    this.props.document.opacity = 0;
-                }
-            }
-        }
-    }
-
-    /**
-     * The function that is called on click to turn Hiding document after presented option on/off.
-     * It also makes sure that the option swithches from fade-after to this one, since both
-     * can't coexist.
-     */
-    @action
-    onHideDocumentAfterPresentedClick = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        this.hideAfterButton = !this.hideAfterButton;
-        if (!this.hideAfterButton) {
-            if (this.props.index <= this.currentIndex) {
-                this.props.document.opacity = 1;
-            }
-        } else {
-            if (this.fadeButton) this.fadeButton = false;
-            if (this.props.presStatus) {
-                if (this.props.index < this.currentIndex) {
-                    this.props.document.opacity = 0;
-                }
-            }
-        }
-    }
-
-    /**
-     * The function that is called on click to turn fading document after presented option on/off.
-     * It also makes sure that the option swithches from hide-after to this one, since both
-     * can't coexist.
-     */
-    @action
-    onFadeDocumentAfterPresentedClick = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        this.fadeButton = !this.fadeButton;
-        if (!this.fadeButton) {
-            if (this.props.index <= this.currentIndex) {
-                this.props.document.opacity = 1;
-            }
-        } else {
-            this.hideAfterButton = false;
-            if (this.props.presStatus) {
-                if (this.props.index < this.currentIndex) {
-                    this.props.document.opacity = 0.5;
-                }
-            }
-        }
-    }
-
-    /**
-     * The function that is called on click to turn navigation option of docs on/off.
-     */
-    @action
-    onNavigateDocumentClick = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        this.navButton = !this.navButton;
-        if (this.navButton) {
-            this.showButton = false;
-            if (this.currentIndex === this.props.index) {
-                this.props.gotoDocument(this.props.index, this.props.index);
-            }
-        }
-    }
-
-    /**
-    * The function that is called on click to turn zoom option of docs on/off.
-    */
-    @action
-    onZoomDocumentClick = (e: React.MouseEvent) => {
-        e.stopPropagation();
-
-        this.showButton = !this.showButton;
-        if (!this.showButton) {
-            this.props.document.viewScale = 1;
-        } else {
-            this.navButton = false;
-            if (this.currentIndex === this.props.index) {
-                this.props.gotoDocument(this.props.index, this.props.index);
-            }
-        }
-    }
-
-    /**
-     * Function that expands the target inline
-     */
-    @action
-    onExpandTabClick = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        this.embedInline = !this.embedInline
-    }
-
-    /**
-     * Creating a drop target for drag and drop when called.
-     */
-    protected createListDropTarget = (ele: HTMLDivElement) => {
-        this.listdropDisposer && this.listdropDisposer();
-        if (ele) {
-            this.listdropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.listDrop.bind(this) } });
-        }
-    }
-
-    /**
-     * Returns a local transformed coordinate array for given coordinates.
-     */
-    ScreenToLocalListTransform = (xCord: number, yCord: number) => {
-        return [xCord, yCord];
-    }
-
-    /**
-     * This method is called when a element is dropped on a already esstablished target.
-     * It makes sure to do appropirate action depending on if the item is dropped before
-     * or after the target.
-     */
-    listDrop = async (e: Event, de: DragManager.DropEvent) => {
-        let x = this.ScreenToLocalListTransform(de.x, de.y);
-        let rect = this.header!.getBoundingClientRect();
-        let bounds = this.ScreenToLocalListTransform(rect.left, rect.top + rect.height / 2);
-        let before = x[1] < bounds[1];
-        if (de.data instanceof DragManager.DocumentDragData) {
-            let addDoc = (doc: Doc) => Doc.AddDocToList(this.props.mainDocument, "data", doc, this.props.document, before);
-            e.stopPropagation();
-            //where does treeViewId come from
-            let movedDocs = (de.data.options === this.props.mainDocument[Id] ? de.data.draggedDocuments : de.data.droppedDocuments);
-            //console.log("How is this causing an issue");
-            document.removeEventListener("pointermove", this.onDragMove, true);
-            return (de.data.dropAction || de.data.userDropAction) ?
-                de.data.droppedDocuments.reduce((added: boolean, d: Doc) => Doc.AddDocToList(this.props.mainDocument, "data", d, this.props.document, before) || added, false)
-                : (de.data.moveDocument) ?
-                    movedDocs.reduce((added: boolean, d: Doc) => de.data.moveDocument(d, this.props.document, addDoc) || added, false)
-                    : de.data.droppedDocuments.reduce((added: boolean, d: Doc) => Doc.AddDocToList(this.props.mainDocument, "data", d, this.props.document, before), false);
-        }
-        document.removeEventListener("pointermove", this.onDragMove, true);
-
-        return false;
-    }
-
-    //This is used to add dragging as an event.
-    onPointerEnter = (e: React.PointerEvent): void => {
-        if (e.buttons === 1 && SelectionManager.GetIsDragging()) {
-
-            this.header!.className = "presentationView-item";
-
-            if (this.currentIndex === this.props.index) {
-                //this doc is selected
-                this.header!.className = "presentationView-item presentationView-selected";
-            }
-            document.addEventListener("pointermove", this.onDragMove, true);
-        }
-    }
-
-    //This is used to remove the dragging when dropped.
-    onPointerLeave = (e: React.PointerEvent): void => {
-        this.header!.className = "presentationView-item";
-
-        if (this.currentIndex === this.props.index) {
-            //this doc is selected
-            this.header!.className = "presentationView-item presentationView-selected";
-
-        }
-        document.removeEventListener("pointermove", this.onDragMove, true);
-    }
-
-    /**
-     * This method is passed in to be used when dragging a document.
-     * It makes it possible to show dropping lines on drop targets.
-     */
-    onDragMove = (e: PointerEvent): void => {
-        Doc.UnBrushDoc(this.props.document);
-        let x = this.ScreenToLocalListTransform(e.clientX, e.clientY);
-        let rect = this.header!.getBoundingClientRect();
-        let bounds = this.ScreenToLocalListTransform(rect.left, rect.top + rect.height / 2);
-        let before = x[1] < bounds[1];
-        this.header!.className = "presentationView-item";
-        if (before) {
-            this.header!.className += " presentationView-item-above";
-        }
-        else if (!before) {
-            this.header!.className += " presentationView-item-below";
-        }
-        e.stopPropagation();
-    }
-
-    /**
-     * This method is passed in to on down event of presElement, so that drag and
-     * drop can be completed with DragManager functionality.
-     */
-    @action
-    move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
-        return this.props.document !== target && this.props.removeDocByRef(doc) && addDoc(doc);
-    }
-    /**
-     * This function is a getter to get if a document is in previewMode.
-     */
-    private get embedInline() {
-        return BoolCast(this.props.document.embedOpen);
-    }
-
-    /**
-     * This function sets document in presentation preview mode as the given value.
-     */
-    private set embedInline(value: boolean) {
-        this.props.document.embedOpen = value;
-    }
-
-    /**
-     * The function that recreates that context menu of presentation elements.
-     */
-    onContextMenu = (e: React.MouseEvent<HTMLDivElement>) => {
-        e.preventDefault();
-        e.stopPropagation();
-        ContextMenu.Instance.addItem({ description: this.embedInline ? "Collapse Inline" : "Expand Inline", event: () => this.embedInline = !this.embedInline, icon: "expand" });
-        ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
-    }
-
-    /**
-     * The function that is responsible for rendering the a preview or not for this
-     * presentation element.
-     */
-    renderEmbeddedInline = () => {
-        if (!this.embedInline) {
-            return (null);
-        }
-
-        let propDocWidth = NumCast(this.props.document.nativeWidth);
-        let propDocHeight = NumCast(this.props.document.nativeHeight);
-        let scale = () => {
-            let newScale = 175 / NumCast(this.props.document.nativeWidth, 175);
-            return newScale;
-        };
-        return (
-            <div style={{
-                position: "relative",
-                height: propDocHeight === 0 ? 100 : propDocHeight * scale(),
-                width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
-                marginTop: 15
-
-            }}>
-                <DocumentView
-                    fitToBox={StrCast(this.props.document.type).indexOf(DocumentType.COL) !== -1}
-                    Document={this.props.document}
-                    addDocument={returnFalse}
-                    removeDocument={returnFalse}
-                    ruleProvider={undefined}
-                    ScreenToLocalTransform={Transform.Identity}
-                    addDocTab={returnFalse}
-                    pinToPres={returnFalse}
-                    renderDepth={1}
-                    PanelWidth={() => 350}
-                    PanelHeight={() => 90}
-                    focus={emptyFunction}
-                    backgroundColor={returnEmptyString}
-                    parentActive={returnFalse}
-                    whenActiveChanged={returnFalse}
-                    bringToFront={emptyFunction}
-                    zoomToScale={emptyFunction}
-                    getScale={returnOne}
-                    ContainingCollectionView={undefined}
-                    ContainingCollectionDoc={undefined}
-                    ContentScaling={scale}
-                />
-                <div style={{
-                    width: " 100%",
-                    height: " 100%",
-                    position: "absolute",
-                    left: 0,
-                    top: 0,
-                    background: "transparent",
-                    zIndex: 2,
-
-                }}></div>
-            </div>
-        );
-    }
-
-    render() {
-        let p = this.props;
-        let title = p.document.title;
-
-        let className = " presentationView-item";
-        if (this.currentIndex === p.index) {
-            //this doc is selected
-            className += " presentationView-selected";
-        }
-        let dropAction = StrCast(this.props.document.dropAction) as dropActionType;
-        let onItemDown = SetupDrag(this.presElRef, () => p.document, this.move, dropAction, this.props.mainDocument[Id], true);
-        return (
-            <div className={className} onContextMenu={this.onContextMenu} key={p.document[Id] + p.index}
-                ref={this.presElRef}
-                onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}
-                onPointerDown={onItemDown}
-                style={{
-                    outlineColor: "maroon",
-                    outlineStyle: "dashed",
-                    outlineWidth: Doc.IsBrushed(p.document) ? `1px` : "0px",
-                }}
-                onClick={e => { p.gotoDocument(p.index, this.currentIndex); e.stopPropagation(); }}>
-                <strong className="presentationView-name">
-                    {`${p.index + 1}. ${title}`}
-                </strong>
-                <button className="presentation-icon" onPointerDown={(e) => e.stopPropagation()} onClick={e => { this.props.deleteDocument(p.index); e.stopPropagation(); }}>X</button>
-                <br></br>
-                <button title="Zoom" className={this.showButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} /></button>
-                <button title="Navigate" className={this.navButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} /></button>
-                <button title="Hide Document Till Presented" className={this.hideTillShownButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={fileSolid} /></button>
-                <button title="Fade Document After Presented" className={this.fadeButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
-                <button title="Hide Document After Presented" className={this.hideAfterButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
-                <button title="Group With Up" className={this.groupButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onGroupClick}> <FontAwesomeIcon icon={"arrow-up"} /> </button>
-                <button title="Expand Inline" className={this.expandInlineButton ? "presentation-interaction-selected" : "presentation-interaction"} onPointerDown={(e) => e.stopPropagation()} onClick={this.onExpandTabClick}><FontAwesomeIcon icon={"arrow-down"} /></button>
-
-                <br />
-                {this.renderEmbeddedInline()}
-            </div>
-        );
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresentationList.tsx b/src/client/views/presentationview/PresentationList.tsx
deleted file mode 100644
index 483461e5a..000000000
--- a/src/client/views/presentationview/PresentationList.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { action } from "mobx";
-import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { NumCast } from "../../../new_fields/Types";
-import PresentationElement from "./PresentationElement";
-import "./PresentationView.scss";
-import React = require("react");
-
-
-interface PresListProps {
-    mainDocument: Doc;
-    deleteDocument(index: number): void;
-    gotoDocument(index: number, fromDoc: number): Promise<void>;
-    setChildrenDocs: (docList: Doc[]) => void;
-    presStatus: boolean;
-    removeDocByRef(doc: Doc): boolean;
-}
-
-
-@observer
-/**
- * Component that takes in a document prop and a boolean whether it's collapsed or not.
- */
-export default class PresentationViewList extends React.Component<PresListProps> {
-
-
-    /**
-     * Initially every document starts with a viewScale 1, which means
-     * that they will be displayed in a canvas with scale 1.
-     */
-    @action
-    initializeScaleViews = (docList: Doc[]) => {
-        docList.forEach((doc: Doc) => {
-            let curScale = NumCast(doc.viewScale, null);
-            if (curScale === undefined) {
-                doc.viewScale = 1;
-            }
-        });
-    }
-
-    render() {
-        const children = DocListCast(this.props.mainDocument.data);
-        this.initializeScaleViews(children);
-        this.props.setChildrenDocs(children);
-        return (
-            <div className="presentationView-listCont" >
-                {children.map((doc: Doc, index: number) =>
-                    <PresentationElement
-                        key={doc[Id]}
-                        mainDocument={this.props.mainDocument}
-                        document={doc}
-                        index={index}
-                        deleteDocument={this.props.deleteDocument}
-                        gotoDocument={this.props.gotoDocument}
-                        allListElements={children}
-                        presStatus={this.props.presStatus}
-                        removeDocByRef={this.props.removeDocByRef}
-                    />
-                )}
-            </div>
-        );
-    }
-}
diff --git a/src/client/views/presentationview/PresentationView.scss b/src/client/views/presentationview/PresentationView.scss
deleted file mode 100644
index 5c40a8808..000000000
--- a/src/client/views/presentationview/PresentationView.scss
+++ /dev/null
@@ -1,113 +0,0 @@
-.presentationView-cont {
-    position: absolute;
-    z-index: 2;
-    box-shadow: #AAAAAA .2vw .2vw .4vw;
-    right: 0;
-    top: 0;
-    bottom: 0;
-    letter-spacing: 2px;
-    overflow: hidden;
-    transition: 0.7s opacity ease;
-    pointer-events: all;
-}
-
-.presentationView-item {
-    padding: 10px;
-    display: inline-block;
-    width: 100%;
-    -webkit-touch-callout: none;
-    -webkit-user-select: none;
-    -khtml-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none;
-    transition: all .1s;
-
-    .documentView-node {
-        
-        position: absolute;
-        z-index: 1;
-    }
-}
-
-.presentationView-item-above {
-    border-top: black 2px solid;
-}
-
-.presentationView-item-below {
-    border-bottom: black 2px solid;
-}
-
-.presentationView-listCont {
-    padding-left: 10px;
-    padding-right: 10px;
-}
-
-.presentationView-item:hover {
-    transition: all .1s;
-    background: #AAAAAA;
-    border-radius: 12px;
-}
-
-.presentationView-selected {
-    background: gray;
-    color: black;
-    border-radius: 12px;
-    box-shadow: black 2px 2px 5px;
-}
-
-.presentationView-heading {
-    background: gray;
-    padding: 10px;
-    display: inline-block;
-    width: 100%;
-}
-
-.presentationView-title {
-    padding-top: 3px;
-    padding-bottom: 3px;
-    font-size: 25px;
-    display: inline-block;
-    width: calc(100% - 200px);
-    letter-spacing: 2px;
-}
-
-.presentation-icon {
-    float: right;
-}
-
-.presentation-interaction {
-    color: gray;
-    float: left;
-}
-
-.presentation-interaction-selected {
-    color: white;
-    float: left;
-}
-
-.presentationView-name {
-    font-size: 15px;
-    display: inline-block;
-}
-
-.presentation-button {
-    margin-right: 2.5%;
-    margin-left: 2.5%;
-    width: 20%;
-    border-radius: 5px;
-}
-
-.presentation-buttons {
-    padding: 10px;
-}
-
-.presentation-next:hover {
-    transition: all .1s;
-    background: #AAAAAA
-}
-
-.presentation-back:hover {
-    transition: all .1s;
-    background: #AAAAAA
-}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 3a2ac5286e556be726440547309937945f650393 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 30 Sep 2019 17:42:00 -0400
Subject: minor presentation fixes

---
 src/client/views/nodes/PresBox.tsx                 | 25 ++++-----
 .../views/presentationview/PresElementBox.tsx      | 60 +++++++++++-----------
 2 files changed, 44 insertions(+), 41 deletions(-)

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

diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 526416e57..d3a24eb7a 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -37,7 +37,7 @@ export class PresBox extends React.Component<FieldViewProps> {
         //asking to get document at current index
         let docAtCurrentNext = await this.getDocAtIndex(current + 1);
         if (docAtCurrentNext !== undefined) {
-            let presDocs = DocListCast(this.props.Document.data);
+            let presDocs = DocListCast(this.props.Document[this.props.fieldKey]);
             let nextSelected = current + 1;
 
             for (; nextSelected < presDocs.length - 1; nextSelected++) {
@@ -210,7 +210,7 @@ export class PresBox extends React.Component<FieldViewProps> {
 
     @undoBatch
     public removeDocument = (doc: Doc) => {
-        const value = FieldValue(Cast(this.props.Document.data, listSpec(Doc)));
+        const value = FieldValue(Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)));
         if (value) {
             let indexOfDoc = value.indexOf(doc);
             if (indexOfDoc !== - 1) {
@@ -296,14 +296,14 @@ export class PresBox extends React.Component<FieldViewProps> {
     toggleMinimize = undoBatch(action((e: React.PointerEvent) => {
         if (this.props.Document.minimizedView) {
             this.props.Document.minimizedView = false;
-            Doc.RemoveDocFromList((CurrentUserUtils.UserDocument.overlays as Doc), "data", this.props.Document);
+            Doc.RemoveDocFromList((CurrentUserUtils.UserDocument.overlays as Doc), this.props.fieldKey, this.props.Document);
             CollectionDockingView.AddRightSplit(this.props.Document, this.props.DataDoc);
         } else {
             this.props.Document.minimizedView = true;
             this.props.Document.x = e.clientX + 25;
             this.props.Document.y = e.clientY - 25;
             this.props.addDocTab && this.props.addDocTab(this.props.Document, this.props.DataDoc, "close");
-            Doc.AddDocToList((CurrentUserUtils.UserDocument.overlays as Doc), "data", this.props.Document);
+            Doc.AddDocToList((CurrentUserUtils.UserDocument.overlays as Doc), this.props.fieldKey, this.props.Document);
         }
     }));
 
@@ -325,6 +325,11 @@ export class PresBox extends React.Component<FieldViewProps> {
         });
     }
 
+    selectElement = (doc: Doc) => {
+        let index = DocListCast(this.props.Document[this.props.fieldKey]).indexOf(doc);
+        index !== -1 && this.gotoDocument(index, NumCast(this.props.Document.selectedDoc));
+    }
+
     render() {
         this.initializeScaleViews(this.childDocs);
         return (
@@ -339,15 +344,11 @@ export class PresBox extends React.Component<FieldViewProps> {
                 </div>
                 {this.props.Document.minimizedView ? (null) :
                     <div className="presBox-listCont" >
-                        {this.childDocs.map((doc, index) =>
-                            <PresElementBox
-                                {... this.props}
-                                key={doc[Id]}
-                                index={index}
-                                presentationDoc={this.props.Document}
-                                Document={doc}
-                                gotoDocument={this.gotoDocument}
+                        {this.childDocs.map(doc =>
+                            <PresElementBox key={doc[Id]}  {... this.props} Document={doc}
                                 removeDocument={this.removeDocument}
+                                focus={this.selectElement}
+                                presBox={this}
                             />
                         )}
                     </div>}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index fe2aea27b..1b4c841e7 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -4,7 +4,7 @@ import { faArrowDown, faArrowUp, faFile as fileSolid, faFileDownload, faLocation
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
+import { Doc, DocListCast } from "../../../new_fields/Doc";
 import { Id } from "../../../new_fields/FieldSymbols";
 import { BoolCast, NumCast, StrCast } from "../../../new_fields/Types";
 import { emptyFunction, returnEmptyString, returnFalse, returnOne } from "../../../Utils";
@@ -16,6 +16,7 @@ import { DocumentView } from "../nodes/DocumentView";
 import React = require("react");
 import "./PresElementBox.scss";
 import { FieldViewProps, FieldView } from '../nodes/FieldView';
+import { PresBox } from '../nodes/PresBox';
 
 
 library.add(faArrowUp);
@@ -26,9 +27,7 @@ library.add(faSearch);
 library.add(faArrowDown);
 
 interface PresElementProps {
-    presentationDoc: Doc;
-    index: number;
-    gotoDocument(index: number, fromDoc: number): Promise<void>;
+    presBox: PresBox;
 }
 
 /**
@@ -43,7 +42,10 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
     private listdropDisposer?: DragManager.DragDropDisposer;
     private presElRef: React.RefObject<HTMLDivElement> = React.createRef();
 
-    @computed get currentIndex() { return NumCast(this.props.presentationDoc.selectedDoc); }
+    @computed get myIndex() { return DocListCast(this.props.presBox.props.Document[this.props.presBox.props.fieldKey]).indexOf(this.props.Document) }
+    @computed get presentationDoc() { return this.props.presBox.props.Document; }
+    @computed get presentationFieldKey() { return this.props.presBox.props.fieldKey; }
+    @computed get currentIndex() { return NumCast(this.presentationDoc.selectedDoc); }
     @computed get showButton() { return BoolCast(this.props.Document.showButton); }
     @computed get navButton() { return BoolCast(this.props.Document.navButton); }
     @computed get hideTillShownButton() { return BoolCast(this.props.Document.hideTillShownButton); }
@@ -80,12 +82,12 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
         e.stopPropagation();
         this.hideTillShownButton = !this.hideTillShownButton;
         if (!this.hideTillShownButton) {
-            if (this.props.index >= this.currentIndex) {
+            if (this.myIndex >= this.currentIndex) {
                 (this.props.Document.target as Doc).opacity = 1;
             }
         } else {
-            if (this.props.presentationDoc.presStatus) {
-                if (this.props.index > this.currentIndex) {
+            if (this.presentationDoc.presStatus) {
+                if (this.myIndex > this.currentIndex) {
                     (this.props.Document.target as Doc).opacity = 0;
                 }
             }
@@ -102,13 +104,13 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
         e.stopPropagation();
         this.hideAfterButton = !this.hideAfterButton;
         if (!this.hideAfterButton) {
-            if (this.props.index <= this.currentIndex) {
+            if (this.myIndex <= this.currentIndex) {
                 (this.props.Document.target as Doc).opacity = 1;
             }
         } else {
             if (this.fadeButton) this.fadeButton = false;
-            if (this.props.presentationDoc.presStatus) {
-                if (this.props.index < this.currentIndex) {
+            if (this.presentationDoc.presStatus) {
+                if (this.myIndex < this.currentIndex) {
                     (this.props.Document.target as Doc).opacity = 0;
                 }
             }
@@ -125,13 +127,13 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
         e.stopPropagation();
         this.fadeButton = !this.fadeButton;
         if (!this.fadeButton) {
-            if (this.props.index <= this.currentIndex) {
+            if (this.myIndex <= this.currentIndex) {
                 (this.props.Document.target as Doc).opacity = 1;
             }
         } else {
             this.hideAfterButton = false;
-            if (this.props.presentationDoc.presStatus) {
-                if (this.props.index < this.currentIndex) {
+            if (this.presentationDoc.presStatus) {
+                if (this.myIndex < this.currentIndex) {
                     (this.props.Document.target as Doc).opacity = 0.5;
                 }
             }
@@ -147,8 +149,8 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
         this.navButton = !this.navButton;
         if (this.navButton) {
             this.showButton = false;
-            if (this.currentIndex === this.props.index) {
-                this.props.gotoDocument(this.props.index, this.props.index);
+            if (this.currentIndex === this.myIndex) {
+                this.props.focus(this.props.Document);
             }
         }
     }
@@ -165,8 +167,8 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
             this.props.Document.viewScale = 1;
         } else {
             this.navButton = false;
-            if (this.currentIndex === this.props.index) {
-                this.props.gotoDocument(this.props.index, this.props.index);
+            if (this.currentIndex === this.myIndex) {
+                this.props.focus(this.props.Document);
             }
         }
     }
@@ -195,17 +197,17 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
         let bounds = this.ScreenToLocalListTransform(rect.left, rect.top + rect.height / 2);
         let before = x[1] < bounds[1];
         if (de.data instanceof DragManager.DocumentDragData) {
-            let addDoc = (doc: Doc) => Doc.AddDocToList(this.props.presentationDoc, "data", doc, this.props.Document, before);
+            let addDoc = (doc: Doc) => Doc.AddDocToList(this.presentationDoc, this.presentationFieldKey, doc, this.props.Document, before);
             e.stopPropagation();
             //where does treeViewId come from
-            let movedDocs = (de.data.options === this.props.presentationDoc[Id] ? de.data.draggedDocuments : de.data.droppedDocuments);
+            let movedDocs = (de.data.options === this.presentationDoc[Id] ? de.data.draggedDocuments : de.data.droppedDocuments);
             //console.log("How is this causing an issue");
             document.removeEventListener("pointermove", this.onDragMove, true);
             return (de.data.dropAction || de.data.userDropAction) ?
-                de.data.droppedDocuments.reduce((added: boolean, d: Doc) => Doc.AddDocToList(this.props.presentationDoc, "data", d, this.props.Document, before) || added, false)
+                de.data.droppedDocuments.reduce((added: boolean, d: Doc) => Doc.AddDocToList(this.presentationDoc, this.presentationFieldKey, d, this.props.Document, before) || added, false)
                 : (de.data.moveDocument) ?
                     movedDocs.reduce((added: boolean, d: Doc) => de.data.moveDocument(d, this.props.Document, addDoc) || added, false)
-                    : de.data.droppedDocuments.reduce((added: boolean, d: Doc) => Doc.AddDocToList(this.props.presentationDoc, "data", d, this.props.Document, before), false);
+                    : de.data.droppedDocuments.reduce((added: boolean, d: Doc) => Doc.AddDocToList(this.presentationDoc, this.presentationFieldKey, d, this.props.Document, before), false);
         }
         document.removeEventListener("pointermove", this.onDragMove, true);
 
@@ -215,7 +217,7 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
     //This is used to add dragging as an event.
     onPointerEnter = (e: React.PointerEvent): void => {
         if (e.buttons === 1 && SelectionManager.GetIsDragging()) {
-            this.header!.className = "presElementBox-item" + (this.currentIndex === this.props.index ? "presElementBox-selected" : "");
+            this.header!.className = "presElementBox-item" + (this.currentIndex === this.myIndex ? "presElementBox-selected" : "");
 
             document.addEventListener("pointermove", this.onDragMove, true);
         }
@@ -223,7 +225,7 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
 
     //This is used to remove the dragging when dropped.
     onPointerLeave = (e: React.PointerEvent): void => {
-        this.header!.className = "presElementBox-item" + (this.currentIndex === this.props.index ? " presElementBox-selected" : "");
+        this.header!.className = "presElementBox-item" + (this.currentIndex === this.myIndex ? " presElementBox-selected" : "");
 
         document.removeEventListener("pointermove", this.onDragMove, true);
     }
@@ -298,18 +300,18 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
     render() {
         let p = this.props;
 
-        let className = "presElementBox-item" + (this.currentIndex === p.index ? " presElementBox-selected" : "");
+        let className = "presElementBox-item" + (this.currentIndex === this.myIndex ? " presElementBox-selected" : "");
         let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
-        let onItemDown = SetupDrag(this.presElRef, () => p.Document, this.move, dropAction, this.props.presentationDoc[Id], true);
+        let onItemDown = SetupDrag(this.presElRef, () => p.Document, this.move, dropAction, this.presentationDoc[Id], true);
         return (
-            <div className={className} key={p.Document[Id] + p.index}
+            <div className={className} key={p.Document[Id] + this.myIndex}
                 ref={this.presElRef}
                 onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}
                 onPointerDown={onItemDown}
                 style={{ outlineWidth: Doc.IsBrushed(p.Document) ? `1px` : "0px", }}
-                onClick={e => p.gotoDocument(p.index, this.currentIndex)}>
+                onClick={e => p.focus(p.Document)}>
                 <strong className="presElementBox-name">
-                    {`${p.index + 1}. ${p.Document.title}`}
+                    {`${this.myIndex + 1}. ${p.Document.title}`}
                 </strong>
                 <button className="presElementBox-icon" onPointerDown={e => e.stopPropagation()} onClick={e => this.props.removeDocument && this.props.removeDocument(p.Document)}>X</button>
                 <br />
-- 
cgit v1.2.3-70-g09d2


From 8790670f8e2173dd2a578500b3f03ad08ef793f2 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 30 Sep 2019 20:56:10 -0400
Subject: switching presentatons to be colllections

---
 .../views/collections/CollectionSchemaView.tsx     |  9 ++-
 .../views/collections/CollectionStackingView.scss  |  2 +-
 .../views/collections/CollectionStackingView.tsx   |  4 +-
 .../views/collections/CollectionTreeView.scss      |  4 +-
 .../views/collections/CollectionTreeView.tsx       | 18 +++---
 src/client/views/collections/CollectionView.tsx    |  8 +--
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 20 +-----
 src/client/views/nodes/PresBox.scss                |  4 +-
 src/client/views/nodes/PresBox.tsx                 | 73 ++++++++++++++--------
 .../views/presentationview/PresElementBox.scss     |  1 +
 .../views/presentationview/PresElementBox.tsx      | 46 +++++++-------
 11 files changed, 101 insertions(+), 88 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 8d931f812..77d86b2fa 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -166,6 +166,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                 width={this.previewWidth}
                 height={this.previewHeight}
                 getTransform={this.getPreviewTransform}
+                CollectionDoc={this.props.CollectionView && this.props.CollectionView.props.Document}
                 CollectionView={this.props.CollectionView}
                 moveDocument={this.props.moveDocument}
                 addDocument={this.props.addDocument}
@@ -906,8 +907,10 @@ interface CollectionSchemaPreviewProps {
     width: () => number;
     height: () => number;
     ruleProvider: Doc | undefined;
+    focus?: (doc: Doc) => void;
     showOverlays?: (doc: Doc) => { title?: string, caption?: string };
     CollectionView?: CollectionView | CollectionPDFView | CollectionVideoView;
+    CollectionDoc?: Doc;
     onClick?: ScriptField;
     getTransform: () => Transform;
     addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -994,7 +997,7 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
                         height: this.props.height(),
                         width: this.props.width()
                     }}>
-                    <DocumentView
+                    <DocumentView {...this.props}
                         DataDoc={this.props.DataDocument}
                         Document={this.props.Document}
                         fitToBox={this.props.fitToBox}
@@ -1006,7 +1009,7 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
                         moveDocument={this.props.moveDocument}
                         whenActiveChanged={this.props.whenActiveChanged}
                         ContainingCollectionView={this.props.CollectionView}
-                        ContainingCollectionDoc={this.props.CollectionView && this.props.CollectionView.props.Document}
+                        ContainingCollectionDoc={this.props.CollectionDoc}
                         addDocTab={this.props.addDocTab}
                         pinToPres={this.props.pinToPres}
                         parentActive={this.props.active}
@@ -1015,7 +1018,7 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
                         ContentScaling={this.contentScaling}
                         PanelWidth={this.PanelWidth}
                         PanelHeight={this.PanelHeight}
-                        focus={emptyFunction}
+                        focus={this.props.focus || emptyFunction}
                         backgroundColor={returnEmptyString}
                         bringToFront={emptyFunction}
                         zoomToScale={emptyFunction}
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 01d4ea2b6..74da4ef85 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -9,7 +9,7 @@
 .collectionStackingView, .collectionMasonryView{
     height: 100%;
     width: 100%;
-    position: absolute;
+    position: relative;
     top: 0;
     overflow-y: auto;
     flex-wrap: wrap;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 1eeb16c4a..6712e8cfe 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -133,7 +133,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     getDisplayDoc(layoutDoc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) {
         let height = () => this.getDocHeight(layoutDoc);
         let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]());
-        return <CollectionSchemaPreview
+        return <CollectionSchemaPreview {...this.props}
             Document={layoutDoc}
             DataDocument={dataDoc}
             showOverlays={this.overlays}
@@ -144,6 +144,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             width={width}
             height={height}
             getTransform={finalDxf}
+            focus={this.props.focus}
+            CollectionDoc={this.props.CollectionView && this.props.CollectionView.props.Document}
             CollectionView={this.props.CollectionView}
             addDocument={this.props.addDocument}
             moveDocument={this.props.moveDocument}
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 197e57808..ab01a1086 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -8,11 +8,11 @@
     box-sizing: border-box;
     height: 100%;
     width:100%;
-    position: absolute;
+    position: relative;
     top:0;
     padding-top: 20px;
     padding-left: 10px;
-    padding-right: 0px;
+    padding-right: 10px;
     background: $light-color-secondary;
     font-size: 13px;
     overflow: auto;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index e5313f68c..a133e2c51 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,12 +1,13 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { faAngleRight, faCamera, faExpand, faTrash, faBell, faCaretDown, faCaretRight, faArrowsAltH, faCaretSquareDown, faCaretSquareRight, faTrashAlt, faPlus, faMinus } from '@fortawesome/free-solid-svg-icons';
+import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faExpand, faMinus, faPlus, faTrash, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, trace, untracked } from "mobx";
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, HeightSym, WidthSym, Opt, Field } from '../../../new_fields/Doc';
+import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
 import { List } from '../../../new_fields/List';
 import { Document, listSpec } from '../../../new_fields/Schema';
+import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
 import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types';
 import { emptyFunction, Utils } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
@@ -17,18 +18,16 @@ import { SelectionManager } from '../../util/SelectionManager';
 import { Transform } from '../../util/Transform';
 import { undoBatch } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
 import { EditableView } from "../EditableView";
 import { MainView } from '../MainView';
+import { KeyValueBox } from '../nodes/KeyValueBox';
 import { Templates } from '../Templates';
 import { CollectionViewType } from './CollectionBaseView';
-import { CollectionDockingView } from './CollectionDockingView';
 import { CollectionSchemaPreview } from './CollectionSchemaView';
 import { CollectionSubView } from "./CollectionSubView";
 import "./CollectionTreeView.scss";
 import React = require("react");
-import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
-import { KeyValueBox } from '../nodes/KeyValueBox';
-import { ContextMenuProps } from '../ContextMenuItem';
 
 
 export interface TreeViewProps {
@@ -250,8 +249,8 @@ class TreeView extends React.Component<TreeViewProps> {
     }
     docWidth = () => {
         let aspect = NumCast(this.props.document.nativeHeight) / NumCast(this.props.document.nativeWidth);
-        if (aspect) return Math.min(this.props.document[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.panelWidth() - 5));
-        return NumCast(this.props.document.nativeWidth) ? Math.min(this.props.document[WidthSym](), this.props.panelWidth() - 5) : this.props.panelWidth() - 5;
+        if (aspect) return Math.min(this.props.document[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.panelWidth() - 20));
+        return NumCast(this.props.document.nativeWidth) ? Math.min(this.props.document[WidthSym](), this.props.panelWidth() - 20) : this.props.panelWidth() - 20;
     }
     docHeight = () => {
         let bounds = this.boundsOfCollectionDocument;
@@ -331,6 +330,7 @@ class TreeView extends React.Component<TreeViewProps> {
                     width={this.docWidth}
                     height={this.docHeight}
                     getTransform={this.docTransform}
+                    CollectionDoc={this.props.containingCollection}
                     CollectionView={undefined}
                     addDocument={emptyFunction as any}
                     moveDocument={this.props.moveDocument}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 90fa00202..6eb444dde 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -1,25 +1,23 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faEye } from '@fortawesome/free-regular-svg-icons';
-import { faColumns, faEllipsisV, faFingerprint, faImage, faProjectDiagram, faSignature, faSquare, faTh, faThList, faTree, faCopy } from '@fortawesome/free-solid-svg-icons';
+import { faColumns, faCopy, faEllipsisV, faFingerprint, faImage, faProjectDiagram, faSignature, faSquare, faTh, faThList, faTree } from '@fortawesome/free-solid-svg-icons';
 import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
 import { observer } from "mobx-react";
 import * as React from 'react';
-import { Doc, DocListCastAsync } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
-import { StrCast, Cast } from '../../../new_fields/Types';
+import { StrCast } from '../../../new_fields/Types';
 import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from '../ContextMenuItem';
 import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import { CollectionBaseView, CollectionRenderProps, CollectionViewType } from './CollectionBaseView';
 import { CollectionDockingView } from "./CollectionDockingView";
+import { AddCustomFreeFormLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import { CollectionSchemaView } from "./CollectionSchemaView";
 import { CollectionStackingView } from './CollectionStackingView';
 import { CollectionTreeView } from "./CollectionTreeView";
 import { CollectionViewBaseChrome } from './CollectionViewChromes';
-import { ImageField } from '../../../new_fields/URLField';
-import { AddCustomFreeFormLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
 export const COLLECTION_BORDER_WIDTH = 2;
 
 library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index a9699d17b..6fc809f7f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -443,11 +443,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps {
         return {
+            ...this.props,
             DataDoc: childData,
             Document: childLayout,
-            addDocument: this.props.addDocument,
-            removeDocument: this.props.removeDocument,
-            moveDocument: this.props.moveDocument,
             ruleProvider: this.Document.isRuleProvider && childLayout.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider, //bcz: hack! - currently ruleProviders apply to documents in nested colleciton, not direct children of themselves
             onClick: undefined, // this.props.onClick,  // bcz: check this out -- I don't think we want to inherit click handlers, or we at least need a way to ignore them
             ScreenToLocalTransform: childLayout.z ? this.getTransformOverlay : this.getTransform,
@@ -460,37 +458,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             focus: this.focusDocument,
             backgroundColor: this.getClusterColor,
             parentActive: this.props.active,
-            whenActiveChanged: this.props.whenActiveChanged,
             bringToFront: this.bringToFront,
-            addDocTab: this.props.addDocTab,
-            pinToPres: this.props.pinToPres,
             zoomToScale: this.zoomToScale,
             getScale: this.getScale
         };
     }
     getDocumentViewProps(layoutDoc: Doc): DocumentViewProps {
         return {
-            DataDoc: this.props.DataDoc,
-            Document: this.props.Document,
-            addDocument: this.props.addDocument,
-            removeDocument: this.props.removeDocument,
-            moveDocument: this.props.moveDocument,
-            ruleProvider: this.props.ruleProvider,
-            onClick: this.props.onClick,
+            ...this.props,
             ScreenToLocalTransform: this.getTransform,
-            renderDepth: this.props.renderDepth,
             PanelWidth: layoutDoc[WidthSym],
             PanelHeight: layoutDoc[HeightSym],
             ContentScaling: returnOne,
             ContainingCollectionView: this.props.CollectionView,
-            ContainingCollectionDoc: this.props.ContainingCollectionDoc,
             focus: this.focusDocument,
             backgroundColor: returnEmptyString,
             parentActive: this.props.active,
-            whenActiveChanged: this.props.whenActiveChanged,
             bringToFront: this.bringToFront,
-            addDocTab: this.props.addDocTab,
-            pinToPres: this.props.pinToPres,
             zoomToScale: this.zoomToScale,
             getScale: this.getScale
         };
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 2aadd77aa..e5a79ab11 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -15,6 +15,7 @@
     pointer-events: all;
 
     .presBox-listCont {
+        position: relative;
         padding-left: 10px;
         padding-right: 10px;
     }
@@ -29,5 +30,4 @@
             border-radius: 5px;
         }
     }
-}
-
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index d3a24eb7a..ab777d534 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -2,7 +2,7 @@ import React = require("react");
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faArrowLeft, faArrowRight, faEdit, faMinus, faPlay, faPlus, faStop, faTimes } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, observable, runInAction, computed } from "mobx";
+import { action, computed, reaction, IReactionDisposer } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
 import { listSpec } from "../../../new_fields/Schema";
@@ -10,12 +10,15 @@ import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
 import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
 import { DocumentManager } from "../../util/DocumentManager";
 import { undoBatch } from "../../util/UndoManager";
+import { CollectionViewType } from "../collections/CollectionBaseView";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
+import { CollectionView } from "../collections/CollectionView";
 import { ContextMenu } from "../ContextMenu";
-import "./PresBox.scss";
 import { FieldView, FieldViewProps } from './FieldView';
-import { PresElementBox } from "../presentationview/PresElementBox";
-import { Id } from "../../../new_fields/FieldSymbols";
+import "./PresBox.scss";
+import { DocumentType } from "../../documents/DocumentTypes";
+import { Docs } from "../../documents/Documents";
+import { ComputedField } from "../../../new_fields/ScriptField";
 
 library.add(faArrowLeft);
 library.add(faArrowRight);
@@ -29,6 +32,29 @@ library.add(faEdit);
 @observer
 export class PresBox extends React.Component<FieldViewProps> {
     public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(PresBox, fieldKey); }
+    _docListChangedReaction: IReactionDisposer | undefined;
+    componentDidMount() {
+        this._docListChangedReaction = reaction(() => {
+            const value = FieldValue(Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)));
+            return value ? value.slice() : value;
+        }, () => {
+            const value = FieldValue(Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)));
+            if (value) {
+                value.forEach((item, i) => {
+                    if (item instanceof Doc && item.type !== DocumentType.PRESELEMENT) {
+                        let pinDoc = Docs.Create.PresElementBoxDocument();
+                        Doc.GetProto(pinDoc).target = item;
+                        Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
+                        value.splice(i, 1, pinDoc);
+                    }
+                })
+            }
+        });
+    }
+
+    componentWillUnmount() {
+        this._docListChangedReaction && this._docListChangedReaction();
+    }
 
     @computed get childDocs() { return DocListCast(this.props.Document[this.props.fieldKey]); }
 
@@ -275,20 +301,14 @@ export class PresBox extends React.Component<FieldViewProps> {
     //directly at start.
     startPresentation = (startIndex: number) => {
         this.childDocs.map(doc => {
-            if (doc.hideTillShownButton) {
-                if (this.childDocs.indexOf(doc) > startIndex) {
-                    doc.opacity = 0;
-                }
+            if (doc.hideTillShownButton && this.childDocs.indexOf(doc) > startIndex) {
+                doc.opacity = 0;
             }
-            if (doc.hideAfterButton) {
-                if (this.childDocs.indexOf(doc) < startIndex) {
-                    doc.opacity = 0;
-                }
+            if (doc.hideAfterButton && this.childDocs.indexOf(doc) < startIndex) {
+                doc.opacity = 0;
             }
-            if (doc.fadeButton) {
-                if (this.childDocs.indexOf(doc) < startIndex) {
-                    doc.opacity = 0.5;
-                }
+            if (doc.fadeButton && this.childDocs.indexOf(doc) < startIndex) {
+                doc.opacity = 0.5;
             }
         });
     }
@@ -316,8 +336,13 @@ export class PresBox extends React.Component<FieldViewProps> {
      * that they will be displayed in a canvas with scale 1.
      */
     @action
-    initializeScaleViews = (docList: Doc[]) => {
+    initializeScaleViews = (docList: Doc[], viewtype: number) => {
+        this.props.Document.chromeStatus = "disabled";
+        let hgt = (viewtype === CollectionViewType.Tree) ? 50 : 72;
         docList.forEach((doc: Doc) => {
+            doc.presBox = this.props.Document;
+            doc.presBoxKey = this.props.fieldKey;
+            doc.height = hgt;
             let curScale = NumCast(doc.viewScale, null);
             if (curScale === undefined) {
                 doc.viewScale = 1;
@@ -325,13 +350,14 @@ export class PresBox extends React.Component<FieldViewProps> {
         });
     }
 
+
     selectElement = (doc: Doc) => {
         let index = DocListCast(this.props.Document[this.props.fieldKey]).indexOf(doc);
         index !== -1 && this.gotoDocument(index, NumCast(this.props.Document.selectedDoc));
     }
 
     render() {
-        this.initializeScaleViews(this.childDocs);
+        this.initializeScaleViews(this.childDocs, NumCast(this.props.Document.viewType));
         return (
             <div className="presBox-cont" onContextMenu={this.specificContextMenu}>
                 <div className="presBox-buttons">
@@ -344,14 +370,9 @@ export class PresBox extends React.Component<FieldViewProps> {
                 </div>
                 {this.props.Document.minimizedView ? (null) :
                     <div className="presBox-listCont" >
-                        {this.childDocs.map(doc =>
-                            <PresElementBox key={doc[Id]}  {... this.props} Document={doc}
-                                removeDocument={this.removeDocument}
-                                focus={this.selectElement}
-                                presBox={this}
-                            />
-                        )}
-                    </div>}
+                        <CollectionView {...this.props} focus={this.selectElement} />
+                    </div>
+                }
             </div>
         );
     }
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index c7d846718..51f2d2ab8 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -1,6 +1,7 @@
 .presElementBox-item {
     padding: 10px;
     display: inline-block;
+    pointer-events: all;
     width: 100%;
     outline-color: maroon;
     outline-style: dashed;
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 1b4c841e7..7692800c3 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -12,11 +12,11 @@ import { DocumentType } from "../../documents/DocumentTypes";
 import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
+import { CollectionViewType } from '../collections/CollectionBaseView';
 import { DocumentView } from "../nodes/DocumentView";
-import React = require("react");
+import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import "./PresElementBox.scss";
-import { FieldViewProps, FieldView } from '../nodes/FieldView';
-import { PresBox } from '../nodes/PresBox';
+import React = require("react");
 
 
 library.add(faArrowUp);
@@ -25,26 +25,22 @@ library.add(faLocationArrow);
 library.add(fileRegular as any);
 library.add(faSearch);
 library.add(faArrowDown);
-
-interface PresElementProps {
-    presBox: PresBox;
-}
-
 /**
  * This class models the view a document added to presentation will have in the presentation.
  * It involves some functionality for its buttons and options.
  */
 @observer
-export class PresElementBox extends React.Component<PresElementProps & FieldViewProps> {
+export class PresElementBox extends React.Component<FieldViewProps> {
 
     public static LayoutString() { return FieldView.LayoutString(PresElementBox); }
     private header?: HTMLDivElement | undefined;
     private listdropDisposer?: DragManager.DragDropDisposer;
     private presElRef: React.RefObject<HTMLDivElement> = React.createRef();
+    private _embedHeight = 100;
 
-    @computed get myIndex() { return DocListCast(this.props.presBox.props.Document[this.props.presBox.props.fieldKey]).indexOf(this.props.Document) }
-    @computed get presentationDoc() { return this.props.presBox.props.Document; }
-    @computed get presentationFieldKey() { return this.props.presBox.props.fieldKey; }
+    @computed get myIndex() { return DocListCast(this.presentationDoc[this.presentationFieldKey]).indexOf(this.props.Document); }
+    @computed get presentationDoc() { return this.props.Document.presBox as Doc; }
+    @computed get presentationFieldKey() { return StrCast(this.props.Document.presBoxKey); }
     @computed get currentIndex() { return NumCast(this.presentationDoc.selectedDoc); }
     @computed get showButton() { return BoolCast(this.props.Document.showButton); }
     @computed get navButton() { return BoolCast(this.props.Document.navButton); }
@@ -266,12 +262,12 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
         let scale = () => 175 / NumCast(this.props.Document.nativeWidth, 175);
         return (
             <div className="presElementBox-embedded" style={{
-                height: propDocHeight === 0 ? 100 : propDocHeight * scale(),
+                height: propDocHeight === 0 ? this._embedHeight : propDocHeight * scale(),
                 width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
             }}>
                 <DocumentView
                     fitToBox={StrCast(this.props.Document.type).indexOf(DocumentType.COL) !== -1}
-                    Document={this.props.Document.target as Doc}
+                    Document={this.props.Document.target}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
                     ruleProvider={undefined}
@@ -300,6 +296,7 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
     render() {
         let p = this.props;
 
+        let treecontainer = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.viewType === CollectionViewType.Tree;
         let className = "presElementBox-item" + (this.currentIndex === this.myIndex ? " presElementBox-selected" : "");
         let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
         let onItemDown = SetupDrag(this.presElRef, () => p.Document, this.move, dropAction, this.presentationDoc[Id], true);
@@ -310,18 +307,25 @@ export class PresElementBox extends React.Component<PresElementProps & FieldView
                 onPointerDown={onItemDown}
                 style={{ outlineWidth: Doc.IsBrushed(p.Document) ? `1px` : "0px", }}
                 onClick={e => p.focus(p.Document)}>
-                <strong className="presElementBox-name">
-                    {`${this.myIndex + 1}. ${p.Document.title}`}
-                </strong>
-                <button className="presElementBox-icon" onPointerDown={e => e.stopPropagation()} onClick={e => this.props.removeDocument && this.props.removeDocument(p.Document)}>X</button>
-                <br />
+                {treecontainer ? (null) : <>
+                    <strong className="presElementBox-name">
+                        {`${this.myIndex + 1}. ${p.Document.title}`}
+                    </strong>
+                    <button className="presElementBox-icon" onPointerDown={e => e.stopPropagation()} onClick={e => this.props.removeDocument && this.props.removeDocument(p.Document)}>X</button>
+                    <br />
+                </>
+                }
                 <button title="Zoom" className={"presElementBox-interaction" + (this.showButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} /></button>
                 <button title="Navigate" className={"presElementBox-interaction" + (this.navButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} /></button>
                 <button title="Hide Til Presented" className={"presElementBox-interaction" + (this.hideTillShownButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={fileSolid} /></button>
                 <button title="Fade After Presented" className={"presElementBox-interaction" + (this.fadeButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
                 <button title="Hide After Presented" className={"presElementBox-interaction" + (this.hideAfterButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
-                <button title="Group With Up" className={"presElementBox-interaction" + (this.groupButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action(() => this.groupButton = !this.groupButton)}> <FontAwesomeIcon icon={"arrow-up"} /> </button>
-                <button title="Expand Inline" className={"presElementBox-interaction" + (this.embedInline ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action(() => this.embedInline = !this.embedInline)}><FontAwesomeIcon icon={"arrow-down"} /></button>
+                <button title="Group With Up" className={"presElementBox-interaction" + (this.groupButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action((e: any) => { e.stopPropagation(); this.groupButton = !this.groupButton; })}> <FontAwesomeIcon icon={"arrow-up"} /> </button>
+                <button title="Expand Inline" className={"presElementBox-interaction" + (this.embedInline ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action((e: any) => {
+                    this.embedInline = !this.embedInline;
+                    this.props.Document.height = NumCast(this.props.Document.height) + (this.embedInline ? 1 : -1) * this._embedHeight;
+                    e.stopPropagation();
+                })}><FontAwesomeIcon icon={"arrow-down"} /></button>
 
                 <br />
                 {this.renderEmbeddedInline()}
-- 
cgit v1.2.3-70-g09d2


From 2a393bd745667fa920d105bf69827c75dc687f08 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 1 Oct 2019 01:33:57 -0400
Subject: final updates to presentation view to improve layout. fixes for
 chromeHeight

---
 .../views/collections/CollectionDockingView.tsx    |  2 +-
 .../views/collections/CollectionStackingView.tsx   |  6 ++--
 .../views/collections/CollectionTreeView.tsx       |  2 +-
 src/client/views/collections/CollectionView.tsx    | 19 +++++++----
 .../views/collections/CollectionViewChromes.tsx    |  3 +-
 src/client/views/nodes/PresBox.tsx                 | 10 ++++--
 .../views/presentationview/PresElementBox.scss     | 14 ++++++--
 .../views/presentationview/PresElementBox.tsx      | 38 ++++++++++------------
 8 files changed, 52 insertions(+), 42 deletions(-)

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

diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index d83530d4f..246546c9e 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -573,7 +573,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         //add this new doc to props.Document
         let curPres = Cast(CurrentUserUtils.UserDocument.curPresentation, Doc) as Doc;
         if (curPres) {
-            let pinDoc = Docs.Create.PresElementBoxDocument();
+            let pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
             Doc.GetProto(pinDoc).target = doc;
             Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
             const data = Cast(curPres.data, listSpec(Doc));
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index cb272ef1c..c7060f110 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -203,9 +203,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @undoBatch
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        // bcz: this is here for now to account for the presentation stacking view being offset from the document top in PresBox's.  Should generalize this somehow.
-        let offsethack = Number(this._masonryGridRef && this._masonryGridRef.parentElement!.parentElement!.offsetTop);
-        let where = [de.x, de.y - offsethack];
+        let where = [de.x, de.y];
         let targInd = -1;
         let plusOne = false;
         if (de.data instanceof DragManager.DocumentDragData) {
@@ -285,7 +283,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         let outerXf = Utils.GetScreenTransform(this._masonryGridRef!);
         let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
         return this.props.ScreenToLocalTransform().
-            translate(offset[0], offset[1]).
+            translate(offset[0], offset[1] + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0)).
             scale(NumCast(doc.width, 1) / this.columnWidth);
     }
     masonryChildren(docs: Doc[]) {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index a133e2c51..6ce5d8e20 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -81,7 +81,7 @@ class TreeView extends React.Component<TreeViewProps> {
     private _header?: React.RefObject<HTMLDivElement> = React.createRef();
     private _treedropDisposer?: DragManager.DragDropDisposer;
     private _dref = React.createRef<HTMLDivElement>();
-    get defaultExpandedView() { return this.childDocs ? this.fieldKey : "fields"; }
+    get defaultExpandedView() { return this.childDocs ? this.fieldKey : this.props.document.defaultExpandedView ? StrCast(this.props.document.defaultExpandedView) : ""; }
     @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
     @computed get treeViewOpen() { return (BoolCast(this.props.document.treeViewOpen) && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; }
     set treeViewOpen(c: boolean) { if (this.props.preventTreeViewOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = c; }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 6eb444dde..534246326 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -50,20 +50,25 @@ export class CollectionView extends React.Component<FieldViewProps> {
         this._reactionDisposer && this._reactionDisposer();
     }
 
+    // bcz: Argh?  What's the height of the collection chomes??  
+    chromeHeight = () => {
+        return (this.props.ChromeHeight ? this.props.ChromeHeight() : 0) + (this.props.Document.chromeStatus === "enabled" ? -60 : 0);
+    }
+
     private SubViewHelper = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
         let props = { ...this.props, ...renderProps };
         switch (this.isAnnotationOverlay ? CollectionViewType.Freeform : type) {
-            case CollectionViewType.Schema: return (<CollectionSchemaView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
+            case CollectionViewType.Schema: return (<CollectionSchemaView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />);
             // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip
-            case CollectionViewType.Docking: return (<CollectionDockingView chromeCollapsed={true} key="collview" {...props} CollectionView={this} />);
-            case CollectionViewType.Tree: return (<CollectionTreeView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
-            case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />); }
-            case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />); }
-            case CollectionViewType.Pivot: { this.props.Document.freeformLayoutEngine = "pivot"; return (<CollectionFreeFormView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />); }
+            case CollectionViewType.Docking: return (<CollectionDockingView chromeCollapsed={true} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />);
+            case CollectionViewType.Tree: return (<CollectionTreeView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />);
+            case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />); }
+            case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />); }
+            case CollectionViewType.Pivot: { this.props.Document.freeformLayoutEngine = "pivot"; return (<CollectionFreeFormView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />); }
             case CollectionViewType.Freeform:
             default:
                 this.props.Document.freeformLayoutEngine = undefined;
-                return (<CollectionFreeFormView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
+                return (<CollectionFreeFormView chromeCollapsed={this._collapsed} key="collview" {...props} ChromeHeight={this.chromeHeight} CollectionView={this} />);
         }
         return (null);
     }
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 47b300efc..23001f0f5 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -10,7 +10,6 @@ import { ScriptField } from "../../../new_fields/ScriptField";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import { Utils, emptyFunction } from "../../../Utils";
 import { DragManager } from "../../util/DragManager";
-import { CompileScript } from "../../util/Scripting";
 import { undoBatch } from "../../util/UndoManager";
 import { EditableView } from "../EditableView";
 import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
@@ -375,7 +374,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     render() {
         let collapsed = this.props.CollectionView.props.Document.chromeStatus !== "enabled";
         return (
-            <div className="collectionViewChrome-cont" style={{ top: collapsed ? -70 : 0 }}>
+            <div className="collectionViewChrome-cont" style={{ top: collapsed ? -70 : 0, height: collapsed ? 0 : undefined }}>
                 <div className="collectionViewChrome">
                     <div className="collectionViewBaseChrome">
                         <button className="collectionViewBaseChrome-collapse"
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index ab777d534..66608fb8d 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -42,7 +42,7 @@ export class PresBox extends React.Component<FieldViewProps> {
             if (value) {
                 value.forEach((item, i) => {
                     if (item instanceof Doc && item.type !== DocumentType.PRESELEMENT) {
-                        let pinDoc = Docs.Create.PresElementBoxDocument();
+                        let pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
                         Doc.GetProto(pinDoc).target = item;
                         Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
                         value.splice(i, 1, pinDoc);
@@ -342,7 +342,8 @@ export class PresBox extends React.Component<FieldViewProps> {
         docList.forEach((doc: Doc) => {
             doc.presBox = this.props.Document;
             doc.presBoxKey = this.props.fieldKey;
-            doc.height = hgt;
+            doc.collapsedHeight = hgt;
+            doc.height = ComputedField.MakeFunction("this.collapsedHeight + Number(this.embedOpen ? 100:0)")
             let curScale = NumCast(doc.viewScale, null);
             if (curScale === undefined) {
                 doc.viewScale = 1;
@@ -356,6 +357,9 @@ export class PresBox extends React.Component<FieldViewProps> {
         index !== -1 && this.gotoDocument(index, NumCast(this.props.Document.selectedDoc));
     }
 
+    getTransform = () => {
+        return this.props.ScreenToLocalTransform().translate(-10, -50);// listBox padding-left and pres-box-cont minHeight
+    }
     render() {
         this.initializeScaleViews(this.childDocs, NumCast(this.props.Document.viewType));
         return (
@@ -370,7 +374,7 @@ export class PresBox extends React.Component<FieldViewProps> {
                 </div>
                 {this.props.Document.minimizedView ? (null) :
                     <div className="presBox-listCont" >
-                        <CollectionView {...this.props} focus={this.selectElement} />
+                        <CollectionView {...this.props} focus={this.selectElement} ScreenToLocalTransform={this.getTransform} />
                     </div>
                 }
             </div>
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 51f2d2ab8..34c170be2 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -1,10 +1,12 @@
 .presElementBox-item {
     padding: 10px;
     display: inline-block;
+    background-color: #eeeeee;
     pointer-events: all;
     width: 100%;
     outline-color: maroon;
     outline-style: dashed;
+    border-radius: 12px;
     -webkit-touch-callout: none;
     -webkit-user-select: none;
     -khtml-user-select: none;
@@ -40,9 +42,10 @@
     box-shadow: black 2px 2px 5px;
 }
 
-
-.presElementBox-icon {
+.presElementBox-closeIcon {
     float: right;
+    border-radius: 20px;
+    transform:scale(0.7);
 }
 
 .presElementBox-interaction {
@@ -57,12 +60,17 @@
 
 .presElementBox-name {
     font-size: 15px;
+    position: absolute;
     display: inline-block;
+    width: calc(100% - 45px);
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: pre;
 }
 
 .presElementBox-embedded {
     position: relative;
-    margin-top: 15;
+    margin-top: 30;
 }
 
 .presElementBox-embeddedMask {
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 0e3d8bb7f..fb9474cde 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -31,7 +31,6 @@ library.add(faArrowDown);
 export class PresElementBox extends React.Component<FieldViewProps> {
 
     public static LayoutString() { return FieldView.LayoutString(PresElementBox); }
-    private _embedHeight = 100;
 
     @computed get myIndex() { return DocListCast(this.presentationDoc[this.presentationFieldKey]).indexOf(this.props.Document); }
     @computed get presentationDoc() { return this.props.Document.presBox as Doc; }
@@ -43,9 +42,9 @@ export class PresElementBox extends React.Component<FieldViewProps> {
     @computed get fadeButton() { return BoolCast(this.props.Document.fadeButton); }
     @computed get hideAfterButton() { return BoolCast(this.props.Document.hideAfterButton); }
     @computed get groupButton() { return BoolCast(this.props.Document.groupButton); }
-    @computed get embedInline() { return BoolCast(this.props.Document.embedOpen); }
+    @computed get embedOpen() { return BoolCast(this.props.Document.embedOpen); }
 
-    set embedInline(value: boolean) { this.props.Document.embedOpen = value; }
+    set embedOpen(value: boolean) { this.props.Document.embedOpen = value; }
     set showButton(val: boolean) { this.props.Document.showButton = val; }
     set navButton(val: boolean) { this.props.Document.navButton = val; }
     set hideTillShownButton(val: boolean) { this.props.Document.hideTillShownButton = val; }
@@ -162,7 +161,7 @@ export class PresElementBox extends React.Component<FieldViewProps> {
      * presentation element.
      */
     renderEmbeddedInline = () => {
-        if (!this.embedInline || !(this.props.Document.target instanceof Doc)) {
+        if (!this.embedOpen || !(this.props.Document.target instanceof Doc)) {
             return (null);
         }
 
@@ -171,7 +170,7 @@ export class PresElementBox extends React.Component<FieldViewProps> {
         let scale = () => 175 / NumCast(this.props.Document.nativeWidth, 175);
         return (
             <div className="presElementBox-embedded" style={{
-                height: propDocHeight === 0 ? this._embedHeight : propDocHeight * scale(),
+                height: propDocHeight === 0 ? NumCast(this.props.Document.height) - NumCast(this.props.Document.collapsedHeight) : propDocHeight * scale(),
                 width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
             }}>
                 <DocumentView
@@ -207,31 +206,28 @@ export class PresElementBox extends React.Component<FieldViewProps> {
 
         let treecontainer = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.viewType === CollectionViewType.Tree;
         let className = "presElementBox-item" + (this.currentIndex === this.myIndex ? " presElementBox-selected" : "");
+        let pbi = "presElementBox-interaction";
         return (
             <div className={className} key={p.Document[Id] + this.myIndex}
-                style={{ outlineWidth: Doc.IsBrushed(p.Document) ? `1px` : "0px", }}
-                onClick={e => p.focus(p.Document)}>
+                style={{ outlineWidth: Doc.IsBrushed(p.Document.target as Doc) ? `1px` : "0px", }}
+                onClick={e => { p.focus(p.Document); e.stopPropagation(); }}>
                 {treecontainer ? (null) : <>
                     <strong className="presElementBox-name">
                         {`${this.myIndex + 1}. ${p.Document.title}`}
                     </strong>
-                    <button className="presElementBox-icon" onPointerDown={e => e.stopPropagation()} onClick={e => this.props.removeDocument && this.props.removeDocument(p.Document)}>X</button>
+                    <button className="presElementBox-closeIcon" onPointerDown={e => e.stopPropagation()} onClick={e => this.props.removeDocument && this.props.removeDocument(p.Document)}>X</button>
                     <br />
                 </>
                 }
-                <button title="Zoom" className={"presElementBox-interaction" + (this.showButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} /></button>
-                <button title="Navigate" className={"presElementBox-interaction" + (this.navButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} /></button>
-                <button title="Hide Til Presented" className={"presElementBox-interaction" + (this.hideTillShownButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={fileSolid} /></button>
-                <button title="Fade After Presented" className={"presElementBox-interaction" + (this.fadeButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
-                <button title="Hide After Presented" className={"presElementBox-interaction" + (this.hideAfterButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
-                <button title="Group With Up" className={"presElementBox-interaction" + (this.groupButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action((e: any) => { e.stopPropagation(); this.groupButton = !this.groupButton; })}> <FontAwesomeIcon icon={"arrow-up"} /> </button>
-                <button title="Expand Inline" className={"presElementBox-interaction" + (this.embedInline ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action((e: any) => {
-                    this.embedInline = !this.embedInline;
-                    this.props.Document.height = NumCast(this.props.Document.height) + (this.embedInline ? 1 : -1) * this._embedHeight;
-                    e.stopPropagation();
-                })}><FontAwesomeIcon icon={"arrow-down"} /></button>
-
-                <br />
+                <button title="Zoom" className={pbi + (this.showButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} /></button>
+                <button title="Navigate" className={pbi + (this.navButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} /></button>
+                <button title="Hide Before" className={pbi + (this.hideTillShownButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={fileSolid} /></button>
+                <button title="Fade After" className={pbi + (this.fadeButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onFadeDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
+                <button title="Hide After" className={pbi + (this.hideAfterButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={faFileDownload} /></button>
+                <button title="Group With Up" className={pbi + (this.groupButton ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action((e: any) => { e.stopPropagation(); this.groupButton = !this.groupButton; })}><FontAwesomeIcon icon={"arrow-up"} /></button>
+                <button title="Expand Inline" className={pbi + (this.embedOpen ? "-selected" : "")} onPointerDown={(e) => e.stopPropagation()} onClick={action((e: any) => { e.stopPropagation(); this.embedOpen = !this.embedOpen; })}><FontAwesomeIcon icon={"arrow-down"} /></button>
+
+                <br style={{ lineHeight: 0.1 }} />
                 {this.renderEmbeddedInline()}
             </div>
         );
-- 
cgit v1.2.3-70-g09d2


From 9e1234abe64d289927122ad641e3bcaf0b9eaf6e Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 1 Oct 2019 02:54:03 -0400
Subject: bugs, bugs.  this time with fittobox when called from schema view
 which was passing width and height as functions, not values.  switched to
 PanelWidth and PanelHeight

---
 .../views/collections/CollectionSchemaView.tsx     | 32 +++++++++++-----------
 .../views/collections/CollectionStackingView.tsx   |  4 +--
 .../views/collections/CollectionTreeView.tsx       |  4 +--
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  4 +--
 src/client/views/nodes/PresBox.tsx                 |  4 +--
 .../views/presentationview/PresElementBox.tsx      | 22 ++++++---------
 6 files changed, 33 insertions(+), 37 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 77d86b2fa..59cce7386 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -163,8 +163,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                 childDocs={this.childDocs}
                 renderDepth={this.props.renderDepth}
                 ruleProvider={this.props.Document.isRuleProvider && layoutDoc && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
-                width={this.previewWidth}
-                height={this.previewHeight}
+                PanelWidth={this.previewWidth}
+                PanelHeight={this.previewHeight}
                 getTransform={this.getPreviewTransform}
                 CollectionDoc={this.props.CollectionView && this.props.CollectionView.props.Document}
                 CollectionView={this.props.CollectionView}
@@ -904,8 +904,8 @@ interface CollectionSchemaPreviewProps {
     childDocs?: Doc[];
     renderDepth: number;
     fitToBox?: boolean;
-    width: () => number;
-    height: () => number;
+    PanelWidth: () => number;
+    PanelHeight: () => number;
     ruleProvider: Doc | undefined;
     focus?: (doc: Doc) => void;
     showOverlays?: (doc: Doc) => { title?: string, caption?: string };
@@ -928,12 +928,12 @@ interface CollectionSchemaPreviewProps {
 export class CollectionSchemaPreview extends React.Component<CollectionSchemaPreviewProps>{
     private dropDisposer?: DragManager.DragDropDisposer;
     _mainCont?: HTMLDivElement;
-    private get nativeWidth() { return NumCast(this.props.Document!.nativeWidth, this.props.width()); }
-    private get nativeHeight() { return NumCast(this.props.Document!.nativeHeight, this.props.height()); }
+    private get nativeWidth() { return NumCast(this.props.Document!.nativeWidth, this.props.PanelWidth()); }
+    private get nativeHeight() { return NumCast(this.props.Document!.nativeHeight, this.props.PanelHeight()); }
     private contentScaling = () => {
-        let wscale = this.props.width() / (this.nativeWidth ? this.nativeWidth : this.props.width());
-        if (wscale * this.nativeHeight > this.props.height()) {
-            return this.props.height() / (this.nativeHeight ? this.nativeHeight : this.props.height());
+        let wscale = this.props.PanelWidth() / (this.nativeWidth ? this.nativeWidth : this.props.PanelWidth());
+        if (wscale * this.nativeHeight > this.props.PanelHeight()) {
+            return this.props.PanelHeight() / (this.nativeHeight ? this.nativeHeight : this.props.PanelHeight());
         }
         return wscale;
     }
@@ -962,10 +962,10 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
         }
         return true;
     }
-    private PanelWidth = () => this.nativeWidth ? this.nativeWidth * this.contentScaling() : this.props.width();
-    private PanelHeight = () => this.nativeHeight ? this.nativeHeight * this.contentScaling() : this.props.height();
+    private PanelWidth = () => this.nativeWidth ? this.nativeWidth * this.contentScaling() : this.props.PanelWidth();
+    private PanelHeight = () => this.nativeHeight ? this.nativeHeight * this.contentScaling() : this.props.PanelHeight();
     private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, 0).scale(1 / this.contentScaling());
-    get centeringOffset() { return this.nativeWidth ? (this.props.width() - this.nativeWidth * this.contentScaling()) / 2 : 0; }
+    get centeringOffset() { return this.nativeWidth ? (this.props.PanelWidth() - this.nativeWidth * this.contentScaling()) / 2 : 0; }
     @action
     onPreviewScriptChange = (e: React.ChangeEvent<HTMLInputElement>) => {
         this.props.setPreviewScript(e.currentTarget.value);
@@ -987,15 +987,15 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
             <div ref={this.createTarget}><input className="collectionSchemaView-input" value={this.props.previewScript} onChange={this.onPreviewScriptChange}
                 style={{ left: `calc(50% - ${Math.min(75, (this.props.Document ? this.PanelWidth() / 2 : 75))}px)` }} /></div>;
         return (<div className="collectionSchemaView-previewRegion"
-            style={{ width: this.props.width(), height: this.props.height() }}>
-            {!this.props.Document || !this.props.width ? (null) : (
+            style={{ width: this.props.PanelWidth(), height: this.props.PanelHeight() }}>
+            {!this.props.Document || !this.props.PanelWidth ? (null) : (
                 <div className="collectionSchemaView-previewDoc"
                     style={{
                         transform: `translate(${this.centeringOffset}px, 0px)`,
                         borderRadius: this.borderRounding,
                         display: "inline",
-                        height: this.props.height(),
-                        width: this.props.width()
+                        height: this.props.PanelHeight(),
+                        width: this.props.PanelWidth()
                     }}>
                     <DocumentView {...this.props}
                         DataDoc={this.props.DataDocument}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index c7060f110..e2020601b 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -141,8 +141,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             ruleProvider={this.props.Document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
             fitToBox={this.props.fitToBox}
             onClick={layoutDoc.isTemplate ? this.onClickHandler : this.onChildClickHandler}
-            width={width}
-            height={height}
+            PanelWidth={width}
+            PanelHeight={height}
             getTransform={finalDxf}
             focus={this.props.focus}
             CollectionDoc={this.props.CollectionView && this.props.CollectionView.props.Document}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 6ce5d8e20..ffd1f9170 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -327,8 +327,8 @@ class TreeView extends React.Component<TreeViewProps> {
                     showOverlays={this.noOverlays}
                     ruleProvider={this.props.document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.document : this.props.ruleProvider}
                     fitToBox={this.boundsOfCollectionDocument !== undefined}
-                    width={this.docWidth}
-                    height={this.docHeight}
+                    PanelWidth={this.docWidth}
+                    PanelHeight={this.docHeight}
                     getTransform={this.docTransform}
                     CollectionDoc={this.props.containingCollection}
                     CollectionView={undefined}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 6fc809f7f..27b9a06f5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -745,8 +745,8 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
         const ceny = this.props.centeringShiftY();
         const panx = -this.props.panX();
         const pany = -this.props.panY();
-        const zoom = this.props.zoomScaling();// needs to be a variable outside of the <Measure> otherwise, reactions won't fire
-        return <div className={freeformclass} style={{ borderRadius: "inherit", transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}, ${zoom}) translate(${panx}px, ${pany}px)` }}>
+        const zoom = this.props.zoomScaling();
+        return <div className={freeformclass} style={{ borderRadius: "inherit", transform: `translate(${cenx}px, ${ceny}px) scale(${zoom}) translate(${panx}px, ${pany}px)` }}>
             {this.props.children}
         </div>;
     }
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 66608fb8d..f44ca99b9 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -47,7 +47,7 @@ export class PresBox extends React.Component<FieldViewProps> {
                         Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
                         value.splice(i, 1, pinDoc);
                     }
-                })
+                });
             }
         });
     }
@@ -343,7 +343,7 @@ export class PresBox extends React.Component<FieldViewProps> {
             doc.presBox = this.props.Document;
             doc.presBoxKey = this.props.fieldKey;
             doc.collapsedHeight = hgt;
-            doc.height = ComputedField.MakeFunction("this.collapsedHeight + Number(this.embedOpen ? 100:0)")
+            doc.height = ComputedField.MakeFunction("this.collapsedHeight + Number(this.embedOpen ? 100:0)");
             let curScale = NumCast(doc.viewScale, null);
             if (curScale === undefined) {
                 doc.viewScale = 1;
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index fb9474cde..de3242d32 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -15,6 +15,7 @@ import { DocumentView } from "../nodes/DocumentView";
 import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import "./PresElementBox.scss";
 import React = require("react");
+import { CollectionSchemaPreview } from '../collections/CollectionSchemaView';
 
 
 library.add(faArrowUp);
@@ -173,28 +174,23 @@ export class PresElementBox extends React.Component<FieldViewProps> {
                 height: propDocHeight === 0 ? NumCast(this.props.Document.height) - NumCast(this.props.Document.collapsedHeight) : propDocHeight * scale(),
                 width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
             }}>
-                <DocumentView
-                    fitToBox={StrCast(this.props.Document.type).indexOf(DocumentType.COL) !== -1}
+                <CollectionSchemaPreview
+                    fitToBox={StrCast(this.props.Document.target.type).indexOf(DocumentType.COL) !== -1}
                     Document={this.props.Document.target}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
                     ruleProvider={undefined}
-                    ScreenToLocalTransform={Transform.Identity}
                     addDocTab={returnFalse}
                     pinToPres={returnFalse}
+                    PanelWidth={() => this.props.PanelWidth() - 20}
+                    PanelHeight={() => 100}
+                    setPreviewScript={emptyFunction}
+                    getTransform={Transform.Identity}
+                    active={this.props.active}
+                    moveDocument={this.props.moveDocument!}
                     renderDepth={1}
-                    PanelWidth={() => 350}
-                    PanelHeight={() => 90}
                     focus={emptyFunction}
-                    backgroundColor={returnEmptyString}
-                    parentActive={returnFalse}
                     whenActiveChanged={returnFalse}
-                    bringToFront={emptyFunction}
-                    zoomToScale={emptyFunction}
-                    getScale={returnOne}
-                    ContainingCollectionView={undefined}
-                    ContainingCollectionDoc={undefined}
-                    ContentScaling={scale}
                 />
                 <div className="presElementBox-embeddedMask" />
             </div>
-- 
cgit v1.2.3-70-g09d2


From 9427474b473d70974784a1517a1be902fb8d18ee Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 2 Oct 2019 18:26:55 -0400
Subject: many fixes to pdfs, linking, annotations, presentations.

---
 src/client/documents/Documents.ts                  |  24 ++--
 src/client/util/DocumentManager.ts                 | 125 +++++++++++----------
 src/client/util/RichTextSchema.tsx                 |   9 +-
 src/client/util/SharingManager.tsx                 |   2 +-
 .../views/collections/CollectionBaseView.tsx       |   9 +-
 .../views/collections/CollectionDockingView.tsx    |  10 +-
 src/client/views/collections/CollectionSubView.tsx |   1 +
 .../views/collections/CollectionTreeView.tsx       |   2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  10 +-
 src/client/views/linking/LinkFollowBox.tsx         |  11 +-
 src/client/views/nodes/DocumentView.tsx            |  44 ++------
 src/client/views/nodes/FormattedTextBox.tsx        |  79 ++++++-------
 src/client/views/nodes/ImageBox.tsx                |   2 +-
 src/client/views/nodes/PDFBox.tsx                  |  17 ++-
 src/client/views/nodes/PresBox.tsx                 |  24 ++--
 src/client/views/nodes/VideoBox.tsx                |   2 +-
 src/client/views/pdf/Annotation.tsx                |  17 ++-
 src/client/views/pdf/PDFMenu.tsx                   |   6 +-
 src/client/views/pdf/PDFViewer.tsx                 |  72 +++++-------
 .../views/presentationview/PresElementBox.tsx      |  32 +++---
 src/new_fields/Doc.ts                              |   2 +
 21 files changed, 224 insertions(+), 276 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 4d9698532..2d323ea4b 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -653,32 +653,30 @@ export namespace DocUtils {
             }
         });
     }
-    export function MakeLink(source: Doc, target: Doc, targetContext?: Doc, title: string = "", description: string = "", sourceContext?: Doc, id?: string, anchored1?: boolean) {
-        let sv = DocumentManager.Instance.getDocumentView(source);
-        if (sv && sv.props.ContainingCollectionDoc === target) return;
-        if (target === CurrentUserUtils.UserDocument) return undefined;
+    export function MakeLink(source: {doc:Doc,ctx?:Doc}, target: {doc:Doc,ctx?:Doc}, title: string = "", description: string = "", id?: string, anchored1?: boolean) {
+        let sv = DocumentManager.Instance.getDocumentView(source.doc);
+        if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
+        if (target.doc === CurrentUserUtils.UserDocument) return undefined;
 
         let linkDocProto = new Doc(id, true);
         UndoManager.RunInBatch(() => {
             linkDocProto.type = DocumentType.LINK;
 
-            linkDocProto.targetContext = targetContext;
-            linkDocProto.sourceContext = sourceContext;
-            linkDocProto.title = title === "" ? source.title + " to " + target.title : title;
+            linkDocProto.targetContext = target.ctx;
+            linkDocProto.sourceContext = source.ctx;
+            linkDocProto.title = title === "" ? source.doc.title + " to " + target.doc.title : title;
             linkDocProto.linkDescription = description;
 
-            linkDocProto.anchor1 = source;
-            linkDocProto.anchor1Page = source.curPage;
+            linkDocProto.anchor1 = source.doc;
             linkDocProto.anchor1Groups = new List<Doc>([]);
             linkDocProto.anchor1anchored = anchored1;
-            linkDocProto.anchor2 = target;
-            linkDocProto.anchor2Page = target.curPage;
+            linkDocProto.anchor2 = target.doc;
             linkDocProto.anchor2Groups = new List<Doc>([]);
 
             LinkManager.Instance.addLink(linkDocProto);
 
-            Doc.GetProto(source).links = ComputedField.MakeFunction("links(this)");
-            Doc.GetProto(target).links = ComputedField.MakeFunction("links(this)");
+            Doc.GetProto(source.doc).links = ComputedField.MakeFunction("links(this)");
+            Doc.GetProto(target.doc).links = ComputedField.MakeFunction("links(this)");
         }, "make link");
         return linkDocProto;
     }
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 4e6968f08..4ebcdf83c 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,7 +1,7 @@
 import { action, computed, observable } from 'mobx';
 import { Doc, DocListCastAsync } from '../../new_fields/Doc';
 import { Id } from '../../new_fields/FieldSymbols';
-import { Cast, NumCast } from '../../new_fields/Types';
+import { Cast, NumCast, StrCast } from '../../new_fields/Types';
 import { CollectionDockingView } from '../views/collections/CollectionDockingView';
 import { CollectionPDFView } from '../views/collections/CollectionPDFView';
 import { CollectionVideoView } from '../views/collections/CollectionVideoView';
@@ -56,9 +56,9 @@ export class DocumentManager {
         return this.getDocumentViewsById(doc[Id]);
     }
 
-    public getDocumentViewById(id: string, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | null {
+    public getDocumentViewById(id: string, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | undefined {
 
-        let toReturn: DocumentView | null = null;
+        let toReturn: DocumentView | undefined;
         let passes = preferredCollection ? [preferredCollection, undefined] : [undefined];
 
         for (let pass of passes) {
@@ -81,10 +81,14 @@ export class DocumentManager {
         return toReturn;
     }
 
-    public getDocumentView(toFind: Doc, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | null {
+    public getDocumentView(toFind: Doc, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | undefined {
         return this.getDocumentViewById(toFind[Id], preferredCollection);
     }
 
+    public getFirstDocumentView(toFind: Doc): DocumentView | undefined {
+        const views = this.getDocumentViews(toFind);
+        return views.length ? views[0] : undefined;
+    }
     public getDocumentViews(toFind: Doc): DocumentView[] {
 
         let toReturn: DocumentView[] = [];
@@ -127,72 +131,70 @@ export class DocumentManager {
         return pairs;
     }
 
-
-    @undoBatch
-    public jumpToDocument = async (docDelegate: Doc, willZoom: boolean, forceDockFunc: boolean = false, dockFunc?: (doc: Doc) => void, linkPage?: number, docContext?: Doc): Promise<void> => {
-        let doc = Doc.GetProto(docDelegate);
-        const contextDoc = await Cast(doc.annotationOn, Doc);
-        if (contextDoc) {
-            contextDoc.scrollY = NumCast(doc.y) - NumCast(contextDoc.height) / 2 * 72 / 96;
-        }
-
-        let docView: DocumentView | null;
-        // using forceDockFunc as a flag for splitting linked to doc to the right...can change later if needed
-        if (!forceDockFunc && (docView = DocumentManager.Instance.getDocumentView(doc))) {
-            Doc.BrushDoc(docView.props.Document);
-            if (linkPage !== undefined) docView.props.Document.curPage = linkPage;
-            UndoManager.RunInBatch(() => docView!.props.focus(docView!.props.Document, willZoom), "focus");
+    public jumpToDocument = async (targetDoc: Doc, willZoom: boolean, dockFunc?: (doc: Doc) => void, docContext?: Doc, closeContextIfNotFound: boolean = false): Promise<void> => {
+        const docView = DocumentManager.Instance.getFirstDocumentView(targetDoc);
+        const annotatedDoc = await Cast(targetDoc.annotationOn, Doc);
+        if (docView) {  // we have a docView already and aren't forced to create a new one ... just focus on the document.  TODO move into view if necessary otherwise just highlight?
+            annotatedDoc && docView.props.focus(annotatedDoc, false);
+            docView.props.focus(targetDoc, willZoom);
         } else {
-            if (!contextDoc) {
-                let docs = docContext ? await DocListCastAsync(docContext.data) : undefined;
-                let found = false;
-                // bcz: this just searches within the context for the target -- perhaps it should recursively search through all children?
-                docs && docs.map(d => found = found || Doc.AreProtosEqual(d, docDelegate));
-                if (docContext && found) {
-                    let targetContextView: DocumentView | null;
-
-                    if (!forceDockFunc && docContext && (targetContextView = DocumentManager.Instance.getDocumentView(docContext))) {
-                        docContext.panTransformType = "Ease";
-                        targetContextView.props.focus(docDelegate, willZoom);
-                    } else {
-                        (dockFunc || CollectionDockingView.AddRightSplit)(docContext, undefined);
-                        setTimeout(() => {
-                            let dv = DocumentManager.Instance.getDocumentView(docContext);
-                            dv && this.jumpToDocument(docDelegate, willZoom, forceDockFunc,
-                                doc => dv!.props.focus(dv!.props.Document, true, 1, () => dv!.props.addDocTab(doc, undefined, "inPlace")),
-                                linkPage);
-                        }, 1050);
-                    }
-                } else {
-                    const actualDoc = Doc.MakeAlias(docDelegate);
-                    Doc.BrushDoc(actualDoc);
-                    if (linkPage !== undefined) actualDoc.curPage = linkPage;
-                    (dockFunc || CollectionDockingView.AddRightSplit)(actualDoc, undefined);
-                }
+            const contextDocs = docContext ? await DocListCastAsync(docContext.data) : undefined;
+            const contextDoc = contextDocs && contextDocs.find(doc => Doc.AreProtosEqual(doc, targetDoc)) ? docContext : undefined;
+            const targetDocContext = (annotatedDoc ? annotatedDoc : contextDoc);
+
+            if (!targetDocContext) { // we don't have a view and there's no context specified ... create a new view of the target using the dockFunc or default
+                (dockFunc || CollectionDockingView.AddRightSplit)(Doc.BrushDoc(Doc.MakeAlias(targetDoc)), undefined);
             } else {
-                let contextView: DocumentView | null;
-                Doc.BrushDoc(docDelegate);
-                let contextViews = DocumentManager.Instance.getDocumentViews(contextDoc);
-                if (!forceDockFunc && contextViews.length) {
-                    contextView = contextViews[0];
-                    SelectionManager.SelectDoc(contextView, false); // force unrendered annotations to be created
-                    contextDoc.panTransformType = "Ease";
+                const targetDocContextView = DocumentManager.Instance.getFirstDocumentView(targetDocContext);
+                if (targetDocContextView) { // we have a context view and aren't forced to create a new one ... focus on the context
+                    targetDocContext.panTransformType = "Ease";
+                    targetDocContext.scrollY = 0;
+                    targetDocContextView.props.focus(targetDocContextView.props.Document, willZoom);
+
+                    // now find the target document within the context
                     setTimeout(() => {
-                        SelectionManager.DeselectDoc(contextView!);
-                        docView = DocumentManager.Instance.getDocumentView(docDelegate);
-                        docView && contextView!.props.focus(contextView!.props.Document, willZoom);
-                        docView && UndoManager.RunInBatch(() => docView!.props.focus(docView!.props.Document, willZoom), "focus");
+                        const retryDocView = DocumentManager.Instance.getDocumentView(targetDoc);
+                        if (retryDocView) {
+                            retryDocView.props.focus(targetDoc, willZoom); // focus on the target if it now exists in the context
+                        } else {
+                            if (closeContextIfNotFound && targetDocContextView.props.removeDocument) targetDocContextView.props.removeDocument(targetDocContextView.props.Document);
+                            (dockFunc || CollectionDockingView.AddRightSplit)(Doc.BrushDoc(Doc.MakeAlias(targetDoc)), undefined); // otherwise create a new view of the target
+                        }
                     }, 0);
-                } else {
-                    (dockFunc || CollectionDockingView.AddRightSplit)(contextDoc, undefined);
+                } else {  // there's no context view so we need to create one first and try again
+                    targetDocContext.scrollY = 0;
+                    (dockFunc || CollectionDockingView.AddRightSplit)(targetDocContext, undefined);
                     setTimeout(() => {
-                        this.jumpToDocument(docDelegate, willZoom, forceDockFunc, dockFunc, linkPage);
-                    }, 1000);
+                        const foundTargetDocContextView = DocumentManager.Instance.getDocumentView(targetDocContext);
+                        if (foundTargetDocContextView) { // we should always find a target context here....
+                            this.jumpToDocument(targetDoc, willZoom, dockFunc, undefined, true); // so call jump to doc again and if the doc isn't found, it will be created.
+                        }
+                    }, 2000); // the long timeout gives the context view a chance to create its children.  think pdf's which need to be activated to render their annotations.
                 }
             }
         }
     }
 
+    public async FollowLink(doc: Doc, focus: (doc: Doc, maxLocation: string) => void, zoom: boolean = false, reverse: boolean = false, currentContext?: Doc) {
+        let linkDocs = LinkManager.Instance.getAllRelatedLinks(doc);
+        SelectionManager.DeselectAll();
+        let firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc) && !linkDoc.anchor1anchored);
+        let secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc) && !linkDoc.anchor2anchored);
+        const firstDocWithoutView = firstDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor2 as Doc).length === 0);
+        const secondDocWithoutView = secondDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor1 as Doc).length === 0);
+        let first = firstDocWithoutView ? [firstDocWithoutView] : firstDocs;
+        let second = secondDocWithoutView ? [secondDocWithoutView] : secondDocs;
+        let linkFollowDocs = first.length ? [first[0].anchor2 as Doc, first[0].anchor1 as Doc] : second.length ? [second[0].anchor1 as Doc, second[0].anchor2 as Doc] : undefined;
+        let linkFollowDocContexts = first.length ? [await (first[0].targetContext) as Doc, await (first[0].sourceContext) as Doc] : second.length ? [await (second[0].sourceContext) as Doc, await (second[0].targetContext) as Doc] : [undefined, undefined];
+        if (linkFollowDocs && !linkFollowDocs.some(l => l instanceof Promise)) {
+            let maxLocation = StrCast(linkFollowDocs[0].maximizeLocation, "inTab");
+            let targetContext = !Doc.AreProtosEqual(linkFollowDocContexts[reverse ? 1 : 0], currentContext) ? linkFollowDocContexts[reverse ? 1 : 0] : undefined;
+            DocumentManager.Instance.jumpToDocument(linkFollowDocs[reverse ? 1 : 0], zoom,
+                // open up target if it's not already in view ... by zooming into the button document first and setting flag to reset zoom afterwards
+                (doc: Doc) => focus(doc, maxLocation), targetContext);
+        }
+    }
+
     @action
     zoomIntoScale = (docDelegate: Doc, scale: number) => {
         let docView = DocumentManager.Instance.getDocumentView(Doc.GetProto(docDelegate));
@@ -202,8 +204,7 @@ export class DocumentManager {
     getScaleOfDocView = (docDelegate: Doc) => {
         let doc = Doc.GetProto(docDelegate);
 
-        let docView: DocumentView | null;
-        docView = DocumentManager.Instance.getDocumentView(doc);
+        const docView = DocumentManager.Instance.getDocumentView(doc);
         if (docView) {
             return docView.props.getScale();
         } else {
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 64821d8db..49bd93942 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -627,17 +627,16 @@ export class ImageResizeView {
                         let jumpToDoc = await Cast(linkDoc.anchor2, Doc);
                         if (jumpToDoc) {
                             if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
-
-                                DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page)));
+                                DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey);
                                 return;
                             }
                         }
                         if (targetContext) {
-                            DocumentManager.Instance.jumpToDocument(targetContext, e.ctrlKey, false, document => addDocTab(document, undefined, location ? location : "inTab"));
+                            DocumentManager.Instance.jumpToDocument(targetContext, e.ctrlKey, document => addDocTab(document, undefined, location ? location : "inTab"));
                         } else if (jumpToDoc) {
-                            DocumentManager.Instance.jumpToDocument(jumpToDoc, e.ctrlKey, false, document => addDocTab(document, undefined, location ? location : "inTab"));
+                            DocumentManager.Instance.jumpToDocument(jumpToDoc, e.ctrlKey, document => addDocTab(document, undefined, location ? location : "inTab"));
                         } else {
-                            DocumentManager.Instance.jumpToDocument(linkDoc, e.ctrlKey, false, document => addDocTab(document, undefined, location ? location : "inTab"));
+                            DocumentManager.Instance.jumpToDocument(linkDoc, e.ctrlKey, document => addDocTab(document, undefined, location ? location : "inTab"));
                         }
                     }
                 });
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index f427e40b1..1cde2aa8e 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -192,7 +192,7 @@ export default class SharingManager extends React.Component<{}> {
                 onClick={() => {
                     let context: Opt<CollectionVideoView | CollectionPDFView | CollectionView>;
                     if (this.targetDoc && this.targetDocView && (context = this.targetDocView.props.ContainingCollectionView)) {
-                        DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, undefined, undefined, context.props.Document);
+                        DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, context.props.Document);
                     }
                 }}
                 onPointerEnter={action(() => {
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index e928887e2..38d050e5c 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -5,7 +5,7 @@ import { Doc, DocListCast } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
 import { List } from '../../../new_fields/List';
 import { listSpec } from '../../../new_fields/Schema';
-import { BoolCast, Cast, NumCast, PromiseValue, StrCast } from '../../../new_fields/Types';
+import { BoolCast, Cast, NumCast, PromiseValue, StrCast, FieldValue } from '../../../new_fields/Types';
 import { DocumentManager } from '../../util/DocumentManager';
 import { SelectionManager } from '../../util/SelectionManager';
 import { ContextMenu } from '../ContextMenu';
@@ -130,8 +130,11 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
         let value = Cast(targetDataDoc[targetField], listSpec(Doc), []);
         let index = value.reduce((p, v, i) => (v instanceof Doc && v === doc) ? i : p, -1);
         index = index !== -1 ? index : value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1);
-        PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn =>
-            annotationOn === this.dataDoc.Document && (doc.annotationOn = undefined));
+        PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn => {
+            if (Doc.AreProtosEqual(annotationOn, FieldValue(Cast(this.dataDoc.extendsDoc, Doc)))) {
+                Doc.GetProto(doc).annotationOn = undefined;
+            }
+        });
 
         if (index !== -1) {
             value.splice(index, 1);
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 98aff41d3..14e513157 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -574,8 +574,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         let curPres = Cast(CurrentUserUtils.UserDocument.curPresentation, Doc) as Doc;
         if (curPres) {
             let pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
-            Doc.GetProto(pinDoc).target = doc;
-            Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
+            Doc.GetProto(pinDoc).presentationTargetDoc = doc;
+            Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.presentationTargetDoc instanceof Doc) && this.presentationTargetDoc.title.toString()');
             const data = Cast(curPres.data, listSpec(Doc));
             if (data) {
                 data.push(pinDoc);
@@ -614,8 +614,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         }
     }
 
-    panelWidth = () => this._document!.ignoreAspect || this._document!.fitWidth ? this._panelWidth : Math.min(this._panelWidth, Math.max(NumCast(this._document!.width), this.nativeWidth()));
-    panelHeight = () => this._document!.ignoreAspect || this._document!.fitWidth ? this._panelHeight : Math.min(this._panelHeight, Math.max(NumCast(this._document!.height), this.nativeHeight()));
+    panelWidth = () => this._document && this._document.maxWidth ? Math.min(Math.max(NumCast(this._document.width), NumCast(this._document.nativeWidth)), this._panelWidth) : this._panelWidth;
+    panelHeight = () => this._panelHeight;
 
     nativeWidth = () => !this._document!.ignoreAspect && !this._document!.fitWidth ? NumCast(this._document!.nativeWidth) || this._panelWidth : 0;
     nativeHeight = () => !this._document!.ignoreAspect && !this._document!.fitWidth ? NumCast(this._document!.nativeHeight) || this._panelHeight : 0;
@@ -644,7 +644,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         }
         return Transform.Identity();
     }
-    get previewPanelCenteringOffset() { return this.nativeWidth() && !BoolCast(this._document!.ignoreAspect) ? (this._panelWidth - this.nativeWidth() / this.ScreenToLocalTransform().Scale) / 2 : 0; }
+    get previewPanelCenteringOffset() { return this.nativeWidth() && !this._document!.ignoreAspect ? (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2 : 0; }
 
     addDocTab = (doc: Doc, dataDoc: Opt<Doc>, location: string) => {
         SelectionManager.DeselectAll();
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 155f2718b..28d1eb384 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -31,6 +31,7 @@ export interface CollectionViewProps extends FieldViewProps {
     moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
     PanelWidth: () => number;
     PanelHeight: () => number;
+    VisibleHeight?: () => number;
     chromeCollapsed: boolean;
     setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void;
 }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index ffd1f9170..882a0f144 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -217,7 +217,7 @@ class TreeView extends React.Component<TreeViewProps> {
         if (de.data instanceof DragManager.LinkDragData) {
             let sourceDoc = de.data.linkSourceDocument;
             let destDoc = this.props.document;
-            DocUtils.MakeLink(sourceDoc, destDoc);
+            DocUtils.MakeLink({doc:sourceDoc}, {doc:destDoc});
             e.stopPropagation();
         }
         if (de.data instanceof DragManager.DocumentDragData) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index eb40e0bcb..4bdede48a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -403,8 +403,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         SelectionManager.DeselectAll();
         if (this.props.Document.scrollHeight) {
             let annotOn = Cast(doc.annotationOn, Doc) as Doc;
-            let offset = annotOn && (NumCast(annotOn.height) / 2 * 72 / 96);
-            this.props.Document.scrollY = NumCast(doc.y) - offset;
+            if (!annotOn) {
+                this.props.focus(doc);
+            } else {
+                let contextHgt = Doc.AreProtosEqual(annotOn, this.props.Document) && this.props.VisibleHeight ? this.props.VisibleHeight() : NumCast(annotOn.height);
+                let offset = annotOn && (contextHgt / 2 * 96 / 72);
+                this.props.Document.scrollY = NumCast(doc.y) - offset;
+            }
         } else {
             const newPanX = NumCast(doc.x) + NumCast(doc.width) / 2;
             const newPanY = NumCast(doc.y) + NumCast(doc.height) / 2;
@@ -416,6 +421,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
             this.setPan(newPanX, newPanY);
             this.Document.panTransformType = "Ease";
+            Doc.BrushDoc(this.props.Document);
             this.props.focus(this.props.Document);
             willZoom && this.setScaleToZoom(doc, scale);
 
diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx
index 72fff8e53..53b720a9e 100644
--- a/src/client/views/linking/LinkFollowBox.tsx
+++ b/src/client/views/linking/LinkFollowBox.tsx
@@ -171,7 +171,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     @undoBatch
     openFullScreen = () => {
         if (LinkFollowBox.destinationDoc) {
-            let view: DocumentView | null = DocumentManager.Instance.getDocumentView(LinkFollowBox.destinationDoc);
+            let view = DocumentManager.Instance.getDocumentView(LinkFollowBox.destinationDoc);
             view && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(view);
         }
     }
@@ -250,10 +250,10 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
             let dockingFunc = (document: Doc) => { (LinkFollowBox._addDocTab || this.props.addDocTab)(document, undefined, "inTab"); SelectionManager.DeselectAll(); };
 
             if (LinkFollowBox.destinationDoc === LinkFollowBox.linkDoc.anchor2 && targetContext) {
-                DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, async document => dockingFunc(document), undefined, targetContext);
+                DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, async document => dockingFunc(document), targetContext);
             }
             else if (LinkFollowBox.destinationDoc === LinkFollowBox.linkDoc.anchor1 && sourceContext) {
-                DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, document => dockingFunc(sourceContext!));
+                DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, document => dockingFunc(sourceContext!));
                 if (LinkFollowBox.sourceDoc && LinkFollowBox.destinationDoc) {
                     if (guid) {
                         let views = DocumentManager.Instance.getDocumentViews(jumpToDoc);
@@ -264,12 +264,11 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
                 }
             }
             else if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
-                DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, undefined, undefined,
-                    NumCast((LinkFollowBox.destinationDoc === LinkFollowBox.linkDoc.anchor2 ? LinkFollowBox.linkDoc.anchor2Page : LinkFollowBox.linkDoc.anchor1Page)));
+                DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom);
 
             }
             else {
-                DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, dockingFunc);
+                DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, dockingFunc);
             }
 
             this.highlightDoc();
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a903f8fe2..3273abc1d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -206,7 +206,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     buttonClick = async (altKey: boolean, ctrlKey: boolean) => {
         let maximizedDocs = await DocListCastAsync(this.props.Document.maximizedDocs);
         let summarizedDocs = await DocListCastAsync(this.props.Document.summarizedDocs);
-        let linkedDocs = LinkManager.Instance.getAllRelatedLinks(this.props.Document);
+        let linkDocs = LinkManager.Instance.getAllRelatedLinks(this.props.Document);
         let expandedDocs: Doc[] = [];
         expandedDocs = maximizedDocs ? [...maximizedDocs, ...expandedDocs] : expandedDocs;
         expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs;
@@ -223,28 +223,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 expandedDocs.forEach(maxDoc => (!this.props.addDocTab(maxDoc, undefined, "close") && this.props.addDocTab(maxDoc, undefined, maxLocation)));
             }
         }
-        else if (linkedDocs.length) {
-            SelectionManager.DeselectAll();
-            let first = linkedDocs.filter(d => Doc.AreProtosEqual(d.anchor1 as Doc, this.props.Document) && !d.anchor1anchored);
-            let second = linkedDocs.filter(d => Doc.AreProtosEqual(d.anchor2 as Doc, this.props.Document) && !d.anchor2anchored);
-            let firstUnshown = first.filter(d => DocumentManager.Instance.getDocumentViews(d.anchor2 as Doc).length === 0);
-            let secondUnshown = second.filter(d => DocumentManager.Instance.getDocumentViews(d.anchor1 as Doc).length === 0);
-            if (firstUnshown.length) first = [firstUnshown[0]];
-            if (secondUnshown.length) second = [secondUnshown[0]];
-            let linkedFwdDocs = first.length ? [first[0].anchor2 as Doc, first[0].anchor1 as Doc] : second.length ? [second[0].anchor1 as Doc, second[0].anchor1 as Doc] : undefined;
-
-            // @TODO: shouldn't always follow target context
-            let linkedFwdContextDocs = [first.length ? await (first[0].targetContext) as Doc : undefined, undefined];
-            let linkedFwdPage = [first.length ? NumCast(first[0].anchor2Page, undefined) : undefined, undefined];
-
-            if (linkedFwdDocs && !linkedFwdDocs.some(l => l instanceof Promise)) {
-                let maxLocation = StrCast(linkedFwdDocs[0].maximizeLocation, "inTab");
-                let targetContext = !Doc.AreProtosEqual(linkedFwdContextDocs[altKey ? 1 : 0], this.props.ContainingCollectionDoc) ? linkedFwdContextDocs[altKey ? 1 : 0] : undefined;
-                DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false,
-                    // open up target if it's not already in view ... by zooming into the button document first and setting flag to reset zoom afterwards
-                    doc => this.props.focus(this.props.Document, true, 1, () => this.props.addDocTab(doc, undefined, maxLocation)),
-                    linkedFwdPage[altKey ? 1 : 0], targetContext);
-            }
+        else if (linkDocs.length) {
+            DocumentManager.Instance.FollowLink(this.props.Document,
+                (doc: Doc, maxLocation: string) => this.props.focus(this.props.Document, true, 1, () => this.props.addDocTab(doc, undefined, maxLocation)),
+                ctrlKey, altKey, this.props.ContainingCollectionDoc);
         }
     }
 
@@ -352,15 +334,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         if (de.data instanceof DragManager.AnnotationDragData) {
             /// this whole section for handling PDF annotations looks weird.  Need to rethink this to make it cleaner
             e.stopPropagation();
-            let sourceDoc = de.data.annotationDocument;
-            let targetDoc = this.props.Document;
-            let annotations = await DocListCastAsync(sourceDoc.annotations);
-            sourceDoc.linkedToDoc = true;
-            de.data.targetContext = this.props.ContainingCollectionDoc;
-            targetDoc.targetContext = de.data.targetContext;
-            annotations && annotations.forEach(anno => anno.target = targetDoc);
-
-            DocUtils.MakeLink(sourceDoc, targetDoc, this.props.ContainingCollectionDoc, `Link from ${StrCast(sourceDoc.title)}`);
+            (de.data as any).linkedToDoc = true;
+
+            DocUtils.MakeLink({ doc: de.data.annotationDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, `Link from ${StrCast(de.data.annotationDocument.title)}`);
         }
         if (de.data instanceof DragManager.DocumentDragData && de.data.applyAsTemplate) {
             Doc.ApplyTemplateTo(de.data.draggedDocuments[0], this.props.Document);
@@ -371,7 +347,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             // const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
             // const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
             de.data.linkSourceDocument !== this.props.Document &&
-                (de.data.linkDocument = DocUtils.MakeLink(de.data.linkSourceDocument, this.props.Document, this.props.ContainingCollectionDoc, undefined, "in-text link being created")); // TODODO this is where in text links get passed
+                (de.data.linkDocument = DocUtils.MakeLink({ doc: de.data.linkSourceDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, "in-text link being created")); // TODODO this is where in text links get passed
         }
     }
 
@@ -407,7 +383,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             let portalID = (this.Document.title + ".portal").replace(/^-/, "").replace(/\([0-9]*\)$/, "");
             DocServer.GetRefField(portalID).then(existingPortal => {
                 let portal = existingPortal instanceof Doc ? existingPortal : Docs.Create.FreeformDocument([], { width: (this.Document.width || 0) + 10, height: this.Document.height || 0, title: portalID });
-                DocUtils.MakeLink(this.props.Document, portal, undefined, portalID);
+                DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: portal }, portalID, "portal link");
                 this.Document.isButton = true;
             });
         }
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 449f56b16..749886d9a 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -9,7 +9,7 @@ import { Fragment, Node, Node as ProsNode, NodeType, Slice, Mark, ResolvedPos }
 import { EditorState, Plugin, Transaction, TextSelection, NodeSelection } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { DateField } from '../../../new_fields/DateField';
-import { Doc, DocListCast, Opt, WidthSym } from "../../../new_fields/Doc";
+import { Doc, DocListCast, Opt, WidthSym, DocListCastAsync } from "../../../new_fields/Doc";
 import { Copy, Id } from '../../../new_fields/FieldSymbols';
 import { List } from '../../../new_fields/List';
 import { RichTextField } from "../../../new_fields/RichTextField";
@@ -230,7 +230,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                     this.dataDoc[key] = doc || Docs.Create.FreeformDocument([], { title: value, width: 500, height: 500 }, value);
                     DocUtils.Publish(this.dataDoc[key] as Doc, value, this.props.addDocument, this.props.removeDocument);
                     if (linkDoc) { (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc; }
-                    else DocUtils.MakeLink(this.dataDoc, this.dataDoc[key] as Doc, undefined, "Ref:" + value, undefined, undefined, id, true);
+                    else DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: this.dataDoc[key] as Doc }, "Ref:" + value, "link to named target", id, true);
                 });
             });
         });
@@ -342,7 +342,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
             let model: NodeType = [".mov", ".mp4"].includes(url) ? schema.nodes.video : schema.nodes.image;
             let pos = this._editorView!.posAtCoords({ left: de.x, top: de.y });
             this._editorView!.dispatch(this._editorView!.state.tr.insert(pos!.pos, model.create({ src: url, docid: target[Id] })));
-            DocUtils.MakeLink(this.dataDoc, target, undefined, "ImgRef:" + target.title, undefined, undefined, target[Id]);
+            DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: target }, "ImgRef:" + target.title);
             this.tryUpdateHeight();
             e.stopPropagation();
         } else if (de.data instanceof DragManager.DocumentDragData) {
@@ -667,55 +667,42 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
 
     handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => {
         let cbe = event as ClipboardEvent;
-        let docId: string;
-        let regionId: string;
-        if (!cbe.clipboardData) {
-            return false;
-        }
-        let linkId: string;
-        docId = cbe.clipboardData.getData("dash/pdfOrigin");
-        regionId = cbe.clipboardData.getData("dash/pdfRegion");
-        if (!docId || !regionId) {
-            return false;
-        }
-
-        DocServer.GetRefField(docId).then(doc => {
-            DocServer.GetRefField(regionId).then(region => {
-                if (!(doc instanceof Doc) || !(region instanceof Doc)) {
-                    return;
-                }
-
-                let annotations = DocListCast(region.annotations);
-                annotations.forEach(anno => anno.target = this.props.Document);
-                let fieldExtDoc = Doc.fieldExtensionDoc(doc, "data");
-                let targetAnnotations = DocListCast(fieldExtDoc.annotations);
-                if (targetAnnotations) {
-                    targetAnnotations.push(region);
-                    fieldExtDoc.annotations = new List<Doc>(targetAnnotations);
-                }
+        const pdfDocId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfOrigin");
+        const pdfRegionId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfRegion");
+        if (pdfDocId && pdfRegionId) {
+            DocServer.GetRefField(pdfDocId).then(pdfDoc => {
+                DocServer.GetRefField(pdfRegionId).then(pdfRegion => {
+                    if ((pdfDoc instanceof Doc) && (pdfRegion instanceof Doc)) {
+                        setTimeout(async () => {
+                            let targetAnnotations = await DocListCastAsync(Doc.fieldExtensionDoc(pdfDoc, "data").annotations);// bcz: NO... this assumes the pdf is using its 'data' field.  need to have the PDF's view handle updating its own annotations
+                            targetAnnotations && targetAnnotations.push(pdfRegion);
+                        });
 
-                let link = DocUtils.MakeLink(this.props.Document, region, doc);
-                if (link) {
-                    cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
-                    linkId = link[Id];
-                    let frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(doc.title)));
-                    slice = new Slice(frag, slice.openStart, slice.openEnd);
-                    var tr = view.state.tr.replaceSelection(slice);
-                    view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
-                }
+                        let link = DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: pdfRegion, ctx: pdfDoc }, "note on " + pdfDoc.title, "pasted PDF link");
+                        if (link) {
+                            cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
+                            let linkId = link[Id];
+                            let frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId));
+                            slice = new Slice(frag, slice.openStart, slice.openEnd);
+                            var tr = view.state.tr.replaceSelection(slice);
+                            view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
+                        }
+                    }
+                });
             });
-        });
+            return true;
+        }
+        return false;
 
-        return true;
 
         function addMarkToFrag(frag: Fragment, marker: (node: Node) => Node) {
             const nodes: Node[] = [];
             frag.forEach(node => nodes.push(marker(node)));
             return Fragment.fromArray(nodes);
         }
-        function addLinkMark(node: Node, title: string) {
+        function addLinkMark(node: Node, title: string, linkId: string) {
             if (!node.isText) {
-                const content = addMarkToFrag(node.content, (node: Node) => addLinkMark(node, title));
+                const content = addMarkToFrag(node.content, (node: Node) => addLinkMark(node, title, linkId));
                 return node.copy(content);
             }
             const marks = [...node.marks];
@@ -879,16 +866,16 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
 
                                 if (jumpToDoc) {
                                     if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
-                                        DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page)));
+                                        DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey);
                                         return;
                                     }
                                 }
                                 if (targetContext && (!jumpToDoc || targetContext !== await jumpToDoc.annotationOn)) {
-                                    DocumentManager.Instance.jumpToDocument(jumpToDoc || targetContext, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"), undefined, targetContext);
+                                    DocumentManager.Instance.jumpToDocument(jumpToDoc || targetContext, ctrlKey, document => this.props.addDocTab(document, undefined, location ? location : "inTab"), targetContext);
                                 } else if (jumpToDoc) {
-                                    DocumentManager.Instance.jumpToDocument(jumpToDoc, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
+                                    DocumentManager.Instance.jumpToDocument(jumpToDoc, ctrlKey, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
                                 } else {
-                                    DocumentManager.Instance.jumpToDocument(linkDoc, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
+                                    DocumentManager.Instance.jumpToDocument(linkDoc, ctrlKey, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
                                 }
                             }
                         });
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 9e9fe1324..fe4f75cad 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -299,7 +299,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
                 let rotation = NumCast(this.dataDoc.rotation) % 180;
                 let realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
                 let aspect = realsize.height / realsize.width;
-                if (layoutdoc.nativeHeight !== 0 && layoutdoc.nativeWidth !== 0 && (Math.abs(NumCast(layoutdoc.height) - realsize.height) > 1 || Math.abs(NumCast(layoutdoc.width) - realsize.width) > 1)) {
+                if (layoutdoc.nativeHeight !== 0 && layoutdoc.nativeWidth !== 0 && (Math.abs(1 - NumCast(layoutdoc.nativeHeight) / NumCast(layoutdoc.nativeWidth) / (realsize.height / realsize.width)) > 0.1)) {
                     setTimeout(action(() => {
                         layoutdoc.height = layoutdoc[WidthSym]() * aspect;
                         layoutdoc.nativeHeight = realsize.height;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 617b580dd..88cd2cdc4 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -57,11 +57,8 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
     }
     loaded = (nw: number, nh: number, np: number) => {
         this.dataDoc.numPages = np;
-        if (!this.Document.nativeWidth || !this.Document.nativeHeight || !this.Document.scrollHeight) {
-            let oldaspect = (this.Document.nativeHeight || 0) / (this.Document.nativeWidth || 1);
-            this.Document.nativeWidth = nw * 96 / 72;
-            this.Document.nativeHeight = this.Document.nativeHeight ? nw * 96 / 72 * oldaspect : nh * 96 / 72;
-        }
+        this.Document.nativeWidth = nw * 96 / 72;
+        this.Document.nativeHeight = nh * 96 / 72;
         !this.Document.fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw));
     }
 
@@ -177,12 +174,14 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
 
         ContextMenu.Instance.addItem({ description: "Pdf Funcs...", subitems: funcs, icon: "asterisk" });
     }
+    _initialScale: number | undefined;
     render() {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
         let classname = "pdfBox-cont" + (InkingControl.Instance.selectedTool || !this.active ? "" : "-interactive");
         let noPdf = !(pdfUrl instanceof PdfField) || !this._pdf;
-        if (!noPdf && (this.props.isSelected() || this.props.ScreenToLocalTransform().Scale < 2.5)) this._everActive = true;
-        return (!this._everActive ?
+        if (this._initialScale === undefined) this._initialScale = this.props.ScreenToLocalTransform().Scale;
+        if (this.props.isSelected() || this.props.Document.scrollY !== undefined) this._everActive = true;
+        return (noPdf || (!this._everActive && this.props.ScreenToLocalTransform().Scale > 2.5) ?
             <div className="pdfBox-title-outer" >
                 <div className={classname} >
                     <strong className="pdfBox-title" >{` ${this.props.Document.title}`}</strong>
@@ -203,11 +202,11 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
                     setPdfViewer={this.setPdfViewer} ContainingCollectionView={this.props.ContainingCollectionView}
                     renderDepth={this.props.renderDepth} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth}
                     Document={this.props.Document} DataDoc={this.dataDoc} ContentScaling={this.props.ContentScaling}
-                    addDocTab={this.props.addDocTab} GoToPage={this.gotoPage}
+                    addDocTab={this.props.addDocTab} GoToPage={this.gotoPage} focus={this.props.focus}
                     pinToPres={this.props.pinToPres} addDocument={this.props.addDocument}
                     ScreenToLocalTransform={this.props.ScreenToLocalTransform} select={this.props.select}
                     isSelected={this.props.isSelected} whenActiveChanged={this.whenActiveChanged}
-                    fieldKey={this.props.fieldKey} fieldExtensionDoc={this.extensionDoc} startupLive={this.props.ScreenToLocalTransform().Scale < 2.5 ? true : false} />
+                    fieldKey={this.props.fieldKey} fieldExtensionDoc={this.extensionDoc} startupLive={this._initialScale < 2.5 ? true : false} />
                 {this.settingsPanel()}
             </div>);
     }
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index f44ca99b9..180ed9032 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -43,8 +43,8 @@ export class PresBox extends React.Component<FieldViewProps> {
                 value.forEach((item, i) => {
                     if (item instanceof Doc && item.type !== DocumentType.PRESELEMENT) {
                         let pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
-                        Doc.GetProto(pinDoc).target = item;
-                        Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
+                        Doc.GetProto(pinDoc).presentationTargetDoc = item;
+                        Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.presentationTargetDoc instanceof Doc) && this.presentationTargetDoc.title.toString()');
                         value.splice(i, 1, pinDoc);
                     }
                 });
@@ -124,13 +124,13 @@ export class PresBox extends React.Component<FieldViewProps> {
         this.childDocs.forEach((doc, ind) => {
             //the order of cases is aligned based on priority
             if (doc.hideTillShownButton && ind <= index) {
-                (doc.target as Doc).opacity = 1;
+                (doc.presentationTargetDoc as Doc).opacity = 1;
             }
             if (doc.hideAfterButton && ind < index) {
-                (doc.target as Doc).opacity = 0;
+                (doc.presentationTargetDoc as Doc).opacity = 0;
             }
             if (doc.fadeButton && ind < index) {
-                (doc.target as Doc).opacity = 0.5;
+                (doc.presentationTargetDoc as Doc).opacity = 0.5;
             }
         });
     }
@@ -145,13 +145,13 @@ export class PresBox extends React.Component<FieldViewProps> {
             //the order of cases is aligned based on priority
 
             if (key.hideAfterButton && ind >= index) {
-                (key.target as Doc).opacity = 1;
+                (key.presentationTargetDoc as Doc).opacity = 1;
             }
             if (key.fadeButton && ind >= index) {
-                (key.target as Doc).opacity = 1;
+                (key.presentationTargetDoc as Doc).opacity = 1;
             }
             if (key.hideTillShownButton && ind > index) {
-                (key.target as Doc).opacity = 0;
+                (key.presentationTargetDoc as Doc).opacity = 0;
             }
         });
     }
@@ -162,7 +162,7 @@ export class PresBox extends React.Component<FieldViewProps> {
      * te option open, navigates to that element.
      */
     navigateToElement = async (curDoc: Doc, fromDocIndex: number) => {
-        let fromDoc = this.childDocs[fromDocIndex].target as Doc;
+        let fromDoc = this.childDocs[fromDocIndex].presentationTargetDoc as Doc;
         let docToJump = curDoc;
         let willZoom = false;
 
@@ -190,7 +190,7 @@ export class PresBox extends React.Component<FieldViewProps> {
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
         if (docToJump === curDoc) {
             //checking if curDoc has navigation open
-            let target = await curDoc.target as Doc;
+            let target = await curDoc.presentationTargetDoc as Doc;
             if (curDoc.navButton) {
                 DocumentManager.Instance.jumpToDocument(target, false);
             } else if (curDoc.showButton) {
@@ -210,8 +210,8 @@ export class PresBox extends React.Component<FieldViewProps> {
         let curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
 
         //awaiting jump so that new scale can be found, since jumping is async
-        await DocumentManager.Instance.jumpToDocument(await docToJump.target as Doc, willZoom);
-        let newScale = DocumentManager.Instance.getScaleOfDocView(await curDoc.target as Doc);
+        await DocumentManager.Instance.jumpToDocument(await docToJump.presentationTargetDoc as Doc, willZoom);
+        let newScale = DocumentManager.Instance.getScaleOfDocView(await curDoc.presentationTargetDoc as Doc);
         curDoc.viewScale = newScale;
         //saving the scale that user was on
         if (curScale !== 1) {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index b7d9a1eab..573197117 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -129,7 +129,7 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
                         width: 150, height: height / width * 150, title: "--snapshot" + NumCast(this.props.Document.curPage) + " image-"
                     });
                     this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.addDocument && this.props.ContainingCollectionView.props.addDocument(imageSummary, false);
-                    DocUtils.MakeLink(imageSummary, this.props.Document);
+                    DocUtils.MakeLink({doc:imageSummary}, {doc: this.props.Document}, "snapshot from " + this.props.Document.title, "video frame snapshot");
                 }
             });
         }
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 3ed85f6a5..f7f52b3ef 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -1,7 +1,7 @@
 import React = require("react");
 import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, HeightSym, WidthSym, Opt } from "../../../new_fields/Doc";
+import { Doc, DocListCast, HeightSym, WidthSym, Opt, DocListCastAsync } from "../../../new_fields/Doc";
 import { Id } from "../../../new_fields/FieldSymbols";
 import { List } from "../../../new_fields/List";
 import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types";
@@ -14,6 +14,7 @@ interface IAnnotationProps {
     fieldExtensionDoc: Doc;
     addDocTab: (document: Doc, dataDoc: Opt<Doc>, where: string) => boolean;
     pinToPres: (document: Doc) => void;
+    focus: (doc: Doc) => void;
 }
 
 export default class Annotation extends React.Component<IAnnotationProps> {
@@ -60,6 +61,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
     }
 
     componentWillUnmount() {
+        this._brushDisposer && this._brushDisposer();
         this._reactionDisposer && this._reactionDisposer();
     }
 
@@ -94,14 +96,11 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
             PDFMenu.Instance.jumpTo(e.clientX, e.clientY, true);
         }
         else if (e.button === 0) {
-            let targetDoc = await Cast(this.props.document.target, Doc);
-            if (targetDoc) {
-                let context = await Cast(targetDoc.targetContext, Doc);
-                if (context) {
-                    DocumentManager.Instance.jumpToDocument(targetDoc, false, false,
-                        ((doc) => this.props.addDocTab(targetDoc!, undefined, e.ctrlKey ? "onRight" : "inTab")),
-                        undefined, undefined);
-                }
+            let annoGroup = await Cast(this.props.document.group, Doc);
+            if (annoGroup) {
+                DocumentManager.Instance.FollowLink(annoGroup,
+                    (doc: Doc, maxLocation: string) => this.props.addDocTab(doc, undefined, e.ctrlKey ? "onRight" : "inTab"),
+                    false, false, undefined);
             }
         }
     }
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index 2202351ee..e62542014 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -31,7 +31,7 @@ export default class PDFMenu extends React.Component {
     @observable public Pinned: boolean = false;
 
     public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = emptyFunction;
-    public Highlight: (d: Doc | undefined, color: string) => void = emptyFunction;
+    public Highlight: (color: string) => void = emptyFunction;
     public Delete: () => void = emptyFunction;
     public Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction;
     public AddTag: (key: string, value: string) => boolean = returnFalse;
@@ -156,11 +156,11 @@ export default class PDFMenu extends React.Component {
     @action
     highlightClicked = (e: React.MouseEvent) => {
         if (!this.Pinned) {
-            this.Highlight(undefined, "#f4f442");
+            this.Highlight("#f4f442");
         }
         else {
             this.Highlighting = !this.Highlighting;
-            this.Highlight(undefined, "#f4f442");
+            this.Highlight("#f4f442");
         }
     }
 
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 33226eac4..20dfc4d8c 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -10,7 +10,6 @@ import { listSpec } from "../../../new_fields/Schema";
 import { ScriptField } from "../../../new_fields/ScriptField";
 import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import smoothScroll, { Utils, emptyFunction, returnOne } from "../../../Utils";
-import { DocServer } from "../../DocServer";
 import { Docs, DocUtils } from "../../documents/Documents";
 import { DragManager } from "../../util/DragManager";
 import { CompiledScript, CompileScript } from "../../util/Scripting";
@@ -44,6 +43,7 @@ interface IViewerProps {
     select: (isCtrlPressed: boolean) => void;
     startupLive: boolean;
     renderDepth: number;
+    focus: (doc: Doc) => void;
     isSelected: () => boolean;
     loaded: (nw: number, nh: number, np: number) => void;
     active: () => boolean;
@@ -108,7 +108,8 @@ export class PDFViewer extends React.Component<IViewerProps> {
         // file address of the pdf
         this._coverPath = JSON.parse(await rp.get(Utils.prepend(`/thumbnail${this.props.url.substring("files/".length, this.props.url.length - ".pdf".length)}-${NumCast(this.props.Document.curPage, 1)}.PNG`)));
         runInAction(() => this._showWaiting = this._showCover = true);
-        this._selectionReactionDisposer = reaction(() => this.props.isSelected(), () => this.props.isSelected() && SelectionManager.SelectedDocuments().length === 1 && this.setupPdfJsViewer(), { fireImmediately: this.props.startupLive });
+        this.props.startupLive && this.setupPdfJsViewer();
+        this._selectionReactionDisposer = reaction(() => this.props.isSelected(), () => (this.props.isSelected() && SelectionManager.SelectedDocuments().length === 1) && this.setupPdfJsViewer(), { fireImmediately: true });
         this._reactionDisposer = reaction(
             () => this.props.Document.scrollY,
             (scrollY) => {
@@ -136,19 +137,11 @@ export class PDFViewer extends React.Component<IViewerProps> {
         if (this.props.active() && e.clipboardData) {
             e.clipboardData.setData("text/plain", this._selectionText);
             e.clipboardData.setData("dash/pdfOrigin", this.props.Document[Id]);
-            e.clipboardData.setData("dash/pdfRegion", this.makeAnnotationDocument(undefined, "#0390fc")[Id]);
+            e.clipboardData.setData("dash/pdfRegion", this.makeAnnotationDocument("#0390fc")[Id]);
             e.preventDefault();
         }
     }
 
-    paste = (e: ClipboardEvent) => {
-        if (e.clipboardData && e.clipboardData.getData("dash/pdfOrigin") === this.props.Document[Id]) {
-            let linkDocId = e.clipboardData.getData("dash/linkDoc");
-            linkDocId && DocServer.GetRefField(linkDocId).then(async (link) =>
-                (link instanceof Doc) && (Doc.GetProto(link).anchor2 = this.makeAnnotationDocument(await Cast(Doc.GetProto(link), Doc), "#0390fc", false)));
-        }
-    }
-
     setSelectionText = (text: string) => this._selectionText = text;
 
     @action
@@ -194,13 +187,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
             { fireImmediately: true }
         );
 
-        document.removeEventListener("copy", this.copy);
-        document.addEventListener("copy", this.copy);
-        document.addEventListener("pagesinit", action(() => {
-            this.pdfViewer.currentScaleValue = this._zoomed = 1;
-            this.gotoPage(NumCast(this.props.Document.curPage, 1));
-        }));
-        document.addEventListener("pagerendered", action(() => this._showCover = this._showWaiting = false));
         this.createPdfViewer();
     }
 
@@ -212,6 +198,13 @@ export class PDFViewer extends React.Component<IViewerProps> {
             }
             return;
         }
+        document.removeEventListener("copy", this.copy);
+        document.addEventListener("copy", this.copy);
+        document.addEventListener("pagesinit", action(() => {
+            this.pdfViewer.currentScaleValue = this._zoomed = 1;
+            this.gotoPage(NumCast(this.props.Document.curPage, 1));
+        }));
+        document.addEventListener("pagerendered", action(() => this._showCover = this._showWaiting = false));
         var pdfLinkService = new PDFJSViewer.PDFLinkService();
         let pdfFindController = new PDFJSViewer.PDFFindController({
             linkService: pdfLinkService,
@@ -229,19 +222,18 @@ export class PDFViewer extends React.Component<IViewerProps> {
     }
 
     @action
-    makeAnnotationDocument = (sourceDoc: Doc | undefined, color: string, createLink: boolean = true): Doc => {
+    makeAnnotationDocument = (color: string): Doc => {
         let mainAnnoDoc = Docs.Create.InstanceFromProto(new Doc(), "", {});
         let mainAnnoDocProto = Doc.GetProto(mainAnnoDoc);
         let annoDocs: Doc[] = [];
         let minY = Number.MAX_VALUE;
-        if (this._savedAnnotations.size() === 1 && this._savedAnnotations.values()[0].length === 1 && !createLink) {
+        if (this._savedAnnotations.size() === 1 && this._savedAnnotations.values()[0].length === 1) {
             let anno = this._savedAnnotations.values()[0][0];
             let annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: "rgba(255, 0, 0, 0.1)", title: "Annotation on " + StrCast(this.props.Document.title) });
             if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
             if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
             if (anno.style.height) annoDoc.height = parseInt(anno.style.height);
             if (anno.style.width) annoDoc.width = parseInt(anno.style.width);
-            annoDoc.target = sourceDoc;
             annoDoc.group = mainAnnoDoc;
             annoDoc.color = color;
             annoDoc.type = AnnotationTypes.Region;
@@ -258,7 +250,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
                 if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
                 if (anno.style.height) annoDoc.height = parseInt(anno.style.height);
                 if (anno.style.width) annoDoc.width = parseInt(anno.style.width);
-                annoDoc.target = sourceDoc;
                 annoDoc.group = mainAnnoDoc;
                 annoDoc.color = color;
                 annoDoc.type = AnnotationTypes.Region;
@@ -272,9 +263,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
         }
         mainAnnoDocProto.title = "Annotation on " + StrCast(this.props.Document.title);
         mainAnnoDocProto.annotationOn = this.props.Document;
-        if (sourceDoc && createLink) {
-            DocUtils.MakeLink(sourceDoc, mainAnnoDocProto, undefined, `Annotation from ${StrCast(this.props.Document.title)}`);
-        }
         this._savedAnnotations.clear();
         this.Index = -1;
         return mainAnnoDoc;
@@ -529,7 +517,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
         }
 
         if (PDFMenu.Instance.Highlighting) {
-            this.highlight(undefined, "goldenrod");
+            this.highlight("goldenrod");
         }
         else {
             PDFMenu.Instance.StartDrag = this.startDrag;
@@ -540,9 +528,9 @@ export class PDFViewer extends React.Component<IViewerProps> {
     }
 
     @action
-    highlight = (targetDoc: Doc | undefined, color: string) => {
+    highlight = (color: string) => {
         // creates annotation documents for current highlights
-        let annotationDoc = this.makeAnnotationDocument(targetDoc, color, false);
+        let annotationDoc = this.makeAnnotationDocument(color);
         Doc.AddDocToList(this.props.fieldExtensionDoc, this.props.fieldExt, annotationDoc);
         return annotationDoc;
     }
@@ -555,20 +543,14 @@ export class PDFViewer extends React.Component<IViewerProps> {
     startDrag = (e: PointerEvent, ele: HTMLElement): void => {
         e.preventDefault();
         e.stopPropagation();
-        let targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "New Annotation" });
-        targetDoc.targetPage = this.getPageFromScroll(this._marqueeY);
-        let annotationDoc = this.highlight(undefined, "red");
-        annotationDoc.linkedToDoc = false;
+        let targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "Note linked to " + this.props.Document.title });
+        let annotationDoc = this.highlight("red");
         let dragData = new DragManager.AnnotationDragData(this.props.Document, annotationDoc, targetDoc);
         DragManager.StartAnnotationDrag([ele], dragData, e.pageX, e.pageY, {
             handlers: {
-                dragComplete: () => {
-                    if (!annotationDoc.linkedToDoc) {
-                        let annotations = DocListCast(annotationDoc.annotations);
-                        annotations && annotations.forEach(anno => anno.target = targetDoc);
-                        DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(this.props.Document.title)}`);
-                    }
-                }
+                dragComplete: () => !(dragData as any).linkedToDoc &&
+                    DocUtils.MakeLink({ doc: annotationDoc }, { doc: dragData.dropDocument, ctx: dragData.targetContext }, `Annotation from ${StrCast(this.props.Document.title)}`, "link from PDF")
+
             },
             hideSource: false
         });
@@ -602,6 +584,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
 
     @action.bound
     removeDocument(doc: Doc): boolean {
+        Doc.GetProto(doc).annotationOn = undefined;
         //TODO This won't create the field if it doesn't already exist
         let targetDataDoc = this.props.fieldExtensionDoc;
         let targetField = this.props.fieldExt;
@@ -634,10 +617,10 @@ export class PDFViewer extends React.Component<IViewerProps> {
 
     getCoverImage = () => {
         if (!this.props.Document[HeightSym]() || !this.props.Document.nativeHeight) {
-            setTimeout(() => {
+            setTimeout((() => {
                 this.props.Document.height = this.props.Document[WidthSym]() * this._coverPath.height / this._coverPath.width;
                 this.props.Document.nativeHeight = nativeWidth * this._coverPath.height / this._coverPath.width;
-            }, 0);
+            }).bind(this), 0);
         }
         let nativeWidth = NumCast(this.props.Document.nativeWidth);
         let nativeHeight = NumCast(this.props.Document.nativeHeight);
@@ -659,7 +642,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
     @computed get annotationLayer() {
         return <div className="pdfViewer-annotationLayer" style={{ height: NumCast(this.props.Document.nativeHeight) }} ref={this._annotationLayer}>
             {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) =>
-                <Annotation {...this.props} anno={anno} key={`${anno[Id]}-annotation`} />)}
+                <Annotation {...this.props} focus={this.props.focus} anno={anno} key={`${anno[Id]}-annotation`} />)}
         </div>;
     }
     @computed get pdfViewerDiv() {
@@ -686,7 +669,8 @@ export class PDFViewer extends React.Component<IViewerProps> {
                     setPreviewCursor={this.setPreviewCursor}
                     PanelHeight={() => NumCast(this.props.Document.scrollHeight, NumCast(this.props.Document.nativeHeight))}
                     PanelWidth={() => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : NumCast(this.props.Document.nativeWidth)}
-                    focus={emptyFunction}
+                    VisibleHeight={() => this.props.PanelHeight() / this.props.ContentScaling() * 72 / 96}
+                    focus={this.props.focus}
                     isSelected={this.props.isSelected}
                     select={emptyFunction}
                     active={this.active}
@@ -694,7 +678,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
                     whenActiveChanged={this.whenActiveChanged}
                     removeDocument={this.removeDocument}
                     moveDocument={this.moveDocument}
-                    addDocument={(doc: Doc, allow: boolean | undefined) => { Doc.AddDocToList(this.props.fieldExtensionDoc, this.props.fieldExt, doc); return true; }}
+                    addDocument={(doc: Doc, allow: boolean | undefined) => { Doc.GetProto(doc).annotationOn = this.props.Document; Doc.AddDocToList(this.props.fieldExtensionDoc, this.props.fieldExt, doc); return true; }}
                     CollectionView={this.props.ContainingCollectionView}
                     ScreenToLocalTransform={this.scrollXf}
                     ruleProvider={undefined}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index de3242d32..daf000dc7 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -63,13 +63,11 @@ export class PresElementBox extends React.Component<FieldViewProps> {
         this.hideTillShownButton = !this.hideTillShownButton;
         if (!this.hideTillShownButton) {
             if (this.myIndex >= this.currentIndex) {
-                (this.props.Document.target as Doc).opacity = 1;
+                (this.props.Document.presentationTargetDoc as Doc).opacity = 1;
             }
         } else {
-            if (this.presentationDoc.presStatus) {
-                if (this.myIndex > this.currentIndex) {
-                    (this.props.Document.target as Doc).opacity = 0;
-                }
+            if (this.presentationDoc.presStatus && this.myIndex > this.currentIndex) {
+                (this.props.Document.presentationTargetDoc as Doc).opacity = 0;
             }
         }
     }
@@ -85,14 +83,12 @@ export class PresElementBox extends React.Component<FieldViewProps> {
         this.hideAfterButton = !this.hideAfterButton;
         if (!this.hideAfterButton) {
             if (this.myIndex <= this.currentIndex) {
-                (this.props.Document.target as Doc).opacity = 1;
+                (this.props.Document.presentationTargetDoc as Doc).opacity = 1;
             }
         } else {
             if (this.fadeButton) this.fadeButton = false;
-            if (this.presentationDoc.presStatus) {
-                if (this.myIndex < this.currentIndex) {
-                    (this.props.Document.target as Doc).opacity = 0;
-                }
+            if (this.presentationDoc.presStatus && this.myIndex < this.currentIndex) {
+                (this.props.Document.presentationTargetDoc as Doc).opacity = 0;
             }
         }
     }
@@ -108,14 +104,12 @@ export class PresElementBox extends React.Component<FieldViewProps> {
         this.fadeButton = !this.fadeButton;
         if (!this.fadeButton) {
             if (this.myIndex <= this.currentIndex) {
-                (this.props.Document.target as Doc).opacity = 1;
+                (this.props.Document.presentationTargetDoc as Doc).opacity = 1;
             }
         } else {
             this.hideAfterButton = false;
-            if (this.presentationDoc.presStatus) {
-                if (this.myIndex < this.currentIndex) {
-                    (this.props.Document.target as Doc).opacity = 0.5;
-                }
+            if (this.presentationDoc.presStatus && (this.myIndex < this.currentIndex)) {
+                (this.props.Document.presentationTargetDoc as Doc).opacity = 0.5;
             }
         }
     }
@@ -162,7 +156,7 @@ export class PresElementBox extends React.Component<FieldViewProps> {
      * presentation element.
      */
     renderEmbeddedInline = () => {
-        if (!this.embedOpen || !(this.props.Document.target instanceof Doc)) {
+        if (!this.embedOpen || !(this.props.Document.presentationTargetDoc instanceof Doc)) {
             return (null);
         }
 
@@ -175,8 +169,8 @@ export class PresElementBox extends React.Component<FieldViewProps> {
                 width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
             }}>
                 <CollectionSchemaPreview
-                    fitToBox={StrCast(this.props.Document.target.type).indexOf(DocumentType.COL) !== -1}
-                    Document={this.props.Document.target}
+                    fitToBox={StrCast(this.props.Document.presentationTargetDoc.type).indexOf(DocumentType.COL) !== -1}
+                    Document={this.props.Document.presentationTargetDoc}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
                     ruleProvider={undefined}
@@ -205,7 +199,7 @@ export class PresElementBox extends React.Component<FieldViewProps> {
         let pbi = "presElementBox-interaction";
         return (
             <div className={className} key={p.Document[Id] + this.myIndex}
-                style={{ outlineWidth: Doc.IsBrushed(p.Document.target as Doc) ? `1px` : "0px", }}
+                style={{ outlineWidth: Doc.IsBrushed(p.Document.presentationTargetDoc as Doc) ? `1px` : "0px", }}
                 onClick={e => { p.focus(p.Document); e.stopPropagation(); }}>
                 {treecontainer ? (null) : <>
                     <strong className="presElementBox-name">
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index aeffc81c4..58304cebb 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -665,10 +665,12 @@ export namespace Doc {
     export function BrushDoc(doc: Doc) {
         brushManager.BrushedDoc.set(doc, true);
         brushManager.BrushedDoc.set(Doc.GetDataDoc(doc), true);
+        return doc;
     }
     export function UnBrushDoc(doc: Doc) {
         brushManager.BrushedDoc.delete(doc);
         brushManager.BrushedDoc.delete(Doc.GetDataDoc(doc));
+        return doc;
     }
 
     export class HighlightBrush {
-- 
cgit v1.2.3-70-g09d2


From 3ba540a0aecc624f9c81f32102441d6d137ade85 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 5 Oct 2019 10:35:33 -0400
Subject: fixed adding to presentation box when minimized

---
 src/client/views/OverlayView.tsx                              | 11 ++++++-----
 .../collections/collectionFreeForm/CollectionFreeFormView.tsx |  4 ++--
 src/client/views/nodes/DocumentView.tsx                       |  5 +++--
 src/client/views/nodes/PresBox.tsx                            |  9 ++++-----
 4 files changed, 15 insertions(+), 14 deletions(-)

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

diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index bb6dd5076..95c7b2683 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -145,6 +145,7 @@ export class OverlayView extends React.Component {
             return (null);
         }
         return CurrentUserUtils.UserDocument.overlays instanceof Doc && DocListCast(CurrentUserUtils.UserDocument.overlays.data).map(d => {
+            d.inOverlay = true;
             let offsetx = 0, offsety = 0;
             let onPointerMove = action((e: PointerEvent) => {
                 if (e.buttons === 1) {
@@ -170,14 +171,14 @@ export class OverlayView extends React.Component {
                 document.addEventListener("pointerup", onPointerUp);
             };
             return <div className="overlayView-doc" key={d[Id]} onPointerDown={onPointerDown} style={{ transform: `translate(${d.x}px, ${d.y}px)`, display: d.isMinimized ? "none" : "" }}>
-                <DocumentContentsView
+                <DocumentView
                     Document={d}
                     ChromeHeight={returnZero}
-                    isSelected={returnFalse}
-                    select={emptyFunction}
-                    ruleProvider={undefined}
-                    layoutKey={"layout"}
+                    // isSelected={returnFalse}
+                    // select={emptyFunction}
+                    // layoutKey={"layout"}
                     bringToFront={emptyFunction}
+                    ruleProvider={undefined}
                     addDocument={undefined}
                     removeDocument={undefined}
                     ContentScaling={returnOne}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 4bdede48a..7b29f2c2a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -338,7 +338,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     onPointerWheel = (e: React.WheelEvent): void => {
-        if (this.props.Document.lockedPosition || this.isAnnotationOverlay) return;
+        if (this.props.Document.lockedPosition || this.props.Document.inOverlay || this.isAnnotationOverlay) return;
         if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming
             e.stopPropagation();
         }
@@ -360,7 +360,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     setPan(panX: number, panY: number) {
-        if (!this.props.Document.lockedPosition) {
+        if (!this.props.Document.lockedPosition || this.props.Document.inOverlay) {
             this.props.Document.panTransformType = "None";
             var scale = this.getLocalTransform().inverse().Scale;
             const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 54fafc20b..e50008fdf 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -111,6 +111,7 @@ export const documentSchema = createSchema({
     type: "string",             // enumerated type of document
     maximizeLocation: "string", // flag for where to place content when following a click interaction (e.g., onRight, inPlace, inTab) 
     lockedPosition: "boolean",  // whether the document can be spatially manipulated
+    inOverlay: "boolean",       // whether the document is rendered in an OverlayView which handles selection/dragging differently
     borderRounding: "string",   // border radius rounding of document
     searchFields: "string",     // the search fields to display when this document matches a search in its metadata
     heading: "number",          // the logical layout 'heading' of this document (used by rule provider to stylize h1 header elements, from h2, etc)
@@ -243,7 +244,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 this._hitTemplateDrag = true;
             }
         }
-        if (this.active && e.button === 0 && !this.Document.lockedPosition) e.stopPropagation(); // events stop at the lowest document that is active.  if right dragging, we let it go through though to allow for context menu clicks. PointerMove callbacks should remove themselves if the move event gets stopPropagated by a lower-level handler (e.g, marquee drag);
+        if (this.active && e.button === 0 && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation(); // events stop at the lowest document that is active.  if right dragging, we let it go through though to allow for context menu clicks. PointerMove callbacks should remove themselves if the move event gets stopPropagated by a lower-level handler (e.g, marquee drag);
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
         document.addEventListener("pointermove", this.onPointerMove);
@@ -253,7 +254,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         if (e.cancelBubble && this.active) {
             document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView)
         }
-        else if (!e.cancelBubble && (SelectionManager.IsSelected(this) || this.props.parentActive()) && !this.Document.lockedPosition) {
+        else if (!e.cancelBubble && (SelectionManager.IsSelected(this) || this.props.parentActive()) && !this.Document.lockedPosition && !this.Document.inOverlay) {
             if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
                 if (!e.altKey && !this.topMost && e.buttons === 1) {
                     document.removeEventListener("pointermove", this.onPointerMove);
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 180ed9032..15fafb022 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -314,12 +314,11 @@ export class PresBox extends React.Component<FieldViewProps> {
     }
 
     toggleMinimize = undoBatch(action((e: React.PointerEvent) => {
-        if (this.props.Document.minimizedView) {
-            this.props.Document.minimizedView = false;
+        if (this.props.Document.inOverlay) {
             Doc.RemoveDocFromList((CurrentUserUtils.UserDocument.overlays as Doc), this.props.fieldKey, this.props.Document);
             CollectionDockingView.AddRightSplit(this.props.Document, this.props.DataDoc);
+            this.props.Document.inOverlay = false;
         } else {
-            this.props.Document.minimizedView = true;
             this.props.Document.x = e.clientX + 25;
             this.props.Document.y = e.clientY - 25;
             this.props.addDocTab && this.props.addDocTab(this.props.Document, this.props.DataDoc, "close");
@@ -370,9 +369,9 @@ export class PresBox extends React.Component<FieldViewProps> {
                         <FontAwesomeIcon icon={this.props.Document.presStatus ? "stop" : "play"} />
                     </button>
                     <button className="presBox-button" title="Next" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></button>
-                    <button className="presBox-button" title={this.props.Document.minimizedView ? "Expand" : "Minimize"} onClick={this.toggleMinimize}><FontAwesomeIcon icon={"eye"} /></button>
+                    <button className="presBox-button" title={this.props.Document.inOverlay ? "Expand" : "Minimize"} onClick={this.toggleMinimize}><FontAwesomeIcon icon={"eye"} /></button>
                 </div>
-                {this.props.Document.minimizedView ? (null) :
+                {this.props.Document.inOverlay ? (null) :
                     <div className="presBox-listCont" >
                         <CollectionView {...this.props} focus={this.selectElement} ScreenToLocalTransform={this.getTransform} />
                     </div>
-- 
cgit v1.2.3-70-g09d2

