From a4543fdc90f8c19e4a032294c2f7d16a3152662f Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Tue, 30 Jun 2020 13:33:04 -0500
Subject: working with linked text

---
 .../formattedText/FormattedTextBoxComment.tsx      | 120 ++++++++++++++++-----
 1 file changed, 92 insertions(+), 28 deletions(-)

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

diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 90f2c0aa6..a4153a40c 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -16,6 +16,13 @@ import React = require("react");
 import { Docs } from "../../../documents/Documents";
 import wiki from "wikijs";
 import { DocumentType } from "../../../documents/DocumentTypes";
+import { computed, action, observable } from "mobx";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { LinkManager } from "../../../util/LinkManager";
+import { LinkDocPreview } from "../LinkDocPreview";
+import { DocumentLinksButton } from "../DocumentLinksButton";
+import { ContextMenu } from "../../ContextMenu";
+import { MainView } from "../../MainView";
 
 export let formattedTextBoxCommentPlugin = new Plugin({
     view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -62,6 +69,10 @@ export class FormattedTextBoxComment {
     static mark: Mark;
     static textBox: FormattedTextBox | undefined;
     static linkDoc: Doc | undefined;
+
+    static targetDoc: Doc | undefined;
+    static _editRef = React.createRef<HTMLDivElement>();
+
     constructor(view: any) {
         if (!FormattedTextBoxComment.tooltip) {
             const root = document.getElementById("root");
@@ -75,8 +86,8 @@ export class FormattedTextBoxComment {
             FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
             FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
             FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
-            FormattedTextBoxComment.tooltip.style.maxWidth = "350px";
-            FormattedTextBoxComment.tooltip.style.maxHeight = "250px";
+            FormattedTextBoxComment.tooltip.style.maxWidth = "225px";
+            FormattedTextBoxComment.tooltip.style.maxHeight = "225px";
             FormattedTextBoxComment.tooltip.style.width = "100%";
             FormattedTextBoxComment.tooltip.style.height = "100%";
             FormattedTextBoxComment.tooltip.style.overflow = "hidden";
@@ -106,6 +117,31 @@ export class FormattedTextBoxComment {
         }
     }
 
+    @action
+    public static deleteLink = (): void => {
+        FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
+        //this.props.showLinks();
+        LinkDocPreview.LinkInfo = undefined;
+        DocumentLinksButton.EditLink = undefined;
+    }
+
+    @action
+    public static onContextMenu = (e: React.MouseEvent) => {
+        DocumentLinksButton.EditLink = undefined;
+        LinkDocPreview.LinkInfo = undefined;
+        e.preventDefault();
+        ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => FormattedTextBoxComment.followDefault(), icon: "arrow-right" });
+        ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
+    }
+
+    @action.bound
+    public static async followDefault() {
+        DocumentLinksButton.EditLink = undefined;
+        LinkDocPreview.LinkInfo = undefined;
+        FormattedTextBoxComment.targetDoc ? DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, FormattedTextBoxComment.targetDoc,
+            doc => MainView.addDocTabFunc(doc, "onRight"), false) : null;
+    }
+
     public static Hide() {
         FormattedTextBoxComment.textBox = undefined;
         FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
@@ -119,6 +155,22 @@ export class FormattedTextBoxComment {
         FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "");
     }
 
+    @action
+    onClick = (e: PointerEvent) => {
+        if (FormattedTextBoxComment._editRef && !FormattedTextBoxComment._editRef.current?.contains(e.target as Node)) {
+            FormattedTextBoxComment.linkDoc = undefined;
+            FormattedTextBoxComment.targetDoc = undefined;
+        }
+    }
+    @action
+    componentDidMount() {
+        document.addEventListener("pointerdown", this.onClick);
+    }
+
+    componentWillUnmount() {
+        document.removeEventListener("pointerdown", this.onClick);
+    }
+
     static showCommentbox(set: string, view: EditorView, nbef: number) {
         const state = view.state;
         if (set !== "none") {
@@ -157,6 +209,7 @@ export class FormattedTextBoxComment {
         (FormattedTextBoxComment.tooltipText as any).href = "";
         FormattedTextBoxComment.tooltipText.style.whiteSpace = "";
         FormattedTextBoxComment.tooltipText.style.overflow = "";
+
         // this section checks to see if the insertion point is over text entered by a different user.  If so, it sets ths comment text to indicate the user and the modification date
         if (state.selection.$from) {
             nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark);
@@ -209,33 +262,44 @@ export class FormattedTextBoxComment {
                                 target._scrollY = NumCast(anchor?.y);
                             }
                             if (target?.author) {
+
+                                const docPreview = <div style={{ backgroundColor: "white" }}> {target.title}
+                                    <div className="wrapper" style={{ float: "right" }}>
+                                        <div title="Delete link" className="button" style={{ display: "inline" }} ref={this._editRef} onPointerDown={this.deleteLink}>
+                                            <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+                                        <div title="Follow link" className="button" style={{ display: "inline" }} onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+                                            <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
+                                        </div>
+                                    </div>
+                                    <ContentFittingDocumentView
+                                        Document={target}
+                                        LibraryPath={emptyPath}
+                                        fitToBox={true}
+                                        moveDocument={returnFalse}
+                                        rootSelected={returnFalse}
+                                        ScreenToLocalTransform={Transform.Identity}
+                                        parentActive={returnFalse}
+                                        addDocument={returnFalse}
+                                        removeDocument={returnFalse}
+                                        addDocTab={returnFalse}
+                                        pinToPres={returnFalse}
+                                        dontRegisterView={true}
+                                        docFilters={returnEmptyFilter}
+                                        ContainingCollectionDoc={undefined}
+                                        ContainingCollectionView={undefined}
+                                        renderDepth={0}
+                                        PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
+                                        PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
+                                        focus={emptyFunction}
+                                        whenActiveChanged={returnFalse}
+                                        bringToFront={returnFalse}
+                                        ContentScaling={returnOne}
+                                        NativeWidth={returnZero}
+                                        NativeHeight={returnZero}
+                                    />
+                                </div>;
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
-                                ReactDOM.render(<ContentFittingDocumentView
-                                    Document={target}
-                                    LibraryPath={emptyPath}
-                                    fitToBox={true}
-                                    moveDocument={returnFalse}
-                                    rootSelected={returnFalse}
-                                    ScreenToLocalTransform={Transform.Identity}
-                                    parentActive={returnFalse}
-                                    addDocument={returnFalse}
-                                    removeDocument={returnFalse}
-                                    addDocTab={returnFalse}
-                                    pinToPres={returnFalse}
-                                    dontRegisterView={true}
-                                    docFilters={returnEmptyFilter}
-                                    ContainingCollectionDoc={undefined}
-                                    ContainingCollectionView={undefined}
-                                    renderDepth={0}
-                                    PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
-                                    PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
-                                    focus={emptyFunction}
-                                    whenActiveChanged={returnFalse}
-                                    bringToFront={returnFalse}
-                                    ContentScaling={returnOne}
-                                    NativeWidth={returnZero}
-                                    NativeHeight={returnZero}
-                                />, FormattedTextBoxComment.tooltipText);
+                                ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText);
                                 FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%";
                                 FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%";
                             }
-- 
cgit v1.2.3-70-g09d2


From 3cc69c7f5ae7f7a747ab72b522ea81af38dd7f20 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Tue, 30 Jun 2020 16:45:23 -0500
Subject: slight mods to inline links

---
 src/client/views/nodes/LinkDocPreview.tsx          | 79 +++++++++++-----------
 .../formattedText/FormattedTextBoxComment.tsx      |  6 +-
 2 files changed, 45 insertions(+), 40 deletions(-)

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

diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 1d2c022a7..d02896436 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -98,45 +98,46 @@ export class LinkDocPreview extends React.Component<Props> {
                     {this._toolTipText}
                 </div>
             </div> :
-            <div style={{
-                border: "6px solid white",
-            }}>
-                <div style={{ backgroundColor: "white" }}> {this._targetDoc.title}
-                    <div className="wrapper" style={{ float: "right" }}>
-                        <div title="Delete link" className="button" style={{ display: "inline" }} ref={this._editRef} onPointerDown={this.deleteLink}>
-                            <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
-                        <div title="Follow link" className="button" style={{ display: "inline" }} onClick={this.followDefault} onContextMenu={this.onContextMenu}>
-                            <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
-                        </div>
-                    </div>
-                </div>
-                <ContentFittingDocumentView
-                    Document={this._targetDoc}
-                    LibraryPath={emptyPath}
-                    fitToBox={true}
-                    backgroundColor={this.props.backgroundColor}
-                    moveDocument={returnFalse}
-                    rootSelected={returnFalse}
-                    ScreenToLocalTransform={Transform.Identity}
-                    parentActive={returnFalse}
-                    addDocument={returnFalse}
-                    removeDocument={returnFalse}
-                    addDocTab={returnFalse}
-                    pinToPres={returnFalse}
-                    dontRegisterView={true}
-                    docFilters={returnEmptyFilter}
-                    ContainingCollectionDoc={undefined}
-                    ContainingCollectionView={undefined}
-                    renderDepth={0}
-                    PanelWidth={this.width}
-                    PanelHeight={this.height}
-                    focus={emptyFunction}
-                    whenActiveChanged={returnFalse}
-                    bringToFront={returnFalse}
-                    ContentScaling={returnOne}
-                    NativeWidth={returnZero}
-                    NativeHeight={returnZero}
-                /></div>;
+            // <div style={{
+            //     border: "6px solid white",
+            // }}>
+            //     <div style={{ backgroundColor: "white" }}> {this._targetDoc.title}
+            //         <div className="wrapper" style={{ float: "right" }}>
+            //             <div title="Delete link" className="button" style={{ display: "inline" }} ref={this._editRef} onPointerDown={this.deleteLink}>
+            //                 <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+            //             <div title="Follow link" className="button" style={{ display: "inline" }} onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+            //                 <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
+            //             </div>
+            //         </div>
+            //     </div>
+            <ContentFittingDocumentView
+                Document={this._targetDoc}
+                LibraryPath={emptyPath}
+                fitToBox={true}
+                backgroundColor={this.props.backgroundColor}
+                moveDocument={returnFalse}
+                rootSelected={returnFalse}
+                ScreenToLocalTransform={Transform.Identity}
+                parentActive={returnFalse}
+                addDocument={returnFalse}
+                removeDocument={returnFalse}
+                addDocTab={returnFalse}
+                pinToPres={returnFalse}
+                dontRegisterView={true}
+                docFilters={returnEmptyFilter}
+                ContainingCollectionDoc={undefined}
+                ContainingCollectionView={undefined}
+                renderDepth={0}
+                PanelWidth={this.width}
+                PanelHeight={this.height}
+                focus={emptyFunction}
+                whenActiveChanged={returnFalse}
+                bringToFront={returnFalse}
+                ContentScaling={returnOne}
+                NativeWidth={returnZero}
+                NativeHeight={returnZero}
+            />;
+        //</div>;
     }
 
     render() {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index a4153a40c..8eeeae051 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -73,6 +73,8 @@ export class FormattedTextBoxComment {
     static targetDoc: Doc | undefined;
     static _editRef = React.createRef<HTMLDivElement>();
 
+    static openDoc: any;
+
     constructor(view: any) {
         if (!FormattedTextBoxComment.tooltip) {
             const root = document.getElementById("root");
@@ -99,6 +101,7 @@ export class FormattedTextBoxComment {
                 if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
                     if (FormattedTextBoxComment.linkDoc.author) {
                         if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+                            FormattedTextBoxComment.openDoc = textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
                             textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
                         } else {
                             DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
@@ -119,6 +122,7 @@ export class FormattedTextBoxComment {
 
     @action
     public static deleteLink = (): void => {
+        console.log(FormattedTextBoxComment.linkDoc);
         FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
         //this.props.showLinks();
         LinkDocPreview.LinkInfo = undefined;
@@ -139,7 +143,7 @@ export class FormattedTextBoxComment {
         DocumentLinksButton.EditLink = undefined;
         LinkDocPreview.LinkInfo = undefined;
         FormattedTextBoxComment.targetDoc ? DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, FormattedTextBoxComment.targetDoc,
-            doc => MainView.addDocTabFunc(doc, "onRight"), false) : null;
+            doc => FormattedTextBoxComment, false) : null;
     }
 
     public static Hide() {
-- 
cgit v1.2.3-70-g09d2


From 044c770b22f23709ac6a1b5429631e6633217282 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 1 Jul 2020 11:04:42 -0500
Subject: modifications to text previews

---
 package-lock.json                                  |  44 +++++---
 src/client/views/linking/LinkMenuItem.scss         |   1 -
 .../formattedText/FormattedTextBoxComment.scss     |  57 ++++++++--
 .../formattedText/FormattedTextBoxComment.tsx      | 117 +++++++++++----------
 4 files changed, 141 insertions(+), 78 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 3136a9cc2..d42e286e2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2976,7 +2976,8 @@
                         },
                         "ansi-regex": {
                             "version": "2.1.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "aproba": {
                             "version": "1.2.0",
@@ -2994,11 +2995,13 @@
                         },
                         "balanced-match": {
                             "version": "1.0.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "brace-expansion": {
                             "version": "1.1.11",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "balanced-match": "^1.0.0",
                                 "concat-map": "0.0.1"
@@ -3011,15 +3014,18 @@
                         },
                         "code-point-at": {
                             "version": "1.1.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "concat-map": {
                             "version": "0.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "console-control-strings": {
                             "version": "1.1.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "core-util-is": {
                             "version": "1.0.2",
@@ -3122,7 +3128,8 @@
                         },
                         "inherits": {
                             "version": "2.0.4",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "ini": {
                             "version": "1.3.5",
@@ -3132,6 +3139,7 @@
                         "is-fullwidth-code-point": {
                             "version": "1.0.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "number-is-nan": "^1.0.0"
                             }
@@ -3144,17 +3152,20 @@
                         "minimatch": {
                             "version": "3.0.4",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "brace-expansion": "^1.1.7"
                             }
                         },
                         "minimist": {
                             "version": "1.2.5",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "safe-buffer": "^5.1.2",
                                 "yallist": "^3.0.0"
@@ -3171,6 +3182,7 @@
                         "mkdirp": {
                             "version": "0.5.3",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "minimist": "^1.2.5"
                             }
@@ -3226,7 +3238,8 @@
                         },
                         "npm-normalize-package-bin": {
                             "version": "1.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "npm-packlist": {
                             "version": "1.4.8",
@@ -3251,7 +3264,8 @@
                         },
                         "number-is-nan": {
                             "version": "1.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "object-assign": {
                             "version": "4.1.1",
@@ -3261,6 +3275,7 @@
                         "once": {
                             "version": "1.4.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "wrappy": "1"
                             }
@@ -3329,7 +3344,8 @@
                         },
                         "safe-buffer": {
                             "version": "5.1.2",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "safer-buffer": {
                             "version": "2.1.2",
@@ -3359,6 +3375,7 @@
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "code-point-at": "^1.0.0",
                                 "is-fullwidth-code-point": "^1.0.0",
@@ -3376,6 +3393,7 @@
                         "strip-ansi": {
                             "version": "3.0.1",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "ansi-regex": "^2.0.0"
                             }
@@ -3414,11 +3432,13 @@
                         },
                         "wrappy": {
                             "version": "1.0.2",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "yallist": {
                             "version": "3.1.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         }
                     }
                 }
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index fd0954f65..1669fc39d 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -61,7 +61,6 @@
         margin: 0;
         margin-right: 6px;
         border-radius: 50%;
-        cursor: pointer;
         pointer-events: auto;
         background-color: $dark-color;
         color: $light-color;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index 2dd63ec21..d83583db1 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -8,10 +8,12 @@
     margin-bottom: 7px;
     -webkit-transform: translateX(-50%);
     transform: translateX(-50%);
-  }
-  .FormattedTextBox-tooltip:before {
+}
+
+.FormattedTextBox-tooltip:before {
     content: "";
-    height: 0; width: 0;
+    height: 0;
+    width: 0;
     position: absolute;
     left: 50%;
     margin-left: -5px;
@@ -19,10 +21,12 @@
     border: 5px solid transparent;
     border-bottom-width: 0;
     border-top-color: silver;
-  }
-  .FormattedTextBox-tooltip:after {
+}
+
+.FormattedTextBox-tooltip:after {
     content: "";
-    height: 0; width: 0;
+    height: 0;
+    width: 0;
     position: absolute;
     left: 50%;
     margin-left: -5px;
@@ -30,4 +34,43 @@
     border: 5px solid transparent;
     border-bottom-width: 0;
     border-top-color: white;
-  }
\ No newline at end of file
+}
+
+.FormattedTextBox-buttons {
+    display: none;
+    position: absolute;
+    top: 50%;
+    right: 0;
+    transform: translateY(-50%);
+
+    .button {
+        width: 20px;
+        height: 20px;
+        margin: 0;
+        margin-right: 6px;
+        border-radius: 50%;
+        pointer-events: auto;
+        background-color: rgb(53, 146, 199);
+        color: rgb(150, 211, 248);
+        font-size: 65%;
+        transition: transform 0.2s;
+        text-align: center;
+        position: relative;
+
+        .fa-icon {
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+        }
+
+        &:last-child {
+            margin-right: 0;
+        }
+
+        &:hover {
+            background: rgb(53, 146, 199);
+            ;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 8eeeae051..15cd68c26 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -2,7 +2,7 @@ import { Mark, ResolvedPos } from "prosemirror-model";
 import { EditorState, Plugin } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import * as ReactDOM from 'react-dom';
-import { Doc, DocCastAsync } from "../../../../fields/Doc";
+import { Doc, DocCastAsync, Opt } from "../../../../fields/Doc";
 import { Cast, FieldValue, NumCast } from "../../../../fields/Types";
 import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne, returnEmptyFilter } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
@@ -16,13 +16,11 @@ import React = require("react");
 import { Docs } from "../../../documents/Documents";
 import wiki from "wikijs";
 import { DocumentType } from "../../../documents/DocumentTypes";
-import { computed, action, observable } from "mobx";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { LinkManager } from "../../../util/LinkManager";
-import { LinkDocPreview } from "../LinkDocPreview";
-import { DocumentLinksButton } from "../DocumentLinksButton";
-import { ContextMenu } from "../../ContextMenu";
-import { MainView } from "../../MainView";
+import { action } from "mobx";
+// import { LinkManager } from "../../../util/LinkManager";
+// import { LinkDocPreview } from "../LinkDocPreview";
+// import { DocumentLinksButton } from "../DocumentLinksButton";
 
 export let formattedTextBoxCommentPlugin = new Plugin({
     view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -70,10 +68,8 @@ export class FormattedTextBoxComment {
     static textBox: FormattedTextBox | undefined;
     static linkDoc: Doc | undefined;
 
-    static targetDoc: Doc | undefined;
-    static _editRef = React.createRef<HTMLDivElement>();
-
-    static openDoc: any;
+    static _deleteRef: Opt<HTMLDivElement | null>;
+    static _followRef: Opt<HTMLDivElement | null>;
 
     constructor(view: any) {
         if (!FormattedTextBoxComment.tooltip) {
@@ -88,8 +84,8 @@ export class FormattedTextBoxComment {
             FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
             FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
             FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
-            FormattedTextBoxComment.tooltip.style.maxWidth = "225px";
-            FormattedTextBoxComment.tooltip.style.maxHeight = "225px";
+            FormattedTextBoxComment.tooltip.style.maxWidth = "350px";
+            FormattedTextBoxComment.tooltip.style.maxHeight = "250px";
             FormattedTextBoxComment.tooltip.style.width = "100%";
             FormattedTextBoxComment.tooltip.style.height = "100%";
             FormattedTextBoxComment.tooltip.style.overflow = "hidden";
@@ -100,13 +96,25 @@ export class FormattedTextBoxComment {
                 const textBox = FormattedTextBoxComment.textBox;
                 if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
                     if (FormattedTextBoxComment.linkDoc.author) {
+
+                        // if (FormattedTextBoxComment._deleteRef && FormattedTextBoxComment._deleteRef.contains(e.target as any)) {
+                        //     FormattedTextBoxComment.deleteLink();
+                        // } else if (FormattedTextBoxComment._followRef && FormattedTextBoxComment._followRef.contains(e.target as any)) {
+                        //     if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+                        //         textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+                        //     } else {
+                        //         DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
+                        //             (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+                        //     }
+                        // } else {
                         if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
-                            FormattedTextBoxComment.openDoc = textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
                             textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
                         } else {
                             DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
                                 (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
                         }
+                        //}
+
                     }
                 } else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) {
                     textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400, UseCors: true }), "onRight");
@@ -117,33 +125,16 @@ export class FormattedTextBoxComment {
                 e.preventDefault();
             };
             root && root.appendChild(FormattedTextBoxComment.tooltip);
-        }
+        };
     }
 
     @action
     public static deleteLink = (): void => {
         console.log(FormattedTextBoxComment.linkDoc);
-        FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
-        //this.props.showLinks();
-        LinkDocPreview.LinkInfo = undefined;
-        DocumentLinksButton.EditLink = undefined;
-    }
-
-    @action
-    public static onContextMenu = (e: React.MouseEvent) => {
-        DocumentLinksButton.EditLink = undefined;
-        LinkDocPreview.LinkInfo = undefined;
-        e.preventDefault();
-        ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => FormattedTextBoxComment.followDefault(), icon: "arrow-right" });
-        ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
-    }
-
-    @action.bound
-    public static async followDefault() {
-        DocumentLinksButton.EditLink = undefined;
-        LinkDocPreview.LinkInfo = undefined;
-        FormattedTextBoxComment.targetDoc ? DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, FormattedTextBoxComment.targetDoc,
-            doc => FormattedTextBoxComment, false) : null;
+        // FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
+        // //this.props.showLinks();
+        // LinkDocPreview.LinkInfo = undefined;
+        // DocumentLinksButton.EditLink = undefined;
     }
 
     public static Hide() {
@@ -159,22 +150,6 @@ export class FormattedTextBoxComment {
         FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "");
     }
 
-    @action
-    onClick = (e: PointerEvent) => {
-        if (FormattedTextBoxComment._editRef && !FormattedTextBoxComment._editRef.current?.contains(e.target as Node)) {
-            FormattedTextBoxComment.linkDoc = undefined;
-            FormattedTextBoxComment.targetDoc = undefined;
-        }
-    }
-    @action
-    componentDidMount() {
-        document.addEventListener("pointerdown", this.onClick);
-    }
-
-    componentWillUnmount() {
-        document.removeEventListener("pointerdown", this.onClick);
-    }
-
     static showCommentbox(set: string, view: EditorView, nbef: number) {
         const state = view.state;
         if (set !== "none") {
@@ -213,7 +188,6 @@ export class FormattedTextBoxComment {
         (FormattedTextBoxComment.tooltipText as any).href = "";
         FormattedTextBoxComment.tooltipText.style.whiteSpace = "";
         FormattedTextBoxComment.tooltipText.style.overflow = "";
-
         // this section checks to see if the insertion point is over text entered by a different user.  If so, it sets ths comment text to indicate the user and the modification date
         if (state.selection.$from) {
             nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark);
@@ -266,12 +240,12 @@ export class FormattedTextBoxComment {
                                 target._scrollY = NumCast(anchor?.y);
                             }
                             if (target?.author) {
-
+                                FormattedTextBoxComment.showCommentbox("", view, nbef);
                                 const docPreview = <div style={{ backgroundColor: "white" }}> {target.title}
                                     <div className="wrapper" style={{ float: "right" }}>
-                                        <div title="Delete link" className="button" style={{ display: "inline" }} ref={this._editRef} onPointerDown={this.deleteLink}>
+                                        <div title="Delete link" className="FormattedTextBoxComment-button" style={{ display: "inline" }} ref={(r) => this._deleteRef = r}>
                                             <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
-                                        <div title="Follow link" className="button" style={{ display: "inline" }} onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+                                        <div title="Follow link" className="FormattedTextBoxComment-button" style={{ display: "inline" }} ref={(r) => this._followRef = r}>
                                             <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
                                         </div>
                                     </div>
@@ -303,7 +277,34 @@ export class FormattedTextBoxComment {
                                     />
                                 </div>;
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
-                                ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText);
+
+                                ReactDOM.render(<ContentFittingDocumentView
+                                    Document={target}
+                                    LibraryPath={emptyPath}
+                                    fitToBox={true}
+                                    moveDocument={returnFalse}
+                                    rootSelected={returnFalse}
+                                    ScreenToLocalTransform={Transform.Identity}
+                                    parentActive={returnFalse}
+                                    addDocument={returnFalse}
+                                    removeDocument={returnFalse}
+                                    addDocTab={returnFalse}
+                                    pinToPres={returnFalse}
+                                    dontRegisterView={true}
+                                    docFilters={returnEmptyFilter}
+                                    ContainingCollectionDoc={undefined}
+                                    ContainingCollectionView={undefined}
+                                    renderDepth={0}
+                                    PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
+                                    PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
+                                    focus={emptyFunction}
+                                    whenActiveChanged={returnFalse}
+                                    bringToFront={returnFalse}
+                                    ContentScaling={returnOne}
+                                    NativeWidth={returnZero}
+                                    NativeHeight={returnZero}
+                                />, FormattedTextBoxComment.tooltipText);
+
                                 FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%";
                                 FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%";
                             }
@@ -317,4 +318,4 @@ export class FormattedTextBoxComment {
     }
 
     destroy() { }
-}
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 581ba904dc9bd02f6e2d81f42c45f38f6ad26cab Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 1 Jul 2020 13:14:02 -0500
Subject: textbox comment changes

---
 src/client/views/MainView.tsx                      | 40 +++++----
 .../formattedText/FormattedTextBoxComment.scss     |  4 +-
 .../formattedText/FormattedTextBoxComment.tsx      | 97 +++++++++-------------
 3 files changed, 62 insertions(+), 79 deletions(-)

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

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 9328198d0..200486279 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -65,7 +65,7 @@ export class MainView extends React.Component {
     public static Instance: MainView;
     private _buttonBarHeight = 36;
     private _flyoutSizeOnDown = 0;
-    private static _urlState: HistoryUtil.DocUrl;
+    private _urlState: HistoryUtil.DocUrl;
     private _docBtnRef = React.createRef<HTMLDivElement>();
     private _mainViewRef = React.createRef<HTMLDivElement>();
 
@@ -73,12 +73,12 @@ export class MainView extends React.Component {
     @observable private _panelHeight: number = 0;
     @observable private _flyoutTranslate: boolean = true;
     @observable public flyoutWidth: number = 250;
-    private get darkScheme() { return BoolCast(Cast(MainView.userDoc?.activeWorkspace, Doc, null)?.darkScheme); }
+    private get darkScheme() { return BoolCast(Cast(this.userDoc?.activeWorkspace, Doc, null)?.darkScheme); }
 
-    @computed private static get userDoc() { return Doc.UserDoc(); }
-    @computed private get mainContainer() { return MainView.userDoc ? FieldValue(Cast(MainView.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; }
+    @computed private get userDoc() { return Doc.UserDoc(); }
+    @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; }
     @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs && docs.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
-    @computed public get sidebarButtonsDoc() { return Cast(MainView.userDoc["tabs-buttons"], Doc) as Doc; }
+    @computed public get sidebarButtonsDoc() { return Cast(this.userDoc["tabs-buttons"], Doc) as Doc; }
 
     public isPointerDown = false;
 
@@ -119,7 +119,7 @@ export class MainView extends React.Component {
     constructor(props: Readonly<{}>) {
         super(props);
         MainView.Instance = this;
-        MainView._urlState = HistoryUtil.parseUrl(window.location) || {} as any;
+        this._urlState = HistoryUtil.parseUrl(window.location) || {} as any;
         // causes errors to be generated when modifying an observable outside of an action
         configure({ enforceActions: "observed" });
         if (window.location.pathname !== "/home") {
@@ -128,7 +128,7 @@ export class MainView extends React.Component {
                 const type = pathname[0];
                 if (type === "doc") {
                     CurrentUserUtils.MainDocId = pathname[1];
-                    if (!MainView.userDoc) {
+                    if (!this.userDoc) {
                         runInAction(() => this.flyoutWidth = 0);
                         DocServer.GetRefField(CurrentUserUtils.MainDocId).then(action((field: Opt<Field>) =>
                             field instanceof Doc && (CurrentUserUtils.GuestTarget = field)));
@@ -172,14 +172,14 @@ export class MainView extends React.Component {
     initAuthenticationRouters = async () => {
         // Load the user's active workspace, or create a new one if initial session after signup
         const received = CurrentUserUtils.MainDocId;
-        if (received && !MainView.userDoc) {
+        if (received && !this.userDoc) {
             reaction(
                 () => CurrentUserUtils.GuestTarget,
                 target => target && this.createNewWorkspace(),
                 { fireImmediately: true }
             );
         } else {
-            if (received && MainView._urlState.sharing) {
+            if (received && this._urlState.sharing) {
                 reaction(() => CollectionDockingView.Instance && CollectionDockingView.Instance.initialized,
                     initialized => initialized && received && DocServer.GetRefField(received).then(docField => {
                         if (docField instanceof Doc && docField._viewType !== CollectionViewType.Docking) {
@@ -188,7 +188,7 @@ export class MainView extends React.Component {
                     }),
                 );
             }
-            const doc = MainView.userDoc && await Cast(MainView.userDoc.activeWorkspace, Doc);
+            const doc = this.userDoc && await Cast(this.userDoc.activeWorkspace, Doc);
             if (doc) {
                 this.openWorkspace(doc);
             } else {
@@ -199,7 +199,7 @@ export class MainView extends React.Component {
 
     @action
     createNewWorkspace = async (id?: string) => {
-        const workspaces = Cast(MainView.userDoc.myWorkspaces, Doc) as Doc;
+        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
         const workspaceCount = DocListCast(workspaces.data).length + 1;
         const freeformOptions: DocumentOptions = {
             x: 0,
@@ -228,10 +228,10 @@ export class MainView extends React.Component {
 
         if (doc) {  // this has the side-effect of setting the main container since we're assigning the active/guest workspace
             !("presentationView" in doc) && (doc.presentationView = new List<Doc>([Docs.Create.TreeDocument([], { title: "Presentation" })]));
-            MainView.userDoc ? (MainView.userDoc.activeWorkspace = doc) : (CurrentUserUtils.GuestWorkspace = doc);
+            this.userDoc ? (this.userDoc.activeWorkspace = doc) : (CurrentUserUtils.GuestWorkspace = doc);
         }
-        const state = MainView._urlState;
-        if (state.sharing === true && !MainView.userDoc) {
+        const state = this._urlState;
+        if (state.sharing === true && !this.userDoc) {
             DocServer.Control.makeReadOnly();
         } else {
             fromHistory || HistoryUtil.pushState({
@@ -257,7 +257,7 @@ export class MainView extends React.Component {
         }
         // if there is a pending doc, and it has new data, show it (syip: we use a timeout to prevent collection docking view from being uninitialized)
         setTimeout(async () => {
-            const col = MainView.userDoc && await Cast(MainView.userDoc.rightSidebarCollection, Doc);
+            const col = this.userDoc && await Cast(this.userDoc.rightSidebarCollection, Doc);
             col && Cast(col.data, listSpec(Doc)) && runInAction(() => MainViewNotifs.NotifsCol = col);
         }, 100);
         return true;
@@ -387,7 +387,7 @@ export class MainView extends React.Component {
     mainContainerXf = () => this.sidebarScreenToLocal().translate(0, -this._buttonBarHeight);
 
     @computed get flyout() {
-        const sidebarContent = MainView.userDoc?.["tabs-panelContainer"];
+        const sidebarContent = this.userDoc?.["tabs-panelContainer"];
         if (!(sidebarContent instanceof Doc)) {
             return (null);
         }
@@ -459,8 +459,8 @@ export class MainView extends React.Component {
     }
 
     @computed get mainContent() {
-        const sidebar = MainView.userDoc?.["tabs-panelContainer"];
-        return !MainView.userDoc || !(sidebar instanceof Doc) ? (null) : (
+        const sidebar = this.userDoc?.["tabs-panelContainer"];
+        return !this.userDoc || !(sidebar instanceof Doc) ? (null) : (
             <div className="mainView-mainContent" style={{
                 color: this.darkScheme ? "rgb(205,205,205)" : "black",
                 height: RichTextMenu.Instance?.Pinned ? `calc(100% - ${ANTIMODEMENU_HEIGHT})` : "100%"
@@ -628,7 +628,5 @@ Scripting.addGlobal(function copyWorkspace() {
     const workspaces = Cast(Doc.UserDoc().myWorkspaces, Doc, null);
     Doc.AddDocToList(workspaces, "data", copiedWorkspace);
     // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
-
-
-    // setTimeout(() => .openWorkspace(copiedWorkspace), 0);
+    setTimeout(() => MainView.Instance.openWorkspace(copiedWorkspace), 0);
 });
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index d83583db1..adef7f81f 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -43,7 +43,7 @@
     right: 0;
     transform: translateY(-50%);
 
-    .button {
+    .FormattedTextBox-button {
         width: 20px;
         height: 20px;
         margin: 0;
@@ -57,7 +57,7 @@
         text-align: center;
         position: relative;
 
-        .fa-icon {
+        .FormattedTextBox-fa-icon {
             position: absolute;
             top: 50%;
             left: 50%;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 15cd68c26..c600e4861 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -18,9 +18,9 @@ import wiki from "wikijs";
 import { DocumentType } from "../../../documents/DocumentTypes";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action } from "mobx";
-// import { LinkManager } from "../../../util/LinkManager";
-// import { LinkDocPreview } from "../LinkDocPreview";
-// import { DocumentLinksButton } from "../DocumentLinksButton";
+import { LinkManager } from "../../../util/LinkManager";
+import { LinkDocPreview } from "../LinkDocPreview";
+import { DocumentLinksButton } from "../DocumentLinksButton";
 
 export let formattedTextBoxCommentPlugin = new Plugin({
     view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -97,23 +97,23 @@ export class FormattedTextBoxComment {
                 if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
                     if (FormattedTextBoxComment.linkDoc.author) {
 
-                        // if (FormattedTextBoxComment._deleteRef && FormattedTextBoxComment._deleteRef.contains(e.target as any)) {
-                        //     FormattedTextBoxComment.deleteLink();
-                        // } else if (FormattedTextBoxComment._followRef && FormattedTextBoxComment._followRef.contains(e.target as any)) {
-                        //     if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
-                        //         textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
-                        //     } else {
-                        //         DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
-                        //             (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
-                        //     }
-                        // } else {
-                        if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
-                            textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+                        if (FormattedTextBoxComment._deleteRef && FormattedTextBoxComment._deleteRef.contains(e.target as any)) {
+                            this.deleteLink();
+                        } else if (FormattedTextBoxComment._followRef && FormattedTextBoxComment._followRef.contains(e.target as any)) {
+                            if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+                                textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+                            } else {
+                                DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
+                                    (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+                            }
                         } else {
-                            DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
-                                (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+                            if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+                                textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+                            } else {
+                                DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
+                                    (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+                            }
                         }
-                        //}
 
                     }
                 } else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) {
@@ -125,16 +125,16 @@ export class FormattedTextBoxComment {
                 e.preventDefault();
             };
             root && root.appendChild(FormattedTextBoxComment.tooltip);
-        };
+        }
     }
 
     @action
-    public static deleteLink = (): void => {
-        console.log(FormattedTextBoxComment.linkDoc);
-        // FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
-        // //this.props.showLinks();
-        // LinkDocPreview.LinkInfo = undefined;
-        // DocumentLinksButton.EditLink = undefined;
+    deleteLink = () => {
+        FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
+        LinkDocPreview.LinkInfo = undefined;
+        DocumentLinksButton.EditLink = undefined;
+        //FormattedTextBoxComment.tooltipText = undefined;
+        FormattedTextBoxComment.Hide();
     }
 
     public static Hide() {
@@ -241,12 +241,22 @@ export class FormattedTextBoxComment {
                             }
                             if (target?.author) {
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
-                                const docPreview = <div style={{ backgroundColor: "white" }}> {target.title}
+                                const docPreview = <div style={{ backgroundColor: "white", border: "7px solid white" }}>
+                                    {target.title}
                                     <div className="wrapper" style={{ float: "right" }}>
-                                        <div title="Delete link" className="FormattedTextBoxComment-button" style={{ display: "inline" }} ref={(r) => this._deleteRef = r}>
-                                            <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
-                                        <div title="Follow link" className="FormattedTextBoxComment-button" style={{ display: "inline" }} ref={(r) => this._followRef = r}>
-                                            <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
+                                        <div title="Delete link" className="FormattedTextBoxComment-button" style={{
+                                            display: "inline",
+                                            paddingLeft: "5px",
+                                            paddingRight: "5px"
+                                        }} ref={(r) => this._deleteRef = r}>
+                                            <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="trash" size="sm"
+                                            /></div>
+                                        <div title="Follow link" className="FormattedTextBoxComment-button" style={{
+                                            display: "inline",
+                                            paddingRight: "5px"
+                                        }} ref={(r) => this._followRef = r}>
+                                            <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="arrow-right"
+                                                size="sm" />
                                         </div>
                                     </div>
                                     <ContentFittingDocumentView
@@ -278,32 +288,7 @@ export class FormattedTextBoxComment {
                                 </div>;
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
 
-                                ReactDOM.render(<ContentFittingDocumentView
-                                    Document={target}
-                                    LibraryPath={emptyPath}
-                                    fitToBox={true}
-                                    moveDocument={returnFalse}
-                                    rootSelected={returnFalse}
-                                    ScreenToLocalTransform={Transform.Identity}
-                                    parentActive={returnFalse}
-                                    addDocument={returnFalse}
-                                    removeDocument={returnFalse}
-                                    addDocTab={returnFalse}
-                                    pinToPres={returnFalse}
-                                    dontRegisterView={true}
-                                    docFilters={returnEmptyFilter}
-                                    ContainingCollectionDoc={undefined}
-                                    ContainingCollectionView={undefined}
-                                    renderDepth={0}
-                                    PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
-                                    PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
-                                    focus={emptyFunction}
-                                    whenActiveChanged={returnFalse}
-                                    bringToFront={returnFalse}
-                                    ContentScaling={returnOne}
-                                    NativeWidth={returnZero}
-                                    NativeHeight={returnZero}
-                                />, FormattedTextBoxComment.tooltipText);
+                                ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText);
 
                                 FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%";
                                 FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%";
-- 
cgit v1.2.3-70-g09d2


From 5022535496730c0b02db5fb74a1e1e224bcaf745 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Thu, 2 Jul 2020 14:46:24 -0500
Subject: cleaned text link preview

---
 .../views/nodes/formattedText/FormattedTextBox.tsx |   2 +-
 .../formattedText/FormattedTextBoxComment.scss     |  47 ++++++++--
 .../formattedText/FormattedTextBoxComment.tsx      | 100 ++++++++++++++-------
 3 files changed, 105 insertions(+), 44 deletions(-)

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

diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 1ffa16e43..d4222b4bc 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1430,7 +1430,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                                 setTimeout(() => this._editorView!.focus(), 500);
                                 e.stopPropagation();
                             }} >
-                            <FontAwesomeIcon className="formattedTExtBox-audioFont"
+                            <FontAwesomeIcon className="formattedTextBox-audioFont"
                                 style={{ color: this._recording ? "red" : "blue", opacity: this._recording ? 1 : 0.5, display: this.props.isSelected() ? "" : "none" }} icon={"microphone"} size="sm" />
                         </div>}
                 </div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index adef7f81f..9089e7039 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -36,32 +36,61 @@
     border-top-color: white;
 }
 
-.FormattedTextBox-buttons {
+.FormattedTextBoxComment-buttons {
     display: none;
     position: absolute;
     top: 50%;
     right: 0;
     transform: translateY(-50%);
 
-    .FormattedTextBox-button {
+    .FormattedTextBoxComment-button {
         width: 20px;
         height: 20px;
         margin: 0;
         margin-right: 6px;
         border-radius: 50%;
         pointer-events: auto;
-        background-color: rgb(53, 146, 199);
-        color: rgb(150, 211, 248);
+        background-color: rgb(38, 40, 41);
+        color: rgb(178, 181, 184);
         font-size: 65%;
         transition: transform 0.2s;
         text-align: center;
         position: relative;
 
-        .FormattedTextBox-fa-icon {
-            position: absolute;
-            top: 50%;
-            left: 50%;
-            transform: translate(-50%, -50%);
+        // margin-top: "auto";
+        //     margin-bottom: "auto";
+        //     background: black;
+        //     color: white;
+        //     display: inline-block;
+        //     border-radius: 18px;
+        //     font-size: 12.5px;
+        //     width: 18px;
+        //     height: 18px;
+        //     margin-top: auto;
+        //     margin-bottom: auto;
+        //     margin-right: 3px;
+        //     cursor: pointer;
+        //     transition: transform 0.2s;
+
+        .FormattedTextBoxComment-fa-icon {
+            margin-top: "auto";
+            margin-bottom: "auto";
+            background: black;
+            color: white;
+            display: inline-block;
+            border-radius: 18px;
+            font-size: 12.5px;
+            width: 18px;
+            height: 18px;
+            margin-top: auto;
+            margin-bottom: auto;
+            margin-right: 3px;
+            cursor: pointer;
+            transition: transform 0.2s;
+            // position: absolute;
+            // top: 50%;
+            // left: 50%;
+            // transform: translate(-50%, -50%);
         }
 
         &:last-child {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 21033f315..56826e5c7 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -84,8 +84,8 @@ export class FormattedTextBoxComment {
             FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
             FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
             FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
-            FormattedTextBoxComment.tooltip.style.maxWidth = "350px";
-            FormattedTextBoxComment.tooltip.style.maxHeight = "250px";
+            FormattedTextBoxComment.tooltip.style.maxWidth = "200px";
+            FormattedTextBoxComment.tooltip.style.maxHeight = "206px";
             FormattedTextBoxComment.tooltip.style.width = "100%";
             FormattedTextBoxComment.tooltip.style.height = "100%";
             FormattedTextBoxComment.tooltip.style.overflow = "hidden";
@@ -241,50 +241,82 @@ export class FormattedTextBoxComment {
                             }
                             if (target?.author) {
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
-                                const docPreview = <div style={{ backgroundColor: "white", border: "7px solid white" }}>
+                                const docPreview = <div style={{ backgroundColor: "white", border: "8px solid white" }}>
                                     {target.title}
                                     <div className="wrapper" style={{ float: "right" }}>
                                         <div title="Delete link" className="FormattedTextBoxComment-button" style={{
                                             display: "inline",
-                                            paddingLeft: "5px",
-                                            paddingRight: "5px"
+                                            paddingLeft: "6px",
+                                            paddingRight: "6px",
+                                            paddingTop: "2.5px",
+                                            paddingBottom: "2.5px",
+                                            width: "20px",
+                                            height: "20px",
+                                            margin: 0,
+                                            marginRight: "6px",
+                                            borderRadius: "50%",
+                                            pointerEvents: "auto",
+                                            backgroundColor: "rgb(38, 40, 41)",
+                                            color: "rgb(178, 181, 184)",
+                                            transition: "transform 0.2s",
+                                            textAlign: "center",
+                                            position: "relative"
                                         }} ref={(r) => this._deleteRef = r}>
-                                            <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="trash" size="sm"
-                                            /></div>
+                                            <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="trash"
+                                                size="sm" /></div>
                                         <div title="Follow link" className="FormattedTextBoxComment-button" style={{
                                             display: "inline",
-                                            paddingRight: "5px"
+                                            paddingLeft: "6px",
+                                            paddingRight: "6px",
+                                            paddingTop: "2.5px",
+                                            paddingBottom: "2.5px",
+                                            width: "20px",
+                                            height: "20px",
+                                            margin: 0,
+                                            marginRight: "6px",
+                                            borderRadius: "50%",
+                                            pointerEvents: "auto",
+                                            backgroundColor: "rgb(38, 40, 41)",
+                                            color: "rgb(178, 181, 184)",
+                                            transition: "transform 0.2s",
+                                            textAlign: "center",
+                                            position: "relative"
                                         }} ref={(r) => this._followRef = r}>
                                             <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="arrow-right"
                                                 size="sm" />
                                         </div>
                                     </div>
-                                    <ContentFittingDocumentView
-                                        Document={target}
-                                        LibraryPath={emptyPath}
-                                        fitToBox={true}
-                                        moveDocument={returnFalse}
-                                        rootSelected={returnFalse}
-                                        ScreenToLocalTransform={Transform.Identity}
-                                        parentActive={returnFalse}
-                                        addDocument={returnFalse}
-                                        removeDocument={returnFalse}
-                                        addDocTab={returnFalse}
-                                        pinToPres={returnFalse}
-                                        dontRegisterView={true}
-                                        docFilters={returnEmptyFilter}
-                                        ContainingCollectionDoc={undefined}
-                                        ContainingCollectionView={undefined}
-                                        renderDepth={0}
-                                        PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
-                                        PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
-                                        focus={emptyFunction}
-                                        whenActiveChanged={returnFalse}
-                                        bringToFront={returnFalse}
-                                        ContentScaling={returnOne}
-                                        NativeWidth={returnZero}
-                                        NativeHeight={returnZero}
-                                    />
+                                    <div className="wrapper" style={{
+                                        maxWidth: "180px", maxHeight: "168px", overflow: "hidden",
+                                        overflowY: "hidden", paddingTop: "5px"
+                                    }}>
+                                        <ContentFittingDocumentView
+                                            Document={target}
+                                            LibraryPath={emptyPath}
+                                            fitToBox={true}
+                                            moveDocument={returnFalse}
+                                            rootSelected={returnFalse}
+                                            ScreenToLocalTransform={Transform.Identity}
+                                            parentActive={returnFalse}
+                                            addDocument={returnFalse}
+                                            removeDocument={returnFalse}
+                                            addDocTab={returnFalse}
+                                            pinToPres={returnFalse}
+                                            dontRegisterView={true}
+                                            docFilters={returnEmptyFilter}
+                                            ContainingCollectionDoc={undefined}
+                                            ContainingCollectionView={undefined}
+                                            renderDepth={0}
+                                            PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
+                                            PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
+                                            focus={emptyFunction}
+                                            whenActiveChanged={returnFalse}
+                                            bringToFront={returnFalse}
+                                            ContentScaling={returnOne}
+                                            NativeWidth={returnZero}
+                                            NativeHeight={returnZero}
+                                        />
+                                    </div>
                                 </div>;
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
 
-- 
cgit v1.2.3-70-g09d2


From 2b1af3fab4cc51f8cbb577ed51842cec1774a355 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 8 Jul 2020 13:22:49 -0500
Subject: restructured textbox comment, cleaned menu UI

---
 src/client/views/linking/LinkEditor.scss           | 15 ++--
 src/client/views/linking/LinkEditor.tsx            |  3 +-
 src/client/views/linking/LinkMenu.scss             | 71 ++++++++++------
 src/client/views/linking/LinkMenu.tsx              | 18 ++--
 src/client/views/linking/LinkMenuItem.scss         | 29 ++++---
 src/client/views/linking/LinkMenuItem.tsx          | 10 ++-
 .../formattedText/FormattedTextBoxComment.scss     | 99 +++++++++-------------
 .../formattedText/FormattedTextBoxComment.tsx      | 53 +++---------
 8 files changed, 143 insertions(+), 155 deletions(-)

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

diff --git a/src/client/views/linking/LinkEditor.scss b/src/client/views/linking/LinkEditor.scss
index 937427e46..87afc99eb 100644
--- a/src/client/views/linking/LinkEditor.scss
+++ b/src/client/views/linking/LinkEditor.scss
@@ -40,6 +40,10 @@
     font-size: 9px;
     //font-style: italic;
     text-decoration-color: grey;
+
+    .button {
+        color: black;
+    }
 }
 
 .linkEditor-description {
@@ -61,7 +65,7 @@
             //border-radius: 4px;
             padding-left: 2px;
             padding-right: 2px;
-            margin-right: 4px;
+            //margin-right: 4px;
             color: black;
             text-decoration-color: grey;
         }
@@ -69,14 +73,14 @@
         .linkEditor-description-add-button {
             display: inline;
             /* float: right; */
-            border-radius: 9px;
+            border-radius: 7px;
             font-size: 9px;
             background-color: black;
             /* padding: 3px; */
             padding-top: 4px;
-            padding-left: 3px;
+            padding-left: 7px;
             padding-bottom: 4px;
-            padding-right: 5px;
+            padding-right: 8px;
             height: 80%;
             color: white;
         }
@@ -102,10 +106,11 @@
             padding-left: 2px;
             padding-right: 2px;
             text-decoration-color: black;
-            color: black;
+            color: rgb(94, 94, 94);
 
             .linkEditor-followingDropdown-icon {
                 float: right;
+                color: black;
             }
         }
 
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index 7af11bca1..a26685318 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -339,6 +339,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
             <div className="linkEditor-description-input">
                 <div className="linkEditor-description-editing">
                     <input
+                        style={{ width: "100%" }}
                         id="input"
                         value={this.description}
                         placeholder={"enter link label"}
@@ -420,7 +421,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
                         destination.proto?.title ?? destination.title ?? "untitled"}</b></p>
                     {/* <button className="linkEditor-button" onPointerDown={() => this.deleteLink()} title="Delete link">
                         <FontAwesomeIcon icon="trash" size="sm" /></button> */}
-                    <FontAwesomeIcon icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} />
+                    <FontAwesomeIcon className="button" icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} />
                 </div>
                 {this.showInfo ? <div className="linkEditor-moreInfo">
                     <div>{this.props.linkDoc.author ? <div> <b>Author:</b> {this.props.linkDoc.author}</div> : null}</div>
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index 422ab0430..4f7ac3275 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -1,37 +1,59 @@
 @import "../globalCssVariables";
 
 .linkMenu {
-    width: 100%;
+    width: auto;
     height: auto;
 
-    border: 1px solid black;
 
-    // &:hover {
-    //     width: calc(auto + 26px);
-    // }
-}
+    .linkMenu-list {
 
-.linkMenu-list {
+        display: inline-block;
 
-    border: 1px solid black;
+        border: 1px solid black;
 
-    box-shadow: 3px 3px 1.5px grey;
+        box-shadow: 3px 3px 1.5px grey;
 
-    max-height: 170px;
-    overflow-y: scroll;
-    position: absolute;
-    z-index: 10;
-    background: white;
-    min-width: 150px;
-    //border-radius: 5px;
-    //padding-top: 6.5px;
-    //padding-bottom: 6.5px;
-    //padding-left: 6.5px;
-    //padding-right: 2px;
-    width: calc(auto + 50px);
+        max-height: 170px;
+        overflow-y: scroll;
+        position: relative;
+        z-index: 10;
+        background: white;
+        min-width: 170px;
+        //border-radius: 5px;
+        //padding-top: 6.5px;
+        //padding-bottom: 6.5px;
+        //padding-left: 6.5px;
+        //padding-right: 2px;
+        //width: calc(auto + 50px);
 
-    &:last-child {
-        border-bottom: none;
+        white-space: nowrap;
+
+        overflow-x: hidden;
+
+        &:last-child {
+            border-bottom: none;
+        }
+
+        &:hover {
+            padding-right: 65px;
+            display: inline-block;
+        }
+    }
+
+    .linkMenu-listEditor {
+
+        display: inline-block;
+
+        border: 1px solid black;
+
+        box-shadow: 3px 3px 1.5px grey;
+
+        max-height: 170px;
+        overflow-y: scroll;
+        position: relative;
+        z-index: 10;
+        background: white;
+        min-width: 170px;
     }
 }
 
@@ -39,6 +61,7 @@
     border-bottom: 0.5px solid lightgray;
     //@extend: 5px 0;
 
+
     &:last-child {
         border-bottom: none;
     }
@@ -54,7 +77,7 @@
             }
 
             p.expand-one {
-                width: calc(100% + 26px);
+                width: calc(100% + 20px);
             }
 
             .linkEditor-tableButton {
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 478ac3fe6..234cd5e07 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -90,16 +90,16 @@ export class LinkMenu extends React.Component<Props> {
         const sourceDoc = this.props.docView.props.Document;
         const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc);
         return <div className="linkMenu" ref={this._linkMenuRef} >
-            <div className="linkMenu-list"
-                style={{
-                    left: this.props.location[0], top: this.props.location[1],
-                    //overflowY: "scroll",
-                }}>
-                {!this._editingLink ?
-                    this.renderAllGroups(groups) :
+             {!this._editingLink ? <div className="linkMenu-list" style={{
+                  left: this.props.location[0], top: this.props.location[1] }}>
+              {this.renderAllGroups(groups)} 
+              </div> : <div className="linkMenu-listEditor" style={{
+                  left: this.props.location[0], top: this.props.location[1]}}>
                     <LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink}
                         showLinks={action(() => this._editingLink = undefined)} />
-                }
-            </div> </div>;
+                </div> 
+            }
+
+        </div>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index 8578d0b75..9f1f82ce2 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -26,6 +26,8 @@
                 color: rgb(85, 120, 196);
                 font-size: 14px;
                 padding-bottom: 2px;
+                padding-right: 4px;
+                margin-right: 4px;
             }
 
             .linkMenu-description {
@@ -36,12 +38,16 @@
             }
 
             p {
-                //padding: 4px 2px;
+                padding-right: 4px;
                 line-height: 12px;
                 border-radius: 5px;
-                overflow-wrap: break-word;
+                //overflow-wrap: break-word;
                 user-select: none;
             }
+
+            &:hover {
+                padding-right: 8px;
+            }
         }
 
     }
@@ -60,6 +66,7 @@
 
     &:hover {
 
+        width: calc(100% + 58px);
 
         .linkMenu-item-buttons {
             display: flex;
@@ -74,19 +81,13 @@
                 text-overflow: break;
             }
 
-            &.expand-two p {
-                width: calc(100% - 52px);
-                //text-decoration: underline;
-                //color: rgb(15, 57, 148);
-                //background-color: lightgray;
-            }
+            // &.expand-two p {
+            //     width: calc(100% - 63px);
+            // }
 
-            &.expand-three p {
-                width: calc(100% - 84px);
-                //text-decoration: underline;
-                //color: rgb(15, 57, 148);
-                //background-color: lightgray;
-            }
+            // &.expand-three p {
+            //     width: calc(100% - 93px);
+            // }
         }
     }
 }
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 59a88a1d9..57993d240 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -1,5 +1,5 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes, faPencilAlt } from '@fortawesome/free-solid-svg-icons';
+import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes, faPencilAlt, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, observable } from 'mobx';
 import { observer } from "mobx-react";
@@ -15,7 +15,7 @@ import { setupMoveUpEvents, emptyFunction } from '../../../Utils';
 import { DocumentView } from '../nodes/DocumentView';
 import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
 import { LinkDocPreview } from '../nodes/LinkDocPreview';
-library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt);
+library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash);
 
 
 interface LinkMenuItemProps {
@@ -179,6 +179,8 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
         const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
         const canExpand = keys ? keys.length > 0 : false;
 
+        const eyeIcon = this.props.linkDoc.shown ? "eye-slash" : "eye";
+
         return (
             <div className="linkMenu-item">
                 <div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}>
@@ -203,6 +205,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                             {canExpand ? <div title="Show more" className="button" onPointerDown={e => this.toggleShowMore(e)}>
                                 <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
 
+                            <div title="Show link" className="button" ref={this._editRef} onPointerDown={emptyFunction}>
+                                <FontAwesomeIcon className="fa-icon" icon={eyeIcon} size="sm" /></div>
+
+
                             <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}>
                                 <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
                             <div title="Delete link" className="button" onPointerDown={this.deleteLink}>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index 9089e7039..286ccf22d 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -8,6 +8,45 @@
     margin-bottom: 7px;
     -webkit-transform: translateX(-50%);
     transform: translateX(-50%);
+    box-shadow: 3px 3px 1.5px grey;
+
+    .FormattedTextBoxComment-title {
+        background-color: white;
+        border: 8px solid white;
+
+        .FormattedTextBoxComment-button {
+            display: inline;
+            padding-left: 6px;
+            padding-right: 6px;
+            padding-top: 2.5px;
+            padding-bottom: 2.5px;
+            width: 20px;
+            height: 20px;
+            margin: 0;
+            margin-right: 6px;
+            border-radius: 50%;
+            pointer-events: auto;
+            background-color: rgb(0, 0, 0);
+            color: rgb(255, 255, 255);
+            transition: transform 0.2s;
+            text-align: center;
+            position: relative;
+            font: 10px;
+
+            &:hover {
+                background-color: rgb(77, 77, 77);
+                cursor: grab;
+            }
+        }
+
+        .FormattedTextBoxComment-preview-wrapper {
+            max-width: 180px;
+            max-height: 168px;
+            overflow: hidden;
+            overflow-y: hidden;
+            padding-top: 5px;
+        }
+    }
 }
 
 .FormattedTextBox-tooltip:before {
@@ -42,64 +81,4 @@
     top: 50%;
     right: 0;
     transform: translateY(-50%);
-
-    .FormattedTextBoxComment-button {
-        width: 20px;
-        height: 20px;
-        margin: 0;
-        margin-right: 6px;
-        border-radius: 50%;
-        pointer-events: auto;
-        background-color: rgb(38, 40, 41);
-        color: rgb(178, 181, 184);
-        font-size: 65%;
-        transition: transform 0.2s;
-        text-align: center;
-        position: relative;
-
-        // margin-top: "auto";
-        //     margin-bottom: "auto";
-        //     background: black;
-        //     color: white;
-        //     display: inline-block;
-        //     border-radius: 18px;
-        //     font-size: 12.5px;
-        //     width: 18px;
-        //     height: 18px;
-        //     margin-top: auto;
-        //     margin-bottom: auto;
-        //     margin-right: 3px;
-        //     cursor: pointer;
-        //     transition: transform 0.2s;
-
-        .FormattedTextBoxComment-fa-icon {
-            margin-top: "auto";
-            margin-bottom: "auto";
-            background: black;
-            color: white;
-            display: inline-block;
-            border-radius: 18px;
-            font-size: 12.5px;
-            width: 18px;
-            height: 18px;
-            margin-top: auto;
-            margin-bottom: auto;
-            margin-right: 3px;
-            cursor: pointer;
-            transition: transform 0.2s;
-            // position: absolute;
-            // top: 50%;
-            // left: 50%;
-            // transform: translate(-50%, -50%);
-        }
-
-        &:last-child {
-            margin-right: 0;
-        }
-
-        &:hover {
-            background: rgb(53, 146, 199);
-            ;
-        }
-    }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 56826e5c7..79b09b374 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -241,52 +241,22 @@ export class FormattedTextBoxComment {
                             }
                             if (target?.author) {
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
-                                const docPreview = <div style={{ backgroundColor: "white", border: "8px solid white" }}>
+
+
+                                const docPreview = <div className="FormattedTextBoxComment-title">
                                     {target.title}
                                     <div className="wrapper" style={{ float: "right" }}>
-                                        <div title="Delete link" className="FormattedTextBoxComment-button" style={{
-                                            display: "inline",
-                                            paddingLeft: "6px",
-                                            paddingRight: "6px",
-                                            paddingTop: "2.5px",
-                                            paddingBottom: "2.5px",
-                                            width: "20px",
-                                            height: "20px",
-                                            margin: 0,
-                                            marginRight: "6px",
-                                            borderRadius: "50%",
-                                            pointerEvents: "auto",
-                                            backgroundColor: "rgb(38, 40, 41)",
-                                            color: "rgb(178, 181, 184)",
-                                            transition: "transform 0.2s",
-                                            textAlign: "center",
-                                            position: "relative"
-                                        }} ref={(r) => this._deleteRef = r}>
-                                            <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="trash"
+                                        <div title="Delete link" className="FormattedTextBoxComment-button"
+                                            ref={(r) => this._deleteRef = r}>
+                                            <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="trash" color="white"
                                                 size="sm" /></div>
-                                        <div title="Follow link" className="FormattedTextBoxComment-button" style={{
-                                            display: "inline",
-                                            paddingLeft: "6px",
-                                            paddingRight: "6px",
-                                            paddingTop: "2.5px",
-                                            paddingBottom: "2.5px",
-                                            width: "20px",
-                                            height: "20px",
-                                            margin: 0,
-                                            marginRight: "6px",
-                                            borderRadius: "50%",
-                                            pointerEvents: "auto",
-                                            backgroundColor: "rgb(38, 40, 41)",
-                                            color: "rgb(178, 181, 184)",
-                                            transition: "transform 0.2s",
-                                            textAlign: "center",
-                                            position: "relative"
-                                        }} ref={(r) => this._followRef = r}>
-                                            <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="arrow-right"
+                                        <div title="Follow link" className="FormattedTextBoxComment-button"
+                                            ref={(r) => this._followRef = r}>
+                                            <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="arrow-right" color="white"
                                                 size="sm" />
                                         </div>
                                     </div>
-                                    <div className="wrapper" style={{
+                                    <div className="FormattedTextBoxComment-preview-wrapper" style={{
                                         maxWidth: "180px", maxHeight: "168px", overflow: "hidden",
                                         overflowY: "hidden", paddingTop: "5px"
                                     }}>
@@ -318,6 +288,9 @@ export class FormattedTextBoxComment {
                                         />
                                     </div>
                                 </div>;
+
+
+
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
 
                                 ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText);
-- 
cgit v1.2.3-70-g09d2


From 93dfc57bd89e586aa9747cde37937bad479a0597 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Thu, 9 Jul 2020 16:21:17 -0500
Subject: fixed textbox preview

---
 .../collectionFreeForm/CollectionFreeFormView.tsx       |  5 ++++-
 .../nodes/formattedText/FormattedTextBoxComment.scss    | 14 +++++++++-----
 .../nodes/formattedText/FormattedTextBoxComment.tsx     | 17 +++++++----------
 3 files changed, 20 insertions(+), 16 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index fdc8536f8..2f712d609 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1183,7 +1183,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         if (this._marqueeRef?.current) {
             const dragX = e.detail.clientX;
             const dragY = e.detail.clientY;
-            const bounds = this._marqueeRef.current?.getBoundingClientRect()!;
+            const bounds = this._marqueeRef.current?.getBoundingClientRect();
+
+            console.log("bottom: " + bounds.bottom);
+            console.log("right: " + bounds.right);
 
             if (dragX - bounds.left < 25) {
                 console.log("PAN left ");
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index 286ccf22d..7af209842 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -4,7 +4,7 @@
     z-index: 20;
     background: white;
     border: 1px solid silver;
-    border-radius: 2px;
+    border-radius: 7px;
     margin-bottom: 7px;
     -webkit-transform: translateX(-50%);
     transform: translateX(-50%);
@@ -40,11 +40,15 @@
         }
 
         .FormattedTextBoxComment-preview-wrapper {
-            max-width: 180px;
-            max-height: 168px;
+            width: 170px;
+            height: 170px;
             overflow: hidden;
-            overflow-y: hidden;
-            padding-top: 5px;
+            //padding-top: 5px;
+            margin-top: 10px;
+            margin-bottom: 8px;
+            align-content: center;
+            justify-content: center;
+            background-color: rgb(160, 160, 160);
         }
     }
 }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 79b09b374..a9185be21 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -84,8 +84,8 @@ export class FormattedTextBoxComment {
             FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
             FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
             FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
-            FormattedTextBoxComment.tooltip.style.maxWidth = "200px";
-            FormattedTextBoxComment.tooltip.style.maxHeight = "206px";
+            FormattedTextBoxComment.tooltip.style.maxWidth = "190px";
+            FormattedTextBoxComment.tooltip.style.maxHeight = "220px";
             FormattedTextBoxComment.tooltip.style.width = "100%";
             FormattedTextBoxComment.tooltip.style.height = "100%";
             FormattedTextBoxComment.tooltip.style.overflow = "hidden";
@@ -256,10 +256,7 @@ export class FormattedTextBoxComment {
                                                 size="sm" />
                                         </div>
                                     </div>
-                                    <div className="FormattedTextBoxComment-preview-wrapper" style={{
-                                        maxWidth: "180px", maxHeight: "168px", overflow: "hidden",
-                                        overflowY: "hidden", paddingTop: "5px"
-                                    }}>
+                                    <div className="FormattedTextBoxComment-preview-wrapper">
                                         <ContentFittingDocumentView
                                             Document={target}
                                             LibraryPath={emptyPath}
@@ -277,14 +274,14 @@ export class FormattedTextBoxComment {
                                             ContainingCollectionDoc={undefined}
                                             ContainingCollectionView={undefined}
                                             renderDepth={0}
-                                            PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
-                                            PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
+                                            PanelWidth={() => 170} //Math.min(350, NumCast(target._width, 350))}
+                                            PanelHeight={() => 170} //Math.min(250, NumCast(target._height, 250))}
                                             focus={emptyFunction}
                                             whenActiveChanged={returnFalse}
                                             bringToFront={returnFalse}
                                             ContentScaling={returnOne}
-                                            NativeWidth={returnZero}
-                                            NativeHeight={returnZero}
+                                            NativeWidth={() => target._nativeWidth ? NumCast(target._nativeWidth) : 0}
+                                            NativeHeight={() => target._nativeHeight ? NumCast(target._nativeHeight) : 0}
                                         />
                                     </div>
                                 </div>;
-- 
cgit v1.2.3-70-g09d2


From 5e120375015d916a883232bf1235b1b133d7f9f0 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Fri, 10 Jul 2020 00:07:18 -0500
Subject: added tooltips and textboxcomment cleanup and descriptions

---
 src/client/views/linking/LinkMenuItem.tsx          | 21 ++++---
 src/client/views/nodes/DocumentLinksButton.tsx     | 50 +++++++++--------
 .../formattedText/FormattedTextBoxComment.scss     | 65 ++++++++++++++--------
 .../formattedText/FormattedTextBoxComment.tsx      | 60 ++++++++++++++------
 4 files changed, 127 insertions(+), 69 deletions(-)

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

diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 05ec10f71..07630c3ff 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -15,6 +15,7 @@ import { setupMoveUpEvents, emptyFunction } from '../../../Utils';
 import { DocumentView } from '../nodes/DocumentView';
 import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
 import { LinkDocPreview } from '../nodes/LinkDocPreview';
+import Tooltip from '@material-ui/core/Tooltip';
 library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash);
 
 
@@ -228,13 +229,19 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                             {canExpand ? <div title="Show more" className="button" onPointerDown={e => this.toggleShowMore(e)}>
                                 <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
 
-                            <div title="Show link" className="button" ref={this._editRef} onPointerDown={emptyFunction}>
-                                <FontAwesomeIcon className="fa-icon" icon={eyeIcon} size="sm" /></div>
-
-                            <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}>
-                                <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
-                            <div title="Delete link" className="button" onPointerDown={this.deleteLink}>
-                                <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+                            <Tooltip title="Show Link">
+                                <div title="Show link" className="button" ref={this._editRef} onPointerDown={emptyFunction}>
+                                    <FontAwesomeIcon className="fa-icon" icon={eyeIcon} size="sm" /></div>
+                            </Tooltip>
+
+                            <Tooltip title="Edit Link">
+                                <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}>
+                                    <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
+                            </Tooltip>
+                            <Tooltip title="Delete Link">
+                                <div title="Delete link" className="button" onPointerDown={this.deleteLink}>
+                                    <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+                            </Tooltip>
                             {/* <div title="Follow link" className="button" onPointerDown={this.followDefault} onContextMenu={this.onContextMenu}>
                                 <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" /></div> */}
                         </div>
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 1af3318cb..f61ae2dd0 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -13,6 +13,7 @@ import { LinkDocPreview } from "./LinkDocPreview";
 import { LinkCreatedBox } from "./LinkCreatedBox";
 import { LinkDescriptionPopup } from "./LinkDescriptionPopup";
 import { LinkManager } from "../../util/LinkManager";
+import { Tooltip } from "@material-ui/core";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -149,30 +150,33 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
 
         const title = this.props.InMenu ? "Drag or tap to create links" : "Tap to view links";
 
+        const linkButton = <div title={title} ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
+            <div className={"documentLinksButton"} style={{
+                backgroundColor: DocumentLinksButton.StartLink && !!!this.props.InMenu ? "transparent" : this.props.InMenu ? "black" : "",
+                color: this.props.InMenu ? "white" : "black",
+                width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px", fontWeight: "bold"
+            }}
+                onPointerDown={this.onLinkButtonDown} onClick={this.onLinkClick}
+            // onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
+            // onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = {
+            //     addDocTab: this.props.View.props.addDocTab,
+            //     linkSrc: this.props.View.props.Document,
+            //     linkDoc: links[0],
+            //     Location: [e.clientX, e.clientY + 20]
+            // }))} 
+            >
+                {links.length && !!!this.props.InMenu ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
+            </div>
+            {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"}
+                style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }}
+                onPointerDown={this.completeLink} onClick={e => this.finishLinkClick(e)} /> : (null)}
+            {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"}
+                style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} /> : (null)}
+        </div>;
         return (!links.length || links[0].hidden) && !this.props.AlwaysOn ? (null) :
-            <div title={title} ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
-                <div className={"documentLinksButton"} style={{
-                    backgroundColor: DocumentLinksButton.StartLink && !!!this.props.InMenu ? "transparent" : this.props.InMenu ? "black" : "",
-                    color: this.props.InMenu ? "white" : "black",
-                    width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px", fontWeight: "bold"
-                }}
-                    onPointerDown={this.onLinkButtonDown} onClick={this.onLinkClick}
-                // onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
-                // onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = {
-                //     addDocTab: this.props.View.props.addDocTab,
-                //     linkSrc: this.props.View.props.Document,
-                //     linkDoc: links[0],
-                //     Location: [e.clientX, e.clientY + 20]
-                // }))} 
-                >
-                    {links.length && !!!this.props.InMenu ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
-                </div>
-                {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"}
-                    style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }}
-                    onPointerDown={this.completeLink} onClick={e => this.finishLinkClick(e)} /> : (null)}
-                {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"}
-                    style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} /> : (null)}
-            </div>;
+            <Tooltip title={title}>
+                {linkButton}
+            </Tooltip>;
     }
     render() {
         return this.linkButton;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index 7af209842..83f99122a 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -10,32 +10,53 @@
     transform: translateX(-50%);
     box-shadow: 3px 3px 1.5px grey;
 
-    .FormattedTextBoxComment-title {
+    .FormattedTextBoxComment {
         background-color: white;
         border: 8px solid white;
 
-        .FormattedTextBoxComment-button {
-            display: inline;
-            padding-left: 6px;
-            padding-right: 6px;
-            padding-top: 2.5px;
-            padding-bottom: 2.5px;
-            width: 20px;
-            height: 20px;
-            margin: 0;
-            margin-right: 6px;
-            border-radius: 50%;
-            pointer-events: auto;
-            background-color: rgb(0, 0, 0);
-            color: rgb(255, 255, 255);
-            transition: transform 0.2s;
-            text-align: center;
-            position: relative;
-            font: 10px;
+        //display: flex;
+        .FormattedTextBoxComment-info {
 
-            &:hover {
-                background-color: rgb(77, 77, 77);
-                cursor: grab;
+            margin-bottom: 9px;
+
+            .FormattedTextBoxComment-title {
+                padding-right: 4px;
+                float: left;
+
+                .FormattedTextBoxComment-description {
+                    text-decoration: none;
+                    font-style: italic;
+                    color: rgb(95, 97, 102);
+                    font-size: 10px;
+                    padding-bottom: 4px;
+                    margin-bottom: 5px;
+
+                }
+            }
+
+            .FormattedTextBoxComment-button {
+                display: inline;
+                padding-left: 6px;
+                padding-right: 6px;
+                padding-top: 2.5px;
+                padding-bottom: 2.5px;
+                width: 17px;
+                height: 17px;
+                margin: 0;
+                margin-right: 3px;
+                border-radius: 50%;
+                pointer-events: auto;
+                background-color: rgb(0, 0, 0);
+                color: rgb(255, 255, 255);
+                transition: transform 0.2s;
+                text-align: center;
+                position: relative;
+                font-size: 12px;
+
+                &:hover {
+                    background-color: rgb(77, 77, 77);
+                    cursor: grab;
+                }
             }
         }
 
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index a9185be21..acdc7c56b 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -3,7 +3,7 @@ import { EditorState, Plugin } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import * as ReactDOM from 'react-dom';
 import { Doc, DocCastAsync, Opt } from "../../../../fields/Doc";
-import { Cast, FieldValue, NumCast } from "../../../../fields/Types";
+import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types";
 import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne, returnEmptyFilter } from "../../../../Utils";
 import { DocServer } from "../../../DocServer";
 import { DocumentManager } from "../../../util/DocumentManager";
@@ -21,6 +21,7 @@ import { action } from "mobx";
 import { LinkManager } from "../../../util/LinkManager";
 import { LinkDocPreview } from "../LinkDocPreview";
 import { DocumentLinksButton } from "../DocumentLinksButton";
+import Tooltip from "@material-ui/core/Tooltip";
 
 export let formattedTextBoxCommentPlugin = new Plugin({
     view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -85,13 +86,13 @@ export class FormattedTextBoxComment {
             FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
             FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
             FormattedTextBoxComment.tooltip.style.maxWidth = "190px";
-            FormattedTextBoxComment.tooltip.style.maxHeight = "220px";
+            FormattedTextBoxComment.tooltip.style.maxHeight = "235px";
             FormattedTextBoxComment.tooltip.style.width = "100%";
             FormattedTextBoxComment.tooltip.style.height = "100%";
             FormattedTextBoxComment.tooltip.style.overflow = "hidden";
             FormattedTextBoxComment.tooltip.style.display = "none";
             FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipInput);
-            FormattedTextBoxComment.tooltip.onpointerdown = (e: PointerEvent) => {
+            FormattedTextBoxComment.tooltip.onpointerdown = async (e: PointerEvent) => {
                 const keep = e.target && (e.target as any).type === "checkbox" ? true : false;
                 const textBox = FormattedTextBoxComment.textBox;
                 if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
@@ -103,8 +104,22 @@ export class FormattedTextBoxComment {
                             if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
                                 textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
                             } else {
-                                DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
-                                    (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+                                const anchor = FieldValue(Doc.AreProtosEqual(FieldValue(Cast(FormattedTextBoxComment.linkDoc.anchor1, Doc)), textBox.dataDoc) ?
+                                    Cast(FormattedTextBoxComment.linkDoc.anchor2, Doc) : (Cast(FormattedTextBoxComment.linkDoc.anchor1, Doc))
+                                    || FormattedTextBoxComment.linkDoc);
+                                const target = anchor?.annotationOn ? await DocCastAsync(anchor.annotationOn) : anchor;
+
+                                if (FormattedTextBoxComment.linkDoc.follow) {
+                                    if (FormattedTextBoxComment.linkDoc.follow === "Default") {
+                                        DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document, doc => textBox.props.addDocTab(doc, "onRight"), false);
+                                    } else if (FormattedTextBoxComment.linkDoc.follow === "Always open in right tab") {
+                                        if (target) { textBox.props.addDocTab(target, "onRight"); }
+                                    } else if (FormattedTextBoxComment.linkDoc.follow === "Always open in new tab") {
+                                        if (target) { textBox.props.addDocTab(target, "inTab"); }
+                                    }
+                                } else {
+                                    DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document, doc => textBox.props.addDocTab(doc, "onRight"), false);
+                                }
                             }
                         } else {
                             if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
@@ -243,19 +258,30 @@ export class FormattedTextBoxComment {
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
 
 
-                                const docPreview = <div className="FormattedTextBoxComment-title">
-                                    {target.title}
-                                    <div className="wrapper" style={{ float: "right" }}>
-                                        <div title="Delete link" className="FormattedTextBoxComment-button"
-                                            ref={(r) => this._deleteRef = r}>
-                                            <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="trash" color="white"
-                                                size="sm" /></div>
-                                        <div title="Follow link" className="FormattedTextBoxComment-button"
-                                            ref={(r) => this._followRef = r}>
-                                            <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="arrow-right" color="white"
-                                                size="sm" />
+                                const docPreview = <div className="FormattedTextBoxComment">
+                                    <div className="FormattedTextBoxComment-info">
+                                        <div className="FormattedTextBoxComment-title">
+                                            {target.title}
+                                            {FormattedTextBoxComment.linkDoc.description !== "" ? <p className="FormattedTextBoxComment-description">
+                                                {StrCast(FormattedTextBoxComment.linkDoc.description)}</p> : null}
                                         </div>
-                                    </div>
+                                        <div className="wrapper" style={{ float: "right" }}>
+
+                                            <Tooltip title="Delete Link" placement="top">
+                                                <div title="Delete link" className="FormattedTextBoxComment-button"
+                                                    ref={(r) => this._deleteRef = r}>
+                                                    <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="trash" color="white"
+                                                        size="sm" /></div>
+                                            </Tooltip>
+
+                                            <Tooltip title="Follow Link" placement="top">
+                                                <div title="Follow link" className="FormattedTextBoxComment-button"
+                                                    ref={(r) => this._followRef = r}>
+                                                    <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="arrow-right" color="white"
+                                                        size="sm" />
+                                                </div>
+                                            </Tooltip>
+                                        </div> </div>
                                     <div className="FormattedTextBoxComment-preview-wrapper">
                                         <ContentFittingDocumentView
                                             Document={target}
-- 
cgit v1.2.3-70-g09d2


From 3e242feb9a79e1200ecc5679306d0680e6d1fa01 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Fri, 10 Jul 2020 00:43:05 -0500
Subject: adding ...

---
 src/client/views/collections/CollectionLinearView.tsx   | 17 ++++++++++++-----
 src/client/views/linking/LinkMenuItem.tsx               |  8 +++++++-
 .../nodes/formattedText/FormattedTextBoxComment.tsx     | 11 +++++++----
 3 files changed, 26 insertions(+), 10 deletions(-)

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

diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index c370415be..2dd48aa27 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -16,6 +16,7 @@ import { Id } from '../../../fields/FieldSymbols';
 import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { LinkDescriptionPopup } from '../nodes/LinkDescriptionPopup';
+import { Tooltip } from '@material-ui/core';
 
 
 type LinearDocument = makeInterface<[typeof documentSchema,]>;
@@ -171,11 +172,17 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                     onPointerDown={e => e.stopPropagation()} >
                     <span className="bottomPopup-text" >
                         Creating link from: {DocumentLinksButton.StartLink.title} </span>
-                    <span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}
-                    > Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"}
-                    </span>
-                    <span className="bottomPopup-exit" onClick={this.exitLongLinks}
-                    >Exit</span>
+                    <Tooltip title={LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" :
+                        "Turn on description pop-up"} placement="top">
+                        <span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}
+                        > Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"}
+                        </span>
+                    </Tooltip>
+
+                    <Tooltip title="Exit link clicking mode" placement="top">
+                        <span className="bottomPopup-exit" onClick={this.exitLongLinks}
+                        >Exit</span>
+                    </Tooltip>
 
                     {/* <FontAwesomeIcon icon="times-circle" size="lg" style={{ color: "red" }}
                         onClick={this.exitLongLinks} /> */}
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 07630c3ff..f1a744ff2 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -197,6 +197,11 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                                                         this.props.destinationDoc.type === "import" ? "cloud-upload-alt" :
                                                             this.props.destinationDoc.type === "docholder" ? "expand" : "question";
 
+        const title = StrCast(this.props.destinationDoc.title).length > 18 ?
+            StrCast(this.props.destinationDoc.title).substr(0, 19) + "..." : this.props.destinationDoc.title;
+
+
+        console.log(StrCast(this.props.destinationDoc.title).length);
 
         return (
             <div className="linkMenu-item">
@@ -220,7 +225,8 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                                     <FontAwesomeIcon className="destination-icon" icon={destinationIcon} size="sm" /></div>
                                 <p className="linkMenu-destination-title"
                                     onPointerDown={this.followDefault}>
-                                    {StrCast(this.props.destinationDoc.title)}</p>
+                                    {title}
+                                </p>
                             </div>
                             {this.props.linkDoc.description !== "" ? <p className="linkMenu-description">
                                 {StrCast(this.props.linkDoc.description)}</p> : null} </div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index acdc7c56b..f1602bfbc 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -85,7 +85,7 @@ export class FormattedTextBoxComment {
             FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
             FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
             FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
-            FormattedTextBoxComment.tooltip.style.maxWidth = "190px";
+            FormattedTextBoxComment.tooltip.style.maxWidth = "200px";
             FormattedTextBoxComment.tooltip.style.maxHeight = "235px";
             FormattedTextBoxComment.tooltip.style.width = "100%";
             FormattedTextBoxComment.tooltip.style.height = "100%";
@@ -257,11 +257,14 @@ export class FormattedTextBoxComment {
                             if (target?.author) {
                                 FormattedTextBoxComment.showCommentbox("", view, nbef);
 
+                                const title = StrCast(target.title).length > 16 ?
+                                    StrCast(target.title).substr(0, 16) + "..." : target.title;
+
 
                                 const docPreview = <div className="FormattedTextBoxComment">
                                     <div className="FormattedTextBoxComment-info">
                                         <div className="FormattedTextBoxComment-title">
-                                            {target.title}
+                                            {title}
                                             {FormattedTextBoxComment.linkDoc.description !== "" ? <p className="FormattedTextBoxComment-description">
                                                 {StrCast(FormattedTextBoxComment.linkDoc.description)}</p> : null}
                                         </div>
@@ -300,8 +303,8 @@ export class FormattedTextBoxComment {
                                             ContainingCollectionDoc={undefined}
                                             ContainingCollectionView={undefined}
                                             renderDepth={0}
-                                            PanelWidth={() => 170} //Math.min(350, NumCast(target._width, 350))}
-                                            PanelHeight={() => 170} //Math.min(250, NumCast(target._height, 250))}
+                                            PanelWidth={() => 175} //Math.min(350, NumCast(target._width, 350))}
+                                            PanelHeight={() => 175} //Math.min(250, NumCast(target._height, 250))}
                                             focus={emptyFunction}
                                             whenActiveChanged={returnFalse}
                                             bringToFront={returnFalse}
-- 
cgit v1.2.3-70-g09d2


From 20ab61d762e4c92e9ace6eb9b577667a9a8dc1e3 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Fri, 10 Jul 2020 12:05:53 -0500
Subject: fixed tooltip error, label styling

---
 src/client/views/linking/LinkMenuItem.scss            |  3 +++
 src/client/views/linking/LinkMenuItem.tsx             | 19 +++++++++++++------
 src/client/views/nodes/DocumentLinksButton.tsx        |  2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx    | 10 ++++++----
 .../nodes/formattedText/FormattedTextBoxComment.tsx   |  6 +++---
 5 files changed, 26 insertions(+), 14 deletions(-)

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

diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index f759aef5e..3ecb306f9 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -77,6 +77,9 @@
                 color: rgb(95, 97, 102);
                 font-size: 10px;
                 margin-left: 20px;
+                max-width: 125px;
+                height: auto;
+                white-space: break-spaces;
             }
 
             p {
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index f1a744ff2..f7d189b20 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -15,7 +15,8 @@ import { setupMoveUpEvents, emptyFunction } from '../../../Utils';
 import { DocumentView } from '../nodes/DocumentView';
 import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
 import { LinkDocPreview } from '../nodes/LinkDocPreview';
-import Tooltip from '@material-ui/core/Tooltip';
+import { Tooltip } from '@material-ui/core';
+import { RichTextField } from '../../../fields/RichTextField';
 library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash);
 
 
@@ -203,6 +204,12 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
 
         console.log(StrCast(this.props.destinationDoc.title).length);
 
+        //  ...
+        // from anika to bob: here's where the text that is specifically linked would show up (linkDoc.storedText)
+        // ...
+        const source = this.props.sourceDoc.type === "rtf" ? this.props.linkDoc.storedText ?
+            "stored text would show up here" : undefined : undefined;
+
         return (
             <div className="linkMenu-item">
                 <div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}>
@@ -218,8 +225,8 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                         onPointerDown={this.onLinkButtonDown}>
 
                         <div className="linkMenu-text">
-                            {this.props.linkDoc.linkedText ? <p className="linkMenu-source-title">
-                                <b>Source: {StrCast(this.props.linkDoc.linkedText)}</b></p> : null}
+                            {source ? <p className="linkMenu-source-title">
+                                <b>Source: {source}</b></p> : null}
                             <div className="linkMenu-title-wrapper">
                                 <div className="destination-icon-wrapper" >
                                     <FontAwesomeIcon className="destination-icon" icon={destinationIcon} size="sm" /></div>
@@ -236,16 +243,16 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                                 <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
 
                             <Tooltip title="Show Link">
-                                <div title="Show link" className="button" ref={this._editRef} onPointerDown={emptyFunction}>
+                                <div className="button" ref={this._editRef} onPointerDown={emptyFunction}>
                                     <FontAwesomeIcon className="fa-icon" icon={eyeIcon} size="sm" /></div>
                             </Tooltip>
 
                             <Tooltip title="Edit Link">
-                                <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}>
+                                <div className="button" ref={this._editRef} onPointerDown={this.onEdit}>
                                     <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
                             </Tooltip>
                             <Tooltip title="Delete Link">
-                                <div title="Delete link" className="button" onPointerDown={this.deleteLink}>
+                                <div className="button" onPointerDown={this.deleteLink}>
                                     <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
                             </Tooltip>
                             {/* <div title="Follow link" className="button" onPointerDown={this.followDefault} onContextMenu={this.onContextMenu}>
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index f61ae2dd0..22431117e 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -150,7 +150,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
 
         const title = this.props.InMenu ? "Drag or tap to create links" : "Tap to view links";
 
-        const linkButton = <div title={title} ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
+        const linkButton = <div ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
             <div className={"documentLinksButton"} style={{
                 backgroundColor: DocumentLinksButton.StartLink && !!!this.props.InMenu ? "transparent" : this.props.InMenu ? "black" : "",
                 color: this.props.InMenu ? "white" : "black",
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 4f6927d3d..e3411ccf5 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -175,8 +175,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     doLinkOnDeselect() {
 
-        console.log("link on deselect");
-
         Array.from(this.linkOnDeselect.entries()).map(entry => {
             const key = entry[0];
             const value = entry[1];
@@ -186,11 +184,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 DocServer.GetRefField(id).then(linkDoc => {
                     this.dataDoc[key] = doc || Docs.Create.FreeformDocument([], { title: value, _width: 500, _height: 500 }, value);
                     DocUtils.Publish(this.dataDoc[key] as Doc, value, this.props.addDocument, this.props.removeDocument);
-                    if (linkDoc) { (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc; }
-                    else DocUtils.MakeLink({ doc: this.rootDoc }, { doc: this.dataDoc[key] as Doc }, "portal link", "link to named target", id);
+                    if (linkDoc) {
+                        (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc;
+                    } else {
+                        DocUtils.MakeLink({ doc: this.rootDoc }, { doc: this.dataDoc[key] as Doc }, "portal link", "link to named target", id);
+                    }
                 });
             });
         });
+
         this.linkOnDeselect.clear();
     }
 
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index f1602bfbc..fa2548cb5 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -21,7 +21,7 @@ import { action } from "mobx";
 import { LinkManager } from "../../../util/LinkManager";
 import { LinkDocPreview } from "../LinkDocPreview";
 import { DocumentLinksButton } from "../DocumentLinksButton";
-import Tooltip from "@material-ui/core/Tooltip";
+import { Tooltip } from "@material-ui/core";
 
 export let formattedTextBoxCommentPlugin = new Plugin({
     view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -271,14 +271,14 @@ export class FormattedTextBoxComment {
                                         <div className="wrapper" style={{ float: "right" }}>
 
                                             <Tooltip title="Delete Link" placement="top">
-                                                <div title="Delete link" className="FormattedTextBoxComment-button"
+                                                <div className="FormattedTextBoxComment-button"
                                                     ref={(r) => this._deleteRef = r}>
                                                     <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="trash" color="white"
                                                         size="sm" /></div>
                                             </Tooltip>
 
                                             <Tooltip title="Follow Link" placement="top">
-                                                <div title="Follow link" className="FormattedTextBoxComment-button"
+                                                <div className="FormattedTextBoxComment-button"
                                                     ref={(r) => this._followRef = r}>
                                                     <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="arrow-right" color="white"
                                                         size="sm" />
-- 
cgit v1.2.3-70-g09d2


From 0dafe85b7d0c826340299a7e6b51190a6eaa7004 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Mon, 13 Jul 2020 17:56:46 -0500
Subject: fixed preview backgrounds, text size, tooltip size, adding labels,
 conditional end link btn, tooltips size

---
 src/client/views/DocumentButtonBar.tsx             | 106 +++++++++++----------
 src/client/views/DocumentDecorations.tsx           |  12 +--
 src/client/views/MainView.tsx                      |   4 +-
 .../views/collections/CollectionLinearView.tsx     |   9 +-
 src/client/views/linking/LinkEditor.scss           |  24 ++++-
 src/client/views/linking/LinkEditor.tsx            |  27 ++++--
 src/client/views/linking/LinkMenuItem.scss         |   1 +
 src/client/views/linking/LinkMenuItem.tsx          |   6 +-
 src/client/views/nodes/DocumentLinksButton.scss    |  12 +--
 src/client/views/nodes/DocumentLinksButton.tsx     |  24 ++---
 src/client/views/nodes/LinkDocPreview.tsx          |   3 +-
 .../formattedText/FormattedTextBoxComment.tsx      |   4 +-
 12 files changed, 135 insertions(+), 97 deletions(-)

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

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index a3d24b3b6..c132eb5bb 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -119,7 +119,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         const targetDoc = this.view0?.props.Document;
         const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
         const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none";
-        return !targetDoc ? (null) : <Tooltip title={`${published ? "Push" : "Publish"} to Google Docs`}>
+        return !targetDoc ? (null) : <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{`${published ? "Push" : "Publish"} to Google Docs`}</div></React.Fragment>}>
             <div
                 className="documentButtonBar-linker"
                 style={{ animation }}
@@ -138,46 +138,49 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         const targetDoc = this.view0?.props.Document;
         const dataDoc = targetDoc && Doc.GetProto(targetDoc);
         const animation = this.isAnimatingFetch ? "spin 0.5s linear infinite" : "none";
+
+        const title = (() => {
+            switch (this.openHover) {
+                default:
+                case UtilityButtonState.Default: return `${!dataDoc?.unchanged ? "Pull from" : "Fetch"} Google Docs`;
+                case UtilityButtonState.OpenRight: return "Open in Right Split";
+                case UtilityButtonState.OpenExternally: return "Open in new Browser Tab";
+            }
+        })();
+
         return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? (null) : <Tooltip
-            title={(() => {
-                switch (this.openHover) {
-                    default:
-                    case UtilityButtonState.Default: return `${!dataDoc.unchanged ? "Pull from" : "Fetch"} Google Docs`;
-                    case UtilityButtonState.OpenRight: return "Open in Right Split";
-                    case UtilityButtonState.OpenExternally: return "Open in new Browser Tab";
-                }
-            })()}
-        ><div className="documentButtonBar-linker"
-            style={{ backgroundColor: this.pullColor }}
-            onPointerEnter={action(e => {
-                if (e.altKey) {
-                    this.openHover = UtilityButtonState.OpenExternally;
-                } else if (e.shiftKey) {
-                    this.openHover = UtilityButtonState.OpenRight;
-                }
-            })}
-            onPointerLeave={action(() => this.openHover = UtilityButtonState.Default)}
-            onClick={async e => {
-                const googleDocUrl = `https://docs.google.com/document/d/${dataDoc[GoogleRef]}/edit`;
-                if (e.shiftKey) {
-                    e.preventDefault();
-                    let googleDoc = await Cast(dataDoc.googleDoc, Doc);
-                    if (!googleDoc) {
-                        const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, UseCors: false };
-                        googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
-                        dataDoc.googleDoc = googleDoc;
+            title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{title}</div></React.Fragment>}>
+            <div className="documentButtonBar-linker"
+                style={{ backgroundColor: this.pullColor }}
+                onPointerEnter={action(e => {
+                    if (e.altKey) {
+                        this.openHover = UtilityButtonState.OpenExternally;
+                    } else if (e.shiftKey) {
+                        this.openHover = UtilityButtonState.OpenRight;
+                    }
+                })}
+                onPointerLeave={action(() => this.openHover = UtilityButtonState.Default)}
+                onClick={async e => {
+                    const googleDocUrl = `https://docs.google.com/document/d/${dataDoc[GoogleRef]}/edit`;
+                    if (e.shiftKey) {
+                        e.preventDefault();
+                        let googleDoc = await Cast(dataDoc.googleDoc, Doc);
+                        if (!googleDoc) {
+                            const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, UseCors: false };
+                            googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
+                            dataDoc.googleDoc = googleDoc;
+                        }
+                        CollectionDockingView.AddRightSplit(googleDoc);
+                    } else if (e.altKey) {
+                        e.preventDefault();
+                        window.open(googleDocUrl);
+                    } else {
+                        this.clearPullColor();
+                        DocumentButtonBar.hasPulledHack = false;
+                        targetDoc[Pulls] = NumCast(targetDoc[Pulls]) + 1;
+                        dataDoc.unchanged && runInAction(() => this.isAnimatingFetch = true);
                     }
-                    CollectionDockingView.AddRightSplit(googleDoc);
-                } else if (e.altKey) {
-                    e.preventDefault();
-                    window.open(googleDocUrl);
-                } else {
-                    this.clearPullColor();
-                    DocumentButtonBar.hasPulledHack = false;
-                    targetDoc[Pulls] = NumCast(targetDoc[Pulls]) + 1;
-                    dataDoc.unchanged && runInAction(() => this.isAnimatingFetch = true);
-                }
-            }}>
+                }}>
                 <FontAwesomeIcon className="documentdecorations-icon" size="sm"
                     style={{ WebkitAnimation: animation, MozAnimation: animation }}
                     icon={(() => {
@@ -195,7 +198,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
     get pinButton() {
         const targetDoc = this.view0?.props.Document;
         const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
-        return !targetDoc ? (null) : <Tooltip title={Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}>
+        return !targetDoc ? (null) : <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></React.Fragment>}>
             <div className="documentButtonBar-linker"
                 style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
                 onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
@@ -207,14 +210,15 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
     @computed
     get metadataButton() {
         const view0 = this.view0;
-        return !view0 ? (null) : <Tooltip title="Show metadata panel"><div className="documentButtonBar-linkFlyout">
-            <Flyout anchorPoint={anchorPoints.LEFT_TOP}
-                content={<MetadataEntryMenu docs={() => this.props.views().filter(dv => dv).map(dv => dv!.props.Document)} suggestWithFunction />  /* tfs: @bcz This might need to be the data document? */}>
-                <div className={"documentButtonBar-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
-                    {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" />}
-                </div>
-            </Flyout>
-        </div></Tooltip>;
+        return !view0 ? (null) : <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Show metadata panel</div></React.Fragment>}>
+            <div className="documentButtonBar-linkFlyout">
+                <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+                    content={<MetadataEntryMenu docs={() => this.props.views().filter(dv => dv).map(dv => dv!.props.Document)} suggestWithFunction />  /* tfs: @bcz This might need to be the data document? */}>
+                    <div className={"documentButtonBar-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
+                        {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" />}
+                    </div>
+                </Flyout>
+            </div></Tooltip>;
     }
 
     @computed
@@ -255,7 +259,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         Array.from(Object.values(Templates.TemplateList)).map(template =>
             templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean)));
         return !view0 ? (null) :
-            <Tooltip title="Tap: Customize layout.  Drag: Create alias" >
+            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Tap: Customize layout.  Drag: Create alias</div></React.Fragment>}>
                 <div className="documentButtonBar-linkFlyout" ref={this._dragRef}>
                     <Flyout anchorPoint={anchorPoints.LEFT_TOP} onOpen={action(() => this._aliasDown = true)} onClose={action(() => this._aliasDown = false)}
                         content={!this._aliasDown ? (null) : <TemplateMenu docViews={views.filter(v => v).map(v => v as DocumentView)} templates={templates} />}>
@@ -276,9 +280,9 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
             <div className="documentButtonBar-button">
                 <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={true} />
             </div>
-            <div className="documentButtonBar-button">
+            {DocumentLinksButton.StartLink ? <div className="documentButtonBar-button">
                 <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={false} />
-            </div>
+            </div> : null}
             <div className="documentButtonBar-button">
                 {this.templateButton}
             </div>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index d7324e1a6..2e3c63cf2 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -547,11 +547,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         }
         const minimal = bounds.r - bounds.x < 100 ? true : false;
         const maximizeIcon = minimal ? (
-            <Tooltip title="Show context menu" placement="top">
+            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Show context menu</div></React.Fragment>} placement="top">
                 <div className="documentDecorations-contextMenu" onPointerDown={this.onSettingsDown}>
                     <FontAwesomeIcon size="lg" icon="cog" />
                 </div></Tooltip>) : (
-                <Tooltip title="Iconify" placement="top">
+                <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Iconify</div></React.Fragment>} placement="top">
                     <div className="documentDecorations-minimizeButton" onClick={this.onCloseClick}>
                         {/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/}
                         <FontAwesomeIcon className="documentdecorations-times" icon={faTimes} size="lg" />
@@ -575,7 +575,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 </div>}
             </> :
             <>
-                {minimal ? (null) : <Tooltip title="Show context menu" placement="top"><div className="documentDecorations-contextMenu" key="menu" onPointerDown={this.onSettingsDown}>
+                {minimal ? (null) : <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Show context menu</div></React.Fragment>} placement="top"><div className="documentDecorations-contextMenu" key="menu" onPointerDown={this.onSettingsDown}>
                     <FontAwesomeIcon size="lg" icon="cog" />
                 </div></Tooltip>}
                 <div className="documentDecorations-title" key="title" onPointerDown={this.onTitleDown} >
@@ -614,11 +614,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     {maximizeIcon}
                     {titleArea}
                     {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) :
-                        <Tooltip title={`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`} placement="top">
+                        <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}</div></React.Fragment>} placement="top">
                             <div className="documentDecorations-iconifyButton" onPointerDown={this.onIconifyDown}>
                                 {"_"}
                             </div></Tooltip>}
-                    <Tooltip title="Open Document in Tab" placement="top"><div className="documentDecorations-closeButton" onPointerDown={this.onMaximizeDown}>
+                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Open Document In Tab</div></React.Fragment>} placement="top"><div className="documentDecorations-closeButton" onPointerDown={this.onMaximizeDown}>
                         {SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
                     </div></Tooltip>
                     <div id="documentDecorations-rotation" className="documentDecorations-rotation"
@@ -641,7 +641,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     <div id="documentDecorations-bottomRightResizer" className="documentDecorations-resizer"
                         onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
                     {seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? (null) :
-                        <Tooltip title="tap to select containing document" placement="top">
+                        <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>tap to select containing document</div></React.Fragment>} placement="top">
                             <div id="documentDecorations-levelSelector" className="documentDecorations-selector"
                                 onPointerDown={this.onSelectorUp} onContextMenu={e => e.preventDefault()}>
                                 <FontAwesomeIcon className="documentdecorations-times" icon={faArrowAltCircleUp} size="lg" />
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 2ed528836..a54973489 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -6,7 +6,7 @@ import {
     faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
     faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTimesCircle,
     faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight,
-    faHeading, faRulerCombined, faFillDrip, faUnlink
+    faHeading, faRulerCombined, faFillDrip, faUnlink, faHandPaper
 } from '@fortawesome/free-solid-svg-icons';
 import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -147,7 +147,7 @@ export class MainView extends React.Component {
             faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
             faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell,
             faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight,
-            faHeading, faRulerCombined, faFillDrip, faUnlink);
+            faHeading, faRulerCombined, faFillDrip, faUnlink, faHandPaper);
         this.initEventListeners();
         this.initAuthenticationRouters();
     }
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index dd4df20c9..319cca70f 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -124,7 +124,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
 
         return <div className="collectionLinearView-outer">
             <div className="collectionLinearView" ref={this.createDashEventsTarget} >
-                <Tooltip title={BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"} placement="top">
+                <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}</div></React.Fragment>} placement="top">
                     {menuOpener}
                 </Tooltip>
                 <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.linearViewIsExpanded)} ref={this.addMenuToggle}
@@ -177,14 +177,15 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                     onPointerDown={e => e.stopPropagation()} >
                     <span className="bottomPopup-text" >
                         Creating link from: {DocumentLinksButton.StartLink.title} </span>
-                    <Tooltip title={LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" :
-                        "Turn on description pop-up"} placement="top">
+
+                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" :
+                        "Turn on description pop-up"} </div></React.Fragment>} placement="top">
                         <span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}
                         > Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"}
                         </span>
                     </Tooltip>
 
-                    <Tooltip title="Exit link clicking mode" placement="top">
+                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Exit link clicking mode </div></React.Fragment>} placement="top">
                         <span className="bottomPopup-exit" onClick={this.exitLongLinks}
                         >Clear</span>
                     </Tooltip>
diff --git a/src/client/views/linking/LinkEditor.scss b/src/client/views/linking/LinkEditor.scss
index 87afc99eb..d26b7920a 100644
--- a/src/client/views/linking/LinkEditor.scss
+++ b/src/client/views/linking/LinkEditor.scss
@@ -13,6 +13,10 @@
     width: 18px;
     height: 18px;
     padding: 0;
+
+    &:hover {
+        cursor: pointer;
+    }
 }
 
 .linkEditor-info {
@@ -28,7 +32,13 @@
     .linkEditor-linkedTo {
         width: calc(100% - 26px);
         padding-left: 5px;
-        padding-right: 5px
+        padding-right: 5px;
+
+        .linkEditor-downArrow {
+            &:hover {
+                cursor: pointer;
+            }
+        }
     }
 }
 
@@ -43,6 +53,10 @@
 
     .button {
         color: black;
+
+        &:hover {
+            cursor: pointer;
+        }
     }
 }
 
@@ -83,6 +97,10 @@
             padding-right: 8px;
             height: 80%;
             color: white;
+
+            &:hover {
+                cursor: pointer;
+            }
         }
     }
 }
@@ -92,6 +110,10 @@
     padding-right: 6.5px;
     padding-bottom: 6px;
 
+    &:hover {
+        cursor: pointer;
+    }
+
     .linkEditor-followingDropdown-label {
         color: black;
     }
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index a26685318..1cc981d42 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -13,6 +13,7 @@ import { DocumentView } from "../nodes/DocumentView";
 import { DocumentLinksButton } from "../nodes/DocumentLinksButton";
 import { EditableView } from "../EditableView";
 import { RefObject } from "react";
+import { Tooltip } from "@material-ui/core";
 
 library.add(faArrowLeft, faEllipsisV, faTable, faTrash, faCog, faExchangeAlt, faTimes, faPlus);
 
@@ -285,15 +286,12 @@ interface LinkEditorProps {
 @observer
 export class LinkEditor extends React.Component<LinkEditorProps> {
 
-
     @observable description = StrCast(LinkManager.currentLink?.description);
     @observable openDropdown: boolean = false;
-
     @observable followBehavior = this.props.linkDoc.follow ? this.props.linkDoc.follow : "Default";
-
     @observable showInfo: boolean = false;
-
     @computed get infoIcon() { if (this.showInfo) { return "chevron-up"; } return "chevron-down"; }
+    @observable private buttonColor: string = "black";
 
 
     //@observable description = this.props.linkDoc.description ? StrCast(this.props.linkDoc.description) : "DESCRIPTION";
@@ -308,6 +306,10 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
     setDescripValue = (value: string) => {
         if (LinkManager.currentLink) {
             LinkManager.currentLink.description = value;
+            this.buttonColor = "rgb(62, 133, 55)";
+            setTimeout(action(() => {
+                this.buttonColor = "black";
+            }), 750);
             return true;
         }
     }
@@ -349,7 +351,8 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
                     ></input>
                 </div>
                 <div className="linkEditor-description-add-button"
-                    onPointerDown={this.onDown}>Add</div>
+                    style={{ backgroundColor: this.buttonColor }}
+                    onPointerDown={this.onDown}>Set</div>
             </div></div>;
     }
 
@@ -413,15 +416,19 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
         return !destination ? (null) : (
             <div className="linkEditor">
                 <div className="linkEditor-info">
-                    <button className="linkEditor-button-back"
-                        style={{ display: this.props.hideback ? "none" : "" }}
-                        onClick={this.props.showLinks}>
-                        <FontAwesomeIcon icon="arrow-left" size="sm" /> </button>
+                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Return to link menu</div></React.Fragment>} placement="top">
+                        <button className="linkEditor-button-back"
+                            style={{ display: this.props.hideback ? "none" : "" }}
+                            onClick={this.props.showLinks}>
+                            <FontAwesomeIcon icon="arrow-left" size="sm" /> </button>
+                    </Tooltip>
                     <p className="linkEditor-linkedTo">Editing Link to: <b>{
                         destination.proto?.title ?? destination.title ?? "untitled"}</b></p>
                     {/* <button className="linkEditor-button" onPointerDown={() => this.deleteLink()} title="Delete link">
                         <FontAwesomeIcon icon="trash" size="sm" /></button> */}
-                    <FontAwesomeIcon className="button" icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} />
+                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Show more link information</div></React.Fragment>} placement="top">
+                        <div className="linkEditor-downArrow"><FontAwesomeIcon className="button" icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} /></div>
+                    </Tooltip>
                 </div>
                 {this.showInfo ? <div className="linkEditor-moreInfo">
                     <div>{this.props.linkDoc.author ? <div> <b>Author:</b> {this.props.linkDoc.author}</div> : null}</div>
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index f70f5a23e..4e13ef8c8 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -67,6 +67,7 @@
                         color: rgb(60, 90, 156);
                         //display: inline;
                         text-overflow: break;
+                        cursor: pointer;
                     }
                 }
             }
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index b451f0168..ff9401696 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -253,16 +253,16 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                             {canExpand ? <div title="Show more" className="button" onPointerDown={e => this.toggleShowMore(e)}>
                                 <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
 
-                            <Tooltip title={showTitle}>
+                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{showTitle}</div></React.Fragment>}>
                                 <div className="button" ref={this._editRef} onPointerDown={this.showLink}>
                                     <FontAwesomeIcon className="fa-icon" icon={eyeIcon} size="sm" /></div>
                             </Tooltip>
 
-                            <Tooltip title="Edit Link">
+                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Edit Link</div></React.Fragment>}>
                                 <div className="button" ref={this._editRef} onPointerDown={this.onEdit}>
                                     <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
                             </Tooltip>
-                            <Tooltip title="Delete Link">
+                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Delete Link</div></React.Fragment>}>
                                 <div className="button" onPointerDown={this.deleteLink}>
                                     <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
                             </Tooltip>
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
index 35d99d44b..97e714cd5 100644
--- a/src/client/views/nodes/DocumentLinksButton.scss
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -13,18 +13,18 @@
     color: black;
     text-transform: uppercase;
     letter-spacing: 2px;
-    font-size: 75%;
+    font-size: 10px;
     transition: transform 0.2s;
     text-align: center;
     display: flex;
     justify-content: center;
     align-items: center;
 
-    // &:hover {
-    //     background: deepskyblue;
-    //     transform: scale(1.05);
-    //     cursor: pointer;
-    // }
+    &:hover {
+        // background: deepskyblue;
+        // transform: scale(1.05);
+        cursor: pointer;
+    }
 }
 
 .documentLinksButton {
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 83710cfbf..96ff0157e 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -168,8 +168,8 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
         const links = DocListCast(this.props.View.props.Document.links);
 
         const menuTitle = this.props.StartLink ? "Drag or tap to start link" : "Tap to complete link";
-
-        const title = this.props.InMenu ? menuTitle : "Tap to view links";
+        const buttonTitle = "Tap to view links";
+        const title = this.props.InMenu ? menuTitle : buttonTitle;
 
 
         const startLink = <img
@@ -202,14 +202,10 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
             //     Location: [e.clientX, e.clientY + 20]
             // }))} 
             >
-                {/* {this.props.InMenu ? this.props.StartLink ? <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" /> :
-                    <FontAwesomeIcon className="documentdecorations-icon" icon="unlink" size="sm" /> : links.length} */}
 
-                {/* {this.props.InMenu ? this.props.StartLink ? <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" /> :
-                    link : links.length} */}
+                {this.props.InMenu ? this.props.StartLink ? <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" /> :
+                    <FontAwesomeIcon className="documentdecorations-icon" icon="hand-paper" size="sm" /> : links.length}
 
-                {this.props.InMenu ? this.props.StartLink ? startLink :
-                    endLink : links.length}
             </div>
             {DocumentLinksButton.StartLink && this.props.InMenu && !!!this.props.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"}
                 style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }}
@@ -217,10 +213,16 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
             {DocumentLinksButton.StartLink === this.props.View && this.props.InMenu && this.props.StartLink ? <div className={"documentLinksButton-startLink"}
                 style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} /> : (null)}
         </div>;
+
         return (!links.length) && !this.props.AlwaysOn ? (null) :
-            <Tooltip title={title}>
-                {linkButton}
-            </Tooltip>;
+            this.props.InMenu ?
+                <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{title}</div></React.Fragment>}>
+                    {linkButton}
+                </Tooltip> : !!!DocumentLinksButton.EditLink ?
+                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{title}</div></React.Fragment>}>
+                        {linkButton}
+                    </Tooltip> :
+                    linkButton;
     }
     render() {
         return this.linkButton;
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 079920f56..1caa82380 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -123,7 +123,8 @@ export class LinkDocPreview extends React.Component<Props> {
                 bringToFront={returnFalse}
                 ContentScaling={returnOne}
                 NativeWidth={returnZero}
-                NativeHeight={returnZero} />;
+                NativeHeight={returnZero}
+                backgroundColor={this.props.backgroundColor} />;
     }
 
     render() {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index fa2548cb5..c98b5eac1 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -270,14 +270,14 @@ export class FormattedTextBoxComment {
                                         </div>
                                         <div className="wrapper" style={{ float: "right" }}>
 
-                                            <Tooltip title="Delete Link" placement="top">
+                                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Delete Link</div></React.Fragment>} placement="top">
                                                 <div className="FormattedTextBoxComment-button"
                                                     ref={(r) => this._deleteRef = r}>
                                                     <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="trash" color="white"
                                                         size="sm" /></div>
                                             </Tooltip>
 
-                                            <Tooltip title="Follow Link" placement="top">
+                                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Follow Link</div></React.Fragment>} placement="top">
                                                 <div className="FormattedTextBoxComment-button"
                                                     ref={(r) => this._followRef = r}>
                                                     <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="arrow-right" color="white"
-- 
cgit v1.2.3-70-g09d2


From 3fdee81100954e66f54c73661cb11967993ff467 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 15 Jul 2020 15:24:53 -0400
Subject: fixed tooltips to share a csss style.  added tooltips for richtext.

---
 src/client/documents/Documents.ts                  |  2 +-
 src/client/views/DocumentButtonBar.tsx             | 10 ++---
 src/client/views/DocumentDecorations.tsx           | 15 +++----
 src/client/views/MainView.scss                     |  4 ++
 .../views/collections/CollectionLinearView.tsx     | 20 +++++----
 src/client/views/collections/CollectionMenu.tsx    | 13 +++---
 src/client/views/collections/CollectionView.tsx    |  3 +-
 .../CollectionFreeFormLinkView.tsx                 | 12 +++---
 src/client/views/linking/LinkEditor.tsx            | 14 +++----
 src/client/views/linking/LinkMenuItem.tsx          | 19 +++------
 src/client/views/nodes/DocumentLinksButton.tsx     |  5 +--
 src/client/views/nodes/DocumentView.tsx            | 25 +++--------
 .../formattedText/FormattedTextBoxComment.tsx      |  4 +-
 .../views/nodes/formattedText/RichTextMenu.tsx     | 49 +++++++++++++---------
 src/client/views/pdf/PDFViewer.tsx                 |  2 +-
 15 files changed, 94 insertions(+), 103 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 1fd533b62..b57f4c6c7 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -915,7 +915,7 @@ export namespace DocUtils {
 
         const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id);
         linkDoc.linkDisplay = true;
-        linkDoc.hideAnhors = true;
+        linkDoc.hidden = true;
         linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null);
         Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") "  + self.anchor2?.title');
 
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 05538a28e..45f4c7393 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -118,7 +118,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         const targetDoc = this.view0?.props.Document;
         const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
         const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none";
-        return !targetDoc ? (null) : <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{`${published ? "Push" : "Publish"} to Google Docs`}</div></React.Fragment>}>
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{`${published ? "Push" : "Publish"} to Google Docs`}</div></>}>
             <div
                 className="documentButtonBar-linker"
                 style={{ animation }}
@@ -148,7 +148,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         })();
 
         return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? (null) : <Tooltip
-            title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{title}</div></React.Fragment>}>
+            title={<><div className="dash-tooltip">{title}</div></>}>
             <div className="documentButtonBar-linker"
                 style={{ backgroundColor: this.pullColor }}
                 onPointerEnter={action(e => {
@@ -197,7 +197,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
     get pinButton() {
         const targetDoc = this.view0?.props.Document;
         const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
-        return !targetDoc ? (null) : <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></React.Fragment>}>
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}>
             <div className="documentButtonBar-linker"
                 style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
                 onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
@@ -209,7 +209,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
     @computed
     get metadataButton() {
         const view0 = this.view0;
-        return !view0 ? (null) : <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Show metadata panel</div></React.Fragment>}>
+        return !view0 ? (null) : <Tooltip title={<><div className="dash-tooltip">Show metadata panel</div></>}>
             <div className="documentButtonBar-linkFlyout">
                 <Flyout anchorPoint={anchorPoints.LEFT_TOP}
                     content={<MetadataEntryMenu docs={this.props.views().filter(dv => dv).map(dv => dv!.props.Document)} suggestWithFunction />  /* tfs: @bcz This might need to be the data document? */}>
@@ -258,7 +258,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         Array.from(Object.values(Templates.TemplateList)).map(template =>
             templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean)));
         return !view0 ? (null) :
-            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Tap: Customize layout.  Drag: Create alias</div></React.Fragment>}>
+            <Tooltip title={<><div className="dash-tooltip">Tap: Customize layout.  Drag: Create alias</div></>}>
                 <div className="documentButtonBar-linkFlyout" ref={this._dragRef}>
                     <Flyout anchorPoint={anchorPoints.LEFT_TOP} onOpen={action(() => this._aliasDown = true)} onClose={action(() => this._aliasDown = false)}
                         content={!this._aliasDown ? (null) : <TemplateMenu docViews={views.filter(v => v).map(v => v as DocumentView)} templates={templates} />}>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 2fd017f7b..376b1d46b 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -81,6 +81,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => {
             if (documentView.props.renderDepth === 0 ||
                 documentView.props.treeViewDoc ||
+                !documentView.ContentDiv ||
                 Doc.AreProtosEqual(documentView.props.Document, Doc.UserDoc())) {
                 return bounds;
             }
@@ -88,7 +89,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             var [sptX, sptY] = transform.transformPoint(0, 0);
             let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight());
             if (documentView.props.Document.type === DocumentType.LINK) {
-                const docuBox = documentView.ContentDiv!.getElementsByClassName("linkAnchorBox-cont");
+                const docuBox = documentView.ContentDiv.getElementsByClassName("linkAnchorBox-cont");
                 if (docuBox.length) {
                     const rect = docuBox[0].getBoundingClientRect();
                     sptX = rect.left;
@@ -544,11 +545,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         }
         const minimal = bounds.r - bounds.x < 100 ? true : false;
         const maximizeIcon = minimal ? (
-            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Show context menu</div></React.Fragment>} placement="top">
+            <Tooltip title={<><div className="dash-tooltip">Show context menu</div></>} placement="top">
                 <div className="documentDecorations-contextMenu" onPointerDown={this.onSettingsDown}>
                     <FontAwesomeIcon size="lg" icon="cog" />
                 </div></Tooltip>) : (
-                <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Iconify</div></React.Fragment>} placement="top">
+                <Tooltip title={<><div className="dash-tooltip">Iconify</div></>} placement="top">
                     <div className="documentDecorations-minimizeButton" onClick={this.onCloseClick}>
                         {/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/}
                         <FontAwesomeIcon className="documentdecorations-times" icon={faTimes} size="lg" />
@@ -572,7 +573,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 </div>}
             </> :
             <>
-                {minimal ? (null) : <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Show context menu</div></React.Fragment>} placement="top"><div className="documentDecorations-contextMenu" key="menu" onPointerDown={this.onSettingsDown}>
+                {minimal ? (null) : <Tooltip title={<><div className="dash-tooltip">Show context menu</div></>} placement="top"><div className="documentDecorations-contextMenu" key="menu" onPointerDown={this.onSettingsDown}>
                     <FontAwesomeIcon size="lg" icon="cog" />
                 </div></Tooltip>}
                 <div className="documentDecorations-title" key="title" onPointerDown={this.onTitleDown} >
@@ -611,11 +612,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     {maximizeIcon}
                     {titleArea}
                     {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) :
-                        <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}</div></React.Fragment>} placement="top">
+                        <Tooltip title={<><div className="dash-tooltip">{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}</div></>} placement="top">
                             <div className="documentDecorations-iconifyButton" onPointerDown={this.onIconifyDown}>
                                 {"_"}
                             </div></Tooltip>}
-                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Open Document In Tab</div></React.Fragment>} placement="top"><div className="documentDecorations-closeButton" onPointerDown={this.onMaximizeDown}>
+                    <Tooltip title={<><div className="dash-tooltip">Open Document In Tab</div></>} placement="top"><div className="documentDecorations-closeButton" onPointerDown={this.onMaximizeDown}>
                         {SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
                     </div></Tooltip>
                     <div id="documentDecorations-rotation" className="documentDecorations-rotation"
@@ -638,7 +639,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     <div id="documentDecorations-bottomRightResizer" className="documentDecorations-resizer"
                         onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div>
                     {seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? (null) :
-                        <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>tap to select containing document</div></React.Fragment>} placement="top">
+                        <Tooltip title={<><div className="dash-tooltip">tap to select containing document</div></>} placement="top">
                             <div id="documentDecorations-levelSelector" className="documentDecorations-selector"
                                 onPointerDown={this.onSelectorUp} onContextMenu={e => e.preventDefault()}>
                                 <FontAwesomeIcon className="documentdecorations-times" icon={faArrowAltCircleUp} size="lg" />
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 5b142ffda..e1ddbc533 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -1,6 +1,10 @@
 @import "globalCssVariables";
 @import "nodeModuleOverrides";
 
+.dash-tooltip {
+    font-size: 11px;
+    padding: 2px;
+}
 
 .mainView-tabButtons {
     position: relative;
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 319cca70f..407524353 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -124,7 +124,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
 
         return <div className="collectionLinearView-outer">
             <div className="collectionLinearView" ref={this.createDashEventsTarget} >
-                <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}</div></React.Fragment>} placement="top">
+                <Tooltip title={<><div className="dash-tooltip">{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}</div></>} placement="top">
                     {menuOpener}
                 </Tooltip>
                 <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.linearViewIsExpanded)} ref={this.addMenuToggle}
@@ -176,18 +176,20 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                 }}
                     onPointerDown={e => e.stopPropagation()} >
                     <span className="bottomPopup-text" >
-                        Creating link from: {DocumentLinksButton.StartLink.title} </span>
+                        Creating link from: {DocumentLinksButton.StartLink.title}
+                    </span>
 
-                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" :
-                        "Turn on description pop-up"} </div></React.Fragment>} placement="top">
-                        <span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}
-                        > Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"}
+                    <Tooltip title={<><div className="dash-tooltip">{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" :
+                        "Turn on description pop-up"} </div></>} placement="top">
+                        <span className="bottomPopup-descriptions" onClick={this.changeDescriptionSetting}>
+                            Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"}
                         </span>
                     </Tooltip>
 
-                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Exit link clicking mode </div></React.Fragment>} placement="top">
-                        <span className="bottomPopup-exit" onClick={this.exitLongLinks}
-                        >Clear</span>
+                    <Tooltip title={<><div className="dash-tooltip">Exit link clicking mode </div></>} placement="top">
+                        <span className="bottomPopup-exit" onClick={this.exitLongLinks}>
+                            Clear
+                        </span>
                     </Tooltip>
 
                     {/* <FontAwesomeIcon icon="times-circle" size="lg" style={{ color: "red" }}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 827c3e299..0696b93db 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -38,12 +38,13 @@ export default class CollectionMenu extends AntimodeMenu {
     }
 
     render() {
-        return this.getElement([
-            !this.SelectedCollection ? <></> : <CollectionViewBaseChrome CollectionView={this.SelectedCollection} type={StrCast(this.SelectedCollection.props.Document._viewType) as CollectionViewType} />,
-            <button className="antimodeMenu-button" key="pin menu" title="Pin menu" onClick={this.toggleMenuPin} style={{ backgroundColor: "#121721" }}>
-                <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
-            </button>
-        ]);
+        const button = <button className="antimodeMenu-button" key="pin menu" title="Pin menu" onClick={this.toggleMenuPin} style={{ backgroundColor: "#121721" }}>
+            <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
+        </button>;
+
+        return this.getElement(!this.SelectedCollection ? [button] :
+            [<CollectionViewBaseChrome key="chrome" CollectionView={this.SelectedCollection} type={StrCast(this.SelectedCollection.props.Document._viewType) as CollectionViewType} />,
+            button]);
     }
 }
 
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index c1a6b5b0d..c1da23470 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -142,6 +142,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                     const context = Cast(doc.context, Doc, null);
                     if (context && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) {
                         const pushpin = Docs.Create.FontIconDocument({
+                            title: "pushpin",
                             icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), _backgroundColor: "#0000003d", color: "#ACCEF7",
                             _width: 15, _height: 15, _xPadding: 0, isLinkButton: true, displayTimecode: Cast(doc.displayTimecode, "number", null)
                         });
@@ -150,8 +151,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                         Doc.SetInPlace(doc, "annotationOn", undefined, true);
                         Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin);
                         const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", "");
-                        const first = DocListCast(pushpin.links).find(d => d instanceof Doc);
-                        first && (first.hidden = true);
                         doc.displayTimecode = undefined;
                     }
                     doc.context = this.props.Document;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index dea936113..0933d525a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -29,13 +29,13 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
     componentDidMount() {
         this._anchorDisposer = reaction(() => [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)],
             action(() => {
-                if (SnappingManager.GetIsDragging()) return;
+                if (SnappingManager.GetIsDragging() || !this.props.A.ContentDiv || !this.props.B.ContentDiv) return;
                 setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render()
                 setTimeout(action(() => (!this.props.LinkDocs.length || !this.props.LinkDocs[0].linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line.
-                const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : [];
-                const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : [];
-                const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv!);
-                const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv!);
+                const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : [];
+                const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : [];
+                const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv);
+                const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv);
                 const a = adiv.getBoundingClientRect();
                 const b = bdiv.getBoundingClientRect();
                 const abounds = adiv.parentElement!.getBoundingClientRect();
@@ -103,7 +103,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
 
 
     render() {
-        if (SnappingManager.GetIsDragging() || !this.props.LinkDocs.length) return null;
+        if (SnappingManager.GetIsDragging() || !this.props.A.ContentDiv || !this.props.B.ContentDiv || !this.props.LinkDocs.length) return (null);
         this.props.A.props.ScreenToLocalTransform().transform(this.props.B.props.ScreenToLocalTransform());
         const acont = this.props.A.ContentDiv!.getElementsByClassName("linkAnchorBox-cont");
         const bcont = this.props.B.ContentDiv!.getElementsByClassName("linkAnchorBox-cont");
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index 1cc981d42..ed2bea722 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -288,7 +288,6 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
 
     @observable description = StrCast(LinkManager.currentLink?.description);
     @observable openDropdown: boolean = false;
-    @observable followBehavior = this.props.linkDoc.follow ? this.props.linkDoc.follow : "Default";
     @observable showInfo: boolean = false;
     @computed get infoIcon() { if (this.showInfo) { return "chevron-up"; } return "chevron-down"; }
     @observable private buttonColor: string = "black";
@@ -364,8 +363,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
     @action
     changeFollowBehavior = (follow: string) => {
         this.openDropdown = false;
-        this.followBehavior = follow;
-        this.props.linkDoc.follow = follow;
+        Doc.GetProto(this.props.linkDoc).followLinkLocation = follow;
     }
 
     @computed
@@ -376,7 +374,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
             <div className="linkEditor-followingDropdown-dropdown">
                 <div className="linkEditor-followingDropdown-header"
                     onPointerDown={this.changeDropdown}>
-                    {this.followBehavior}
+                    {StrCast(this.props.linkDoc.followLinkLocation, "Default")}
                     <FontAwesomeIcon className="linkEditor-followingDropdown-icon"
                         icon={this.openDropdown ? "chevron-up" : "chevron-down"}
                         size={"lg"} />
@@ -388,11 +386,11 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
                         Default
                         </div>
                     <div className="linkEditor-followingDropdown-option"
-                        onPointerDown={() => this.changeFollowBehavior("Always open in right tab")}>
+                        onPointerDown={() => this.changeFollowBehavior("onRight")}>
                         Always open in right tab
                         </div>
                     <div className="linkEditor-followingDropdown-option"
-                        onPointerDown={() => this.changeFollowBehavior("Always open in new tab")}>
+                        onPointerDown={() => this.changeFollowBehavior("inTab")}>
                         Always open in new tab
                         </div>
                 </div>
@@ -416,7 +414,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
         return !destination ? (null) : (
             <div className="linkEditor">
                 <div className="linkEditor-info">
-                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Return to link menu</div></React.Fragment>} placement="top">
+                    <Tooltip title={<><div className="dash-tooltip">Return to link menu</div></>} placement="top">
                         <button className="linkEditor-button-back"
                             style={{ display: this.props.hideback ? "none" : "" }}
                             onClick={this.props.showLinks}>
@@ -426,7 +424,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
                         destination.proto?.title ?? destination.title ?? "untitled"}</b></p>
                     {/* <button className="linkEditor-button" onPointerDown={() => this.deleteLink()} title="Delete link">
                         <FontAwesomeIcon icon="trash" size="sm" /></button> */}
-                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Show more link information</div></React.Fragment>} placement="top">
+                    <Tooltip title={<><div className="dash-tooltip">Show more link information</div></>} placement="top">
                         <div className="linkEditor-downArrow"><FontAwesomeIcon className="button" icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} /></div>
                     </Tooltip>
                 </div>
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 6782f625b..0e847632b 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -16,7 +16,6 @@ import { DocumentView } from '../nodes/DocumentView';
 import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
 import { LinkDocPreview } from '../nodes/LinkDocPreview';
 import { Tooltip } from '@material-ui/core';
-import { RichTextField } from '../../../fields/RichTextField';
 import { DocumentType } from '../../documents/DocumentTypes';
 library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash);
 
@@ -157,14 +156,8 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
         DocumentLinksButton.EditLink = undefined;
         LinkDocPreview.LinkInfo = undefined;
 
-        if (this.props.linkDoc.follow) {
-            if (this.props.linkDoc.follow === "Default") {
-                DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false);
-            } else if (this.props.linkDoc.follow === "Always open in right tab") {
-                this.props.addDocTab(this.props.destinationDoc, "onRight");
-            } else if (this.props.linkDoc.follow === "Always open in new tab") {
-                this.props.addDocTab(this.props.destinationDoc, "inTab");
-            }
+        if (this.props.linkDoc.followLinkLocation && this.props.linkDoc.followLinkLocation !== "Default") {
+            this.props.addDocTab(this.props.destinationDoc, StrCast(this.props.linkDoc.followLinkLocation));
         } else {
             DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false);
         }
@@ -221,8 +214,6 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                 StrCast(this.props.linkDoc.storedText).substr(0, 18)
                 : this.props.linkDoc.storedText : undefined : undefined;
 
-        const showTitle = this.props.linkDoc.hidden ? "Show link" : "Hide link";
-
         return (
             <div className="linkMenu-item">
                 <div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}>
@@ -255,16 +246,16 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                             {canExpand ? <div title="Show more" className="button" onPointerDown={e => this.toggleShowMore(e)}>
                                 <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
 
-                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{showTitle}</div></React.Fragment>}>
+                            <Tooltip title={<><div className="dash-tooltip">{this.props.linkDoc.hidden ? "Show link" : "Hide link"}</div></>}>
                                 <div className="button" ref={this._editRef} onPointerDown={this.showLink}>
                                     <FontAwesomeIcon className="fa-icon" icon={eyeIcon} size="sm" /></div>
                             </Tooltip>
 
-                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Edit Link</div></React.Fragment>}>
+                            <Tooltip title={<><div className="dash-tooltip">Edit Link</div></>}>
                                 <div className="button" ref={this._editRef} onPointerDown={this.onEdit}>
                                     <FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
                             </Tooltip>
-                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Delete Link</div></React.Fragment>}>
+                            <Tooltip title={<><div className="dash-tooltip">Delete Link</div></>}>
                                 <div className="button" onPointerDown={this.deleteLink}>
                                     <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
                             </Tooltip>
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 01c068966..bbef48e44 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -134,7 +134,6 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                 if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) {
                     const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
                     LinkManager.currentLink = linkDoc;
-                    linkDoc ? linkDoc.hidden = true : null;
 
                     runInAction(() => {
                         if (linkDoc) {
@@ -213,10 +212,10 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
 
         return (!links.length) && !this.props.AlwaysOn ? (null) :
             this.props.InMenu ?
-                <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{title}</div></React.Fragment>}>
+                <Tooltip title={<><div className="dash-tooltip">{title}</div></>}>
                     {linkButton}
                 </Tooltip> : !!!DocumentLinksButton.EditLink ?
-                    <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>{title}</div></React.Fragment>}>
+                    <Tooltip title={<><div className="dash-tooltip">{title}</div></>}>
                         {linkButton}
                     </Tooltip> :
                     linkButton;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a6771443a..c0a8b3a59 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -589,16 +589,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @undoBatch
     toggleLinkButtonBehavior = (): void => {
+        this.Document.ignoreClick = false;
         if (this.Document.isLinkButton || this.onClickHandler || this.Document.ignoreClick) {
             this.Document.isLinkButton = false;
-            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
-            first && (first.hidden = false);
-            this.Document.ignoreClick = false;
             this.Document.onClick = this.layoutDoc.onClick = undefined;
         } else {
             this.Document.isLinkButton = true;
-            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
-            first && (first.hidden = true);
             this.Document.followLinkZoom = false;
             this.Document.followLinkLocation = undefined;
         }
@@ -606,14 +602,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @undoBatch
     toggleFollowInPlace = (): void => {
+        this.Document.ignoreClick = false;
+        this.Document.isLinkButton = !this.Document.isLinkButton;
         if (this.Document.isLinkButton) {
-            this.Document.isLinkButton = false;
-            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
-            first && (first.hidden = false);
-        } else {
-            this.Document.isLinkButton = true;
-            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
-            first && (first.hidden = true);
             this.Document.followLinkZoom = true;
             this.Document.followLinkLocation = "inPlace";
         }
@@ -621,15 +612,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @undoBatch
     toggleFollowOnRight = (): void => {
+        this.Document.ignoreClick = false;
+        this.Document.isLinkButton = !this.Document.isLinkButton;
         if (this.Document.isLinkButton) {
-            this.Document.isLinkButton = false;
-            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
-            first && (first.hidden = false);
-        } else {
-            this.Document.isLinkButton = true;
             this.Document.followLinkZoom = false;
-            const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
-            first && (first.hidden = true);
             this.Document.followLinkLocation = "onRight";
         }
     }
@@ -643,7 +629,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
         const makeLink = action((linkDoc: Doc) => {
             LinkManager.currentLink = linkDoc;
-            linkDoc.hidden = true;
 
             LinkCreatedBox.popupX = de.x;
             LinkCreatedBox.popupY = de.y - 33;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index c98b5eac1..3687d5513 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -270,14 +270,14 @@ export class FormattedTextBoxComment {
                                         </div>
                                         <div className="wrapper" style={{ float: "right" }}>
 
-                                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Delete Link</div></React.Fragment>} placement="top">
+                                            <Tooltip title={<><div className="dash-tooltip">Delete Link</div></>} placement="top">
                                                 <div className="FormattedTextBoxComment-button"
                                                     ref={(r) => this._deleteRef = r}>
                                                     <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="trash" color="white"
                                                         size="sm" /></div>
                                             </Tooltip>
 
-                                            <Tooltip title={<React.Fragment><div style={{ fontSize: "11px", padding: "2px" }}>Follow Link</div></React.Fragment>} placement="top">
+                                            <Tooltip title={<><div className="dash-tooltip">Follow Link</div></>} placement="top">
                                                 <div className="FormattedTextBoxComment-button"
                                                     ref={(r) => this._followRef = r}>
                                                     <FontAwesomeIcon className="FormattedTextBoxComment-fa-icon" icon="arrow-right" color="white"
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index d0e6f3b37..63f6fdc54 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -24,6 +24,7 @@ import "./RichTextMenu.scss";
 import { schema } from "./schema_rts";
 import { TraceMobx } from "../../../../fields/util";
 import { UndoManager } from "../../../util/UndoManager";
+import { Tooltip } from "@material-ui/core";
 const { toggleMark } = require("prosemirror-commands");
 
 library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faOutdent, faIndent, faHandPointLeft, faHandPointRight, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller);
@@ -357,9 +358,11 @@ export default class RichTextMenu extends AntimodeMenu {
         }
 
         return (
-            <button className={"antimodeMenu-button" + (isActive ? " active" : "")} key={title} title={title} onPointerDown={onClick}>
-                <FontAwesomeIcon icon={faIcon as IconProp} size="lg" />
-            </button>
+            <Tooltip title={<div className="dash-tooltip">{title}</div>} key={title} placement="bottom">
+                <button className={"antimodeMenu-button" + (isActive ? " active" : "")} onPointerDown={onClick}>
+                    <FontAwesomeIcon icon={faIcon as IconProp} size="lg" />
+                </button>
+            </Tooltip>
         );
     }
 
@@ -388,7 +391,9 @@ export default class RichTextMenu extends AntimodeMenu {
                 }
             });
         }
-        return <select onChange={onChange} value={activeOption} key={key}>{items}</select>;
+        return <Tooltip key={key} title={<div className="dash-tooltip">{key}</div>} placement="bottom">
+            <select onChange={onChange} value={activeOption}>{items}</select>
+        </Tooltip>;
     }
 
     createNodesDropdown(activeMap: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[], key: string, setter: (val: string) => {}): JSX.Element {
@@ -412,7 +417,10 @@ export default class RichTextMenu extends AntimodeMenu {
                 }
             });
         }
-        return <select value={activeOption} onChange={e => onChange(e.target.value)} key={key}>{items}</select>;
+
+        return <Tooltip key={key} title={<div className="dash-tooltip">{key}</div>} placement="bottom">
+            <select value={activeOption} onChange={e => onChange(e.target.value)}>{items}</select>
+        </Tooltip>;
     }
 
     changeFontSize = (mark: Mark, view: EditorView) => {
@@ -595,10 +603,11 @@ export default class RichTextMenu extends AntimodeMenu {
             label = "No marks are currently stored";
         }
 
-        const button =
-            <button className="antimodeMenu-button" title="" onPointerDown={onBrushClick} style={this.brushMarks?.size > 0 ? { backgroundColor: "121212" } : {}}>
+        const button = <Tooltip title={<div className="dash-tooltip">style brush</div>} placement="bottom">
+            <button className="antimodeMenu-button" onPointerDown={onBrushClick} style={this.brushMarks?.size > 0 ? { backgroundColor: "121212" } : {}}>
                 <FontAwesomeIcon icon="paint-roller" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.brushMarks?.size > 0 ? 45 : 0}deg)` }} />
-            </button>;
+            </button>
+        </Tooltip>;
 
         const dropdownContent =
             <div className="dropdown">
@@ -667,11 +676,12 @@ export default class RichTextMenu extends AntimodeMenu {
             self.TextView.EditorView!.focus();
         }
 
-        const button =
-            <button className="antimodeMenu-button color-preview-button" title="" onPointerDown={onColorClick}>
+        const button = <Tooltip title={<div className="dash-tooltip">set font color</div>} placement="bottom">
+            <button className="antimodeMenu-button color-preview-button" onPointerDown={onColorClick}>
                 <FontAwesomeIcon icon="palette" size="lg" />
                 <div className="color-preview" style={{ backgroundColor: this.activeFontColor }}></div>
-            </button>;
+            </button>
+        </Tooltip>;
 
         const dropdownContent =
             <div className="dropdown" >
@@ -720,11 +730,12 @@ export default class RichTextMenu extends AntimodeMenu {
             UndoManager.RunInBatch(() => self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch), "rt highlighter");
         }
 
-        const button =
-            <button className="antimodeMenu-button color-preview-button" title="" key="highilghter-button" onPointerDown={onHighlightClick}>
+        const button = <Tooltip title={<div className="dash-tooltip">set highlight color</div>} placement="bottom">
+            <button className="antimodeMenu-button color-preview-button" key="highilghter-button" onPointerDown={onHighlightClick}>
                 <FontAwesomeIcon icon="highlighter" size="lg" />
                 <div className="color-preview" style={{ backgroundColor: this.activeHighlightColor }}></div>
-            </button>;
+            </button>
+        </Tooltip>;
 
         const dropdownContent =
             <div className="dropdown">
@@ -763,7 +774,9 @@ export default class RichTextMenu extends AntimodeMenu {
 
         const link = this.currentLink ? this.currentLink : "";
 
-        const button = <FontAwesomeIcon icon="link" size="lg" />;
+        const button = <Tooltip title={<div className="dash-tooltip">set hyperlink</div>} placement="bottom">
+            <div><FontAwesomeIcon icon="link" size="lg" /> </div>
+        </Tooltip>;
 
         const dropdownContent =
             <div className="dropdown link-menu">
@@ -774,9 +787,7 @@ export default class RichTextMenu extends AntimodeMenu {
                 <button className="remove-button" onPointerDown={e => this.deleteLink()}>Remove link</button>
             </div>;
 
-        return (
-            <ButtonDropdown view={this.view} key={"link button"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} />
-        );
+        return <ButtonDropdown view={this.view} key={"link button"} button={button} dropdownContent={dropdownContent} openDropdownOnButton={true} />;
     }
 
     async getTextLinkTargetTitle() {
@@ -935,7 +946,7 @@ export default class RichTextMenu extends AntimodeMenu {
                 {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => this.activeFontSize = val)),
                 this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => this.activeFontFamily = val)),
                 <div className="richTextMenu-divider" key="divider 4" />,
-                this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes", action((val: string) => this.activeListType = val)),
+                this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", action((val: string) => this.activeListType = val)),
                 this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer),
                 this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote),
                 this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule),
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 4e5fdbfbb..56212a773 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -637,7 +637,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
 
     @action
     onZoomWheel = (e: React.WheelEvent) => {
-        if (this.active()) {
+        if (this.active(true)) {
             e.stopPropagation();
             if (e.ctrlKey) {
                 const curScale = Number(this._pdfViewer.currentScaleValue);
-- 
cgit v1.2.3-70-g09d2


From 828a28e112db3357f52d3923987070129fd64b21 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 22 Jul 2020 11:33:28 -0400
Subject: restored download document.  fixed clone() to clone to be async and
 handles lists properly.

---
 src/client/util/CurrentUserUtils.ts                |  6 +++++
 src/client/util/LinkManager.ts                     | 12 ++-------
 src/client/util/Scripting.ts                       | 10 +++-----
 src/client/views/GlobalKeyHandler.ts               |  4 +--
 src/client/views/PreviewCursor.tsx                 |  4 +--
 .../collections/collectionFreeForm/MarqueeView.tsx |  8 +++---
 src/client/views/linking/LinkEditor.tsx            |  4 +--
 src/client/views/linking/LinkMenuItem.tsx          |  3 ++-
 src/client/views/nodes/DocumentView.tsx            | 14 ++++------
 src/client/views/nodes/LinkDocPreview.tsx          |  9 +------
 .../formattedText/FormattedTextBoxComment.tsx      |  2 ++
 .../views/nodes/formattedText/RichTextMenu.tsx     |  4 ++-
 src/fields/Doc.ts                                  | 30 +++++++++++-----------
 src/server/ApiManagers/DownloadManager.ts          | 12 +++------
 src/server/ApiManagers/UploadManager.ts            | 14 +++-------
 15 files changed, 56 insertions(+), 80 deletions(-)

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

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 03a75381a..23b8f09de 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -22,6 +22,7 @@ import { DocumentType } from "../documents/DocumentTypes";
 import { SchemaHeaderField } from "../../fields/SchemaHeaderField";
 import { DimUnit } from "../views/collections/collectionMulticolumn/CollectionMulticolumnView";
 import { LabelBox } from "../views/nodes/LabelBox";
+import { LinkManager } from "./LinkManager";
 
 export class CurrentUserUtils {
     private static curr_id: string;
@@ -888,3 +889,8 @@ export class CurrentUserUtils {
 
 Scripting.addGlobal(function createNewWorkspace() { return MainView.Instance.createNewWorkspace(); },
     "creates a new workspace when called");
+
+Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); },
+    "returns all the links to the document or its annotations", "(doc: any)");
+Scripting.addGlobal(function directLinks(doc: any) { return new List(LinkManager.Instance.getAllDirectLinks(doc)); },
+    "returns all the links directly to the document", "(doc: any)");
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 974744344..223f0e7ef 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -2,8 +2,6 @@ import { Doc, DocListCast, Opt } from "../../fields/Doc";
 import { List } from "../../fields/List";
 import { listSpec } from "../../fields/Schema";
 import { Cast, StrCast } from "../../fields/Types";
-import { Scripting } from "./Scripting";
-import { undoBatch } from "./UndoManager";
 
 /* 
  * link doc: 
@@ -25,12 +23,12 @@ export class LinkManager {
 
     private static _instance: LinkManager;
 
-
     public static currentLink: Opt<Doc>;
 
     public static get Instance(): LinkManager {
         return this._instance || (this._instance = new this());
     }
+
     private constructor() {
     }
 
@@ -53,7 +51,6 @@ export class LinkManager {
         return false;
     }
 
-    @undoBatch
     public deleteLink(linkDoc: Doc): boolean {
         if (LinkManager.Instance.LinkManagerDoc && linkDoc instanceof Doc) {
             Doc.RemoveDocFromList(LinkManager.Instance.LinkManagerDoc, "data", linkDoc);
@@ -210,9 +207,4 @@ export class LinkManager {
         if (Doc.AreProtosEqual(anchor, a2)) return a1;
         if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc;
     }
-}
-
-Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); },
-    "returns all the links to the document or its annotations", "(doc: any)");
-Scripting.addGlobal(function directLinks(doc: any) { return new List(LinkManager.Instance.getAllDirectLinks(doc)); },
-    "returns all the links directly to the document", "(doc: any)");
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index e6cf50de3..f1e6155d2 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -10,8 +10,6 @@ export { ts };
 // @ts-ignore
 import * as typescriptlib from '!!raw-loader!./type_decls.d';
 import { Doc, Field } from '../../fields/Doc';
-import { Cast } from "../../fields/Types";
-import { listSpec } from "../../fields/Schema";
 
 export interface ScriptSucccess {
     success: true;
@@ -95,10 +93,10 @@ export namespace Scripting {
     export function removeGlobal(name: string) {
         if (getGlobals().includes(name)) {
             delete _scriptingGlobals[name];
-            if (_scriptingDescriptions[name]){
+            if (_scriptingDescriptions[name]) {
                 delete _scriptingDescriptions[name];
             }
-            if (_scriptingParams[name]){
+            if (_scriptingParams[name]) {
                 delete _scriptingParams[name];
             }
             return true;
@@ -123,11 +121,11 @@ export namespace Scripting {
         return _scriptingGlobals;
     }
 
-    export function getDescriptions(){
+    export function getDescriptions() {
         return _scriptingDescriptions;
     }
 
-    export function getParameters(){
+    export function getParameters() {
         return _scriptingParams;
     }
 }
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 4dfa7aec8..b63537b5f 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -309,13 +309,13 @@ export default class KeyManager {
                 const targetDataDoc = Doc.GetProto(first.props.Document);
                 const fieldKey = Doc.LayoutFieldKey(first.props.Document);
                 const docList = DocListCast(targetDataDoc[fieldKey]);
-                docids.map((did, i) => i && DocServer.GetRefField(did).then(doc => {
+                docids.map((did, i) => i && DocServer.GetRefField(did).then(async doc => {
                     count++;
                     if (doc instanceof Doc) {
                         list.push(doc);
                     }
                     if (count === docids.length) {
-                        const added = list.filter(d => !docList.includes(d)).map(d => clone ? Doc.MakeClone(d) : d);
+                        const added = await Promise.all(list.filter(d => !docList.includes(d)).map(async d => clone ? await Doc.MakeClone(d) : d));
                         if (added.length) {
                             added.map(doc => doc.context = targetDataDoc);
                             undoBatch(() => {
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 6583589f3..2d51403d7 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -69,11 +69,11 @@ export class PreviewCursor extends React.Component<{}> {
                     const list: Doc[] = [];
 
                     let first: Doc | undefined;
-                    docids.map((did, i) => i && DocServer.GetRefField(did).then(doc => {
+                    docids.map((did, i) => i && DocServer.GetRefField(did).then(async doc => {
                         count++;
                         if (doc instanceof Doc) {
                             i === 1 && (first = doc);
-                            const alias = clone ? Doc.MakeClone(doc) : doc;
+                            const alias = clone ? await Doc.MakeClone(doc) : doc;
                             const deltaX = NumCast(doc.x) - NumCast(first!.x) - ptx;
                             const deltaY = NumCast(doc.y) - NumCast(first!.y) - pty;
                             alias.x = newPoint[0] + deltaX;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 6db8c8992..84719b2c9 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -189,8 +189,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     onPointerDown = (e: React.PointerEvent): void => {
         this._downX = this._lastX = e.clientX;
         this._downY = this._lastY = e.clientY;
-        if (!(e as any).marqueeHit) {
-            (e as any).marqueeHit = true;
+        if (!(e.nativeEvent as any).marqueeHit) {
+            (e.nativeEvent as any).marqueeHit = true;
             // allow marquee if right click OR alt+left click OR space bar + left click
             if (e.button === 2 || (e.button === 0 && (e.altKey || (MarqueeView.DragMarquee && this.props.active(true))))) {
                 // if (e.altKey || (MarqueeView.DragMarquee && this.props.active(true))) {
@@ -291,8 +291,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD &&
             Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) {
             if (Doc.GetSelectedTool() === InkTool.None) {
-                if (!(e as any).marqueeHit) {
-                    (e as any).marqueeHit = true;
+                if (!(e.nativeEvent as any).marqueeHit) {
+                    (e.nativeEvent as any).marqueeHit = true;
                     !(e.nativeEvent as any).formattedHandled && this.setPreviewCursor(e.clientX, e.clientY, false);
                 }
             }
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index ed2bea722..04329182e 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -14,6 +14,7 @@ import { DocumentLinksButton } from "../nodes/DocumentLinksButton";
 import { EditableView } from "../EditableView";
 import { RefObject } from "react";
 import { Tooltip } from "@material-ui/core";
+import { undoBatch } from "../../util/UndoManager";
 
 library.add(faArrowLeft, faEllipsisV, faTable, faTrash, faCog, faExchangeAlt, faTimes, faPlus);
 
@@ -295,6 +296,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
 
     //@observable description = this.props.linkDoc.description ? StrCast(this.props.linkDoc.description) : "DESCRIPTION";
 
+    @undoBatch
     @action
     deleteLink = (): void => {
         LinkManager.Instance.deleteLink(this.props.linkDoc);
@@ -422,8 +424,6 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
                     </Tooltip>
                     <p className="linkEditor-linkedTo">Editing Link to: <b>{
                         destination.proto?.title ?? destination.title ?? "untitled"}</b></p>
-                    {/* <button className="linkEditor-button" onPointerDown={() => this.deleteLink()} title="Delete link">
-                        <FontAwesomeIcon icon="trash" size="sm" /></button> */}
                     <Tooltip title={<><div className="dash-tooltip">Show more link information</div></>} placement="top">
                         <div className="linkEditor-downArrow"><FontAwesomeIcon className="button" icon={this.infoIcon} size="lg" onPointerDown={this.changeInfo} /></div>
                     </Tooltip>
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 0e847632b..d8ba39f09 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -17,6 +17,7 @@ import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
 import { LinkDocPreview } from '../nodes/LinkDocPreview';
 import { Tooltip } from '@material-ui/core';
 import { DocumentType } from '../../documents/DocumentTypes';
+import { undoBatch } from '../../util/UndoManager';
 library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash);
 
 
@@ -163,10 +164,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
         }
     }
 
+    @undoBatch
     @action
     deleteLink = (): void => {
         LinkManager.Instance.deleteLink(this.props.linkDoc);
-        //this.props.showLinks();
         LinkDocPreview.LinkInfo = undefined;
         DocumentLinksButton.EditLink = undefined;
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 0b5bd707b..12d9890c9 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -794,16 +794,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             }
             moreItems.push({
                 description: "Download document", icon: "download", event: async () => {
-                    const response = await rp.get(Utils.CorsProxy("http://localhost:8983/solr/dash/select"), {
-                        qs: { q: 'world', fq: 'NOT baseProto_b:true AND NOT deleted:true', start: '0', rows: '100', hl: true, 'hl.fl': '*' }
-                    });
-                    console.log(response ? JSON.parse(response) : undefined);
+                    const a = document.createElement("a");
+                    const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`);
+                    a.href = url;
+                    a.download = `DocExport-${this.props.Document[Id]}.zip`;
+                    a.click();
                 }
-                // const a = document.createElement("a");
-                // const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`);
-                // a.href = url;
-                // a.download = `DocExport-${this.props.Document[Id]}.zip`;
-                // a.click();
             });
             moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" });
         }
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 1caa82380..ebb916307 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -15,6 +15,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { LinkManager } from '../../util/LinkManager';
 import { DocumentLinksButton } from './DocumentLinksButton';
 import { ContextMenu } from '../ContextMenu';
+import { undoBatch } from '../../util/UndoManager';
 
 interface Props {
     linkDoc?: Doc;
@@ -31,14 +32,6 @@ export class LinkDocPreview extends React.Component<Props> {
     @observable _toolTipText = "";
     _editRef = React.createRef<HTMLDivElement>();
 
-    @action
-    deleteLink = (): void => {
-        this.props.linkDoc ? LinkManager.Instance.deleteLink(this.props.linkDoc) : null;
-        //this.props.showLinks();
-        LinkDocPreview.LinkInfo = undefined;
-        DocumentLinksButton.EditLink = undefined;
-    }
-
     @action
     onContextMenu = (e: React.MouseEvent) => {
         DocumentLinksButton.EditLink = undefined;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 3687d5513..6f3984f39 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -22,6 +22,7 @@ import { LinkManager } from "../../../util/LinkManager";
 import { LinkDocPreview } from "../LinkDocPreview";
 import { DocumentLinksButton } from "../DocumentLinksButton";
 import { Tooltip } from "@material-ui/core";
+import { undoBatch } from "../../../util/UndoManager";
 
 export let formattedTextBoxCommentPlugin = new Plugin({
     view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -143,6 +144,7 @@ export class FormattedTextBoxComment {
         }
     }
 
+    @undoBatch
     @action
     deleteLink = () => {
         FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 2e0b0e659..47a4911b8 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -23,7 +23,7 @@ import { updateBullets } from "./ProsemirrorExampleTransfer";
 import "./RichTextMenu.scss";
 import { schema } from "./schema_rts";
 import { TraceMobx } from "../../../../fields/util";
-import { UndoManager } from "../../../util/UndoManager";
+import { UndoManager, undoBatch } from "../../../util/UndoManager";
 import { Tooltip } from "@material-ui/core";
 const { toggleMark } = require("prosemirror-commands");
 
@@ -831,6 +831,8 @@ export default class RichTextMenu extends AntimodeMenu {
         ((this.view as any)?.TextView as FormattedTextBox).makeLinkToSelection("", target, "onRight", "", target);
     }
 
+    @undoBatch
+    @action
     deleteLink = () => {
         if (this.view) {
             const link = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.linkAnchor);
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 2f3b7025e..16ade5912 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -483,25 +483,25 @@ export namespace Doc {
         return alias;
     }
 
-
-
-    export function makeClone(doc: Doc, cloneMap: Map<string, Doc>, rtfs: { copy: Doc, key: string, field: RichTextField }[]): Doc {
+    export async function makeClone(doc: Doc, cloneMap: Map<string, Doc>, rtfs: { copy: Doc, key: string, field: RichTextField }[], exclusions: string[]): Promise<Doc> {
         if (Doc.IsBaseProto(doc)) return doc;
         if (cloneMap.get(doc[Id])) return cloneMap.get(doc[Id])!;
         const copy = new Doc(undefined, true);
         cloneMap.set(doc[Id], copy);
         if (LinkManager.Instance.getAllLinks().includes(doc) && LinkManager.Instance.getAllLinks().indexOf(copy) === -1) LinkManager.Instance.addLink(copy);
-        const exclude = Cast(doc.excludeFields, listSpec("string"), []);
-        Object.keys(doc).forEach(key => {
-            if (exclude.includes(key)) return;
+        const filter = Cast(doc.cloneFieldFilter, listSpec("string"), exclusions);
+        Object.keys(doc).forEach(async key => {
+            if (filter.includes(key)) return;
             const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
             const field = ProxyField.WithoutProxy(() => doc[key]);
-            const copyObjectField = (field: ObjectField) => {
-                const list = Cast(doc[key], listSpec(Doc));
-                if (list !== undefined && !(list instanceof Promise)) {
-                    copy[key] = new List<Doc>(list.filter(d => d instanceof Doc).map(d => Doc.makeClone(d as Doc, cloneMap, rtfs)));
+            const copyObjectField = async (field: ObjectField) => {
+                const list = await Cast(doc[key], listSpec(Doc));
+                const docs = list && (await DocListCastAsync(list))?.filter(d => d instanceof Doc);
+                if (docs !== undefined && docs.length) {
+                    const clones = docs.map(async d => await Doc.makeClone(d as Doc, cloneMap, rtfs, exclusions));
+                    copy[key] = new List<Doc>(await Promise.all(clones));
                 } else if (doc[key] instanceof Doc) {
-                    copy[key] = key.includes("layout[") ? undefined : Doc.makeClone(doc[key] as Doc, cloneMap, rtfs); // reference documents except copy documents that are expanded teplate fields 
+                    copy[key] = key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, rtfs, exclusions); // reference documents except copy documents that are expanded teplate fields 
                 } else {
                     copy[key] = ObjectField.MakeCopy(field);
                     if (field instanceof RichTextField) {
@@ -513,7 +513,7 @@ export namespace Doc {
             };
             if (key === "proto") {
                 if (doc[key] instanceof Doc) {
-                    copy[key] = Doc.makeClone(doc[key]!, cloneMap, rtfs);
+                    copy[key] = await Doc.makeClone(doc[key]!, cloneMap, rtfs, exclusions);
                 }
             } else {
                 if (field instanceof RefField) {
@@ -535,10 +535,10 @@ export namespace Doc {
         cloneMap.set(doc[Id], copy);
         return copy;
     }
-    export function MakeClone(doc: Doc): Doc {
+    export async function MakeClone(doc: Doc): Promise<Doc> {
         const cloneMap = new Map<string, Doc>();
         const rtfMap: { copy: Doc, key: string, field: RichTextField }[] = [];
-        const copy = Doc.makeClone(doc, cloneMap, rtfMap);
+        const copy = await Doc.makeClone(doc, cloneMap, rtfMap, ["context", "annotationOn", "cloneOf"]);
         rtfMap.map(({ copy, key, field }) => {
             const replacer = (match: any, attr: string, id: string, offset: any, string: any) => {
                 const mapped = cloneMap.get(id);
@@ -657,7 +657,7 @@ export namespace Doc {
 
     export function MakeCopy(doc: Doc, copyProto: boolean = false, copyProtoId?: string): Doc {
         const copy = new Doc(copyProtoId, true);
-        const exclude = Cast(doc.excludeFields, listSpec("string"), []);
+        const exclude = Cast(doc.cloneFieldFilter, listSpec("string"), []);
         Object.keys(doc).forEach(key => {
             if (exclude.includes(key)) return;
             const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
diff --git a/src/server/ApiManagers/DownloadManager.ts b/src/server/ApiManagers/DownloadManager.ts
index c5f3ca717..0d4472fdc 100644
--- a/src/server/ApiManagers/DownloadManager.ts
+++ b/src/server/ApiManagers/DownloadManager.ts
@@ -80,20 +80,14 @@ async function getDocs(id: string) {
         }
         const ids: string[] = [];
         for (const key in doc.fields) {
-            if (!doc.fields.hasOwnProperty(key)) {
-                continue;
-            }
+            if (!doc.fields.hasOwnProperty(key)) { continue; }
             const field = doc.fields[key];
-            if (field === undefined || field === null) {
-                continue;
-            }
+            if (field === undefined || field === null) { continue; }
 
             if (field.__type === "proxy" || field.__type === "prefetch_proxy") {
                 ids.push(field.fieldId);
             } else if (field.__type === "script" || field.__type === "computed") {
-                if (field.captures) {
-                    ids.push(field.captures.fieldId);
-                }
+                field.captures && ids.push(field.captures.fieldId);
             } else if (field.__type === "list") {
                 ids.push(...fn(field));
             } else if (typeof field === "string") {
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 55ceab9fb..0b9e999ac 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -139,13 +139,9 @@ export default class UploadManager extends ApiManager {
                         doc.id = getId(doc.id);
                     }
                     for (const key in doc.fields) {
-                        if (!doc.fields.hasOwnProperty(key)) {
-                            continue;
-                        }
+                        if (!doc.fields.hasOwnProperty(key)) { continue; }
                         const field = doc.fields[key];
-                        if (field === undefined || field === null) {
-                            continue;
-                        }
+                        if (field === undefined || field === null) { continue; }
 
                         if (field.__type === "proxy" || field.__type === "prefetch_proxy") {
                             field.fieldId = getId(field.fieldId);
@@ -208,11 +204,7 @@ export default class UploadManager extends ApiManager {
                                 } catch (e) { console.log(e); }
                                 unlink(path_2, () => { });
                             }
-                            if (id) {
-                                res.send(JSON.stringify(getId(id)));
-                            } else {
-                                res.send(JSON.stringify("error"));
-                            }
+                            res.send(JSON.stringify(id ? getId(id) : "error"));
                         } catch (e) { console.log(e); }
                         resolve();
                     });
-- 
cgit v1.2.3-70-g09d2

