From 1870fbb3cc9ec3fc1054e4afb6b5bf54326e3a25 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 5 Jun 2019 18:41:10 -0400
Subject: small fixes to stacking view and bullet sorting.

---
 src/client/views/collections/CollectionStackingView.tsx | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index da7ea50c6..b2a7955ee 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -1,5 +1,5 @@
 import React = require("react");
-import { action, computed, IReactionDisposer, reaction } from "mobx";
+import { action, computed, IReactionDisposer, reaction, trace } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
 import { Id } from "../../../new_fields/FieldSymbols";
@@ -16,13 +16,13 @@ import { CollectionSubView } from "./CollectionSubView";
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _masonryGridRef: HTMLDivElement | null = null;
     _heightDisposer?: IReactionDisposer;
-    get gridGap() { return 10; }
-    get gridSize() { return 20; }
-    get singleColumn() { return BoolCast(this.props.Document.singleColumn, true); }
-    get columnWidth() { return this.singleColumn ? this.props.PanelWidth() - 4 * this.gridGap : NumCast(this.props.Document.columnWidth, 250); }
+    @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
+    @computed get gridSize() { return NumCast(this.props.Document.gridSize, 20); }
+    @computed get singleColumn() { return BoolCast(this.props.Document.singleColumn, true); }
+    @computed get columnWidth() { return this.singleColumn ? this.props.PanelWidth() - 4 * this.gridGap : NumCast(this.props.Document.columnWidth, 250); }
 
     componentDidMount() {
-        this._heightDisposer = reaction(() => [this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized]), this.columnWidth, this.props.PanelHeight()],
+        this._heightDisposer = reaction(() => [this.props.Document.gridGap, this.gridSize, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
             () => {
                 if (this.singleColumn) {
                     this.props.Document.height = this.childDocs.filter(d => !d.isMinimized).reduce((height, d) => {
-- 
cgit v1.2.3-70-g09d2


From dee6c838fe4dcfab3f6ea22c40506d7a34259757 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 6 Jun 2019 15:33:02 -0400
Subject: removed zoomBasis from resizing.  adjusted stackpanel.

---
 src/client/views/DocumentDecorations.tsx           |  7 +++++--
 .../views/collections/CollectionSchemaView.tsx     |  5 ++---
 .../views/collections/CollectionStackingView.tsx   | 24 ++++++++++++++--------
 3 files changed, 22 insertions(+), 14 deletions(-)

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

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index e845e0407..ee76f718d 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -445,11 +445,14 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 doc.y = (doc.y || 0) + dY * (actualdH - height);
                 if (nwidth > 0 && nheight > 0) {
                     if (Math.abs(dW) > Math.abs(dH)) {
-                        doc.zoomBasis = zoomBasis * width / actualdW;
+                        doc.width = zoomBasis * actualdW;
+                        // doc.zoomBasis = zoomBasis * width / actualdW;
                     }
                     else {
-                        doc.zoomBasis = zoomBasis * height / actualdH;
+                        doc.width = nwidth / nheight * zoomBasis * actualdH;
+                        //doc.zoomBasis = zoomBasis * height / actualdH;
                     }
+                    doc.height = nheight / nwidth * doc.width;
                 } else {
                     doc.width = zoomBasis * actualdW;
                     if (docHeightBefore === doc.height) doc.height = zoomBasis * actualdH;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 26ce4cc54..b9e5a5b65 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -431,13 +431,12 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
         }
     }
     render() {
-        trace();
         let input = this.props.previewScript === undefined ? (null) :
             <input className="collectionSchemaView-input" value={this.props.previewScript} onChange={this.onPreviewScriptChange}
                 style={{ left: `calc(50% - ${Math.min(75, (this.props.Document ? this.PanelWidth() / 2 : 75))}px)` }} />;
-        return (<div className="collectionSchemaView-previewRegion" style={{ width: this.props.width() }}>
+        return (<div className="collectionSchemaView-previewRegion" style={{ width: this.props.width(), height: "100%" }}>
             {!this.props.Document || !this.props.width ? (null) : (
-                <div className="collectionSchemaView-previewDoc" style={{ transform: `translate(${this.centeringOffset}px, 0px)` }}>
+                <div className="collectionSchemaView-previewDoc" style={{ transform: `translate(${this.centeringOffset}px, 0px)`, height: "100%" }}>
                     <DocumentView Document={this.props.Document} isTopMost={false} selectOnLoad={false}
                         addDocument={this.props.addDocument} removeDocument={this.props.removeDocument}
                         ScreenToLocalTransform={this.getTransform}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index b2a7955ee..b85023955 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -19,18 +19,25 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
     @computed get gridSize() { return NumCast(this.props.Document.gridSize, 20); }
     @computed get singleColumn() { return BoolCast(this.props.Document.singleColumn, true); }
-    @computed get columnWidth() { return this.singleColumn ? this.props.PanelWidth() - 4 * this.gridGap : NumCast(this.props.Document.columnWidth, 250); }
+    @computed get columnWidth() { return this.singleColumn ? this.props.PanelWidth() - 4 * this.gridGap : Math.min(this.props.PanelWidth() - 4 * this.gridGap, NumCast(this.props.Document.columnWidth, 250)); }
 
+    singleColDocHeight(d: Doc) {
+        let nw = NumCast(d.nativeWidth);
+        let nh = NumCast(d.nativeHeight);
+        let aspect = nw && nh ? nh / nw : 1;
+        let wid = Math.min(d[WidthSym](), this.columnWidth);
+        return (nw && nh) ? wid * aspect : d[HeightSym]();
+    }
     componentDidMount() {
         this._heightDisposer = reaction(() => [this.props.Document.gridGap, this.gridSize, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
             () => {
                 if (this.singleColumn) {
                     this.props.Document.height = this.childDocs.filter(d => !d.isMinimized).reduce((height, d) => {
-                        let hgt = d[HeightSym]();
-                        let wid = d[WidthSym]();
                         let nw = NumCast(d.nativeWidth);
                         let nh = NumCast(d.nativeHeight);
-                        if (nw && nh) hgt = nh / nw * Math.min(this.columnWidth, wid);
+                        let aspect = nw && nh ? nh / nw : 1;
+                        let wid = Math.min(d[WidthSym](), this.columnWidth);
+                        let hgt = (nw && nh) ? wid * aspect : d[HeightSym]();
                         return height + hgt + 2 * this.gridGap;
                     }, this.gridGap * 2);
                 }
@@ -79,11 +86,11 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             let colWidth = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth;
             let margin = colWidth() < this.columnWidth ? "auto" : undefined;
             let rowHeight = () => {
-                let hgt = d[HeightSym]();
                 let nw = NumCast(d.nativeWidth);
                 let nh = NumCast(d.nativeHeight);
-                if (nw && nh) hgt = nh / nw * colWidth();
-                return hgt;
+                let aspect = nw && nh ? nh / nw : 1;
+                let wid = Math.min(d[WidthSym](), this.columnWidth);
+                return (nw && nh) ? wid * aspect : d[HeightSym]();
             }
             let dxf = () => this.getDocTransform(d, dref.current!).scale(this.columnWidth / d[WidthSym]());
             return <div className="collectionStackingView-masonryDoc"
@@ -112,7 +119,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return this.childDocs.filter(d => !d.isMinimized).map(d => {
             let dref = React.createRef<HTMLDivElement>();
             let dxf = () => this.getDocTransform(d, dref.current!);
-            let colSpan = Math.ceil(Math.min(d[WidthSym](), this.columnWidth + this.gridGap) / (this.gridSize + this.gridGap));
+            let colSpan = Math.ceil((this.columnWidth + this.gridGap) / (this.gridSize + this.gridGap));
             let rowSpan = Math.ceil((this.columnWidth / d[WidthSym]() * d[HeightSym]() + this.gridGap) / (this.gridSize + this.gridGap));
             let childFocus = (doc: Doc) => {
                 doc.libraryBrush = true;
@@ -163,7 +170,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                         padding: `${topMargin}px 0px 0px ${leftMargin}px`,
                         width: this.singleColumn ? "100%" : `${cells * itemCols * (this.gridSize + this.gridGap) + leftMargin}`,
                         height: "100%",
-                        overflow: "hidden",
                         marginRight: "auto",
                         position: "relative",
                         gridGap: this.gridGap,
-- 
cgit v1.2.3-70-g09d2


From 3ed872edc6478a6106c61a99cbcc94a9412136a8 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 6 Jun 2019 16:11:41 -0400
Subject: cleaning up details.

---
 .../views/collections/CollectionStackingView.tsx   | 49 +++++++++-------------
 1 file changed, 20 insertions(+), 29 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index b85023955..50194ba95 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -16,10 +16,12 @@ import { CollectionSubView } from "./CollectionSubView";
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _masonryGridRef: HTMLDivElement | null = null;
     _heightDisposer?: IReactionDisposer;
+    _gridSize = 1;
+    @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
+    @computed get yMargin() { return NumCast(this.props.Document.yMargin, 2 * this.gridGap); }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
-    @computed get gridSize() { return NumCast(this.props.Document.gridSize, 20); }
     @computed get singleColumn() { return BoolCast(this.props.Document.singleColumn, true); }
-    @computed get columnWidth() { return this.singleColumn ? this.props.PanelWidth() - 4 * this.gridGap : Math.min(this.props.PanelWidth() - 4 * this.gridGap, NumCast(this.props.Document.columnWidth, 250)); }
+    @computed get columnWidth() { return this.singleColumn ? this.props.PanelWidth() - 2 * this.xMargin : Math.min(this.props.PanelWidth() - 2 * this.xMargin, NumCast(this.props.Document.columnWidth, 250)); }
 
     singleColDocHeight(d: Doc) {
         let nw = NumCast(d.nativeWidth);
@@ -29,17 +31,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return (nw && nh) ? wid * aspect : d[HeightSym]();
     }
     componentDidMount() {
-        this._heightDisposer = reaction(() => [this.props.Document.gridGap, this.gridSize, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
+        this._heightDisposer = reaction(() => [this.yMargin, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
             () => {
                 if (this.singleColumn) {
-                    this.props.Document.height = this.childDocs.filter(d => !d.isMinimized).reduce((height, d) => {
-                        let nw = NumCast(d.nativeWidth);
-                        let nh = NumCast(d.nativeHeight);
-                        let aspect = nw && nh ? nh / nw : 1;
-                        let wid = Math.min(d[WidthSym](), this.columnWidth);
-                        let hgt = (nw && nh) ? wid * aspect : d[HeightSym]();
-                        return height + hgt + 2 * this.gridGap;
-                    }, this.gridGap * 2);
+                    this.props.Document.height = this.childDocs.filter(d => !d.isMinimized).reduce((height, d) =>
+                        height + this.singleColDocHeight(d) + this.yMargin
+                        , this.yMargin);
                 }
             }, { fireImmediately: true });
     }
@@ -85,18 +82,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             let script = undefined;
             let colWidth = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth;
             let margin = colWidth() < this.columnWidth ? "auto" : undefined;
-            let rowHeight = () => {
-                let nw = NumCast(d.nativeWidth);
-                let nh = NumCast(d.nativeHeight);
-                let aspect = nw && nh ? nh / nw : 1;
-                let wid = Math.min(d[WidthSym](), this.columnWidth);
-                return (nw && nh) ? wid * aspect : d[HeightSym]();
-            }
+            let rowHeight = () => this.singleColDocHeight(d);
             let dxf = () => this.getDocTransform(d, dref.current!).scale(this.columnWidth / d[WidthSym]());
             return <div className="collectionStackingView-masonryDoc"
                 key={d[Id]}
                 ref={dref}
-                style={{ marginTop: `${i ? 2 * this.gridGap : 0}px`, width: colWidth(), height: rowHeight(), marginLeft: margin, marginRight: margin }} >
+                style={{ marginTop: `${i ? this.yMargin : 0}px`, width: colWidth(), height: rowHeight(), marginLeft: margin, marginRight: margin }} >
                 <CollectionSchemaPreview
                     Document={d}
                     width={colWidth}
@@ -119,8 +110,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return this.childDocs.filter(d => !d.isMinimized).map(d => {
             let dref = React.createRef<HTMLDivElement>();
             let dxf = () => this.getDocTransform(d, dref.current!);
-            let colSpan = Math.ceil((this.columnWidth + this.gridGap) / (this.gridSize + this.gridGap));
-            let rowSpan = Math.ceil((this.columnWidth / d[WidthSym]() * d[HeightSym]() + this.gridGap) / (this.gridSize + this.gridGap));
+            let colSpan = Math.ceil((this.columnWidth + this.gridGap) / (this._gridSize + this.gridGap));
+            let rowSpan = Math.ceil((this.columnWidth / d[WidthSym]() * d[HeightSym]() + this.gridGap) / (this._gridSize + this.gridGap));
             let childFocus = (doc: Doc) => {
                 doc.libraryBrush = true;
                 this.props.focus(this.props.Document); // just focus on this collection, not the underlying document because the API doesn't support adding an offset to focus on and we can't pan zoom our contents to be centered.
@@ -158,23 +149,23 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         })
     }
     render() {
-        let leftMargin = 2 * this.gridGap;
-        let topMargin = 2 * this.gridGap;
-        let itemCols = Math.ceil(this.columnWidth / (this.gridSize + this.gridGap));
-        let cells = Math.floor((this.props.PanelWidth() - leftMargin) / (itemCols * (this.gridSize + this.gridGap)));
+        let leftMargin = this.xMargin;
+        let topMargin = this.yMargin;
+        let itemCols = Math.ceil(this.columnWidth / (this._gridSize + this.gridGap));
+        let cells = Math.floor((this.props.PanelWidth() - 2 * leftMargin) / (itemCols * (this._gridSize + this.gridGap)));
         return (
             <div className="collectionStackingView" style={{ height: "100%" }}
                 ref={this.createRef} onWheel={(e: React.WheelEvent) => e.stopPropagation()}>
                 <div className={`collectionStackingView-masonry${this.singleColumn ? "Single" : "Grid"}`}
                     style={{
                         padding: `${topMargin}px 0px 0px ${leftMargin}px`,
-                        width: this.singleColumn ? "100%" : `${cells * itemCols * (this.gridSize + this.gridGap) + leftMargin}`,
-                        height: "100%",
                         marginRight: "auto",
+                        width: this.singleColumn ? "100%" : `${cells * itemCols * (this._gridSize + this.gridGap) + 2 * leftMargin}`,
+                        height: "100%",
                         position: "relative",
                         gridGap: this.gridGap,
-                        gridTemplateColumns: this.singleColumn ? undefined : `repeat(auto-fill, minmax(${this.gridSize}px,1fr))`,
-                        gridAutoRows: this.singleColumn ? undefined : `${this.gridSize}px`
+                        gridTemplateColumns: this.singleColumn ? undefined : `repeat(auto-fill, minmax(${this._gridSize}px,1fr))`,
+                        gridAutoRows: this.singleColumn ? undefined : `${this._gridSize}px`
                     }}
                 >
                     {this.singleColumn ? this.singleColumnChildren : this.children}
-- 
cgit v1.2.3-70-g09d2


From c97070d2a754aa30a1352cf938add2a2b2a4060a Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 6 Jun 2019 16:28:04 -0400
Subject: from last

---
 src/client/views/collections/CollectionStackingView.tsx | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 50194ba95..ddd9471ab 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -81,13 +81,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             let dref = React.createRef<HTMLDivElement>();
             let script = undefined;
             let colWidth = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth;
-            let margin = colWidth() < this.columnWidth ? "auto" : undefined;
             let rowHeight = () => this.singleColDocHeight(d);
             let dxf = () => this.getDocTransform(d, dref.current!).scale(this.columnWidth / d[WidthSym]());
             return <div className="collectionStackingView-masonryDoc"
                 key={d[Id]}
                 ref={dref}
-                style={{ marginTop: `${i ? this.yMargin : 0}px`, width: colWidth(), height: rowHeight(), marginLeft: margin, marginRight: margin }} >
+                style={{ marginTop: `${i ? this.yMargin : 0}px`, width: colWidth(), height: rowHeight(), marginLeft: "auto", marginRight: "auto" }} >
                 <CollectionSchemaPreview
                     Document={d}
                     width={colWidth}
@@ -151,15 +150,15 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     render() {
         let leftMargin = this.xMargin;
         let topMargin = this.yMargin;
-        let itemCols = Math.ceil(this.columnWidth / (this._gridSize + this.gridGap));
+        let itemCols = Math.floor(this.columnWidth / (this._gridSize + this.gridGap));
         let cells = Math.floor((this.props.PanelWidth() - 2 * leftMargin) / (itemCols * (this._gridSize + this.gridGap)));
         return (
             <div className="collectionStackingView" style={{ height: "100%" }}
                 ref={this.createRef} onWheel={(e: React.WheelEvent) => e.stopPropagation()}>
                 <div className={`collectionStackingView-masonry${this.singleColumn ? "Single" : "Grid"}`}
                     style={{
-                        padding: `${topMargin}px 0px 0px ${leftMargin}px`,
-                        marginRight: "auto",
+                        padding: `${topMargin}px 0px 0px 0px`,
+                        margin: "auto",
                         width: this.singleColumn ? "100%" : `${cells * itemCols * (this._gridSize + this.gridGap) + 2 * leftMargin}`,
                         height: "100%",
                         position: "relative",
-- 
cgit v1.2.3-70-g09d2


From cdbba1df80d20bd5852b20d05a1f0b20e3a8a293 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 6 Jun 2019 18:01:16 -0400
Subject: final changes to stack collection?

---
 src/client/views/collections/CollectionStackingView.tsx | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ddd9471ab..af7e02e06 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -106,10 +106,10 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     @computed
     get children() {
-        return this.childDocs.filter(d => !d.isMinimized).map(d => {
+        return this.childDocs.filter(d => !d.isMinimized).map((d, i) => {
             let dref = React.createRef<HTMLDivElement>();
             let dxf = () => this.getDocTransform(d, dref.current!);
-            let colSpan = Math.ceil((this.columnWidth + this.gridGap) / (this._gridSize + this.gridGap));
+            let colSpan = 1;//Math.ceil((this.columnWidth + this.gridGap) / (this._gridSize + this.gridGap));
             let rowSpan = Math.ceil((this.columnWidth / d[WidthSym]() * d[HeightSym]() + this.gridGap) / (this._gridSize + this.gridGap));
             let childFocus = (doc: Doc) => {
                 doc.libraryBrush = true;
@@ -148,22 +148,21 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         })
     }
     render() {
-        let leftMargin = this.xMargin;
-        let topMargin = this.yMargin;
-        let itemCols = Math.floor(this.columnWidth / (this._gridSize + this.gridGap));
-        let cells = Math.floor((this.props.PanelWidth() - 2 * leftMargin) / (itemCols * (this._gridSize + this.gridGap)));
+        let cols = this.singleColumn ? 1 : Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + 2 * this.gridGap));
+        let templatecols = "";
+        for (let i = 0; i < cols; i++) templatecols += `${this.columnWidth}px `;
         return (
             <div className="collectionStackingView" style={{ height: "100%" }}
                 ref={this.createRef} onWheel={(e: React.WheelEvent) => e.stopPropagation()}>
                 <div className={`collectionStackingView-masonry${this.singleColumn ? "Single" : "Grid"}`}
                     style={{
-                        padding: `${topMargin}px 0px 0px 0px`,
+                        padding: `${this.yMargin}px ${this.xMargin}px 0px ${this.xMargin}px`,
                         margin: "auto",
-                        width: this.singleColumn ? "100%" : `${cells * itemCols * (this._gridSize + this.gridGap) + 2 * leftMargin}`,
+                        width: this.singleColumn ? undefined : `${cols * (this.columnWidth + this.gridGap)}px`,
                         height: "100%",
                         position: "relative",
                         gridGap: this.gridGap,
-                        gridTemplateColumns: this.singleColumn ? undefined : `repeat(auto-fill, minmax(${this._gridSize}px,1fr))`,
+                        gridTemplateColumns: this.singleColumn ? undefined : templatecols,
                         gridAutoRows: this.singleColumn ? undefined : `${this._gridSize}px`
                     }}
                 >
-- 
cgit v1.2.3-70-g09d2


From 852bd5c7b7e8d6c01ff0e6dbb5cef35f4bfd9617 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 6 Jun 2019 22:49:25 -0400
Subject: added unfreeze for images, pdfs, etc.  allows margins.  improved
 rotate for images.   added ctrl-drag to resize text.  fixed minimizing to
 work with scaled views

---
 src/client/views/DocumentDecorations.tsx           | 20 +++++++++++++---
 .../views/collections/CollectionStackingView.tsx   | 13 +++++++++-
 src/client/views/nodes/DocumentView.tsx            | 28 +++++++---------------
 src/client/views/nodes/ImageBox.tsx                | 14 +++++++----
 4 files changed, 47 insertions(+), 28 deletions(-)

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

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index ee76f718d..f22fecb98 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -6,7 +6,7 @@ import { observer } from "mobx-react";
 import { Doc } from "../../new_fields/Doc";
 import { List } from "../../new_fields/List";
 import { listSpec } from "../../new_fields/Schema";
-import { Cast, NumCast, StrCast } from "../../new_fields/Types";
+import { Cast, NumCast, StrCast, BoolCast } from "../../new_fields/Types";
 import { emptyFunction, Utils } from "../../Utils";
 import { Docs } from "../documents/Documents";
 import { DocumentManager } from "../util/DocumentManager";
@@ -443,16 +443,30 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 let actualdH = Math.max(height + (dH * scale), 20);
                 doc.x = (doc.x || 0) + dX * (actualdW - width);
                 doc.y = (doc.y || 0) + dY * (actualdH - height);
+                let proto = Doc.GetProto(doc);
+                let fixedAspect = e.ctrlKey || (!BoolCast(proto.ignoreAspect, false) && nwidth && nheight);
+                if (fixedAspect && (!nwidth || !nheight)) {
+                    proto.nativeWidth = doc.width;
+                    proto.nativeHeight = doc.height;
+                    proto.ignoreAspect = true;
+                }
                 if (nwidth > 0 && nheight > 0) {
                     if (Math.abs(dW) > Math.abs(dH)) {
+                        if (!fixedAspect) proto.nativeWidth = zoomBasis * actualdW / (doc.width || 1) * NumCast(proto.nativeWidth);
                         doc.width = zoomBasis * actualdW;
                         // doc.zoomBasis = zoomBasis * width / actualdW;
+                        if (fixedAspect) doc.height = nheight / nwidth * doc.width;
+                        else doc.height = zoomBasis * actualdH;
+                        proto.nativeHeight = (doc.height || 0) / doc.width * NumCast(proto.nativeWidth);
                     }
                     else {
-                        doc.width = nwidth / nheight * zoomBasis * actualdH;
+                        if (!fixedAspect) proto.nativeHeight = zoomBasis * actualdH / (doc.height || 1) * NumCast(proto.nativeHeight);
+                        doc.height = zoomBasis * actualdH;
                         //doc.zoomBasis = zoomBasis * height / actualdH;
+                        if (fixedAspect) doc.width = nwidth / nheight * doc.height;
+                        else doc.width = zoomBasis * actualdW;
+                        proto.nativeWidth = (doc.width || 0) / doc.height * NumCast(proto.nativeHeight);
                     }
-                    doc.height = nheight / nwidth * doc.width;
                 } else {
                     doc.width = zoomBasis * actualdW;
                     if (docHeightBefore === doc.height) doc.height = zoomBasis * actualdH;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index af7e02e06..eeae498a6 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -11,6 +11,7 @@ import { DocumentView } from "../nodes/DocumentView";
 import { CollectionSchemaPreview } from "./CollectionSchemaView";
 import "./CollectionStackingView.scss";
 import { CollectionSubView } from "./CollectionSubView";
+import { ContextMenu } from "../ContextMenu";
 
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
@@ -147,12 +148,22 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             </div>);
         })
     }
+    onContextMenu = (e: React.MouseEvent): void => {
+        if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
+            ContextMenu.Instance.addItem({
+                description: "Toggle multi-column",
+                event: () => this.props.Document.singleColumn = !BoolCast(this.props.Document.singleColumn, false), icon: "file-pdf"
+            });
+        }
+    }
     render() {
-        let cols = this.singleColumn ? 1 : Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + 2 * this.gridGap));
+        let cols = this.singleColumn ? 1 : Math.min(this.childDocs.filter(d => !d.isMinimized).length,
+            Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + 2 * this.gridGap)));
         let templatecols = "";
         for (let i = 0; i < cols; i++) templatecols += `${this.columnWidth}px `;
         return (
             <div className="collectionStackingView" style={{ height: "100%" }}
+                onContextMenu={this.onContextMenu}
                 ref={this.createRef} onWheel={(e: React.WheelEvent) => e.stopPropagation()}>
                 <div className={`collectionStackingView-masonry${this.singleColumn ? "Single" : "Grid"}`}
                     style={{
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7750b9173..36a5358f0 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -189,7 +189,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     toggleMinimized = async () => {
         let minimizedDoc = await Cast(this.props.Document.minimizedDoc, Doc);
         if (minimizedDoc) {
-            let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint(
+            let scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(
                 NumCast(minimizedDoc.x) - NumCast(this.Document.x), NumCast(minimizedDoc.y) - NumCast(this.Document.y));
             this.props.collapseToPoint && this.props.collapseToPoint(scrpt, await DocListCastAsync(minimizedDoc.maximizedDocs));
         }
@@ -246,7 +246,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                                     this.props.addDocTab(getDispDoc(maxDoc), maxLocation)));
                         }
                     } else {
-                        let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2);
+                        let scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2);
                         this.props.collapseToPoint && this.props.collapseToPoint(scrpt, expandedProtoDocs);
                     }
                 }
@@ -374,23 +374,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 
     freezeNativeDimensions = (e: React.MouseEvent): void => {
-        if (NumCast(this.props.Document.nativeWidth)) {
-            let proto = Doc.GetProto(this.props.Document);
-            let nw = proto.nativeWidth;
-            let nh = proto.nativeHeight;
-            proto.nativeWidth = proto.nativeHeight = undefined;
-            this.props.Document.width = this.props.Document.frozenWidth;
-            this.props.Document.height = this.props.Document.frozenHeight;
-        }
-        else {
-            let scale = this.props.ScreenToLocalTransform().Scale * NumCast(this.props.Document.zoomBasis, 1);
-            let scr = this.screenRect();
-            let proto = Doc.GetProto(this.props.Document);
-            this.props.Document.frozenWidth = this.props.Document.width;
-            this.props.Document.frozenHeight = this.props.Document.height;
-            this.props.Document.height = proto.nativeHeight = scr.height * scale;
-            this.props.Document.width = proto.nativeWidth = scr.width * scale;
+        let proto = Doc.GetProto(this.props.Document);
+        if (proto.ignoreAspect === undefined && !proto.nativeWidth) {
+            proto.nativeWidth = this.props.PanelWidth();
+            proto.nativeHeight = this.props.PanelHeight();
+            proto.ignoreAspect = true;
         }
+        proto.ignoreAspect = !BoolCast(proto.ignoreAspect, false);
     }
 
     @action
@@ -412,7 +402,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         subitems.push({ description: "Open Right Alias", event: () => this.props.addDocTab && this.props.addDocTab(Doc.MakeAlias(this.props.Document), "onRight"), icon: "caret-square-right" });
         subitems.push({ description: "Open Fields", event: this.fieldsClicked, icon: "layer-group" });
         cm.addItem({ description: "Open...", subitems: subitems });
-        cm.addItem({ description: NumCast(this.props.Document.nativeWidth) ? "Unfreeze" : "Freeze", event: this.freezeNativeDimensions, icon: "edit" });
+        cm.addItem({ description: BoolCast(this.props.Document.ignoreAspect, false) || !this.props.Document.nativeWidth || !this.props.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "edit" });
         cm.addItem({ description: "Pin to Pres", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" });
         cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" });
         cm.addItem({
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 06ecc794b..0d19508fa 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -136,12 +136,15 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
             subitems.push({ description: "Copy path", event: () => Utils.CopyText(url), icon: "expand-arrows-alt" });
             subitems.push({
                 description: "Rotate", event: action(() => {
-                    this.props.Document.rotation = (NumCast(this.props.Document.rotation) + 90) % 360;
+                    let proto = Doc.GetProto(this.props.Document);
                     let nw = this.props.Document.nativeWidth;
-                    this.props.Document.nativeWidth = this.props.Document.nativeHeight;
-                    this.props.Document.nativeHeight = nw;
+                    let nh = this.props.Document.nativeHeight;
                     let w = this.props.Document.width;
-                    this.props.Document.width = this.props.Document.height;
+                    let h = this.props.Document.height;
+                    proto.rotation = (NumCast(this.props.Document.rotation) + 90) % 360;
+                    proto.nativeWidth = nh;
+                    proto.nativeHeight = nw;
+                    this.props.Document.width = h;
                     this.props.Document.height = w;
                 }), icon: "expand-arrows-alt"
             });
@@ -198,6 +201,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
 
         let id = (this.props as any).id; // bcz: used to set id = "isExpander" in templates.tsx
         let nativeWidth = FieldValue(this.Document.nativeWidth, pw);
+        let nativeHeight = FieldValue(this.Document.nativeHeight, 0);
         let paths: string[] = ["http://www.cs.brown.edu/~bcz/noImage.png"];
         // this._curSuffix = "";
         // if (w > 20) {
@@ -211,7 +215,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
         let interactive = InkingControl.Instance.selectedTool ? "" : "-interactive";
         let rotation = NumCast(this.props.Document.rotation, 0);
         let aspect = (rotation % 180) ? this.props.Document[HeightSym]() / this.props.Document[WidthSym]() : 1;
-        let shift = (rotation % 180) ? (this.props.Document[HeightSym]() - this.props.Document[WidthSym]() / aspect) / 2 : 0;
+        let shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
         return (
             <div id={id} className={`imageBox-cont${interactive}`}
                 onPointerDown={this.onPointerDown}
-- 
cgit v1.2.3-70-g09d2


From ac63044fad5968cca83108f6dd3015ef657840bd Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 7 Jun 2019 10:21:55 -0400
Subject: fixed some pinterest layout issues.

---
 .../views/collections/CollectionBaseView.scss      | 11 ++++++++
 .../views/collections/CollectionBaseView.tsx       |  4 +--
 .../views/collections/CollectionStackingView.scss  | 20 ++++---------
 .../views/collections/CollectionStackingView.tsx   | 33 +++++++++++-----------
 src/client/views/nodes/DocumentView.tsx            |  3 +-
 5 files changed, 36 insertions(+), 35 deletions(-)
 create mode 100644 src/client/views/collections/CollectionBaseView.scss

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

diff --git a/src/client/views/collections/CollectionBaseView.scss b/src/client/views/collections/CollectionBaseView.scss
new file mode 100644
index 000000000..1f5acb96a
--- /dev/null
+++ b/src/client/views/collections/CollectionBaseView.scss
@@ -0,0 +1,11 @@
+@import "../globalCssVariables";
+#collectionBaseView {
+    border-width: 0;
+    box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw;
+    border-color: $light-color-secondary;
+    border-style: solid;
+    border-radius: 0 0 $border-radius $border-radius;
+    box-sizing: border-box;
+    border-radius: inherit;
+    pointer-events: all;
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index cb92464e5..ddec587a9 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -9,6 +9,7 @@ import { Cast, FieldValue, NumCast, PromiseValue } from '../../../new_fields/Typ
 import { SelectionManager } from '../../util/SelectionManager';
 import { ContextMenu } from '../ContextMenu';
 import { FieldViewProps } from '../nodes/FieldView';
+import './CollectionBaseView.scss';
 
 export enum CollectionViewType {
     Invalid,
@@ -178,8 +179,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
         };
         const viewtype = this.collectionViewType;
         return (
-            <div className={this.props.className || "collectionView-cont"}
-                style={{ borderRadius: "inherit", pointerEvents: "all" }}
+            <div id="collectionBaseView" className={this.props.className || "collectionView-cont"}
                 onContextMenu={this.props.onContextMenu} ref={this.props.contentRef}>
                 {viewtype !== undefined ? this.props.children(viewtype, props) : (null)}
             </div>
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 4d84aaaa9..af194aec9 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -1,19 +1,6 @@
 @import "../globalCssVariables";
-
 .collectionStackingView {
-    top: 0;
-    left: 0;
-    display: flex;
-    flex-direction: column;
-    width: 100%;
-    position: absolute;
     overflow-y: auto;
-    border-width: 0;
-    box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw;
-    border-color: $light-color-secondary;
-    border-style: solid;
-    border-radius: 0 0 $border-radius $border-radius;
-    box-sizing: border-box;
 
     .collectionStackingView-docView-container {
         width: 45%;
@@ -33,9 +20,12 @@
         width:100%;
         height:100%;
         position: absolute;
-    }
-    .collectionStackingView-masonryGrid {
         display:grid;
+        top: 0;
+        left: 0;
+        width: 100%;
+        position: absolute;
+        
     }
 
     .collectionStackingView-description {
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index eeae498a6..b8eb4ac84 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -32,11 +32,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return (nw && nh) ? wid * aspect : d[HeightSym]();
     }
     componentDidMount() {
-        this._heightDisposer = reaction(() => [this.yMargin, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
+        this._heightDisposer = reaction(() => [this.yMargin, this.gridGap, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
             () => {
                 if (this.singleColumn) {
-                    this.props.Document.height = this.childDocs.filter(d => !d.isMinimized).reduce((height, d) =>
-                        height + this.singleColDocHeight(d) + this.yMargin
+                    let children = this.childDocs.filter(d => !d.isMinimized);
+                    this.props.Document.height = children.reduce((height, d, i) =>
+                        height + this.singleColDocHeight(d) + (i === children.length - 1 ? this.yMargin : this.gridGap)
                         , this.yMargin);
                 }
             }, { fireImmediately: true });
@@ -78,7 +79,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
 
     @computed
     get singleColumnChildren() {
-        return this.childDocs.filter(d => !d.isMinimized).map((d, i) => {
+        let children = this.childDocs.filter(d => !d.isMinimized);
+        return children.map((d, i) => {
             let dref = React.createRef<HTMLDivElement>();
             let script = undefined;
             let colWidth = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth;
@@ -87,7 +89,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             return <div className="collectionStackingView-masonryDoc"
                 key={d[Id]}
                 ref={dref}
-                style={{ marginTop: `${i ? this.yMargin : 0}px`, width: colWidth(), height: rowHeight(), marginLeft: "auto", marginRight: "auto" }} >
+                style={{ width: colWidth(), height: rowHeight(), marginLeft: "auto", marginRight: "auto" }} >
                 <CollectionSchemaPreview
                     Document={d}
                     width={colWidth}
@@ -107,10 +109,10 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     @computed
     get children() {
+        trace();
         return this.childDocs.filter(d => !d.isMinimized).map((d, i) => {
             let dref = React.createRef<HTMLDivElement>();
             let dxf = () => this.getDocTransform(d, dref.current!);
-            let colSpan = 1;//Math.ceil((this.columnWidth + this.gridGap) / (this._gridSize + this.gridGap));
             let rowSpan = Math.ceil((this.columnWidth / d[WidthSym]() * d[HeightSym]() + this.gridGap) / (this._gridSize + this.gridGap));
             let childFocus = (doc: Doc) => {
                 doc.libraryBrush = true;
@@ -124,7 +126,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     height: NumCast(d.nativeHeight, d[HeightSym]()),
                     transformOrigin: "top left",
                     gridRowEnd: `span ${rowSpan}`,
-                    gridColumnEnd: `span ${colSpan}`,
+                    gridColumnEnd: `span 1`,
                     transform: `scale(${this.columnWidth / NumCast(d.nativeWidth, d[WidthSym]())}, ${this.columnWidth / NumCast(d.nativeWidth, d[WidthSym]())})`
                 }} >
                 <DocumentView key={d[Id]} Document={d}
@@ -157,19 +159,19 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         }
     }
     render() {
-        let cols = this.singleColumn ? 1 : Math.min(this.childDocs.filter(d => !d.isMinimized).length,
-            Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + 2 * this.gridGap)));
+        let cols = this.singleColumn ? 1 : Math.max(1, Math.min(this.childDocs.filter(d => !d.isMinimized).length,
+            Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
         let templatecols = "";
         for (let i = 0; i < cols; i++) templatecols += `${this.columnWidth}px `;
         return (
-            <div className="collectionStackingView" style={{ height: "100%" }}
-                onContextMenu={this.onContextMenu}
-                ref={this.createRef} onWheel={(e: React.WheelEvent) => e.stopPropagation()}>
+            <div className="collectionStackingView">
                 <div className={`collectionStackingView-masonry${this.singleColumn ? "Single" : "Grid"}`}
+                    onContextMenu={this.onContextMenu}
+                    ref={this.createRef} onWheel={(e: React.WheelEvent) => e.stopPropagation()}
                     style={{
-                        padding: `${this.yMargin}px ${this.xMargin}px 0px ${this.xMargin}px`,
+                        padding: this.singleColumn ? `${this.yMargin}px ${this.xMargin}px ${this.yMargin}px ${this.xMargin}px` : `${this.yMargin}px ${this.xMargin}px`,
                         margin: "auto",
-                        width: this.singleColumn ? undefined : `${cols * (this.columnWidth + this.gridGap)}px`,
+                        width: this.singleColumn ? undefined : `${cols * (this.columnWidth + this.gridGap) + 2 * this.xMargin - this.gridGap}px`,
                         height: "100%",
                         position: "relative",
                         gridGap: this.gridGap,
@@ -178,8 +180,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     }}
                 >
                     {this.singleColumn ? this.singleColumnChildren : this.children}
-                </div>
-            </div>
+                </div></div>
         );
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 36a5358f0..ff2b9842f 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,6 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faAlignCenter, faCaretSquareRight, faCompressArrowsAlt, faExpandArrowsAlt, faLayerGroup, faSquare, faTrash, faConciergeBell, faFolder, faMapPin, faLink, faFingerprint, faCrosshairs, faDesktop } from '@fortawesome/free-solid-svg-icons';
-import { action, computed, IReactionDisposer, reaction } from "mobx";
+import { action, computed, IReactionDisposer, reaction, trace } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocListCastAsync } from "../../../new_fields/Doc";
 import { List } from "../../../new_fields/List";
@@ -439,7 +439,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         var scaling = this.props.ContentScaling();
         var nativeHeight = this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%";
         var nativeWidth = this.nativeWidth > 0 ? `${this.nativeWidth}px` : "100%";
-
         return (
             <div className={`documentView-node${this.props.isTopMost ? "-topmost" : ""}`}
                 ref={this._mainCont}
-- 
cgit v1.2.3-70-g09d2


From e1b7feda380f540e677e69e306d91d6b57ce03e7 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 7 Jun 2019 19:42:43 -0400
Subject: tree view reordering.

---
 src/client/documents/Documents.ts                  |  2 +-
 src/client/util/DragManager.ts                     | 16 +++--
 .../views/collections/CollectionDockingView.tsx    |  5 +-
 .../views/collections/CollectionStackingView.tsx   |  1 -
 src/client/views/collections/CollectionSubView.tsx | 24 ++-----
 .../views/collections/CollectionTreeView.scss      | 79 ++++++++++++----------
 src/new_fields/Doc.ts                              |  6 +-
 .../authentication/models/current_user_utils.ts    |  1 +
 8 files changed, 70 insertions(+), 64 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index ab61b915c..5f2d729cf 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -30,7 +30,7 @@ import { Cast, NumCast } from "../../new_fields/Types";
 import { IconField } from "../../new_fields/IconField";
 import { listSpec } from "../../new_fields/Schema";
 import { DocServer } from "../DocServer";
-import { StrokeData, InkField } from "../../new_fields/InkField";
+import { InkField } from "../../new_fields/InkField";
 import { dropActionType } from "../util/DragManager";
 import { DateField } from "../../new_fields/DateField";
 import { UndoManager } from "../util/UndoManager";
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 1e84a0db0..32476b785 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -6,7 +6,7 @@ import { CollectionDockingView } from "../views/collections/CollectionDockingVie
 import * as globalCssVariables from "../views/globalCssVariables.scss";
 
 export type dropActionType = "alias" | "copy" | undefined;
-export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: () => Doc | Promise<Doc>, moveFunc?: DragManager.MoveFunction, dropAction?: dropActionType) {
+export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: () => Doc | Promise<Doc>, moveFunc?: DragManager.MoveFunction, dropAction?: dropActionType, options?: any, dontHideOnDrop?: boolean) {
     let onRowMove = async (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
@@ -16,6 +16,8 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
         var dragData = new DragManager.DocumentDragData([await docFunc()]);
         dragData.dropAction = dropAction;
         dragData.moveDocument = moveFunc;
+        dragData.options = options;
+        dragData.dontHideOnDrop = dontHideOnDrop;
         DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
     };
     let onRowUp = (): void => {
@@ -185,6 +187,7 @@ export namespace DragManager {
     export let AbortDrag: () => void = emptyFunction;
 
     function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) {
+        eles = eles.filter(e => e);
         if (!dragDiv) {
             dragDiv = document.createElement("div");
             dragDiv.className = "dragManager-dragDiv";
@@ -241,6 +244,13 @@ export namespace DragManager {
             //         pdfBox.replaceChild(img, pdfBox.children[0])
             //     }
             // }
+            let set = dragElement.getElementsByTagName('*');
+            for (let i = 0; i < set.length; i++)
+                if (set[i].hasAttribute("style")) {
+                    let s = set[i];
+                    (s as any).style.pointerEvents = "none";
+                }
+
 
             dragDiv.appendChild(dragElement);
             return dragElement;
@@ -259,8 +269,6 @@ export namespace DragManager {
         let lastX = downX;
         let lastY = downY;
         const moveHandler = (e: PointerEvent) => {
-            e.stopPropagation();
-            e.preventDefault();
             if (dragData instanceof DocumentDragData) {
                 dragData.userDropAction = e.ctrlKey || e.altKey ? "alias" : undefined;
             }
@@ -309,7 +317,7 @@ export namespace DragManager {
     }
 
     function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) {
-        let removed = dragEles.map(dragEle => {
+        let removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => {
             // let parent = dragEle.parentElement;
             // if (parent) parent.removeChild(dragEle);
             let ret = [dragEle, dragEle.style.width, dragEle.style.height];
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 8f6c9b1fc..51e29cb54 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -23,6 +23,7 @@ import "./CollectionDockingView.scss";
 import { SubCollectionViewProps } from "./CollectionSubView";
 import { ParentDocSelector } from './ParentDocumentSelector';
 import React = require("react");
+import { MainView } from '../MainView';
 
 @observer
 export class CollectionDockingView extends React.Component<SubCollectionViewProps> {
@@ -457,7 +458,9 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     get previewPanelCenteringOffset() { return (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2; }
 
     addDocTab = (doc: Doc, location: string) => {
-        if (location === "onRight") {
+        if (doc.dockingConfig) {
+            MainView.Instance.openWorkspace(doc);
+        } else if (location === "onRight") {
             CollectionDockingView.Instance.AddRightSplit(doc);
         } else {
             CollectionDockingView.Instance.AddTab(this._stack, doc);
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index b8eb4ac84..0a119a3b4 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -109,7 +109,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     @computed
     get children() {
-        trace();
         return this.childDocs.filter(d => !d.isMinimized).map((d, i) => {
             let dref = React.createRef<HTMLDivElement>();
             let dxf = () => this.getDocTransform(d, dref.current!);
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 06d77fec5..762955a08 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -18,6 +18,7 @@ import { CollectionVideoView } from "./CollectionVideoView";
 import { CollectionView } from "./CollectionView";
 import React = require("react");
 import { FormattedTextBox } from "../nodes/FormattedTextBox";
+import { Id } from "../../../new_fields/FieldSymbols";
 
 export interface CollectionViewProps extends FieldViewProps {
     addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -81,28 +82,15 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
         @action
         protected drop(e: Event, de: DragManager.DropEvent): boolean {
             if (de.data instanceof DragManager.DocumentDragData) {
-                if (de.data.dropAction || de.data.userDropAction) {
-                    ["width", "height", "curPage"].map(key =>
-                        de.data.draggedDocuments.map((draggedDocument: Doc, i: number) =>
-                            PromiseValue(Cast(draggedDocument[key], "number")).then(f => f && (de.data.droppedDocuments[i][key] = f))));
-                }
                 let added = false;
                 if (de.data.dropAction || de.data.userDropAction) {
-                    added = de.data.droppedDocuments.reduce((added: boolean, d) => {
-                        let moved = this.props.addDocument(d);
-                        return moved || added;
-                    }, false);
+                    added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
                 } else if (de.data.moveDocument) {
-                    const move = de.data.moveDocument;
-                    added = de.data.droppedDocuments.reduce((added: boolean, d) => {
-                        let moved = move(d, this.props.Document, this.props.addDocument);
-                        return moved || added;
-                    }, false);
+                    let movedDocs = de.data.options === this.props.Document[Id] ? de.data.draggedDocuments : de.data.droppedDocuments;
+                    added = movedDocs.reduce((added: boolean, d) =>
+                        de.data.moveDocument(d, this.props.Document, this.props.addDocument) || added, false);
                 } else {
-                    added = de.data.droppedDocuments.reduce((added: boolean, d) => {
-                        let moved = this.props.addDocument(d);
-                        return moved || added;
-                    }, false);
+                    added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
                 }
                 e.stopPropagation();
                 return added;
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 458030b28..2dc4b2e80 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -19,10 +19,6 @@
         padding-left: 20px;
     }
 
-    li {
-        margin: 5px 0;
-    }
-
 
     .no-indent {
         padding-left: 0;
@@ -34,30 +30,9 @@
         width: 15px;
         display: block;
         color: $intermediate-color;
-        margin-top: 3px;
+        margin-top: 8px;
         transform: scale(1.3, 1.3);
     }
-
-    .docContainer {
-        margin-left: 10px;
-        display: block;
-        // width:100%;//width: max-content;
-    }
-
-    .docContainer:hover {
-        .treeViewItem-openRight {
-            display: inline-block;
-            height:13px;
-            // display: inline;
-            svg {
-                display:block;
-                padding:0px;
-                margin: 0px;
-            }
-        }
-    }
-
-
     .editableView-container {
         font-weight: bold;
     }
@@ -70,10 +45,6 @@
         display: inline;
     }
 
-    .treeViewItem-openRight {
-        margin-left: 5px;
-        display: none;
-    }
 
     .docContainer:hover {
         .delete-button {
@@ -88,13 +59,51 @@
         font-size: 24px;
     }
 
-    .collection-child {
-        margin-top: 10px;
-        margin-bottom: 10px;
-    }
-
     .collectionTreeView-keyHeader {
         font-style: italic;
         font-size: 8pt;
     }
+}
+
+.docContainer {
+    margin-left: 10px;
+    display: block;
+    // width:100%;//width: max-content;
+
+    .treeViewItem-openRight {
+        margin-left: 5px;
+        display: none;
+    }
+}
+#docContainer-data {
+    margin-top: 5px;
+}
+
+.docContainer:hover {
+    .treeViewItem-openRight {
+        display: inline-block;
+        height:13px;
+        // display: inline;
+        svg {
+            display:block;
+            padding:0px;
+            margin: 0px;
+        }
+    }
+}
+
+.treeViewItem-header {
+    border: transparent 1px solid;
+}
+.treeViewItem-header-above {
+    border: transparent 1px solid;
+    border-top: black 1px solid;
+}
+.treeViewItem-header-below {
+    border: transparent 1px solid;
+    border-bottom: black 1px solid;
+}
+.treeViewItem-header-inside {
+    border: transparent 1px solid;
+    border: black 1px solid;
 }
\ No newline at end of file
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 7f7263cf1..7e02a5bc5 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -211,13 +211,11 @@ export namespace Doc {
         return Array.from(results);
     }
 
-
     export function MakeAlias(doc: Doc) {
-        const alias = new Doc;
         if (!GetT(doc, "isPrototype", "boolean", true)) {
-            alias.proto = doc.proto;
+            return Doc.MakeCopy(doc);
         }
-        return alias;
+        return new Doc;
     }
 
     export function MakeCopy(doc: Doc, copyProto: boolean = false): Doc {
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index e5b7a025b..816c5f269 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -29,6 +29,7 @@ export class CurrentUserUtils {
     private static createUserDocument(id: string): Doc {
         let doc = new Doc(id, true);
         doc.viewType = CollectionViewType.Tree;
+        doc.dropAction = "alias";
         doc.layout = CollectionView.LayoutString();
         doc.title = this.email;
         doc.data = new List<Doc>();
-- 
cgit v1.2.3-70-g09d2


From a2742057084ac0c78ed5f360b1078b5b267eff1f Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sun, 9 Jun 2019 20:32:06 -0400
Subject: added a link context for link targets.

---
 src/client/documents/Documents.ts                  | 30 ++++++++++------------
 src/client/util/DocumentManager.ts                 | 29 ++++++++++++++++-----
 src/client/views/DocumentDecorations.tsx           |  3 +--
 .../views/collections/CollectionBaseView.tsx       |  6 ++---
 .../views/collections/CollectionStackingView.tsx   |  2 +-
 src/client/views/nodes/DocumentView.tsx            | 15 ++++++++---
 6 files changed, 52 insertions(+), 33 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f0fb0c3ed..2ae127e21 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -69,31 +69,27 @@ export interface DocumentOptions {
 const delegateKeys = ["x", "y", "width", "height", "panX", "panY"];
 
 export namespace DocUtils {
-    export function MakeLink(source: Doc, target: Doc) {
+    export function MakeLink(source: Doc, target: Doc, targetContext?: Doc) {
         let protoSrc = source.proto ? source.proto : source;
         let protoTarg = target.proto ? target.proto : target;
         UndoManager.RunInBatch(() => {
             let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 });
-            //let linkDoc = new Doc;
-            linkDoc.proto!.title = "-link name-";
-            linkDoc.proto!.linkDescription = "";
-            linkDoc.proto!.linkTags = "Default";
+            let linkDocProto = Doc.GetProto(linkDoc);
+            linkDocProto.title = source.title + " to " + target.title;
+            linkDocProto.linkDescription = "";
+            linkDocProto.linkTags = "Default";
 
-            linkDoc.proto!.linkedTo = target;
-            linkDoc.proto!.linkedToPage = target.curPage;
-            linkDoc.proto!.linkedFrom = source;
-            linkDoc.proto!.linkedFromPage = source.curPage;
+            linkDocProto.linkedTo = target;
+            linkDocProto.linkedFrom = source;
+            linkDocProto.linkedToPage = target.curPage;
+            linkDocProto.linkedFromPage = source.curPage;
+            linkDocProto.linkedToContext = targetContext;
 
             let linkedFrom = Cast(protoTarg.linkedFromDocs, listSpec(Doc));
-            if (!linkedFrom) {
-                protoTarg.linkedFromDocs = linkedFrom = new List<Doc>();
-            }
-            linkedFrom.push(linkDoc);
-
             let linkedTo = Cast(protoSrc.linkedToDocs, listSpec(Doc));
-            if (!linkedTo) {
-                protoSrc.linkedToDocs = linkedTo = new List<Doc>();
-            }
+            !linkedFrom && (protoTarg.linkedFromDocs = linkedFrom = new List<Doc>());
+            !linkedTo && (protoSrc.linkedToDocs = linkedTo = new List<Doc>());
+            linkedFrom.push(linkDoc);
             linkedTo.push(linkDoc);
             return linkDoc;
         }, "make link");
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 65c4b9e4b..ff0c1560b 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -115,7 +115,7 @@ export class DocumentManager {
     }
 
     @undoBatch
-    public jumpToDocument = async (docDelegate: Doc, forceDockFunc: boolean = false, dockFunc?: (doc: Doc) => void, linkPage?: number): Promise<void> => {
+    public jumpToDocument = async (docDelegate: Doc, forceDockFunc: boolean = false, dockFunc?: (doc: Doc) => void, linkPage?: number, docContext?: Doc): Promise<void> => {
         let doc = Doc.GetProto(docDelegate);
         const contextDoc = await Cast(doc.annotationOn, Doc);
         if (contextDoc) {
@@ -123,6 +123,7 @@ export class DocumentManager {
             const curPage = NumCast(contextDoc.curPage, page);
             if (page !== curPage) contextDoc.curPage = page;
         }
+
         let docView: DocumentView | null;
         // using forceDockFunc as a flag for splitting linked to doc to the right...can change later if needed
         if (!forceDockFunc && (docView = DocumentManager.Instance.getDocumentView(doc))) {
@@ -131,18 +132,34 @@ export class DocumentManager {
             docView.props.focus(docView.props.Document);
         } else {
             if (!contextDoc) {
-                const actualDoc = Doc.MakeAlias(docDelegate);
-                actualDoc.libraryBrush = true;
-                if (linkPage !== undefined) actualDoc.curPage = linkPage;
-                (dockFunc || CollectionDockingView.Instance.AddRightSplit)(actualDoc);
+                if (docContext) {
+                    let targetContextView: DocumentView | null;
+                    if (!forceDockFunc && docContext && (targetContextView = DocumentManager.Instance.getDocumentView(docContext))) {
+                        docContext.panTransformType = "Ease";
+                        targetContextView.props.focus(docDelegate);
+                    } else {
+                        (dockFunc || CollectionDockingView.Instance.AddRightSplit)(docContext);
+                        setTimeout(() => {
+                            this.jumpToDocument(docDelegate, forceDockFunc, dockFunc, linkPage);
+                        }, 10);
+                    }
+                } else {
+                    const actualDoc = Doc.MakeAlias(docDelegate);
+                    actualDoc.libraryBrush = true;
+                    if (linkPage !== undefined) actualDoc.curPage = linkPage;
+                    (dockFunc || CollectionDockingView.Instance.AddRightSplit)(actualDoc);
+                }
             } else {
                 let contextView: DocumentView | null;
                 docDelegate.libraryBrush = true;
                 if (!forceDockFunc && (contextView = DocumentManager.Instance.getDocumentView(contextDoc))) {
                     contextDoc.panTransformType = "Ease";
-                    contextView.props.focus(contextDoc);
+                    contextView.props.focus(docDelegate);
                 } else {
                     (dockFunc || CollectionDockingView.Instance.AddRightSplit)(contextDoc);
+                    setTimeout(() => {
+                        this.jumpToDocument(docDelegate, forceDockFunc, dockFunc, linkPage);
+                    }, 10);
                 }
             }
         }
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index f22fecb98..7260b00cf 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -432,7 +432,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
 
             if (rect.width !== 0 && (dX != 0 || dY != 0 || dW != 0 || dH != 0)) {
                 let doc = PositionDocument(element.props.Document);
-                let docHeightBefore = doc.height;
                 let nwidth = doc.nativeWidth || 0;
                 let nheight = doc.nativeHeight || 0;
                 let zoomBasis = NumCast(doc.zoomBasis, 1);
@@ -469,7 +468,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     }
                 } else {
                     doc.width = zoomBasis * actualdW;
-                    if (docHeightBefore === doc.height) doc.height = zoomBasis * actualdH;
+                    doc.height = zoomBasis * actualdH;
                 }
             }
         });
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index ddec587a9..d120c3a0c 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -101,9 +101,9 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
     addDocument(doc: Doc, allowDuplicates: boolean = false): boolean {
         let props = this.props;
         var curPage = NumCast(props.Document.curPage, -1);
-        Doc.SetOnPrototype(doc, "page", curPage);
+        Doc.GetProto(doc).page = curPage;
         if (curPage >= 0) {
-            Doc.SetOnPrototype(doc, "annotationOn", props.Document);
+            Doc.GetProto(doc).annotationOn = props.Document;
         }
         if (!this.createsCycle(doc, props.Document)) {
             //TODO This won't create the field if it doesn't already exist
@@ -141,7 +141,7 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
                 break;
             }
         }
-        PromiseValue(Cast(doc.annotationOn, Doc)).then((annotationOn) => {
+        PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn => {
             if (annotationOn === props.Document) {
                 doc.annotationOn = undefined;
             }
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 0a119a3b4..cad7cd50c 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -153,7 +153,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
             ContextMenu.Instance.addItem({
                 description: "Toggle multi-column",
-                event: () => this.props.Document.singleColumn = !BoolCast(this.props.Document.singleColumn, false), icon: "file-pdf"
+                event: () => this.props.Document.singleColumn = !BoolCast(this.props.Document.singleColumn, true), icon: "file-pdf"
             });
         }
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 85b8a5596..2ac6d12bf 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -6,7 +6,7 @@ import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocListCastAsync } from "..
 import { List } from "../../../new_fields/List";
 import { ObjectField } from "../../../new_fields/ObjectField";
 import { createSchema, makeInterface } from "../../../new_fields/Schema";
-import { BoolCast, Cast, FieldValue, StrCast, NumCast } from "../../../new_fields/Types";
+import { BoolCast, Cast, FieldValue, StrCast, NumCast, PromiseValue } from "../../../new_fields/Types";
 import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
 import { emptyFunction, Utils } from "../../../Utils";
 import { DocServer } from "../../DocServer";
@@ -261,12 +261,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                         linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : expandedDocs[0],
                         linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : expandedDocs[0]];
 
+                    let linkedFwdContextDocs = [
+                        linkedToDocs.length ? await (linkedToDocs[0].linkedToContext) as Doc : linkedFromDocs.length ? await PromiseValue(linkedFromDocs[0].linkedFromContext) as Doc : undefined,
+                        linkedFromDocs.length ? await (linkedFromDocs[0].linkedFromContext) as Doc : linkedToDocs.length ? await PromiseValue(linkedToDocs[0].linkedToContext) as Doc : undefined];
+
                     let linkedFwdPage = [
                         linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : undefined,
                         linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : undefined];
+
                     if (!linkedFwdDocs.some(l => l instanceof Promise)) {
                         let maxLocation = StrCast(linkedFwdDocs[altKey ? 1 : 0].maximizeLocation, "inTab");
-                        DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0]);
+                        DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0], linkedFwdContextDocs[altKey ? 1 : 0]);
                     }
                 }
             }
@@ -333,6 +338,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             let sourceDoc = de.data.linkSourceDocument;
             let destDoc = this.props.Document;
 
+            e.stopPropagation();
             if (de.mods === "AltKey") {
                 const protoDest = destDoc.proto;
                 const protoSrc = sourceDoc.proto;
@@ -343,10 +349,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 dst.nativeHeight = src.nativeHeight;
             }
             else {
-                DocUtils.MakeLink(sourceDoc, destDoc);
+                const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
+                const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
+                DocUtils.MakeLink(sourceDoc, destDoc, views.length ? views[0].props.Document : undefined);
                 de.data.droppedDocuments.push(destDoc);
             }
-            e.stopPropagation();
         }
     }
 
-- 
cgit v1.2.3-70-g09d2

