From 945fb1c28fa94ee1d2448381d7dd55b99214aad4 Mon Sep 17 00:00:00 2001
From: Monika Hedman <monika_hedman@brown.edu>
Date: Mon, 1 Apr 2019 22:04:42 -0400
Subject: icon not working

---
 src/client/views/nodes/DocumentView.tsx | 669 ++++++++++++++++++++------------
 1 file changed, 411 insertions(+), 258 deletions(-)

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

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 1195128dc..085307461 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,4 +1,13 @@
-import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx";
+import {
+  action,
+  computed,
+  IReactionDisposer,
+  reaction,
+  runInAction,
+  observable
+} from "mobx";
+import { library } from "@fortawesome/fontawesome-svg-core";
+import { faSquare } from "@fortawesome/free-solid-svg-icons";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { Field, Opt, FieldWaiting } from "../../../fields/Field";
@@ -13,30 +22,35 @@ import { DragManager } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionView, CollectionViewType } from "../collections/CollectionView";
+import {
+  CollectionView,
+  CollectionViewType
+} from "../collections/CollectionView";
 import { ContextMenu } from "../ContextMenu";
 import { DocumentContentsView } from "./DocumentContentsView";
 import "./DocumentView.scss";
 import React = require("react");
 import { ServerUtils } from "../../../server/ServerUtil";
+import { DocumentDecorations } from "../DocumentDecorations";
 
+library.add(faSquare);
 
 export interface DocumentViewProps {
-    ContainingCollectionView: Opt<CollectionView>;
-    Document: Document;
-    AddDocument?: (doc: Document, allowDuplicates: boolean) => boolean;
-    RemoveDocument?: (doc: Document) => boolean;
-    ScreenToLocalTransform: () => Transform;
-    isTopMost: boolean;
-    ContentScaling: () => number;
-    PanelWidth: () => number;
-    PanelHeight: () => number;
-    focus: (doc: Document) => void;
-    SelectOnLoad: boolean;
+  ContainingCollectionView: Opt<CollectionView>;
+  Document: Document;
+  AddDocument?: (doc: Document, allowDuplicates: boolean) => boolean;
+  RemoveDocument?: (doc: Document) => boolean;
+  ScreenToLocalTransform: () => Transform;
+  isTopMost: boolean;
+  ContentScaling: () => number;
+  PanelWidth: () => number;
+  PanelHeight: () => number;
+  focus: (doc: Document) => void;
+  SelectOnLoad: boolean;
 }
 export interface JsxArgs extends DocumentViewProps {
-    Keys: { [name: string]: Key }
-    Fields: { [name: string]: Field }
+  Keys: { [name: string]: Key };
+  Fields: { [name: string]: Field };
 }
 
 /*
@@ -55,287 +69,426 @@ Example usage of this function:
     }
 */
 export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs {
-    let Keys: { [name: string]: any } = {}
-    let Fields: { [name: string]: any } = {}
-    for (const key of keys) {
-        let fn = () => { }
-        Object.defineProperty(fn, "name", { value: key + "Key" })
-        Keys[key] = fn;
-    }
-    for (const field of fields) {
-        let fn = () => { }
-        Object.defineProperty(fn, "name", { value: field })
-        Fields[field] = fn;
-    }
-    let args: JsxArgs = {
-        Document: function Document() { },
-        DocumentView: function DocumentView() { },
-        Keys,
-        Fields
-    } as any;
-    return args;
+  let Keys: { [name: string]: any } = {};
+  let Fields: { [name: string]: any } = {};
+  for (const key of keys) {
+    let fn = () => {};
+    Object.defineProperty(fn, "name", { value: key + "Key" });
+    Keys[key] = fn;
+  }
+  for (const field of fields) {
+    let fn = () => {};
+    Object.defineProperty(fn, "name", { value: field });
+    Fields[field] = fn;
+  }
+  let args: JsxArgs = {
+    Document: function Document() {},
+    DocumentView: function DocumentView() {},
+    Keys,
+    Fields
+  } as any;
+  return args;
 }
 
 export interface JsxBindings {
-    Document: Document;
-    isSelected: () => boolean;
-    select: (isCtrlPressed: boolean) => void;
-    isTopMost: boolean;
-    SelectOnLoad: boolean;
-    [prop: string]: any;
+  Document: Document;
+  isSelected: () => boolean;
+  select: (isCtrlPressed: boolean) => void;
+  isTopMost: boolean;
+  SelectOnLoad: boolean;
+  [prop: string]: any;
 }
 
-
-
 @observer
 export class DocumentView extends React.Component<DocumentViewProps> {
-    private _mainCont = React.createRef<HTMLDivElement>();
-    private _downX: number = 0;
-    private _downY: number = 0;
-    private _reactionDisposer: Opt<IReactionDisposer>;
-    @computed get active(): boolean { return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView || this.props.ContainingCollectionView.active(); }
-    @computed get topMost(): boolean { return !this.props.ContainingCollectionView || this.props.ContainingCollectionView.collectionViewType == CollectionViewType.Docking; }
-    @computed get layout(): string { return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>"); }
-    @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array<Key>()); }
-    @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); }
-    screenRect = (): ClientRect | DOMRect => this._mainCont.current ? this._mainCont.current.getBoundingClientRect() : new DOMRect();
-    onPointerDown = (e: React.PointerEvent): void => {
-        this._downX = e.clientX;
-        this._downY = e.clientY;
-        if (e.shiftKey && e.buttons === 2) {
-            if (this.props.isTopMost) {
-                this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey);
-            }
-            else CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e);
-            e.stopPropagation();
-        } else {
-            if (this.active && !e.isDefaultPrevented()) {
-                e.stopPropagation();
-                document.removeEventListener("pointermove", this.onPointerMove)
-                document.addEventListener("pointermove", this.onPointerMove);
-                document.removeEventListener("pointerup", this.onPointerUp)
-                document.addEventListener("pointerup", this.onPointerUp);
-            }
-        }
+  private _mainCont = React.createRef<HTMLDivElement>();
+  private _downX: number = 0;
+  private _downY: number = 0;
+
+  @observable
+  private minimized: boolean = false;
+
+  private _reactionDisposer: Opt<IReactionDisposer>;
+  @computed get active(): boolean {
+    return (
+      SelectionManager.IsSelected(this) ||
+      !this.props.ContainingCollectionView ||
+      this.props.ContainingCollectionView.active()
+    );
+  }
+  @computed get topMost(): boolean {
+    return (
+      !this.props.ContainingCollectionView ||
+      this.props.ContainingCollectionView.collectionViewType ==
+        CollectionViewType.Docking
+    );
+  }
+  @computed get layout(): string {
+    return this.props.Document.GetText(
+      KeyStore.Layout,
+      "<p>Error loading layout data</p>"
+    );
+  }
+  @computed get layoutKeys(): Key[] {
+    return this.props.Document.GetData(
+      KeyStore.LayoutKeys,
+      ListField,
+      new Array<Key>()
+    );
+  }
+  @computed get layoutFields(): Key[] {
+    return this.props.Document.GetData(
+      KeyStore.LayoutFields,
+      ListField,
+      new Array<Key>()
+    );
+  }
+  screenRect = (): ClientRect | DOMRect =>
+    this._mainCont.current
+      ? this._mainCont.current.getBoundingClientRect()
+      : new DOMRect();
+  onPointerDown = (e: React.PointerEvent): void => {
+    this._downX = e.clientX;
+    this._downY = e.clientY;
+    if (e.shiftKey && e.buttons === 2) {
+      if (this.props.isTopMost) {
+        this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey);
+      } else
+        CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e);
+      e.stopPropagation();
+    } else {
+      if (this.active && !e.isDefaultPrevented()) {
+        e.stopPropagation();
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.addEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+        document.addEventListener("pointerup", this.onPointerUp);
+      }
     }
+  };
 
-    private dropDisposer?: DragManager.DragDropDisposer;
+  private dropDisposer?: DragManager.DragDropDisposer;
 
-    componentDidMount() {
-        if (this._mainCont.current) {
-            this.dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } });
-        }
-        runInAction(() => DocumentManager.Instance.DocumentViews.push(this))
-        this._reactionDisposer = reaction(
-            () => this.props.ContainingCollectionView && this.props.ContainingCollectionView.SelectedDocs.slice(),
-            () => {
-                if (this.props.ContainingCollectionView && this.props.ContainingCollectionView.SelectedDocs.indexOf(this.props.Document.Id) != -1)
-                    SelectionManager.SelectDoc(this, true);
-            });
+  componentDidMount() {
+    if (this._mainCont.current) {
+      this.dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, {
+        handlers: { drop: this.drop.bind(this) }
+      });
     }
+    runInAction(() => DocumentManager.Instance.DocumentViews.push(this));
+    this._reactionDisposer = reaction(
+      () =>
+        this.props.ContainingCollectionView &&
+        this.props.ContainingCollectionView.SelectedDocs.slice(),
+      () => {
+        if (
+          this.props.ContainingCollectionView &&
+          this.props.ContainingCollectionView.SelectedDocs.indexOf(
+            this.props.Document.Id
+          ) != -1
+        )
+          SelectionManager.SelectDoc(this, true);
+      }
+    );
+  }
 
-    componentDidUpdate() {
-        if (this.dropDisposer) {
-            this.dropDisposer();
-        }
-        if (this._mainCont.current) {
-            this.dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } });
-        }
+  componentDidUpdate() {
+    if (this.dropDisposer) {
+      this.dropDisposer();
+    }
+    if (this._mainCont.current) {
+      this.dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, {
+        handlers: { drop: this.drop.bind(this) }
+      });
     }
+  }
 
-    componentWillUnmount() {
-        if (this.dropDisposer) {
-            this.dropDisposer();
-        }
-        runInAction(() => DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1))
-        if (this._reactionDisposer) {
-            this._reactionDisposer();
-        }
+  componentWillUnmount() {
+    if (this.dropDisposer) {
+      this.dropDisposer();
+    }
+    runInAction(() =>
+      DocumentManager.Instance.DocumentViews.splice(
+        DocumentManager.Instance.DocumentViews.indexOf(this),
+        1
+      )
+    );
+    if (this._reactionDisposer) {
+      this._reactionDisposer();
     }
+  }
 
-    startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) {
-        if (this._mainCont.current) {
-            const [left, top] = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
-            let dragData = new DragManager.DocumentDragData([this.props.Document]);
-            dragData.aliasOnDrop = dropAliasOfDraggedDoc;
-            dragData.xOffset = x - left;
-            dragData.yOffset = y - top;
-            dragData.removeDocument = (dropCollectionView: CollectionView) => {
-                if (this.props.RemoveDocument && this.props.ContainingCollectionView !== dropCollectionView) {
-                    this.props.RemoveDocument(this.props.Document);
-                }
-            }
-            DragManager.StartDocumentDrag([this._mainCont.current], dragData, {
-                handlers: {
-                    dragComplete: action(() => { }),
-                },
-                hideSource: !dropAliasOfDraggedDoc
-            })
+  startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) {
+    if (this._mainCont.current) {
+      const [left, top] = this.props
+        .ScreenToLocalTransform()
+        .inverse()
+        .transformPoint(0, 0);
+      let dragData = new DragManager.DocumentDragData([this.props.Document]);
+      dragData.aliasOnDrop = dropAliasOfDraggedDoc;
+      dragData.xOffset = x - left;
+      dragData.yOffset = y - top;
+      dragData.removeDocument = (dropCollectionView: CollectionView) => {
+        if (
+          this.props.RemoveDocument &&
+          this.props.ContainingCollectionView !== dropCollectionView
+        ) {
+          this.props.RemoveDocument(this.props.Document);
         }
+      };
+      DragManager.StartDocumentDrag([this._mainCont.current], dragData, {
+        handlers: {
+          dragComplete: action(() => {})
+        },
+        hideSource: !dropAliasOfDraggedDoc
+      });
     }
+  }
 
-    onPointerMove = (e: PointerEvent): void => {
-        if (e.cancelBubble) {
-            return;
-        }
-        if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
-            document.removeEventListener("pointermove", this.onPointerMove)
-            document.removeEventListener("pointerup", this.onPointerUp);
-            if (!this.topMost || e.buttons == 2 || e.altKey) {
-                this.startDragging(e.x, e.y, e.ctrlKey || e.altKey);
-            }
-        }
-        e.stopPropagation();
-        e.preventDefault();
+  onPointerMove = (e: PointerEvent): void => {
+    if (e.cancelBubble) {
+      return;
     }
-    onPointerUp = (e: PointerEvent): void => {
-        document.removeEventListener("pointermove", this.onPointerMove)
-        document.removeEventListener("pointerup", this.onPointerUp)
-        e.stopPropagation();
-        if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) {
-            SelectionManager.SelectDoc(this, e.ctrlKey);
-        }
+    if (
+      Math.abs(this._downX - e.clientX) > 3 ||
+      Math.abs(this._downY - e.clientY) > 3
+    ) {
+      document.removeEventListener("pointermove", this.onPointerMove);
+      document.removeEventListener("pointerup", this.onPointerUp);
+      if (!this.topMost || e.buttons == 2 || e.altKey) {
+        this.startDragging(e.x, e.y, e.ctrlKey || e.altKey);
+      }
     }
-    stopPropogation = (e: React.SyntheticEvent) => {
-        e.stopPropagation();
+    e.stopPropagation();
+    e.preventDefault();
+  };
+  onPointerUp = (e: PointerEvent): void => {
+    document.removeEventListener("pointermove", this.onPointerMove);
+    document.removeEventListener("pointerup", this.onPointerUp);
+    e.stopPropagation();
+    if (
+      Math.abs(e.clientX - this._downX) < 4 &&
+      Math.abs(e.clientY - this._downY) < 4
+    ) {
+      SelectionManager.SelectDoc(this, e.ctrlKey);
     }
+  };
+  stopPropogation = (e: React.SyntheticEvent) => {
+    e.stopPropagation();
+  };
 
-    deleteClicked = (): void => {
-        if (this.props.RemoveDocument) {
-            this.props.RemoveDocument(this.props.Document);
-        }
+  deleteClicked = (): void => {
+    if (this.props.RemoveDocument) {
+      this.props.RemoveDocument(this.props.Document);
     }
+  };
 
-    fieldsClicked = (e: React.MouseEvent): void => {
-        if (this.props.AddDocument) {
-            this.props.AddDocument(Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }), false);
-        }
-    }
-    fullScreenClicked = (e: React.MouseEvent): void => {
-        CollectionDockingView.Instance.OpenFullScreen(this.props.Document);
-        ContextMenu.Instance.clearItems();
-        ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked });
-        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
+  fieldsClicked = (e: React.MouseEvent): void => {
+    if (this.props.AddDocument) {
+      this.props.AddDocument(
+        Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }),
+        false
+      );
     }
+  };
+  fullScreenClicked = (e: React.MouseEvent): void => {
+    CollectionDockingView.Instance.OpenFullScreen(this.props.Document);
+    ContextMenu.Instance.clearItems();
+    ContextMenu.Instance.addItem({
+      description: "Close Full Screen",
+      event: this.closeFullScreenClicked
+    });
+    ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+  };
 
-    closeFullScreenClicked = (e: React.MouseEvent): void => {
-        CollectionDockingView.Instance.CloseFullScreen();
-        ContextMenu.Instance.clearItems();
-        ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
-        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
-    }
+  closeFullScreenClicked = (e: React.MouseEvent): void => {
+    CollectionDockingView.Instance.CloseFullScreen();
+    ContextMenu.Instance.clearItems();
+    ContextMenu.Instance.addItem({
+      description: "Full Screen",
+      event: this.fullScreenClicked
+    });
+    ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+  };
 
-    @action
-    drop = (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.LinkDragData) {
-            let sourceDoc: Document = de.data.linkSourceDocumentView.props.Document;
-            let destDoc: Document = this.props.Document;
-            if (this.props.isTopMost) {
-                return;
-            }
-            let linkDoc: Document = new Document();
+  @action
+  minimize = (e: React.MouseEvent): void => {
+    this.minimized = true;
+    SelectionManager.DeselectAll();
+  };
 
-            destDoc.GetTAsync(KeyStore.Prototype, Document).then((protoDest) =>
-                sourceDoc.GetTAsync(KeyStore.Prototype, Document).then((protoSrc) => runInAction(() => {
-                    linkDoc.Set(KeyStore.Title, new TextField("New Link"));
-                    linkDoc.Set(KeyStore.LinkDescription, new TextField(""));
-                    linkDoc.Set(KeyStore.LinkTags, new TextField("Default"));
+  @action
+  drop = (e: Event, de: DragManager.DropEvent) => {
+    if (de.data instanceof DragManager.LinkDragData) {
+      let sourceDoc: Document = de.data.linkSourceDocumentView.props.Document;
+      let destDoc: Document = this.props.Document;
+      if (this.props.isTopMost) {
+        return;
+      }
+      let linkDoc: Document = new Document();
 
-                    let dstTarg = (protoDest ? protoDest : destDoc);
-                    let srcTarg = (protoSrc ? protoSrc : sourceDoc);
-                    linkDoc.Set(KeyStore.LinkedToDocs, dstTarg);
-                    linkDoc.Set(KeyStore.LinkedFromDocs, srcTarg);
-                    dstTarg.GetOrCreateAsync(KeyStore.LinkedFromDocs, ListField, field => { (field as ListField<Document>).Data.push(linkDoc) })
-                    srcTarg.GetOrCreateAsync(KeyStore.LinkedToDocs, ListField, field => { (field as ListField<Document>).Data.push(linkDoc) })
-                }))
-            )
-            e.stopPropagation();
-        }
-    }
+      destDoc.GetTAsync(KeyStore.Prototype, Document).then(protoDest =>
+        sourceDoc.GetTAsync(KeyStore.Prototype, Document).then(protoSrc =>
+          runInAction(() => {
+            linkDoc.Set(KeyStore.Title, new TextField("New Link"));
+            linkDoc.Set(KeyStore.LinkDescription, new TextField(""));
+            linkDoc.Set(KeyStore.LinkTags, new TextField("Default"));
 
-    onDrop = (e: React.DragEvent) => {
-        if (e.isDefaultPrevented()) {
-            return;
-        }
-        let text = e.dataTransfer.getData("text/plain");
-        if (text && text.startsWith("<div")) {
-            let oldLayout = this.props.Document.GetText(KeyStore.Layout, "");
-            let layout = text.replace("{layout}", oldLayout);
-            this.props.Document.SetText(KeyStore.Layout, layout);
-            e.stopPropagation();
-            e.preventDefault();
-        }
+            let dstTarg = protoDest ? protoDest : destDoc;
+            let srcTarg = protoSrc ? protoSrc : sourceDoc;
+            linkDoc.Set(KeyStore.LinkedToDocs, dstTarg);
+            linkDoc.Set(KeyStore.LinkedFromDocs, srcTarg);
+            dstTarg.GetOrCreateAsync(
+              KeyStore.LinkedFromDocs,
+              ListField,
+              field => {
+                (field as ListField<Document>).Data.push(linkDoc);
+              }
+            );
+            srcTarg.GetOrCreateAsync(
+              KeyStore.LinkedToDocs,
+              ListField,
+              field => {
+                (field as ListField<Document>).Data.push(linkDoc);
+              }
+            );
+          })
+        )
+      );
+      e.stopPropagation();
     }
+  };
 
-    @action
-    onContextMenu = (e: React.MouseEvent): void => {
-        e.stopPropagation();
-        let moved = Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3;
-        if (moved || e.isDefaultPrevented()) {
-            e.preventDefault()
-            return;
-        }
-        e.preventDefault()
+  onDrop = (e: React.DragEvent) => {
+    if (e.isDefaultPrevented()) {
+      return;
+    }
+    let text = e.dataTransfer.getData("text/plain");
+    if (text && text.startsWith("<div")) {
+      let oldLayout = this.props.Document.GetText(KeyStore.Layout, "");
+      let layout = text.replace("{layout}", oldLayout);
+      this.props.Document.SetText(KeyStore.Layout, layout);
+      e.stopPropagation();
+      e.preventDefault();
+    }
+  };
 
-        ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked })
-        ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked })
-        ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) })
-        ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) })
-        ContextMenu.Instance.addItem({
-            description: "Copy URL",
-            event: () => {
-                Utils.CopyText(ServerUtils.prepend("/doc/" + this.props.Document.Id));
-            }
-        });
-        ContextMenu.Instance.addItem({
-            description: "Copy ID",
-            event: () => {
-                Utils.CopyText(this.props.Document.Id);
-            }
-        });
-        //ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) })
-        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
-        if (!this.topMost) {
-            // DocumentViews should stop propagation of this event
-            e.stopPropagation();
-        }
+  @action
+  onContextMenu = (e: React.MouseEvent): void => {
+    e.stopPropagation();
+    let moved =
+      Math.abs(this._downX - e.clientX) > 3 ||
+      Math.abs(this._downY - e.clientY) > 3;
+    if (moved || e.isDefaultPrevented()) {
+      e.preventDefault();
+      return;
+    }
+    e.preventDefault();
 
-        ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked })
-        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
-        SelectionManager.SelectDoc(this, e.ctrlKey);
+    //for testing purposes
+    ContextMenu.Instance.addItem({
+      description: "Minimize",
+      event: this.minimize
+    });
+    ContextMenu.Instance.addItem({
+      description: "Full Screen",
+      event: this.fullScreenClicked
+    });
+    ContextMenu.Instance.addItem({
+      description: "Fields",
+      event: this.fieldsClicked
+    });
+    ContextMenu.Instance.addItem({
+      description: "Center",
+      event: () => this.props.focus(this.props.Document)
+    });
+    ContextMenu.Instance.addItem({
+      description: "Open Right",
+      event: () =>
+        CollectionDockingView.Instance.AddRightSplit(this.props.Document)
+    });
+    ContextMenu.Instance.addItem({
+      description: "Copy URL",
+      event: () => {
+        Utils.CopyText(ServerUtils.prepend("/doc/" + this.props.Document.Id));
+      }
+    });
+    ContextMenu.Instance.addItem({
+      description: "Copy ID",
+      event: () => {
+        Utils.CopyText(this.props.Document.Id);
+      }
+    });
+    //ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) })
+    ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+    if (!this.topMost) {
+      // DocumentViews should stop propagation of this event
+      e.stopPropagation();
     }
 
+    ContextMenu.Instance.addItem({
+      description: "Delete",
+      event: this.deleteClicked
+    });
+    ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+    SelectionManager.SelectDoc(this, e.ctrlKey);
+  };
 
-    isSelected = () => {
-        return SelectionManager.IsSelected(this);
-    }
+  isMinimized = () => {
+    return this.minimized;
+  };
 
-    select = (ctrlPressed: boolean) => {
-        SelectionManager.SelectDoc(this, ctrlPressed)
-    }
+  isSelected = () => {
+    return SelectionManager.IsSelected(this);
+  };
 
-    render() {
-        if (!this.props.Document) {
-            return (null);
-        }
-        var scaling = this.props.ContentScaling();
-        var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
-        var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
-        var backgroundcolor = this.props.Document.GetText(KeyStore.BackgroundColor, "");
-        return (
-            <div className="documentView-node" ref={this._mainCont}
-                style={{
-                    background: backgroundcolor,
-                    width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%",
-                    height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%",
-                    transformOrigin: "left top",
-                    transform: `scale(${scaling} , ${scaling})`
-                }}
-                onDrop={this.onDrop}
-                onContextMenu={this.onContextMenu}
-                onPointerDown={this.onPointerDown} >
-                <DocumentContentsView {...this.props} isSelected={this.isSelected} select={this.select} layoutKey={KeyStore.Layout} />
-            </div >
-        )
+  select = (ctrlPressed: boolean) => {
+    SelectionManager.SelectDoc(this, ctrlPressed);
+  };
+
+  render() {
+    if (!this.props.Document) {
+      return null;
     }
-}
\ No newline at end of file
+    if (this.minimized) {
+      return (
+        //<i class="fas fa-square" />
+        <div className="minimized-box" />
+      );
+    } else {
+      var scaling = this.props.ContentScaling();
+      var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
+      var nativeHeight = this.props.Document.GetNumber(
+        KeyStore.NativeHeight,
+        0
+      );
+      var backgroundcolor = this.props.Document.GetText(
+        KeyStore.BackgroundColor,
+        ""
+      );
+      return (
+        <div
+          className="documentView-node"
+          ref={this._mainCont}
+          style={{
+            background: backgroundcolor,
+            width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%",
+            height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%",
+            transformOrigin: "left top",
+            transform: `scale(${scaling} , ${scaling})`
+          }}
+          onDrop={this.onDrop}
+          onContextMenu={this.onContextMenu}
+          onPointerDown={this.onPointerDown}
+        >
+          <DocumentContentsView
+            {...this.props}
+            isSelected={this.isSelected}
+            select={this.select}
+            layoutKey={KeyStore.Layout}
+          />
+        </div>
+      );
+    }
+  }
+}
-- 
cgit v1.2.3-70-g09d2


From 7fdf7396a8bdb2e4f8c3b27ca99a36727d85adae Mon Sep 17 00:00:00 2001
From: Monika Hedman <monika_hedman@brown.edu>
Date: Mon, 1 Apr 2019 23:07:04 -0400
Subject: minimize sorta works???

---
 src/client/util/DragManager.ts            | 485 +++++++++++++++++-------------
 src/client/views/DocumentDecorations.scss |   9 +-
 src/client/views/nodes/DocumentView.scss  |   6 +-
 src/client/views/nodes/DocumentView.tsx   |  32 +-
 src/client/views/nodes/Sticky.tsx         | 138 ++++-----
 5 files changed, 375 insertions(+), 295 deletions(-)

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

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 9ffe964ef..ee0b5333c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,251 +1,312 @@
 import { DocumentDecorations } from "../views/DocumentDecorations";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
-import { Document } from "../../fields/Document"
+import { Document } from "../../fields/Document";
 import { action } from "mobx";
 import { ImageField } from "../../fields/ImageField";
 import { KeyStore } from "../../fields/KeyStore";
 import { CollectionView } from "../views/collections/CollectionView";
 import { DocumentView } from "../views/nodes/DocumentView";
 
-export function setupDrag(_reference: React.RefObject<HTMLDivElement>, docFunc: () => Document, removeFunc: (containingCollection: CollectionView) => void = () => { }) {
-    let onRowMove = action((e: PointerEvent): void => {
-        e.stopPropagation();
-        e.preventDefault();
+export function setupDrag(
+  _reference: React.RefObject<HTMLDivElement>,
+  docFunc: () => Document,
+  removeFunc: (containingCollection: CollectionView) => void = () => {}
+) {
+  let onRowMove = action(
+    (e: PointerEvent): void => {
+      e.stopPropagation();
+      e.preventDefault();
 
-        document.removeEventListener("pointermove", onRowMove);
-        document.removeEventListener('pointerup', onRowUp);
-        var dragData = new DragManager.DocumentDragData([docFunc()]);
-        dragData.removeDocument = removeFunc;
-        DragManager.StartDocumentDrag([_reference.current!], dragData);
-    });
-    let onRowUp = action((e: PointerEvent): void => {
-        document.removeEventListener("pointermove", onRowMove);
-        document.removeEventListener('pointerup', onRowUp);
-    });
-    let onItemDown = (e: React.PointerEvent) => {
-        // if (this.props.isSelected() || this.props.isTopMost) {
-        if (e.button == 0) {
-            e.stopPropagation();
-            if (e.shiftKey) {
-                CollectionDockingView.Instance.StartOtherDrag([docFunc()], e);
-            } else {
-                document.addEventListener("pointermove", onRowMove);
-                document.addEventListener('pointerup', onRowUp);
-            }
-        }
-        //}
+      document.removeEventListener("pointermove", onRowMove);
+      document.removeEventListener("pointerup", onRowUp);
+      var dragData = new DragManager.DocumentDragData([docFunc()]);
+      dragData.removeDocument = removeFunc;
+      DragManager.StartDocumentDrag([_reference.current!], dragData);
+    }
+  );
+  let onRowUp = action(
+    (e: PointerEvent): void => {
+      document.removeEventListener("pointermove", onRowMove);
+      document.removeEventListener("pointerup", onRowUp);
+    }
+  );
+  let onItemDown = (e: React.PointerEvent) => {
+    // if (this.props.isSelected() || this.props.isTopMost) {
+    if (e.button == 0) {
+      e.stopPropagation();
+      if (e.shiftKey) {
+        CollectionDockingView.Instance.StartOtherDrag([docFunc()], e);
+      } else {
+        document.addEventListener("pointermove", onRowMove);
+        document.addEventListener("pointerup", onRowUp);
+      }
     }
-    return onItemDown;
+    //}
+  };
+  return onItemDown;
 }
 
 export namespace DragManager {
-    export function Root() {
-        const root = document.getElementById("root");
-        if (!root) {
-            throw new Error("No root element found");
-        }
-        return root;
+  export function Root() {
+    const root = document.getElementById("root");
+    if (!root) {
+      throw new Error("No root element found");
     }
+    return root;
+  }
 
-    let dragDiv: HTMLDivElement;
+  let dragDiv: HTMLDivElement;
 
-    export enum DragButtons {
-        Left = 1, Right = 2, Both = Left | Right
-    }
+  export enum DragButtons {
+    Left = 1,
+    Right = 2,
+    Both = Left | Right
+  }
 
-    interface DragOptions {
-        handlers: DragHandlers;
+  interface DragOptions {
+    handlers: DragHandlers;
 
-        hideSource: boolean | (() => boolean);
-    }
+    hideSource: boolean | (() => boolean);
+  }
 
-    export interface DragDropDisposer {
-        (): void;
-    }
+  export interface DragDropDisposer {
+    (): void;
+  }
 
-    export class DragCompleteEvent {
-    }
+  export class DragCompleteEvent {}
 
-    export interface DragHandlers {
-        dragComplete: (e: DragCompleteEvent) => void;
-    }
+  export interface DragHandlers {
+    dragComplete: (e: DragCompleteEvent) => void;
+  }
 
-    export interface DropOptions {
-        handlers: DropHandlers;
-    }
-    export class DropEvent {
-        constructor(readonly x: number, readonly y: number, readonly data: { [id: string]: any }) { }
-    }
+  export interface DropOptions {
+    handlers: DropHandlers;
+  }
+  export class DropEvent {
+    constructor(
+      readonly x: number,
+      readonly y: number,
+      readonly data: { [id: string]: any }
+    ) {}
+  }
 
+  export interface DropHandlers {
+    drop: (e: Event, de: DropEvent) => void;
+  }
 
+  export function MakeDropTarget(
+    element: HTMLElement,
+    options: DropOptions
+  ): DragDropDisposer {
+    if ("canDrop" in element.dataset) {
+      throw new Error(
+        "Element is already droppable, can't make it droppable again"
+      );
+    }
+    element.dataset["canDrop"] = "true";
+    const handler = (e: Event) => {
+      const ce = e as CustomEvent<DropEvent>;
+      options.handlers.drop(e, ce.detail);
+    };
+    element.addEventListener("dashOnDrop", handler);
+    return () => {
+      element.removeEventListener("dashOnDrop", handler);
+      delete element.dataset["canDrop"];
+    };
+  }
 
-    export interface DropHandlers {
-        drop: (e: Event, de: DropEvent) => void;
+  export class DocumentDragData {
+    constructor(dragDoc: Document[]) {
+      this.draggedDocuments = dragDoc;
+      this.droppedDocuments = dragDoc;
     }
+    draggedDocuments: Document[];
+    droppedDocuments: Document[];
+    xOffset?: number;
+    yOffset?: number;
+    aliasOnDrop?: boolean;
+    removeDocument?: (collectionDrop: CollectionView) => void;
+    [id: string]: any;
+  }
 
+  export function StartDocumentDrag(
+    eles: HTMLElement[],
+    dragData: DocumentDragData,
+    options?: DragOptions
+  ) {
+    StartDrag(
+      eles,
+      dragData,
+      options,
+      (dropData: { [id: string]: any }) =>
+        (dropData.droppedDocuments = dragData.aliasOnDrop
+          ? dragData.draggedDocuments.map(d => d.CreateAlias())
+          : dragData.draggedDocuments)
+    );
+  }
 
-    export function MakeDropTarget(element: HTMLElement, options: DropOptions): DragDropDisposer {
-        if ("canDrop" in element.dataset) {
-            throw new Error("Element is already droppable, can't make it droppable again");
-        }
-        element.dataset["canDrop"] = "true";
-        const handler = (e: Event) => {
-            const ce = e as CustomEvent<DropEvent>;
-            options.handlers.drop(e, ce.detail);
-        };
-        element.addEventListener("dashOnDrop", handler);
-        return () => {
-            element.removeEventListener("dashOnDrop", handler);
-            delete element.dataset["canDrop"]
-        };
+  export class LinkDragData {
+    constructor(linkSourceDoc: DocumentView) {
+      this.linkSourceDocumentView = linkSourceDoc;
     }
-
-    export class DocumentDragData {
-        constructor(dragDoc: Document[]) {
-            this.draggedDocuments = dragDoc;
-            this.droppedDocuments = dragDoc;
-        }
-        draggedDocuments: Document[];
-        droppedDocuments: Document[];
-        xOffset?: number;
-        yOffset?: number;
-        aliasOnDrop?: boolean;
-        removeDocument?: (collectionDrop: CollectionView) => void;
-        [id: string]: any;
+    linkSourceDocumentView: DocumentView;
+    [id: string]: any;
+  }
+  export function StartLinkDrag(
+    ele: HTMLElement,
+    dragData: LinkDragData,
+    options?: DragOptions
+  ) {
+    StartDrag([ele], dragData, options);
+  }
+  function StartDrag(
+    eles: HTMLElement[],
+    dragData: { [id: string]: any },
+    options?: DragOptions,
+    finishDrag?: (dropData: { [id: string]: any }) => void
+  ) {
+    if (!dragDiv) {
+      dragDiv = document.createElement("div");
+      dragDiv.className = "dragManager-dragDiv";
+      DragManager.Root().appendChild(dragDiv);
     }
 
-    export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, options?: DragOptions) {
-        StartDrag(eles, dragData, options, (dropData: { [id: string]: any }) => dropData.droppedDocuments = dragData.aliasOnDrop ? dragData.draggedDocuments.map(d => d.CreateAlias()) : dragData.draggedDocuments);
-    }
+    let scaleXs: number[] = [];
+    let scaleYs: number[] = [];
+    let xs: number[] = [];
+    let ys: number[] = [];
 
-    export class LinkDragData {
-        constructor(linkSourceDoc: DocumentView) {
-            this.linkSourceDocumentView = linkSourceDoc;
-        }
-        linkSourceDocumentView: DocumentView;
-        [id: string]: any;
-    }
-    export function StartLinkDrag(ele: HTMLElement, dragData: LinkDragData, options?: DragOptions) {
-        StartDrag([ele], dragData, options);
-    }
-    function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) {
-        if (!dragDiv) {
-            dragDiv = document.createElement("div");
-            dragDiv.className = "dragManager-dragDiv"
-            DragManager.Root().appendChild(dragDiv);
+    const docs: Document[] =
+      dragData instanceof DocumentDragData ? dragData.draggedDocuments : [];
+    let dragElements = eles.map(ele => {
+      const w = ele.offsetWidth,
+        h = ele.offsetHeight;
+      const rect = ele.getBoundingClientRect();
+      const scaleX = rect.width / w,
+        scaleY = rect.height / h;
+      let x = rect.left,
+        y = rect.top;
+      xs.push(x);
+      ys.push(y);
+      scaleXs.push(scaleX);
+      scaleYs.push(scaleY);
+      let dragElement = ele.cloneNode(true) as HTMLElement;
+      dragElement.style.opacity = "0.7";
+      console.log(dragElement);
+      dragElement.style.position = "absolute";
+      dragElement.style.bottom = "";
+      dragElement.style.left = "";
+      dragElement.style.transformOrigin = "0 0";
+      dragElement.style.zIndex = "1000";
+      dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`;
+      dragElement.style.width = `${rect.width / scaleX}px`;
+      dragElement.style.height = `${rect.height / scaleY}px`;
+
+      // bcz: PDFs don't show up if you clone them because they contain a canvas.
+      //      however, PDF's have a thumbnail field that contains an image of their canvas.
+      //      So we replace the pdf's canvas with the image thumbnail
+      if (docs.length) {
+        var pdfBox = dragElement.getElementsByClassName(
+          "pdfBox-cont"
+        )[0] as HTMLElement;
+        let thumbnail = docs[0].GetT(KeyStore.Thumbnail, ImageField);
+        if (pdfBox && pdfBox.childElementCount && thumbnail) {
+          let img = new Image();
+          img!.src = thumbnail.toString();
+          img!.style.position = "absolute";
+          img!.style.width = `${rect.width / scaleX}px`;
+          img!.style.height = `${rect.height / scaleY}px`;
+          pdfBox.replaceChild(img!, pdfBox.children[0]);
         }
+      }
 
-        let scaleXs: number[] = [];
-        let scaleYs: number[] = [];
-        let xs: number[] = [];
-        let ys: number[] = [];
-
-        const docs: Document[] = dragData instanceof DocumentDragData ? dragData.draggedDocuments : [];
-        let dragElements = eles.map(ele => {
-            const w = ele.offsetWidth, h = ele.offsetHeight;
-            const rect = ele.getBoundingClientRect();
-            const scaleX = rect.width / w, scaleY = rect.height / h;
-            let x = rect.left, y = rect.top;
-            xs.push(x); ys.push(y);
-            scaleXs.push(scaleX); scaleYs.push(scaleY);
-            let dragElement = ele.cloneNode(true) as HTMLElement;
-            dragElement.style.opacity = "0.7";
-            dragElement.style.position = "absolute";
-            dragElement.style.bottom = "";
-            dragElement.style.left = "";
-            dragElement.style.transformOrigin = "0 0";
-            dragElement.style.zIndex = "1000";
-            dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`;
-            dragElement.style.width = `${rect.width / scaleX}px`;
-            dragElement.style.height = `${rect.height / scaleY}px`;
-
-            // bcz: PDFs don't show up if you clone them because they contain a canvas.
-            //      however, PDF's have a thumbnail field that contains an image of their canvas.
-            //      So we replace the pdf's canvas with the image thumbnail
-            if (docs.length) {
-                var pdfBox = dragElement.getElementsByClassName("pdfBox-cont")[0] as HTMLElement;
-                let thumbnail = docs[0].GetT(KeyStore.Thumbnail, ImageField);
-                if (pdfBox && pdfBox.childElementCount && thumbnail) {
-                    let img = new Image();
-                    img!.src = thumbnail.toString();
-                    img!.style.position = "absolute";
-                    img!.style.width = `${rect.width / scaleX}px`;
-                    img!.style.height = `${rect.height / scaleY}px`;
-                    pdfBox.replaceChild(img!, pdfBox.children[0])
-                }
-            }
-
-            dragDiv.appendChild(dragElement);
-            return dragElement;
-        });
+      dragDiv.appendChild(dragElement);
+      return dragElement;
+    });
 
-        let hideSource = false;
-        if (options) {
-            if (typeof options.hideSource === "boolean") {
-                hideSource = options.hideSource;
-            } else {
-                hideSource = options.hideSource();
-            }
-        }
-        eles.map(ele => ele.hidden = hideSource);
-
-        const moveHandler = (e: PointerEvent) => {
-            e.stopPropagation();
-            e.preventDefault();
-            if (dragData instanceof DocumentDragData)
-                dragData.aliasOnDrop = e.ctrlKey || e.altKey;
-            if (e.shiftKey) {
-                abortDrag();
-                CollectionDockingView.Instance.StartOtherDrag(docs, { pageX: e.pageX, pageY: e.pageY, preventDefault: () => { }, button: 0 });
-            }
-            dragElements.map((dragElement, i) => dragElement.style.transform = `translate(${xs[i] += e.movementX}px, ${ys[i] += e.movementY}px) scale(${scaleXs[i]}, ${scaleYs[i]})`);
-        };
-
-        const abortDrag = () => {
-            document.removeEventListener("pointermove", moveHandler, true);
-            document.removeEventListener("pointerup", upHandler);
-            dragElements.map(dragElement => dragDiv.removeChild(dragElement));
-            eles.map(ele => ele.hidden = false);
-        }
-        const upHandler = (e: PointerEvent) => {
-            abortDrag();
-            FinishDrag(eles, e, dragData, options, finishDrag);
-        };
-        document.addEventListener("pointermove", moveHandler, true);
-        document.addEventListener("pointerup", upHandler);
+    let hideSource = false;
+    if (options) {
+      if (typeof options.hideSource === "boolean") {
+        hideSource = options.hideSource;
+      } else {
+        hideSource = options.hideSource();
+      }
     }
+    eles.map(ele => (ele.hidden = hideSource));
 
-    function FinishDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) {
-        let removed = dragEles.map(dragEle => {
-            let parent = dragEle.parentElement;
-            if (parent)
-                parent.removeChild(dragEle);
-            return [dragEle, parent];
-        });
-        const target = document.elementFromPoint(e.x, e.y);
-        removed.map(r => {
-            let dragEle: HTMLElement = r[0]!;
-            let parent: HTMLElement | null = r[1];
-            if (parent)
-                parent.appendChild(dragEle);
+    const moveHandler = (e: PointerEvent) => {
+      e.stopPropagation();
+      e.preventDefault();
+      if (dragData instanceof DocumentDragData)
+        dragData.aliasOnDrop = e.ctrlKey || e.altKey;
+      if (e.shiftKey) {
+        abortDrag();
+        CollectionDockingView.Instance.StartOtherDrag(docs, {
+          pageX: e.pageX,
+          pageY: e.pageY,
+          preventDefault: () => {},
+          button: 0
         });
-        if (target) {
-            if (finishDrag)
-                finishDrag(dragData);
-
-            target.dispatchEvent(new CustomEvent<DropEvent>("dashOnDrop", {
-                bubbles: true,
-                detail: {
-                    x: e.x,
-                    y: e.y,
-                    data: dragData
-                }
-            }));
-
-            if (options) {
-                options.handlers.dragComplete({});
-            }
-        }
-        DocumentDecorations.Instance.Hidden = false;
+      }
+      dragElements.map(
+        (dragElement, i) =>
+          (dragElement.style.transform = `translate(${(xs[i] +=
+            e.movementX)}px, ${(ys[i] += e.movementY)}px) scale(${
+            scaleXs[i]
+          }, ${scaleYs[i]})`)
+      );
+    };
+
+    const abortDrag = () => {
+      document.removeEventListener("pointermove", moveHandler, true);
+      document.removeEventListener("pointerup", upHandler);
+      dragElements.map(dragElement => dragDiv.removeChild(dragElement));
+      eles.map(ele => (ele.hidden = false));
+    };
+    const upHandler = (e: PointerEvent) => {
+      abortDrag();
+      FinishDrag(eles, e, dragData, options, finishDrag);
+    };
+    document.addEventListener("pointermove", moveHandler, true);
+    document.addEventListener("pointerup", upHandler);
+  }
+
+  function FinishDrag(
+    dragEles: HTMLElement[],
+    e: PointerEvent,
+    dragData: { [index: string]: any },
+    options?: DragOptions,
+    finishDrag?: (dragData: { [index: string]: any }) => void
+  ) {
+    let removed = dragEles.map(dragEle => {
+      let parent = dragEle.parentElement;
+      if (parent) parent.removeChild(dragEle);
+      return [dragEle, parent];
+    });
+    const target = document.elementFromPoint(e.x, e.y);
+    removed.map(r => {
+      let dragEle: HTMLElement = r[0]!;
+      let parent: HTMLElement | null = r[1];
+      if (parent) parent.appendChild(dragEle);
+    });
+    if (target) {
+      if (finishDrag) finishDrag(dragData);
+
+      target.dispatchEvent(
+        new CustomEvent<DropEvent>("dashOnDrop", {
+          bubbles: true,
+          detail: {
+            x: e.x,
+            y: e.y,
+            data: dragData
+          }
+        })
+      );
+
+      if (options) {
+        options.handlers.dragComplete({});
+      }
     }
-}
\ No newline at end of file
+    DocumentDecorations.Instance.Hidden = false;
+  }
+}
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index 7a43f3087..8f5470574 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -1,4 +1,5 @@
 @import "global_variables";
+
 #documentDecorations-container {
     position: absolute;
     display: grid;
@@ -6,26 +7,32 @@
     grid-template-rows: 8px 1fr 8px 30px;
     grid-template-columns: 8px 1fr 8px;
     pointer-events: none;
+
     #documentDecorations-centerCont {
         background: none;
     }
+
     .documentDecorations-resizer {
         pointer-events: auto;
         background: $alt-accent;
         opacity: 0.8;
     }
+
     #documentDecorations-topLeftResizer,
     #documentDecorations-bottomRightResizer {
         cursor: nwse-resize;
     }
+
     #documentDecorations-topRightResizer,
     #documentDecorations-bottomLeftResizer {
         cursor: nesw-resize;
     }
+
     #documentDecorations-topResizer,
     #documentDecorations-bottomResizer {
         cursor: ns-resize;
     }
+
     #documentDecorations-leftResizer,
     #documentDecorations-rightResizer {
         cursor: ew-resize;
@@ -33,7 +40,7 @@
 }
 
 .documentDecorations-background {
-    background:lightblue;
+    background: lightblue;
     position: absolute;
     opacity: 0.1;
 }
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index 4eda50204..23e072344 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -30,10 +30,12 @@
     height: 10px;
     width: 10px;
     border-radius: 2px;
-    background: #232323
+    background: $dark-color
   }
 
   .minimized-box:hover {
-    background: #232323
+    background: $main-accent;
+    transform: scale(1.15);
+    cursor: pointer;
   }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 085307461..713c12975 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -7,7 +7,6 @@ import {
   observable
 } from "mobx";
 import { library } from "@fortawesome/fontawesome-svg-core";
-import { faSquare } from "@fortawesome/free-solid-svg-icons";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { Field, Opt, FieldWaiting } from "../../../fields/Field";
@@ -33,8 +32,6 @@ import React = require("react");
 import { ServerUtils } from "../../../server/ServerUtil";
 import { DocumentDecorations } from "../DocumentDecorations";
 
-library.add(faSquare);
-
 export interface DocumentViewProps {
   ContainingCollectionView: Opt<CollectionView>;
   Document: Document;
@@ -438,6 +435,11 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     return this.minimized;
   };
 
+  @action
+  expand = () => {
+    this.minimized = false;
+  };
+
   isSelected = () => {
     return SelectionManager.IsSelected(this);
   };
@@ -450,18 +452,26 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     if (!this.props.Document) {
       return null;
     }
+
+    var scaling = this.props.ContentScaling();
+    var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
+    var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
+
     if (this.minimized) {
       return (
-        //<i class="fas fa-square" />
-        <div className="minimized-box" />
+        <div
+          className="minimized-box"
+          ref={this._mainCont}
+          style={{
+            transformOrigin: "left top",
+            transform: `scale(${scaling} , ${scaling})`
+          }}
+          onClick={this.expand}
+          onDrop={this.onDrop}
+          onPointerDown={this.onPointerDown}
+        />
       );
     } else {
-      var scaling = this.props.ContentScaling();
-      var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
-      var nativeHeight = this.props.Document.GetNumber(
-        KeyStore.NativeHeight,
-        0
-      );
       var backgroundcolor = this.props.Document.GetText(
         KeyStore.BackgroundColor,
         ""
diff --git a/src/client/views/nodes/Sticky.tsx b/src/client/views/nodes/Sticky.tsx
index d57dd5c0b..4a4d69e90 100644
--- a/src/client/views/nodes/Sticky.tsx
+++ b/src/client/views/nodes/Sticky.tsx
@@ -1,83 +1,83 @@
-import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app
-import React = require("react")
-import { observer } from "mobx-react"
-import 'react-pdf/dist/Page/AnnotationLayer.css'
+import "react-image-lightbox/style.css"; // This only needs to be imported once in your app
+import React = require("react");
+import { observer } from "mobx-react";
+import "react-pdf/dist/Page/AnnotationLayer.css";
 
 interface IProps {
-    Height: number;
-    Width: number;
-    X: number;
-    Y: number;
+  Height: number;
+  Width: number;
+  X: number;
+  Y: number;
 }
 
 /**
- * Sticky, also known as area highlighting, is used to highlight large selection of the PDF file. 
- * Improvements that could be made: maybe store line array and store that somewhere for future rerendering. 
- * 
- * Written By: Andrew Kim 
+ * Sticky, also known as area highlighting, is used to highlight large selection of the PDF file.
+ * Improvements that could be made: maybe store line array and store that somewhere for future rerendering.
+ *
+ * Written By: Andrew Kim
  */
 @observer
 export class Sticky extends React.Component<IProps> {
+  private initX: number = 0;
+  private initY: number = 0;
 
-    private initX: number = 0;
-    private initY: number = 0;
+  private _ref = React.createRef<HTMLCanvasElement>();
+  private ctx: any; //context that keeps track of sticky canvas
 
-    private _ref = React.createRef<HTMLCanvasElement>();
-    private ctx: any; //context that keeps track of sticky canvas
-
-    /**
-     * drawing. Registers the first point that user clicks when mouse button is pressed down on canvas
-     */
-    drawDown = (e: React.PointerEvent) => {
-        if (this._ref.current) {
-            this.ctx = this._ref.current.getContext("2d");
-            let mouse = e.nativeEvent;
-            this.initX = mouse.offsetX;
-            this.initY = mouse.offsetY;
-            this.ctx.beginPath();
-            this.ctx.lineTo(this.initX, this.initY);
-            this.ctx.strokeStyle = "black";
-            document.addEventListener("pointermove", this.drawMove);
-            document.addEventListener("pointerup", this.drawUp);
-        }
+  /**
+   * drawing. Registers the first point that user clicks when mouse button is pressed down on canvas
+   */
+  drawDown = (e: React.PointerEvent) => {
+    if (this._ref.current) {
+      this.ctx = this._ref.current.getContext("2d");
+      let mouse = e.nativeEvent;
+      this.initX = mouse.offsetX;
+      this.initY = mouse.offsetY;
+      this.ctx.beginPath();
+      this.ctx.lineTo(this.initX, this.initY);
+      this.ctx.strokeStyle = "black";
+      document.addEventListener("pointermove", this.drawMove);
+      document.addEventListener("pointerup", this.drawUp);
     }
+  };
 
-    //when user drags 
-    drawMove = (e: PointerEvent): void => {
-        //x and y mouse movement
-        let x = this.initX += e.movementX,
-            y = this.initY += e.movementY;
-        //connects the point 
-        this.ctx.lineTo(x, y);
-        this.ctx.stroke();
-
-    }
+  //when user drags
+  drawMove = (e: PointerEvent): void => {
+    //x and y mouse movement
+    let x = (this.initX += e.movementX),
+      y = (this.initY += e.movementY);
+    //connects the point
+    this.ctx.lineTo(x, y);
+    this.ctx.stroke();
+  };
 
-    /**
-     * when user lifts the mouse, the drawing ends
-     */
-    drawUp = (e: PointerEvent) => {
-        this.ctx.closePath();
-        console.log(this.ctx);
-        document.removeEventListener("pointermove", this.drawMove);
-    }
+  /**
+   * when user lifts the mouse, the drawing ends
+   */
+  drawUp = (e: PointerEvent) => {
+    this.ctx.closePath();
+    console.log(this.ctx);
+    document.removeEventListener("pointermove", this.drawMove);
+  };
 
-    render() {
-        return (
-            <div onPointerDown={this.drawDown}>
-                <canvas ref={this._ref} height={this.props.Height} width={this.props.Width}
-                    style={{
-                        position: "absolute",
-                        top: "20px",
-                        left: "0px",
-                        zIndex: 1,
-                        background: "yellow",
-                        transform: `translate(${this.props.X}px, ${this.props.Y}px)`,
-                        opacity: 0.4
-                    }}
-                />
-
-            </div>
-        );
-    }
-}
\ No newline at end of file
+  render() {
+    return (
+      <div onPointerDown={this.drawDown}>
+        <canvas
+          ref={this._ref}
+          height={this.props.Height}
+          width={this.props.Width}
+          style={{
+            position: "absolute",
+            top: "20px",
+            left: "0px",
+            zIndex: 1,
+            background: "yellow",
+            transform: `translate(${this.props.X}px, ${this.props.Y}px)`,
+            opacity: 0.4
+          }}
+        />
+      </div>
+    );
+  }
+}
-- 
cgit v1.2.3-70-g09d2


From dd9d087b62545a7a57ea2651eace72f851127623 Mon Sep 17 00:00:00 2001
From: Monika Hedman <monika_hedman@brown.edu>
Date: Tue, 2 Apr 2019 16:51:08 -0400
Subject: drag working

---
 src/client/views/nodes/DocumentView.scss | 22 +++++++++++-----------
 src/client/views/nodes/DocumentView.tsx  | 10 ++++++----
 2 files changed, 17 insertions(+), 15 deletions(-)

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

diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index 23e072344..127a6b535 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -25,17 +25,17 @@
     overflow-y: scroll;
     height: calc(100% - 20px);
   }
+}
 
-  .minimized-box {
-    height: 10px;
-    width: 10px;
-    border-radius: 2px;
-    background: $dark-color
-  }
+.minimized-box {
+  height: 10px;
+  width: 10px;
+  border-radius: 2px;
+  background: $dark-color
+}
 
-  .minimized-box:hover {
-    background: $main-accent;
-    transform: scale(1.15);
-    cursor: pointer;
-  }
+.minimized-box:hover {
+  background: $main-accent;
+  transform: scale(1.15);
+  cursor: pointer;
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 713c12975..c4f329357 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -383,10 +383,12 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     e.preventDefault();
 
     //for testing purposes
-    ContextMenu.Instance.addItem({
-      description: "Minimize",
-      event: this.minimize
-    });
+    if (!this.minimized) {
+      ContextMenu.Instance.addItem({
+        description: "Minimize",
+        event: this.minimize
+      });
+    }
     ContextMenu.Instance.addItem({
       description: "Full Screen",
       event: this.fullScreenClicked
-- 
cgit v1.2.3-70-g09d2


From 36019dc66ae66bac01118ed05bdb5c6466f9bdc8 Mon Sep 17 00:00:00 2001
From: Monika Hedman <monika_hedman@brown.edu>
Date: Tue, 2 Apr 2019 18:05:56 -0400
Subject: done with minimize to box

---
 src/client/util/DragManager.ts          |   1 -
 src/client/views/nodes/DocumentView.tsx |  35 +++++--
 src/fields/Document.ts                  |   5 +
 src/fields/KeyStore.ts                  |  90 ++++++++---------
 src/fields/MinimizedField.tsx           |  29 ++++++
 src/server/Message.ts                   | 168 ++++++++++++++++++--------------
 src/server/ServerUtil.ts                | 151 ++++++++++++++--------------
 7 files changed, 282 insertions(+), 197 deletions(-)
 create mode 100644 src/fields/MinimizedField.tsx

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

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index ee0b5333c..c0f482e18 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -192,7 +192,6 @@ export namespace DragManager {
       scaleYs.push(scaleY);
       let dragElement = ele.cloneNode(true) as HTMLElement;
       dragElement.style.opacity = "0.7";
-      console.log(dragElement);
       dragElement.style.position = "absolute";
       dragElement.style.bottom = "";
       dragElement.style.left = "";
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c4f329357..05058e63d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -31,6 +31,7 @@ import "./DocumentView.scss";
 import React = require("react");
 import { ServerUtils } from "../../../server/ServerUtil";
 import { DocumentDecorations } from "../DocumentDecorations";
+import { MinimizedField } from "../../../fields/MinimizedField";
 
 export interface DocumentViewProps {
   ContainingCollectionView: Opt<CollectionView>;
@@ -102,8 +103,15 @@ export class DocumentView extends React.Component<DocumentViewProps> {
   private _downX: number = 0;
   private _downY: number = 0;
 
+  // @observable
+  // private minimized: boolean = false;
+
   @observable
-  private minimized: boolean = false;
+  private _minimized: boolean = this.props.Document.GetData(
+    KeyStore.Minimized,
+    MinimizedField,
+    false as boolean
+  );
 
   private _reactionDisposer: Opt<IReactionDisposer>;
   @computed get active(): boolean {
@@ -310,7 +318,13 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
   @action
   minimize = (e: React.MouseEvent): void => {
-    this.minimized = true;
+    //hopefully sets field?
+    this._minimized = true as boolean;
+    this.props.Document.SetData(
+      KeyStore.Minimized,
+      true as boolean,
+      MinimizedField
+    );
     SelectionManager.DeselectAll();
   };
 
@@ -383,7 +397,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     e.preventDefault();
 
     //for testing purposes
-    if (!this.minimized) {
+    if (!this.isMinimized()) {
       ContextMenu.Instance.addItem({
         description: "Minimize",
         event: this.minimize
@@ -434,12 +448,21 @@ export class DocumentView extends React.Component<DocumentViewProps> {
   };
 
   isMinimized = () => {
-    return this.minimized;
+    let field = this.props.Document.GetT(KeyStore.Minimized, MinimizedField);
+    if (field && field !== FieldWaiting) {
+      return field.Data;
+    }
+    //return this.minimized;
   };
 
   @action
   expand = () => {
-    this.minimized = false;
+    //this._minimized = false;
+    this.props.Document.SetData(
+      KeyStore.Minimized,
+      false as boolean,
+      MinimizedField
+    );
   };
 
   isSelected = () => {
@@ -459,7 +482,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
     var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
 
-    if (this.minimized) {
+    if (this.isMinimized()) {
       return (
         <div
           className="minimized-box"
diff --git a/src/fields/Document.ts b/src/fields/Document.ts
index 85ff6ddcb..5131d89ca 100644
--- a/src/fields/Document.ts
+++ b/src/fields/Document.ts
@@ -9,6 +9,7 @@ import { Server } from "../client/Server";
 import { Types } from "../server/Message";
 import { UndoManager } from "../client/util/UndoManager";
 import { HtmlField } from "./HtmlField";
+import { MinimizedField } from "./MinimizedField";
 
 export class Document extends Field {
     //TODO tfs: We should probably store FieldWaiting in fields when we request it from the server so that we don't set up multiple server gets for the same document and field
@@ -225,6 +226,10 @@ export class Document extends Field {
         return vval;
     }
 
+    // GetMinimized(key: Key, defaultVal: boolean): boolean {
+    //     return this.GetData(key, MinimizedField, defaultVal);
+    // }
+
     GetHtml(key: Key, defaultVal: string): string {
         return this.GetData(key, HtmlField, defaultVal);
     }
diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts
index 1f039e592..6ed3b1604 100644
--- a/src/fields/KeyStore.ts
+++ b/src/fields/KeyStore.ts
@@ -1,48 +1,50 @@
 import { Key } from "./Key";
+import { KeyTransfer } from "../server/Message";
 
 export namespace KeyStore {
-    export const Prototype = new Key("Prototype");
-    export const X = new Key("X");
-    export const Y = new Key("Y");
-    export const Page = new Key("Page");
-    export const Title = new Key("Title");
-    export const Author = new Key("Author");
-    export const PanX = new Key("PanX");
-    export const PanY = new Key("PanY");
-    export const Scale = new Key("Scale");
-    export const NativeWidth = new Key("NativeWidth");
-    export const NativeHeight = new Key("NativeHeight");
-    export const Width = new Key("Width");
-    export const Height = new Key("Height");
-    export const ZIndex = new Key("ZIndex");
-    export const Data = new Key("Data");
-    export const Annotations = new Key("Annotations");
-    export const ViewType = new Key("ViewType");
-    export const Layout = new Key("Layout");
-    export const BackgroundColor = new Key("BackgroundColor");
-    export const BackgroundLayout = new Key("BackgroundLayout");
-    export const OverlayLayout = new Key("OverlayLayout");
-    export const LayoutKeys = new Key("LayoutKeys");
-    export const LayoutFields = new Key("LayoutFields");
-    export const ColumnsKey = new Key("SchemaColumns");
-    export const SchemaSplitPercentage = new Key("SchemaSplitPercentage");
-    export const Caption = new Key("Caption");
-    export const ActiveWorkspace = new Key("ActiveWorkspace");
-    export const DocumentText = new Key("DocumentText");
-    export const BrushingDocs = new Key("BrushingDocs");
-    export const LinkedToDocs = new Key("LinkedToDocs");
-    export const LinkedFromDocs = new Key("LinkedFromDocs");
-    export const LinkDescription = new Key("LinkDescription");
-    export const LinkTags = new Key("LinkTag");
-    export const Thumbnail = new Key("Thumbnail");
-    export const ThumbnailPage = new Key("ThumbnailPage");
-    export const CurPage = new Key("CurPage");
-    export const AnnotationOn = new Key("AnnotationOn");
-    export const NumPages = new Key("NumPages");
-    export const Ink = new Key("Ink");
-    export const Cursors = new Key("Cursors");
-    export const OptionalRightCollection = new Key("OptionalRightCollection");
-    export const Archives = new Key("Archives");
-    export const Updated = new Key("Updated");
-    export const Workspaces = new Key("Workspaces");
+  export const Prototype = new Key("Prototype");
+  export const X = new Key("X");
+  export const Y = new Key("Y");
+  export const Page = new Key("Page");
+  export const Title = new Key("Title");
+  export const Author = new Key("Author");
+  export const PanX = new Key("PanX");
+  export const PanY = new Key("PanY");
+  export const Scale = new Key("Scale");
+  export const NativeWidth = new Key("NativeWidth");
+  export const NativeHeight = new Key("NativeHeight");
+  export const Width = new Key("Width");
+  export const Height = new Key("Height");
+  export const ZIndex = new Key("ZIndex");
+  export const Data = new Key("Data");
+  export const Annotations = new Key("Annotations");
+  export const ViewType = new Key("ViewType");
+  export const Layout = new Key("Layout");
+  export const BackgroundColor = new Key("BackgroundColor");
+  export const BackgroundLayout = new Key("BackgroundLayout");
+  export const OverlayLayout = new Key("OverlayLayout");
+  export const LayoutKeys = new Key("LayoutKeys");
+  export const LayoutFields = new Key("LayoutFields");
+  export const ColumnsKey = new Key("SchemaColumns");
+  export const SchemaSplitPercentage = new Key("SchemaSplitPercentage");
+  export const Caption = new Key("Caption");
+  export const ActiveWorkspace = new Key("ActiveWorkspace");
+  export const DocumentText = new Key("DocumentText");
+  export const BrushingDocs = new Key("BrushingDocs");
+  export const LinkedToDocs = new Key("LinkedToDocs");
+  export const LinkedFromDocs = new Key("LinkedFromDocs");
+  export const LinkDescription = new Key("LinkDescription");
+  export const LinkTags = new Key("LinkTag");
+  export const Thumbnail = new Key("Thumbnail");
+  export const ThumbnailPage = new Key("ThumbnailPage");
+  export const CurPage = new Key("CurPage");
+  export const AnnotationOn = new Key("AnnotationOn");
+  export const NumPages = new Key("NumPages");
+  export const Ink = new Key("Ink");
+  export const Cursors = new Key("Cursors");
+  export const OptionalRightCollection = new Key("OptionalRightCollection");
+  export const Archives = new Key("Archives");
+  export const Updated = new Key("Updated");
+  export const Workspaces = new Key("Workspaces");
+  export const Minimized = new Key("Minimized");
 }
diff --git a/src/fields/MinimizedField.tsx b/src/fields/MinimizedField.tsx
new file mode 100644
index 000000000..5dfb22e6e
--- /dev/null
+++ b/src/fields/MinimizedField.tsx
@@ -0,0 +1,29 @@
+import { BasicField } from "./BasicField";
+import { FieldId } from "./Field";
+import { Types } from "../server/Message";
+
+export class MinimizedField extends BasicField<boolean> {
+  constructor(
+    data: boolean = false as boolean,
+    id?: FieldId,
+    save: boolean = true as boolean
+  ) {
+    super(data, save, id);
+  }
+
+  ToScriptString(): string {
+    return `new MinimizedField("${this.Data}")`;
+  }
+
+  Copy() {
+    return new MinimizedField(this.Data);
+  }
+
+  ToJson(): { type: Types; data: boolean; _id: string } {
+    return {
+      type: Types.Minimized,
+      data: this.Data,
+      _id: this.Id
+    };
+  }
+}
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 05ae0f19a..29df57419 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -1,125 +1,145 @@
 import { Utils } from "../Utils";
 
 export class Message<T> {
-    private name: string;
-    private guid: string;
+  private name: string;
+  private guid: string;
 
-    get Name(): string {
-        return this.name;
-    }
+  get Name(): string {
+    return this.name;
+  }
 
-    get Message(): string {
-        return this.guid
-    }
+  get Message(): string {
+    return this.guid;
+  }
 
-    constructor(name: string) {
-        this.name = name;
-        this.guid = Utils.GenerateDeterministicGuid(name)
-    }
+  constructor(name: string) {
+    this.name = name;
+    this.guid = Utils.GenerateDeterministicGuid(name);
+  }
 
-    GetValue() {
-        return this.Name;
-    }
+  GetValue() {
+    return this.Name;
+  }
 }
 
 class TestMessageArgs {
-    hello: string = "";
+  hello: string = "";
 }
 
 export class SetFieldArgs {
-    field: string;
-    value: any;
+  field: string;
+  value: any;
 
-    constructor(f: string, v: any) {
-        this.field = f
-        this.value = v
-    }
+  constructor(f: string, v: any) {
+    this.field = f;
+    this.value = v;
+  }
 }
 
 export class GetFieldArgs {
-    field: string;
+  field: string;
 
-    constructor(f: string) {
-        this.field = f
-    }
+  constructor(f: string) {
+    this.field = f;
+  }
 }
 
 export enum Types {
-    Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, Html, Video, Audio, Ink, PDF, Tuple, HistogramOp
+  Number,
+  List,
+  Key,
+  Image,
+  Web,
+  Document,
+  Text,
+  RichText,
+  DocumentReference,
+  Html,
+  Video,
+  Audio,
+  Ink,
+  PDF,
+  Tuple,
+  HistogramOp,
+  Minimized
 }
 
 export class DocumentTransfer implements Transferable {
-    readonly type = Types.Document
-    _id: string
-
-    constructor(readonly obj: { type: Types, data: [string, string][], _id: string }) {
-        this._id = obj._id
-    }
+  readonly type = Types.Document;
+  _id: string;
+
+  constructor(
+    readonly obj: { type: Types; data: [string, string][]; _id: string }
+  ) {
+    this._id = obj._id;
+  }
 }
 
 export class ImageTransfer implements Transferable {
-    readonly type = Types.Image
+  readonly type = Types.Image;
 
-    constructor(readonly _id: string) { }
+  constructor(readonly _id: string) {}
 }
 
 export class KeyTransfer implements Transferable {
-    name: string
-    readonly _id: string
-    readonly type = Types.Key
-
-    constructor(i: string, n: string) {
-        this.name = n
-        this._id = i
-    }
+  name: string;
+  readonly _id: string;
+  readonly type = Types.Key;
+
+  constructor(i: string, n: string) {
+    this.name = n;
+    this._id = i;
+  }
 }
 
 export class ListTransfer implements Transferable {
-    type = Types.List;
+  type = Types.List;
 
-    constructor(readonly _id: string) { }
+  constructor(readonly _id: string) {}
 }
 
 export class NumberTransfer implements Transferable {
-    readonly type = Types.Number
+  readonly type = Types.Number;
 
-    constructor(readonly value: number, readonly _id: string) { }
+  constructor(readonly value: number, readonly _id: string) {}
 }
 
 export class TextTransfer implements Transferable {
-    value: string
-    readonly _id: string
-    readonly type = Types.Text
-
-    constructor(t: string, i: string) {
-        this.value = t
-        this._id = i
-    }
+  value: string;
+  readonly _id: string;
+  readonly type = Types.Text;
+
+  constructor(t: string, i: string) {
+    this.value = t;
+    this._id = i;
+  }
 }
 
 export class RichTextTransfer implements Transferable {
-    value: string
-    readonly _id: string
-    readonly type = Types.Text
-
-    constructor(t: string, i: string) {
-        this.value = t
-        this._id = i
-    }
+  value: string;
+  readonly _id: string;
+  readonly type = Types.Text;
+
+  constructor(t: string, i: string) {
+    this.value = t;
+    this._id = i;
+  }
 }
 
 export interface Transferable {
-    readonly _id: string
-    readonly type: Types
+  readonly _id: string;
+  readonly type: Types;
 }
 
 export namespace MessageStore {
-    export const Foo = new Message<string>("Foo");
-    export const Bar = new Message<string>("Bar");
-    export const AddDocument = new Message<DocumentTransfer>("Add Document");
-    export const SetField = new Message<{ _id: string, data: any, type: Types }>("Set Field")
-    export const GetField = new Message<string>("Get Field")
-    export const GetFields = new Message<string[]>("Get Fields")
-    export const GetDocument = new Message<string>("Get Document");
-    export const DeleteAll = new Message<any>("Delete All");
-}
\ No newline at end of file
+  export const Foo = new Message<string>("Foo");
+  export const Bar = new Message<string>("Bar");
+  export const AddDocument = new Message<DocumentTransfer>("Add Document");
+  export const SetField = new Message<{ _id: string; data: any; type: Types }>(
+    "Set Field"
+  );
+  export const GetField = new Message<string>("Get Field");
+  export const GetFields = new Message<string[]>("Get Fields");
+  export const GetDocument = new Message<string>("Get Document");
+  export const DeleteAll = new Message<any>("Delete All");
+}
diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts
index 98a7a1451..3e24fed3a 100644
--- a/src/server/ServerUtil.ts
+++ b/src/server/ServerUtil.ts
@@ -1,78 +1,85 @@
-
-import { Field } from './../fields/Field';
-import { TextField } from './../fields/TextField';
-import { NumberField } from './../fields/NumberField';
-import { RichTextField } from './../fields/RichTextField';
-import { Key } from './../fields/Key';
-import { ImageField } from './../fields/ImageField';
-import { ListField } from './../fields/ListField';
-import { Document } from './../fields/Document';
-import { Server } from './../client/Server';
-import { Types } from './Message';
-import { Utils } from '../Utils';
-import { HtmlField } from '../fields/HtmlField';
-import { WebField } from '../fields/WebField';
-import { AudioField } from '../fields/AudioField';
-import { VideoField } from '../fields/VideoField';
-import { InkField } from '../fields/InkField';
-import { PDFField } from '../fields/PDFField';
-import { TupleField } from '../fields/TupleField';
-import { HistogramField } from '../client/northstar/dash-fields/HistogramField';
-
-
+import { Field } from "./../fields/Field";
+import { TextField } from "./../fields/TextField";
+import { NumberField } from "./../fields/NumberField";
+import { RichTextField } from "./../fields/RichTextField";
+import { Key } from "./../fields/Key";
+import { ImageField } from "./../fields/ImageField";
+import { ListField } from "./../fields/ListField";
+import { Document } from "./../fields/Document";
+import { Server } from "./../client/Server";
+import { Types } from "./Message";
+import { Utils } from "../Utils";
+import { HtmlField } from "../fields/HtmlField";
+import { WebField } from "../fields/WebField";
+import { AudioField } from "../fields/AudioField";
+import { VideoField } from "../fields/VideoField";
+import { InkField } from "../fields/InkField";
+import { PDFField } from "../fields/PDFField";
+import { TupleField } from "../fields/TupleField";
+import { MinimizedField } from "../fields/MinimizedField";
+import { HistogramField } from "../client/northstar/dash-fields/HistogramField";
 
 export class ServerUtils {
-    public static prepend(extension: string): string { return window.location.origin + extension; }
+  public static prepend(extension: string): string {
+    return window.location.origin + extension;
+  }
 
-    public static FromJson(json: any): Field {
-        let obj = json
-        let data: any = obj.data
-        let id: string = obj._id
-        let type: Types = obj.type
+  public static FromJson(json: any): Field {
+    let obj = json;
+    let data: any = obj.data;
+    let id: string = obj._id;
+    let type: Types = obj.type;
 
-        if (!(data !== undefined && id && type !== undefined)) {
-            console.log("how did you manage to get an object that doesn't have a data or an id?")
-            return new TextField("Something to fill the space", Utils.GenerateGuid());
-        }
+    if (!(data !== undefined && id && type !== undefined)) {
+      console.log(
+        "how did you manage to get an object that doesn't have a data or an id?"
+      );
+      return new TextField("Something to fill the space", Utils.GenerateGuid());
+    }
 
-        switch (type) {
-            case Types.Number:
-                return new NumberField(data, id, false)
-            case Types.Text:
-                return new TextField(data, id, false)
-            case Types.Html:
-                return new HtmlField(data, id, false)
-            case Types.Web:
-                return new WebField(new URL(data), id, false)
-            case Types.RichText:
-                return new RichTextField(data, id, false)
-            case Types.Key:
-                return new Key(data, id, false)
-            case Types.Image:
-                return new ImageField(new URL(data), id, false)
-            case Types.HistogramOp:
-                return HistogramField.FromJson(id, data);
-            case Types.PDF:
-                return new PDFField(new URL(data), id, false)
-            case Types.List:
-                return ListField.FromJson(id, data)
-            case Types.Audio:
-                return new AudioField(new URL(data), id, false)
-            case Types.Video:
-                return new VideoField(new URL(data), id, false)
-            case Types.Tuple:
-                return new TupleField(data, id, false);
-            case Types.Ink:
-                return InkField.FromJson(id, data);
-            case Types.Document:
-                let doc: Document = new Document(id, false)
-                let fields: [string, string][] = data as [string, string][]
-                fields.forEach(element => {
-                    doc._proxies.set(element[0], element[1]);
-                });
-                return doc
-            default:
-                throw Error("Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here");
-        }
+    switch (type) {
+      case Types.Minimized:
+        return new MinimizedField(data, id, false);
+      case Types.Number:
+        return new NumberField(data, id, false);
+      case Types.Text:
+        return new TextField(data, id, false);
+      case Types.Html:
+        return new HtmlField(data, id, false);
+      case Types.Web:
+        console.log("LOOK HERE! " + data);
+        return new WebField(new URL(data), id, false);
+      case Types.RichText:
+        return new RichTextField(data, id, false);
+      case Types.Key:
+        return new Key(data, id, false);
+      case Types.Image:
+        return new ImageField(new URL(data), id, false);
+      case Types.HistogramOp:
+        return HistogramField.FromJson(id, data);
+      case Types.PDF:
+        return new PDFField(new URL(data), id, false);
+      case Types.List:
+        return ListField.FromJson(id, data);
+      case Types.Audio:
+        return new AudioField(new URL(data), id, false);
+      case Types.Video:
+        return new VideoField(new URL(data), id, false);
+      case Types.Tuple:
+        return new TupleField(data, id, false);
+      case Types.Ink:
+        return InkField.FromJson(id, data);
+      case Types.Document:
+        let doc: Document = new Document(id, false);
+        let fields: [string, string][] = data as [string, string][];
+        fields.forEach(element => {
+          doc._proxies.set(element[0], element[1]);
+        });
+        return doc;
+      default:
+        throw Error(
+          "Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here"
+        );
     }
-}
\ No newline at end of file
+  }
+}
-- 
cgit v1.2.3-70-g09d2


From fb5a34562b6855f3c9695e556497203577129a6d Mon Sep 17 00:00:00 2001
From: Monika Hedman <monika_hedman@brown.edu>
Date: Tue, 2 Apr 2019 18:10:56 -0400
Subject: clean up 2

---
 src/client/views/nodes/DocumentView.tsx | 15 ---------------
 1 file changed, 15 deletions(-)

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

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 05058e63d..2b9372e15 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -103,16 +103,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
   private _downX: number = 0;
   private _downY: number = 0;
 
-  // @observable
-  // private minimized: boolean = false;
-
-  @observable
-  private _minimized: boolean = this.props.Document.GetData(
-    KeyStore.Minimized,
-    MinimizedField,
-    false as boolean
-  );
-
   private _reactionDisposer: Opt<IReactionDisposer>;
   @computed get active(): boolean {
     return (
@@ -318,8 +308,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
 
   @action
   minimize = (e: React.MouseEvent): void => {
-    //hopefully sets field?
-    this._minimized = true as boolean;
     this.props.Document.SetData(
       KeyStore.Minimized,
       true as boolean,
@@ -396,7 +384,6 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     }
     e.preventDefault();
 
-    //for testing purposes
     if (!this.isMinimized()) {
       ContextMenu.Instance.addItem({
         description: "Minimize",
@@ -452,12 +439,10 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     if (field && field !== FieldWaiting) {
       return field.Data;
     }
-    //return this.minimized;
   };
 
   @action
   expand = () => {
-    //this._minimized = false;
     this.props.Document.SetData(
       KeyStore.Minimized,
       false as boolean,
-- 
cgit v1.2.3-70-g09d2


From 3b456da9c1d90abcfcf33fc6fd762cad1dff7ca7 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 3 Apr 2019 12:10:31 -0400
Subject: merged with changes to DocumentDecorations so you can
 minimize/maximize without menu

---
 src/client/views/DocumentDecorations.scss |  6 +++++-
 src/client/views/DocumentDecorations.tsx  | 25 ++++++++++++++++++++++++-
 src/client/views/nodes/DocumentView.tsx   | 14 +++++++-------
 3 files changed, 36 insertions(+), 9 deletions(-)

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

diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index c72623546..befe175b5 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -39,12 +39,16 @@
     }
     .title{
         background: lightblue;
-        grid-column-start:1;
+        grid-column-start:2;
         grid-column-end: 4;
         pointer-events: auto;
     }
 }
 
+.documentDecorations-minimizeButton {
+    background: rgb(250, 57, 9);
+    pointer-events: all;
+}
 .documentDecorations-background {
     background: lightblue;
     position: absolute;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 572c265f3..b74737ec9 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -139,11 +139,33 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         e.preventDefault();
     }
 
+    onMinimizeDown = (e: React.PointerEvent): void => {
+        e.stopPropagation();
+        if (e.button === 0) {
+            document.removeEventListener("pointermove", this.onMinimizeMove);
+            document.addEventListener("pointermove", this.onMinimizeMove);
+            document.removeEventListener("pointerup", this.onMinimizeUp);
+            document.addEventListener("pointerup", this.onMinimizeUp);
+        }
+    }
+    onMinimizeMove = (e: PointerEvent): void => {
+        e.stopPropagation();
+        if (e.button === 0) {
+        }
+    }
+    onMinimizeUp = (e: PointerEvent): void => {
+        e.stopPropagation();
+        if (e.button === 0) {
+            SelectionManager.SelectedDocuments().map(dv => dv.minimize());
+            document.removeEventListener("pointermove", this.onMinimizeMove);
+            document.removeEventListener("pointerup", this.onMinimizeUp);
+        }
+    }
+
     onPointerDown = (e: React.PointerEvent): void => {
         e.stopPropagation();
         if (e.button === 0) {
             this._isPointerDown = true;
-            console.log("Pointer down");
             this._resizer = e.currentTarget.id;
             document.removeEventListener("pointermove", this.onPointerMove);
             document.addEventListener("pointermove", this.onPointerMove);
@@ -339,6 +361,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 top: bounds.y - this._resizeBorderWidth / 2 - this._titleHeight,
                 opacity: this._opacity
             }}>
+                <div className="documentDecorations-minimizeButton" onPointerDown={this.onMinimizeDown}>v</div>
                 <input ref={this.keyinput} className="title" type="text" name="dynbox" value={this.getValue()} onChange={this.handleChange} onPointerDown={this.onPointerDown} onKeyPress={this.enterPressed} />
                 <div id="documentDecorations-topLeftResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
                 <div id="documentDecorations-topResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2b9372e15..bc627015c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -70,18 +70,18 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs {
   let Keys: { [name: string]: any } = {};
   let Fields: { [name: string]: any } = {};
   for (const key of keys) {
-    let fn = () => {};
+    let fn = () => { };
     Object.defineProperty(fn, "name", { value: key + "Key" });
     Keys[key] = fn;
   }
   for (const field of fields) {
-    let fn = () => {};
+    let fn = () => { };
     Object.defineProperty(fn, "name", { value: field });
     Fields[field] = fn;
   }
   let args: JsxArgs = {
-    Document: function Document() {},
-    DocumentView: function DocumentView() {},
+    Document: function Document() { },
+    DocumentView: function DocumentView() { },
     Keys,
     Fields
   } as any;
@@ -115,7 +115,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     return (
       !this.props.ContainingCollectionView ||
       this.props.ContainingCollectionView.collectionViewType ==
-        CollectionViewType.Docking
+      CollectionViewType.Docking
     );
   }
   @computed get layout(): string {
@@ -233,7 +233,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
       };
       DragManager.StartDocumentDrag([this._mainCont.current], dragData, {
         handlers: {
-          dragComplete: action(() => {})
+          dragComplete: action(() => { })
         },
         hideSource: !dropAliasOfDraggedDoc
       });
@@ -307,7 +307,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
   };
 
   @action
-  minimize = (e: React.MouseEvent): void => {
+  public minimize = (): void => {
     this.props.Document.SetData(
       KeyStore.Minimized,
       true as boolean,
-- 
cgit v1.2.3-70-g09d2


From 52dade42e61a1d147bf43ece7f2b1d7b3d7b6b6a Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 3 Apr 2019 16:12:31 -0400
Subject: changed boolean.  and editor indentation.

---
 .vscode/settings.json                              |   3 +-
 src/client/views/nodes/DocumentView.tsx            | 854 ++++++++++-----------
 src/fields/BooleanField.ts                         |  25 +
 src/fields/MinimizedField.tsx                      |  29 -
 src/server/ServerUtil.ts                           | 116 +--
 src/server/database.ts                             |  10 +-
 .../upload_a6a70d84ebb65febf7900e29f52cc86d.pdf    | Bin 0 -> 1043556 bytes
 7 files changed, 509 insertions(+), 528 deletions(-)
 create mode 100644 src/fields/BooleanField.ts
 delete mode 100644 src/fields/MinimizedField.tsx
 create mode 100644 src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf

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

diff --git a/.vscode/settings.json b/.vscode/settings.json
index 081b05b38..fc315ffaf 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -7,6 +7,7 @@
         "**/.DS_Store": true,
     },
     "editor.formatOnSave": true,
+    "editor.detectIndentation": false,
     "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false,
     "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true
-}
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index bc627015c..714ab9447 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,19 +1,13 @@
-import {
-  action,
-  computed,
-  IReactionDisposer,
-  reaction,
-  runInAction,
-  observable
-} from "mobx";
-import { library } from "@fortawesome/fontawesome-svg-core";
+import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
-import { Field, Opt, FieldWaiting } from "../../../fields/Field";
+import { Field, FieldWaiting, Opt } from "../../../fields/Field";
 import { Key } from "../../../fields/Key";
 import { KeyStore } from "../../../fields/KeyStore";
 import { ListField } from "../../../fields/ListField";
+import { BooleanField } from "../../../fields/BooleanField";
 import { TextField } from "../../../fields/TextField";
+import { ServerUtils } from "../../../server/ServerUtil";
 import { Utils } from "../../../Utils";
 import { Documents } from "../../documents/Documents";
 import { DocumentManager } from "../../util/DocumentManager";
@@ -21,34 +15,28 @@ import { DragManager } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
-import {
-  CollectionView,
-  CollectionViewType
-} from "../collections/CollectionView";
+import { CollectionView, CollectionViewType } from "../collections/CollectionView";
 import { ContextMenu } from "../ContextMenu";
 import { DocumentContentsView } from "./DocumentContentsView";
 import "./DocumentView.scss";
 import React = require("react");
-import { ServerUtils } from "../../../server/ServerUtil";
-import { DocumentDecorations } from "../DocumentDecorations";
-import { MinimizedField } from "../../../fields/MinimizedField";
 
 export interface DocumentViewProps {
-  ContainingCollectionView: Opt<CollectionView>;
-  Document: Document;
-  AddDocument?: (doc: Document, allowDuplicates: boolean) => boolean;
-  RemoveDocument?: (doc: Document) => boolean;
-  ScreenToLocalTransform: () => Transform;
-  isTopMost: boolean;
-  ContentScaling: () => number;
-  PanelWidth: () => number;
-  PanelHeight: () => number;
-  focus: (doc: Document) => void;
-  SelectOnLoad: boolean;
+    ContainingCollectionView: Opt<CollectionView>;
+    Document: Document;
+    AddDocument?: (doc: Document, allowDuplicates: boolean) => boolean;
+    RemoveDocument?: (doc: Document) => boolean;
+    ScreenToLocalTransform: () => Transform;
+    isTopMost: boolean;
+    ContentScaling: () => number;
+    PanelWidth: () => number;
+    PanelHeight: () => number;
+    focus: (doc: Document) => void;
+    SelectOnLoad: boolean;
 }
 export interface JsxArgs extends DocumentViewProps {
-  Keys: { [name: string]: Key };
-  Fields: { [name: string]: Field };
+    Keys: { [name: string]: Key };
+    Fields: { [name: string]: Field };
 }
 
 /*
@@ -67,448 +55,448 @@ Example usage of this function:
     }
 */
 export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs {
-  let Keys: { [name: string]: any } = {};
-  let Fields: { [name: string]: any } = {};
-  for (const key of keys) {
-    let fn = () => { };
-    Object.defineProperty(fn, "name", { value: key + "Key" });
-    Keys[key] = fn;
-  }
-  for (const field of fields) {
-    let fn = () => { };
-    Object.defineProperty(fn, "name", { value: field });
-    Fields[field] = fn;
-  }
-  let args: JsxArgs = {
-    Document: function Document() { },
-    DocumentView: function DocumentView() { },
-    Keys,
-    Fields
-  } as any;
-  return args;
+    let Keys: { [name: string]: any } = {};
+    let Fields: { [name: string]: any } = {};
+    for (const key of keys) {
+        let fn = () => { };
+        Object.defineProperty(fn, "name", { value: key + "Key" });
+        Keys[key] = fn;
+    }
+    for (const field of fields) {
+        let fn = () => { };
+        Object.defineProperty(fn, "name", { value: field });
+        Fields[field] = fn;
+    }
+    let args: JsxArgs = {
+        Document: function Document() { },
+        DocumentView: function DocumentView() { },
+        Keys,
+        Fields
+    } as any;
+    return args;
 }
 
 export interface JsxBindings {
-  Document: Document;
-  isSelected: () => boolean;
-  select: (isCtrlPressed: boolean) => void;
-  isTopMost: boolean;
-  SelectOnLoad: boolean;
-  [prop: string]: any;
+    Document: Document;
+    isSelected: () => boolean;
+    select: (isCtrlPressed: boolean) => void;
+    isTopMost: boolean;
+    SelectOnLoad: boolean;
+    [prop: string]: any;
 }
 
 @observer
 export class DocumentView extends React.Component<DocumentViewProps> {
-  private _mainCont = React.createRef<HTMLDivElement>();
-  private _downX: number = 0;
-  private _downY: number = 0;
+    private _mainCont = React.createRef<HTMLDivElement>();
+    private _downX: number = 0;
+    private _downY: number = 0;
 
-  private _reactionDisposer: Opt<IReactionDisposer>;
-  @computed get active(): boolean {
-    return (
-      SelectionManager.IsSelected(this) ||
-      !this.props.ContainingCollectionView ||
-      this.props.ContainingCollectionView.active()
-    );
-  }
-  @computed get topMost(): boolean {
-    return (
-      !this.props.ContainingCollectionView ||
-      this.props.ContainingCollectionView.collectionViewType ==
-      CollectionViewType.Docking
-    );
-  }
-  @computed get layout(): string {
-    return this.props.Document.GetText(
-      KeyStore.Layout,
-      "<p>Error loading layout data</p>"
-    );
-  }
-  @computed get layoutKeys(): Key[] {
-    return this.props.Document.GetData(
-      KeyStore.LayoutKeys,
-      ListField,
-      new Array<Key>()
-    );
-  }
-  @computed get layoutFields(): Key[] {
-    return this.props.Document.GetData(
-      KeyStore.LayoutFields,
-      ListField,
-      new Array<Key>()
-    );
-  }
-  screenRect = (): ClientRect | DOMRect =>
-    this._mainCont.current
-      ? this._mainCont.current.getBoundingClientRect()
-      : new DOMRect();
-  onPointerDown = (e: React.PointerEvent): void => {
-    this._downX = e.clientX;
-    this._downY = e.clientY;
-    if (e.shiftKey && e.buttons === 2) {
-      if (this.props.isTopMost) {
-        this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey);
-      } else
-        CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e);
-      e.stopPropagation();
-    } else {
-      if (this.active && !e.isDefaultPrevented()) {
-        e.stopPropagation();
-        document.removeEventListener("pointermove", this.onPointerMove);
-        document.addEventListener("pointermove", this.onPointerMove);
-        document.removeEventListener("pointerup", this.onPointerUp);
-        document.addEventListener("pointerup", this.onPointerUp);
-      }
+    private _reactionDisposer: Opt<IReactionDisposer>;
+    @computed get active(): boolean {
+        return (
+            SelectionManager.IsSelected(this) ||
+            !this.props.ContainingCollectionView ||
+            this.props.ContainingCollectionView.active()
+        );
+    }
+    @computed get topMost(): boolean {
+        return (
+            !this.props.ContainingCollectionView ||
+            this.props.ContainingCollectionView.collectionViewType ==
+            CollectionViewType.Docking
+        );
     }
-  };
+    @computed get layout(): string {
+        return this.props.Document.GetText(
+            KeyStore.Layout,
+            "<p>Error loading layout data</p>"
+        );
+    }
+    @computed get layoutKeys(): Key[] {
+        return this.props.Document.GetData(
+            KeyStore.LayoutKeys,
+            ListField,
+            new Array<Key>()
+        );
+    }
+    @computed get layoutFields(): Key[] {
+        return this.props.Document.GetData(
+            KeyStore.LayoutFields,
+            ListField,
+            new Array<Key>()
+        );
+    }
+    screenRect = (): ClientRect | DOMRect =>
+        this._mainCont.current
+            ? this._mainCont.current.getBoundingClientRect()
+            : new DOMRect();
+    onPointerDown = (e: React.PointerEvent): void => {
+        this._downX = e.clientX;
+        this._downY = e.clientY;
+        if (e.shiftKey && e.buttons === 2) {
+            if (this.props.isTopMost) {
+                this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey);
+            } else
+                CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e);
+            e.stopPropagation();
+        } else {
+            if (this.active && !e.isDefaultPrevented()) {
+                e.stopPropagation();
+                document.removeEventListener("pointermove", this.onPointerMove);
+                document.addEventListener("pointermove", this.onPointerMove);
+                document.removeEventListener("pointerup", this.onPointerUp);
+                document.addEventListener("pointerup", this.onPointerUp);
+            }
+        }
+    };
 
-  private dropDisposer?: DragManager.DragDropDisposer;
+    private dropDisposer?: DragManager.DragDropDisposer;
 
-  componentDidMount() {
-    if (this._mainCont.current) {
-      this.dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, {
-        handlers: { drop: this.drop.bind(this) }
-      });
+    componentDidMount() {
+        if (this._mainCont.current) {
+            this.dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, {
+                handlers: { drop: this.drop.bind(this) }
+            });
+        }
+        runInAction(() => DocumentManager.Instance.DocumentViews.push(this));
+        this._reactionDisposer = reaction(
+            () =>
+                this.props.ContainingCollectionView &&
+                this.props.ContainingCollectionView.SelectedDocs.slice(),
+            () => {
+                if (
+                    this.props.ContainingCollectionView &&
+                    this.props.ContainingCollectionView.SelectedDocs.indexOf(
+                        this.props.Document.Id
+                    ) != -1
+                )
+                    SelectionManager.SelectDoc(this, true);
+            }
+        );
     }
-    runInAction(() => DocumentManager.Instance.DocumentViews.push(this));
-    this._reactionDisposer = reaction(
-      () =>
-        this.props.ContainingCollectionView &&
-        this.props.ContainingCollectionView.SelectedDocs.slice(),
-      () => {
-        if (
-          this.props.ContainingCollectionView &&
-          this.props.ContainingCollectionView.SelectedDocs.indexOf(
-            this.props.Document.Id
-          ) != -1
-        )
-          SelectionManager.SelectDoc(this, true);
-      }
-    );
-  }
 
-  componentDidUpdate() {
-    if (this.dropDisposer) {
-      this.dropDisposer();
-    }
-    if (this._mainCont.current) {
-      this.dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, {
-        handlers: { drop: this.drop.bind(this) }
-      });
+    componentDidUpdate() {
+        if (this.dropDisposer) {
+            this.dropDisposer();
+        }
+        if (this._mainCont.current) {
+            this.dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, {
+                handlers: { drop: this.drop.bind(this) }
+            });
+        }
     }
-  }
 
-  componentWillUnmount() {
-    if (this.dropDisposer) {
-      this.dropDisposer();
+    componentWillUnmount() {
+        if (this.dropDisposer) {
+            this.dropDisposer();
+        }
+        runInAction(() =>
+            DocumentManager.Instance.DocumentViews.splice(
+                DocumentManager.Instance.DocumentViews.indexOf(this),
+                1
+            )
+        );
+        if (this._reactionDisposer) {
+            this._reactionDisposer();
+        }
     }
-    runInAction(() =>
-      DocumentManager.Instance.DocumentViews.splice(
-        DocumentManager.Instance.DocumentViews.indexOf(this),
-        1
-      )
-    );
-    if (this._reactionDisposer) {
-      this._reactionDisposer();
+
+    startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) {
+        if (this._mainCont.current) {
+            const [left, top] = this.props
+                .ScreenToLocalTransform()
+                .inverse()
+                .transformPoint(0, 0);
+            let dragData = new DragManager.DocumentDragData([this.props.Document]);
+            dragData.aliasOnDrop = dropAliasOfDraggedDoc;
+            dragData.xOffset = x - left;
+            dragData.yOffset = y - top;
+            dragData.removeDocument = (dropCollectionView: CollectionView) => {
+                if (
+                    this.props.RemoveDocument &&
+                    this.props.ContainingCollectionView !== dropCollectionView
+                ) {
+                    this.props.RemoveDocument(this.props.Document);
+                }
+            };
+            DragManager.StartDocumentDrag([this._mainCont.current], dragData, {
+                handlers: {
+                    dragComplete: action(() => { })
+                },
+                hideSource: !dropAliasOfDraggedDoc
+            });
+        }
     }
-  }
 
-  startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) {
-    if (this._mainCont.current) {
-      const [left, top] = this.props
-        .ScreenToLocalTransform()
-        .inverse()
-        .transformPoint(0, 0);
-      let dragData = new DragManager.DocumentDragData([this.props.Document]);
-      dragData.aliasOnDrop = dropAliasOfDraggedDoc;
-      dragData.xOffset = x - left;
-      dragData.yOffset = y - top;
-      dragData.removeDocument = (dropCollectionView: CollectionView) => {
+    onPointerMove = (e: PointerEvent): void => {
+        if (e.cancelBubble) {
+            return;
+        }
         if (
-          this.props.RemoveDocument &&
-          this.props.ContainingCollectionView !== dropCollectionView
+            Math.abs(this._downX - e.clientX) > 3 ||
+            Math.abs(this._downY - e.clientY) > 3
         ) {
-          this.props.RemoveDocument(this.props.Document);
+            document.removeEventListener("pointermove", this.onPointerMove);
+            document.removeEventListener("pointerup", this.onPointerUp);
+            if (!this.topMost || e.buttons == 2 || e.altKey) {
+                this.startDragging(e.x, e.y, e.ctrlKey || e.altKey);
+            }
         }
-      };
-      DragManager.StartDocumentDrag([this._mainCont.current], dragData, {
-        handlers: {
-          dragComplete: action(() => { })
-        },
-        hideSource: !dropAliasOfDraggedDoc
-      });
-    }
-  }
-
-  onPointerMove = (e: PointerEvent): void => {
-    if (e.cancelBubble) {
-      return;
-    }
-    if (
-      Math.abs(this._downX - e.clientX) > 3 ||
-      Math.abs(this._downY - e.clientY) > 3
-    ) {
-      document.removeEventListener("pointermove", this.onPointerMove);
-      document.removeEventListener("pointerup", this.onPointerUp);
-      if (!this.topMost || e.buttons == 2 || e.altKey) {
-        this.startDragging(e.x, e.y, e.ctrlKey || e.altKey);
-      }
-    }
-    e.stopPropagation();
-    e.preventDefault();
-  };
-  onPointerUp = (e: PointerEvent): void => {
-    document.removeEventListener("pointermove", this.onPointerMove);
-    document.removeEventListener("pointerup", this.onPointerUp);
-    e.stopPropagation();
-    if (
-      Math.abs(e.clientX - this._downX) < 4 &&
-      Math.abs(e.clientY - this._downY) < 4
-    ) {
-      SelectionManager.SelectDoc(this, e.ctrlKey);
-    }
-  };
-  stopPropogation = (e: React.SyntheticEvent) => {
-    e.stopPropagation();
-  };
+        e.stopPropagation();
+        e.preventDefault();
+    };
+    onPointerUp = (e: PointerEvent): void => {
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+        e.stopPropagation();
+        if (
+            Math.abs(e.clientX - this._downX) < 4 &&
+            Math.abs(e.clientY - this._downY) < 4
+        ) {
+            SelectionManager.SelectDoc(this, e.ctrlKey);
+        }
+    };
+    stopPropogation = (e: React.SyntheticEvent) => {
+        e.stopPropagation();
+    };
 
-  deleteClicked = (): void => {
-    if (this.props.RemoveDocument) {
-      this.props.RemoveDocument(this.props.Document);
-    }
-  };
+    deleteClicked = (): void => {
+        if (this.props.RemoveDocument) {
+            this.props.RemoveDocument(this.props.Document);
+        }
+    };
 
-  fieldsClicked = (e: React.MouseEvent): void => {
-    if (this.props.AddDocument) {
-      this.props.AddDocument(
-        Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }),
-        false
-      );
-    }
-  };
-  fullScreenClicked = (e: React.MouseEvent): void => {
-    CollectionDockingView.Instance.OpenFullScreen(this.props.Document);
-    ContextMenu.Instance.clearItems();
-    ContextMenu.Instance.addItem({
-      description: "Close Full Screen",
-      event: this.closeFullScreenClicked
-    });
-    ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
-  };
+    fieldsClicked = (e: React.MouseEvent): void => {
+        if (this.props.AddDocument) {
+            this.props.AddDocument(
+                Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }),
+                false
+            );
+        }
+    };
+    fullScreenClicked = (e: React.MouseEvent): void => {
+        CollectionDockingView.Instance.OpenFullScreen(this.props.Document);
+        ContextMenu.Instance.clearItems();
+        ContextMenu.Instance.addItem({
+            description: "Close Full Screen",
+            event: this.closeFullScreenClicked
+        });
+        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+    };
 
-  closeFullScreenClicked = (e: React.MouseEvent): void => {
-    CollectionDockingView.Instance.CloseFullScreen();
-    ContextMenu.Instance.clearItems();
-    ContextMenu.Instance.addItem({
-      description: "Full Screen",
-      event: this.fullScreenClicked
-    });
-    ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
-  };
+    closeFullScreenClicked = (e: React.MouseEvent): void => {
+        CollectionDockingView.Instance.CloseFullScreen();
+        ContextMenu.Instance.clearItems();
+        ContextMenu.Instance.addItem({
+            description: "Full Screen",
+            event: this.fullScreenClicked
+        });
+        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+    };
 
-  @action
-  public minimize = (): void => {
-    this.props.Document.SetData(
-      KeyStore.Minimized,
-      true as boolean,
-      MinimizedField
-    );
-    SelectionManager.DeselectAll();
-  };
+    @action
+    public minimize = (): void => {
+        this.props.Document.SetData(
+            KeyStore.Minimized,
+            true as boolean,
+            BooleanField
+        );
+        SelectionManager.DeselectAll();
+    };
 
-  @action
-  drop = (e: Event, de: DragManager.DropEvent) => {
-    if (de.data instanceof DragManager.LinkDragData) {
-      let sourceDoc: Document = de.data.linkSourceDocumentView.props.Document;
-      let destDoc: Document = this.props.Document;
-      if (this.props.isTopMost) {
-        return;
-      }
-      let linkDoc: Document = new Document();
+    @action
+    drop = (e: Event, de: DragManager.DropEvent) => {
+        if (de.data instanceof DragManager.LinkDragData) {
+            let sourceDoc: Document = de.data.linkSourceDocumentView.props.Document;
+            let destDoc: Document = this.props.Document;
+            if (this.props.isTopMost) {
+                return;
+            }
+            let linkDoc: Document = new Document();
 
-      destDoc.GetTAsync(KeyStore.Prototype, Document).then(protoDest =>
-        sourceDoc.GetTAsync(KeyStore.Prototype, Document).then(protoSrc =>
-          runInAction(() => {
-            linkDoc.Set(KeyStore.Title, new TextField("New Link"));
-            linkDoc.Set(KeyStore.LinkDescription, new TextField(""));
-            linkDoc.Set(KeyStore.LinkTags, new TextField("Default"));
+            destDoc.GetTAsync(KeyStore.Prototype, Document).then(protoDest =>
+                sourceDoc.GetTAsync(KeyStore.Prototype, Document).then(protoSrc =>
+                    runInAction(() => {
+                        linkDoc.Set(KeyStore.Title, new TextField("New Link"));
+                        linkDoc.Set(KeyStore.LinkDescription, new TextField(""));
+                        linkDoc.Set(KeyStore.LinkTags, new TextField("Default"));
 
-            let dstTarg = protoDest ? protoDest : destDoc;
-            let srcTarg = protoSrc ? protoSrc : sourceDoc;
-            linkDoc.Set(KeyStore.LinkedToDocs, dstTarg);
-            linkDoc.Set(KeyStore.LinkedFromDocs, srcTarg);
-            dstTarg.GetOrCreateAsync(
-              KeyStore.LinkedFromDocs,
-              ListField,
-              field => {
-                (field as ListField<Document>).Data.push(linkDoc);
-              }
-            );
-            srcTarg.GetOrCreateAsync(
-              KeyStore.LinkedToDocs,
-              ListField,
-              field => {
-                (field as ListField<Document>).Data.push(linkDoc);
-              }
+                        let dstTarg = protoDest ? protoDest : destDoc;
+                        let srcTarg = protoSrc ? protoSrc : sourceDoc;
+                        linkDoc.Set(KeyStore.LinkedToDocs, dstTarg);
+                        linkDoc.Set(KeyStore.LinkedFromDocs, srcTarg);
+                        dstTarg.GetOrCreateAsync(
+                            KeyStore.LinkedFromDocs,
+                            ListField,
+                            field => {
+                                (field as ListField<Document>).Data.push(linkDoc);
+                            }
+                        );
+                        srcTarg.GetOrCreateAsync(
+                            KeyStore.LinkedToDocs,
+                            ListField,
+                            field => {
+                                (field as ListField<Document>).Data.push(linkDoc);
+                            }
+                        );
+                    })
+                )
             );
-          })
-        )
-      );
-      e.stopPropagation();
-    }
-  };
+            e.stopPropagation();
+        }
+    };
 
-  onDrop = (e: React.DragEvent) => {
-    if (e.isDefaultPrevented()) {
-      return;
-    }
-    let text = e.dataTransfer.getData("text/plain");
-    if (text && text.startsWith("<div")) {
-      let oldLayout = this.props.Document.GetText(KeyStore.Layout, "");
-      let layout = text.replace("{layout}", oldLayout);
-      this.props.Document.SetText(KeyStore.Layout, layout);
-      e.stopPropagation();
-      e.preventDefault();
-    }
-  };
+    onDrop = (e: React.DragEvent) => {
+        if (e.isDefaultPrevented()) {
+            return;
+        }
+        let text = e.dataTransfer.getData("text/plain");
+        if (text && text.startsWith("<div")) {
+            let oldLayout = this.props.Document.GetText(KeyStore.Layout, "");
+            let layout = text.replace("{layout}", oldLayout);
+            this.props.Document.SetText(KeyStore.Layout, layout);
+            e.stopPropagation();
+            e.preventDefault();
+        }
+    };
 
-  @action
-  onContextMenu = (e: React.MouseEvent): void => {
-    e.stopPropagation();
-    let moved =
-      Math.abs(this._downX - e.clientX) > 3 ||
-      Math.abs(this._downY - e.clientY) > 3;
-    if (moved || e.isDefaultPrevented()) {
-      e.preventDefault();
-      return;
-    }
-    e.preventDefault();
+    @action
+    onContextMenu = (e: React.MouseEvent): void => {
+        e.stopPropagation();
+        let moved =
+            Math.abs(this._downX - e.clientX) > 3 ||
+            Math.abs(this._downY - e.clientY) > 3;
+        if (moved || e.isDefaultPrevented()) {
+            e.preventDefault();
+            return;
+        }
+        e.preventDefault();
 
-    if (!this.isMinimized()) {
-      ContextMenu.Instance.addItem({
-        description: "Minimize",
-        event: this.minimize
-      });
-    }
-    ContextMenu.Instance.addItem({
-      description: "Full Screen",
-      event: this.fullScreenClicked
-    });
-    ContextMenu.Instance.addItem({
-      description: "Fields",
-      event: this.fieldsClicked
-    });
-    ContextMenu.Instance.addItem({
-      description: "Center",
-      event: () => this.props.focus(this.props.Document)
-    });
-    ContextMenu.Instance.addItem({
-      description: "Open Right",
-      event: () =>
-        CollectionDockingView.Instance.AddRightSplit(this.props.Document)
-    });
-    ContextMenu.Instance.addItem({
-      description: "Copy URL",
-      event: () => {
-        Utils.CopyText(ServerUtils.prepend("/doc/" + this.props.Document.Id));
-      }
-    });
-    ContextMenu.Instance.addItem({
-      description: "Copy ID",
-      event: () => {
-        Utils.CopyText(this.props.Document.Id);
-      }
-    });
-    //ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) })
-    ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
-    if (!this.topMost) {
-      // DocumentViews should stop propagation of this event
-      e.stopPropagation();
-    }
+        if (!this.isMinimized()) {
+            ContextMenu.Instance.addItem({
+                description: "Minimize",
+                event: this.minimize
+            });
+        }
+        ContextMenu.Instance.addItem({
+            description: "Full Screen",
+            event: this.fullScreenClicked
+        });
+        ContextMenu.Instance.addItem({
+            description: "Fields",
+            event: this.fieldsClicked
+        });
+        ContextMenu.Instance.addItem({
+            description: "Center",
+            event: () => this.props.focus(this.props.Document)
+        });
+        ContextMenu.Instance.addItem({
+            description: "Open Right",
+            event: () =>
+                CollectionDockingView.Instance.AddRightSplit(this.props.Document)
+        });
+        ContextMenu.Instance.addItem({
+            description: "Copy URL",
+            event: () => {
+                Utils.CopyText(ServerUtils.prepend("/doc/" + this.props.Document.Id));
+            }
+        });
+        ContextMenu.Instance.addItem({
+            description: "Copy ID",
+            event: () => {
+                Utils.CopyText(this.props.Document.Id);
+            }
+        });
+        //ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) })
+        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+        if (!this.topMost) {
+            // DocumentViews should stop propagation of this event
+            e.stopPropagation();
+        }
 
-    ContextMenu.Instance.addItem({
-      description: "Delete",
-      event: this.deleteClicked
-    });
-    ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
-    SelectionManager.SelectDoc(this, e.ctrlKey);
-  };
+        ContextMenu.Instance.addItem({
+            description: "Delete",
+            event: this.deleteClicked
+        });
+        ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
+        SelectionManager.SelectDoc(this, e.ctrlKey);
+    };
 
-  isMinimized = () => {
-    let field = this.props.Document.GetT(KeyStore.Minimized, MinimizedField);
-    if (field && field !== FieldWaiting) {
-      return field.Data;
-    }
-  };
+    isMinimized = () => {
+        let field = this.props.Document.GetT(KeyStore.Minimized, BooleanField);
+        if (field && field !== FieldWaiting) {
+            return field.Data;
+        }
+    };
 
-  @action
-  expand = () => {
-    this.props.Document.SetData(
-      KeyStore.Minimized,
-      false as boolean,
-      MinimizedField
-    );
-  };
+    @action
+    expand = () => {
+        this.props.Document.SetData(
+            KeyStore.Minimized,
+            false as boolean,
+            BooleanField
+        );
+    };
 
-  isSelected = () => {
-    return SelectionManager.IsSelected(this);
-  };
+    isSelected = () => {
+        return SelectionManager.IsSelected(this);
+    };
 
-  select = (ctrlPressed: boolean) => {
-    SelectionManager.SelectDoc(this, ctrlPressed);
-  };
+    select = (ctrlPressed: boolean) => {
+        SelectionManager.SelectDoc(this, ctrlPressed);
+    };
 
-  render() {
-    if (!this.props.Document) {
-      return null;
-    }
+    render() {
+        if (!this.props.Document) {
+            return null;
+        }
 
-    var scaling = this.props.ContentScaling();
-    var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
-    var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
+        var scaling = this.props.ContentScaling();
+        var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
+        var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
 
-    if (this.isMinimized()) {
-      return (
-        <div
-          className="minimized-box"
-          ref={this._mainCont}
-          style={{
-            transformOrigin: "left top",
-            transform: `scale(${scaling} , ${scaling})`
-          }}
-          onClick={this.expand}
-          onDrop={this.onDrop}
-          onPointerDown={this.onPointerDown}
-        />
-      );
-    } else {
-      var backgroundcolor = this.props.Document.GetText(
-        KeyStore.BackgroundColor,
-        ""
-      );
-      return (
-        <div
-          className="documentView-node"
-          ref={this._mainCont}
-          style={{
-            background: backgroundcolor,
-            width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%",
-            height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%",
-            transformOrigin: "left top",
-            transform: `scale(${scaling} , ${scaling})`
-          }}
-          onDrop={this.onDrop}
-          onContextMenu={this.onContextMenu}
-          onPointerDown={this.onPointerDown}
-        >
-          <DocumentContentsView
-            {...this.props}
-            isSelected={this.isSelected}
-            select={this.select}
-            layoutKey={KeyStore.Layout}
-          />
-        </div>
-      );
+        if (this.isMinimized()) {
+            return (
+                <div
+                    className="minimized-box"
+                    ref={this._mainCont}
+                    style={{
+                        transformOrigin: "left top",
+                        transform: `scale(${scaling} , ${scaling})`
+                    }}
+                    onClick={this.expand}
+                    onDrop={this.onDrop}
+                    onPointerDown={this.onPointerDown}
+                />
+            );
+        } else {
+            var backgroundcolor = this.props.Document.GetText(
+                KeyStore.BackgroundColor,
+                ""
+            );
+            return (
+                <div
+                    className="documentView-node"
+                    ref={this._mainCont}
+                    style={{
+                        background: backgroundcolor,
+                        width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%",
+                        height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%",
+                        transformOrigin: "left top",
+                        transform: `scale(${scaling} , ${scaling})`
+                    }}
+                    onDrop={this.onDrop}
+                    onContextMenu={this.onContextMenu}
+                    onPointerDown={this.onPointerDown}
+                >
+                    <DocumentContentsView
+                        {...this.props}
+                        isSelected={this.isSelected}
+                        select={this.select}
+                        layoutKey={KeyStore.Layout}
+                    />
+                </div>
+            );
+        }
     }
-  }
 }
diff --git a/src/fields/BooleanField.ts b/src/fields/BooleanField.ts
new file mode 100644
index 000000000..7378b30a1
--- /dev/null
+++ b/src/fields/BooleanField.ts
@@ -0,0 +1,25 @@
+import { BasicField } from "./BasicField";
+import { FieldId } from "./Field";
+import { Types } from "../server/Message";
+
+export class BooleanField extends BasicField<boolean> {
+    constructor(data: boolean = false as boolean, id?: FieldId, save: boolean = true as boolean) {
+        super(data, save, id);
+    }
+
+    ToScriptString(): string {
+        return `new BooleanField("${this.Data}")`;
+    }
+
+    Copy() {
+        return new BooleanField(this.Data);
+    }
+
+    ToJson(): { type: Types; data: boolean; _id: string } {
+        return {
+            type: Types.Minimized,
+            data: this.Data,
+            _id: this.Id
+        };
+    }
+}
diff --git a/src/fields/MinimizedField.tsx b/src/fields/MinimizedField.tsx
deleted file mode 100644
index 5dfb22e6e..000000000
--- a/src/fields/MinimizedField.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { BasicField } from "./BasicField";
-import { FieldId } from "./Field";
-import { Types } from "../server/Message";
-
-export class MinimizedField extends BasicField<boolean> {
-  constructor(
-    data: boolean = false as boolean,
-    id?: FieldId,
-    save: boolean = true as boolean
-  ) {
-    super(data, save, id);
-  }
-
-  ToScriptString(): string {
-    return `new MinimizedField("${this.Data}")`;
-  }
-
-  Copy() {
-    return new MinimizedField(this.Data);
-  }
-
-  ToJson(): { type: Types; data: boolean; _id: string } {
-    return {
-      type: Types.Minimized,
-      data: this.Data,
-      _id: this.Id
-    };
-  }
-}
diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts
index f3c5e1d1f..d3409abf4 100644
--- a/src/server/ServerUtil.ts
+++ b/src/server/ServerUtil.ts
@@ -16,69 +16,69 @@ import { VideoField } from "../fields/VideoField";
 import { InkField } from "../fields/InkField";
 import { PDFField } from "../fields/PDFField";
 import { TupleField } from "../fields/TupleField";
-import { MinimizedField } from "../fields/MinimizedField";
+import { BooleanField } from "../fields/BooleanField";
 import { HistogramField } from "../client/northstar/dash-fields/HistogramField";
 
 export class ServerUtils {
-  public static prepend(extension: string): string {
-    return window.location.origin + extension;
-  }
+    public static prepend(extension: string): string {
+        return window.location.origin + extension;
+    }
 
-  public static FromJson(json: any): Field {
-    let obj = json;
-    let data: any = obj.data;
-    let id: string = obj._id;
-    let type: Types = obj.type;
+    public static FromJson(json: any): Field {
+        let obj = json;
+        let data: any = obj.data;
+        let id: string = obj._id;
+        let type: Types = obj.type;
 
-    if (!(data !== undefined && id && type !== undefined)) {
-      console.log(
-        "how did you manage to get an object that doesn't have a data or an id?"
-      );
-      return new TextField("Something to fill the space", Utils.GenerateGuid());
-    }
+        if (!(data !== undefined && id && type !== undefined)) {
+            console.log(
+                "how did you manage to get an object that doesn't have a data or an id?"
+            );
+            return new TextField("Something to fill the space", Utils.GenerateGuid());
+        }
 
-    switch (type) {
-      case Types.Minimized:
-        return new MinimizedField(data, id, false);
-      case Types.Number:
-        return new NumberField(data, id, false);
-      case Types.Text:
-        return new TextField(data, id, false);
-      case Types.Html:
-        return new HtmlField(data, id, false);
-      case Types.Web:
-        return new WebField(new URL(data), id, false);
-      case Types.RichText:
-        return new RichTextField(data, id, false);
-      case Types.Key:
-        return new Key(data, id, false);
-      case Types.Image:
-        return new ImageField(new URL(data), id, false);
-      case Types.HistogramOp:
-        return HistogramField.FromJson(id, data);
-      case Types.PDF:
-        return new PDFField(new URL(data), id, false);
-      case Types.List:
-        return ListField.FromJson(id, data);
-      case Types.Audio:
-        return new AudioField(new URL(data), id, false);
-      case Types.Video:
-        return new VideoField(new URL(data), id, false);
-      case Types.Tuple:
-        return new TupleField(data, id, false);
-      case Types.Ink:
-        return InkField.FromJson(id, data);
-      case Types.Document:
-        let doc: Document = new Document(id, false);
-        let fields: [string, string][] = data as [string, string][];
-        fields.forEach(element => {
-          doc._proxies.set(element[0], element[1]);
-        });
-        return doc;
-      default:
-        throw Error(
-          "Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here"
-        );
+        switch (type) {
+            case Types.Minimized:
+                return new BooleanField(data, id, false);
+            case Types.Number:
+                return new NumberField(data, id, false);
+            case Types.Text:
+                return new TextField(data, id, false);
+            case Types.Html:
+                return new HtmlField(data, id, false);
+            case Types.Web:
+                return new WebField(new URL(data), id, false);
+            case Types.RichText:
+                return new RichTextField(data, id, false);
+            case Types.Key:
+                return new Key(data, id, false);
+            case Types.Image:
+                return new ImageField(new URL(data), id, false);
+            case Types.HistogramOp:
+                return HistogramField.FromJson(id, data);
+            case Types.PDF:
+                return new PDFField(new URL(data), id, false);
+            case Types.List:
+                return ListField.FromJson(id, data);
+            case Types.Audio:
+                return new AudioField(new URL(data), id, false);
+            case Types.Video:
+                return new VideoField(new URL(data), id, false);
+            case Types.Tuple:
+                return new TupleField(data, id, false);
+            case Types.Ink:
+                return InkField.FromJson(id, data);
+            case Types.Document:
+                let doc: Document = new Document(id, false);
+                let fields: [string, string][] = data as [string, string][];
+                fields.forEach(element => {
+                    doc._proxies.set(element[0], element[1]);
+                });
+                return doc;
+            default:
+                throw Error(
+                    "Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here"
+                );
+        }
     }
-  }
 }
diff --git a/src/server/database.ts b/src/server/database.ts
index a42d29aac..616251c72 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -1,8 +1,4 @@
-import { action, configure } from 'mobx';
 import * as mongodb from 'mongodb';
-import { ObjectID } from 'mongodb';
-import { Transferable } from './Message';
-import { Utils } from '../Utils';
 
 export class Database {
     public static Instance = new Database()
@@ -26,9 +22,9 @@ export class Database {
                     console.log(err.message);
                     console.log(err.errmsg);
                 }
-                if (res) {
-                    console.log(JSON.stringify(res.result));
-                }
+                // if (res) {
+                //     console.log(JSON.stringify(res.result));
+                // }
                 callback()
             });
         }
diff --git a/src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf b/src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf
new file mode 100644
index 000000000..dfd6ab339
Binary files /dev/null and b/src/server/public/files/upload_a6a70d84ebb65febf7900e29f52cc86d.pdf differ
-- 
cgit v1.2.3-70-g09d2


From 4fde212cd00bd2f8fc2fa122309af3bb71bba2fd Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 4 Apr 2019 18:18:45 -0400
Subject: improved pdf bitmaps a bit, but still blurry.

---
 src/client/documents/Documents.ts                   |  2 +-
 src/client/views/collections/CollectionViewBase.tsx |  2 +-
 src/client/views/nodes/DocumentView.tsx             |  2 +-
 src/client/views/nodes/PDFBox.tsx                   | 20 +++++++++++---------
 4 files changed, 14 insertions(+), 12 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 0bf275df8..1f0744782 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -136,7 +136,7 @@ export namespace Documents {
     function GetPdfPrototype(): Document {
         if (!pdfProto) {
             pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("AnnotationsKey"),
-                { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
+                { x: 0, y: 0, nativeWidth: 1200, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
             pdfProto.SetNumber(KeyStore.CurPage, 1);
             pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString());
         }
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 9eee23a1d..458bae7ab 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -128,7 +128,7 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
         }
         if (type.indexOf("pdf") !== -1) {
             ctor = Documents.PdfDocument;
-            options.nativeWidth = 600;
+            options.nativeWidth = 1200;
         }
         if (type.indexOf("html") !== -1) {
             if (path.includes('localhost')) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 714ab9447..b9329f269 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -249,7 +249,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
         e.stopPropagation();
-        if (
+        if (!SelectionManager.IsSelected(this) &&
             Math.abs(e.clientX - this._downX) < 4 &&
             Math.abs(e.clientY - this._downY) < 4
         ) {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index c9fed7f66..f9f5bc8f8 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -18,6 +18,7 @@ import "./ImageBox.scss";
 import "./PDFBox.scss";
 import { Sticky } from './Sticky'; //you should look at sticky and annotation, because they are used here
 import React = require("react")
+import { SelectionManager } from "../../util/SelectionManager";
 
 /** ALSO LOOK AT: Annotation.tsx, Sticky.tsx
  * This method renders PDF and puts all kinds of functionalities such as annotation, highlighting, 
@@ -57,6 +58,8 @@ export class PDFBox extends React.Component<FieldViewProps> {
     private _mainDiv = React.createRef<HTMLDivElement>()
     private _pdf = React.createRef<HTMLCanvasElement>();
 
+    @observable private _renderAsSvg = true;
+
     //very useful for keeping track of X and y position throughout the PDF Canvas
     private initX: number = 0;
     private initY: number = 0;
@@ -91,9 +94,9 @@ export class PDFBox extends React.Component<FieldViewProps> {
 
     componentDidMount() {
         this._reactionDisposer = reaction(
-            () => [this.curPage, this.thumbnailPage],
+            () => [SelectionManager.SelectedDocuments().slice()],
             () => {
-                if (this.curPage > 0 && this.thumbnailPage > 0 && this.curPage != this.thumbnailPage) {
+                if (this.curPage > 0 && this.thumbnailPage > 0 && this.curPage != this.thumbnailPage && !this.props.isSelected()) {
                     this.saveThumbnail();
                     this._interactive = true;
                 }
@@ -375,19 +378,21 @@ export class PDFBox extends React.Component<FieldViewProps> {
 
     @action
     saveThumbnail = () => {
+        this._renderAsSvg = false;
         setTimeout(() => {
             var me = this;
             let nwidth = me.props.doc.GetNumber(KeyStore.NativeWidth, 0);
             let nheight = me.props.doc.GetNumber(KeyStore.NativeHeight, 0);
             htmlToImage.toPng(this._mainDiv.current!, { width: nwidth, height: nheight, quality: 1 })
-                .then(function (dataUrl: string) {
+                .then(action((dataUrl: string) => {
                     me.props.doc.SetData(KeyStore.Thumbnail, new URL(dataUrl), ImageField);
                     me.props.doc.SetNumber(KeyStore.ThumbnailPage, me.props.doc.GetNumber(KeyStore.CurPage, -1));
-                })
+                    me._renderAsSvg = true;
+                }))
                 .catch(function (error: any) {
                     console.error('oops, something went wrong!', error);
                 });
-        }, 1000);
+        }, 250);
     }
 
     @action
@@ -427,9 +432,6 @@ export class PDFBox extends React.Component<FieldViewProps> {
             this.props.doc.SetNumber(KeyStore.Height, nativeHeight / nativeWidth * this.props.doc.GetNumber(KeyStore.Width, 0));
             this.props.doc.SetNumber(KeyStore.NativeHeight, nativeHeight);
         }
-        if (!this.props.doc.GetT(KeyStore.Thumbnail, ImageField)) {
-            this.saveThumbnail();
-        }
     }
 
     @computed
@@ -439,7 +441,7 @@ export class PDFBox extends React.Component<FieldViewProps> {
         let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField);
         let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight;
         return <div className="pdfBox-contentContainer" key="container" style={{ transform: `scale(${xf}, ${xf})` }}>
-            <Document file={window.origin + RouteStore.corsProxy + `/${pdfUrl}`} renderMode="svg">
+            <Document file={window.origin + RouteStore.corsProxy + `/${pdfUrl}`} renderMode={this._renderAsSvg ? "svg" : ""}>
                 <Measure onResize={this.setScaling}>
                     {({ measureRef }) =>
                         <div className="pdfBox-page" ref={measureRef}>
-- 
cgit v1.2.3-70-g09d2


From f873d620e9a3804d5a6783d7ea335b27d59b4612 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 5 Apr 2019 13:03:21 -0400
Subject: fixed dragging misalignment

---
 src/client/util/DragManager.ts                     | 53 ++++++++++++----------
 src/client/views/DocumentDecorations.tsx           | 18 ++++----
 .../views/collections/CollectionDockingView.tsx    |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  4 +-
 4 files changed, 43 insertions(+), 34 deletions(-)

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

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index cc47c57e0..043932de5 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -21,7 +21,7 @@ export function setupDrag(
             document.removeEventListener("pointerup", onRowUp);
             var dragData = new DragManager.DocumentDragData([docFunc()]);
             dragData.removeDocument = removeFunc;
-            DragManager.StartDocumentDrag([_reference.current!], dragData);
+            DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
         }
     );
     let onRowUp = action(
@@ -132,11 +132,14 @@ export namespace DragManager {
     export function StartDocumentDrag(
         eles: HTMLElement[],
         dragData: DocumentDragData,
+        downX: number,
+        downY: number,
         options?: DragOptions
     ) {
         StartDrag(
             eles,
             dragData,
+            downX, downY,
             options,
             (dropData: { [id: string]: any }) =>
                 (dropData.droppedDocuments = dragData.aliasOnDrop
@@ -156,13 +159,15 @@ export namespace DragManager {
     export function StartLinkDrag(
         ele: HTMLElement,
         dragData: LinkDragData,
+        downX: number, downY: number,
         options?: DragOptions
     ) {
-        StartDrag([ele], dragData, options);
+        StartDrag([ele], dragData, downX, downY, options);
     }
     function StartDrag(
         eles: HTMLElement[],
         dragData: { [id: string]: any },
+        downX: number, downY: number,
         options?: DragOptions,
         finishDrag?: (dropData: { [id: string]: any }) => void
     ) {
@@ -204,23 +209,22 @@ export namespace DragManager {
             dragElement.style.width = `${rect.width / scaleX}px`;
             dragElement.style.height = `${rect.height / scaleY}px`;
 
-            // bcz: PDFs don't show up if you clone them because they contain a canvas.
+            // bcz: if PDFs are rendered with svg's, then this code isn't needed
+            // bcz: PDFs don't show up if you clone them when rendered using a canvas. 
             //      however, PDF's have a thumbnail field that contains an image of their canvas.
             //      So we replace the pdf's canvas with the image thumbnail
-            if (docs.length) {
-                var pdfBox = dragElement.getElementsByClassName(
-                    "pdfBox-cont"
-                )[0] as HTMLElement;
-                let thumbnail = docs[0].GetT(KeyStore.Thumbnail, ImageField);
-                if (pdfBox && pdfBox.childElementCount && thumbnail) {
-                    let img = new Image();
-                    img!.src = thumbnail.toString();
-                    img!.style.position = "absolute";
-                    img!.style.width = `${rect.width / scaleX}px`;
-                    img!.style.height = `${rect.height / scaleY}px`;
-                    pdfBox.replaceChild(img!, pdfBox.children[0]);
-                }
-            }
+            // if (docs.length) {
+            //     var pdfBox = dragElement.getElementsByClassName("pdfBox-cont")[0] as HTMLElement;
+            //     let thumbnail = docs[0].GetT(KeyStore.Thumbnail, ImageField);
+            //     if (pdfBox && pdfBox.childElementCount && thumbnail) {
+            //         let img = new Image();
+            //         img!.src = thumbnail.toString();
+            //         img!.style.position = "absolute";
+            //         img!.style.width = `${rect.width / scaleX}px`;
+            //         img!.style.height = `${rect.height / scaleY}px`;
+            //         pdfBox.replaceChild(img!, pdfBox.children[0]);
+            //     }
+            // }
 
             dragDiv.appendChild(dragElement);
             return dragElement;
@@ -236,6 +240,8 @@ export namespace DragManager {
         }
         eles.map(ele => (ele.hidden = hideSource));
 
+        let lastX = downX;
+        let lastY = downY;
         const moveHandler = (e: PointerEvent) => {
             e.stopPropagation();
             e.preventDefault();
@@ -250,12 +256,13 @@ export namespace DragManager {
                     button: 0
                 });
             }
-            dragElements.map(
-                (dragElement, i) =>
-                    (dragElement.style.transform = `translate(${(xs[i] +=
-                        e.movementX)}px, ${(ys[i] += e.movementY)}px) scale(${
-                        scaleXs[i]
-                        }, ${scaleYs[i]})`)
+            let moveX = e.pageX - lastX;
+            let moveY = e.pageY - lastY;
+            lastX = e.pageX;
+            lastY = e.pageY;
+            dragElements.map((dragElement, i) => (dragElement.style.transform =
+                `translate(${(xs[i] += moveX)}px, ${(ys[i] += moveY)}px) 
+                scale(${scaleXs[i]}, ${scaleYs[i]})`)
             );
         };
 
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 8bf1a42d1..c7e4a269a 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -126,12 +126,14 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         this._dragging = true;
         document.removeEventListener("pointermove", this.onBackgroundMove);
         document.removeEventListener("pointerup", this.onBackgroundUp);
-        DragManager.StartDocumentDrag(SelectionManager.SelectedDocuments().map(docView => (docView as any)._mainCont!.current!), dragData, {
-            handlers: {
-                dragComplete: action(() => this._dragging = false),
-            },
-            hideSource: true
-        })
+        DragManager.StartDocumentDrag(SelectionManager.SelectedDocuments().map(docView => (docView as any)._mainCont!.current!), dragData,
+            e.x, e.y,
+            {
+                handlers: {
+                    dragComplete: action(() => this._dragging = false),
+                },
+                hideSource: true
+            })
         e.stopPropagation();
     }
 
@@ -219,7 +221,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             document.removeEventListener("pointermove", this.onLinkerButtonMoved)
             document.removeEventListener("pointerup", this.onLinkerButtonUp)
             let dragData = new DragManager.LinkDragData(SelectionManager.SelectedDocuments()[0]);
-            DragManager.StartLinkDrag(this._linkerButton.current, dragData, {
+            DragManager.StartLinkDrag(this._linkerButton.current, dragData, e.pageX, e.pageY, {
                 handlers: {
                     dragComplete: action(() => { }),
                 },
@@ -265,7 +267,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                         moddrag.push(doc);
                 }
                 let dragData = new DragManager.DocumentDragData(moddrag);
-                DragManager.StartDocumentDrag([this._linkButton.current], dragData, {
+                DragManager.StartDocumentDrag([this._linkButton.current], dragData, e.x, e.y, {
                     handlers: {
                         dragComplete: action(() => { }),
                     },
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 39e0dd989..921ee4591 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -200,7 +200,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             let tab = (e.target as any).parentElement as HTMLElement;
             Server.GetField(docid, action((f: Opt<Field>) => {
                 if (f instanceof Document)
-                    DragManager.StartDocumentDrag([tab], new DragManager.DocumentDragData([f as Document]),
+                    DragManager.StartDocumentDrag([tab], new DragManager.DocumentDragData([f as Document]), e.pageX, e.pageY,
                         {
                             handlers: {
                                 dragComplete: action(() => { }),
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index b9329f269..7514e782d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -219,7 +219,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                     this.props.RemoveDocument(this.props.Document);
                 }
             };
-            DragManager.StartDocumentDrag([this._mainCont.current], dragData, {
+            DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, {
                 handlers: {
                     dragComplete: action(() => { })
                 },
@@ -239,7 +239,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             document.removeEventListener("pointermove", this.onPointerMove);
             document.removeEventListener("pointerup", this.onPointerUp);
             if (!this.topMost || e.buttons == 2 || e.altKey) {
-                this.startDragging(e.x, e.y, e.ctrlKey || e.altKey);
+                this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey);
             }
         }
         e.stopPropagation();
-- 
cgit v1.2.3-70-g09d2

