From e7372931b9d28c141aaec9552041b5644c2f415a Mon Sep 17 00:00:00 2001
From: geireann <60007097+geireann@users.noreply.github.com>
Date: Fri, 26 Jun 2020 03:37:08 +0800
Subject: Merge branch 'master' into mobile_revision_direct

And changes to UI of record and image upload
---
 src/client/views/MainView.tsx | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 97953452d..4e2c067ac 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -5,7 +5,7 @@ import {
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     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,
-    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft
+    faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft, faSortAmountDown
 } from '@fortawesome/free-solid-svg-icons';
 import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -55,6 +55,9 @@ import { TimelineMenu } from './animationtimeline/TimelineMenu';
 import { SnappingManager } from '../util/SnappingManager';
 import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 import { DocumentManager } from '../util/DocumentManager';
+import { DocumentLinksButton } from './nodes/DocumentLinksButton';
+import { LinkMenu } from './linking/LinkMenu';
+import { LinkDocPreview } from './nodes/LinkDocPreview';
 
 @observer
 export class MainView extends React.Component {
@@ -135,7 +138,7 @@ export class MainView extends React.Component {
             faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
             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, faQuoteLeft);
+            faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faQuoteLeft, faSortAmountDown);
         this.initEventListeners();
         this.initAuthenticationRouters();
     }
@@ -578,6 +581,10 @@ export class MainView extends React.Component {
                 {this.mainContent}
             </GestureOverlay>
             <PreviewCursor />
+            {DocumentLinksButton.EditLink ? <LinkMenu location={DocumentLinksButton.EditLinkLoc} docView={DocumentLinksButton.EditLink} addDocTab={DocumentLinksButton.EditLink.props.addDocTab} changeFlyout={emptyFunction} /> : (null)}
+            {LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} backgroundColor={this.defaultBackgroundColors}
+                linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href}
+                addDocTab={LinkDocPreview.LinkInfo.addDocTab} /> : (null)}
             <ContextMenu />
             <RadialMenu />
             <PDFMenu />
-- 
cgit v1.2.3-70-g09d2


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

---
 package-lock.json                                  |  10 ++
 package.json                                       |   1 +
 src/client/views/MainView.tsx                      |  56 +++++-----
 src/client/views/linking/LinkMenu.tsx              |   3 +-
 .../formattedText/FormattedTextBoxComment.tsx      | 120 ++++++++++++++++-----
 5 files changed, 133 insertions(+), 57 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/package-lock.json b/package-lock.json
index 53b2fc009..9118cd4b0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -853,6 +853,16 @@
                 "@types/prosemirror-view": "*"
             }
         },
+        "@types/prosemirror-dev-tools": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-dev-tools/-/prosemirror-dev-tools-2.1.0.tgz",
+            "integrity": "sha512-OhnSaC4yrrEMLPRUkEWcHAIPVqgKlLkE4kISqL3cHeAYxASouSPvPMLqhBIbWkGwaozy43DjjVC1OXkxTo+y5Q==",
+            "dev": true,
+            "requires": {
+                "@types/prosemirror-state": "*",
+                "@types/prosemirror-view": "*"
+            }
+        },
         "@types/prosemirror-history": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/@types/prosemirror-history/-/prosemirror-history-1.0.1.tgz",
diff --git a/package.json b/package.json
index 8f67704cb..765002d37 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
         "@types/passport-local": "^1.0.33",
         "@types/pdfjs-dist": "^2.1.4",
         "@types/prosemirror-commands": "^1.0.1",
+        "@types/prosemirror-dev-tools": "^2.1.0",
         "@types/prosemirror-history": "^1.0.1",
         "@types/prosemirror-inputrules": "^1.0.2",
         "@types/prosemirror-keymap": "^1.0.2",
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index cea664543..daf26cfd7 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 _urlState: HistoryUtil.DocUrl;
+    private static _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(this.userDoc?.activeWorkspace, Doc, null)?.darkScheme); }
+    private get darkScheme() { return BoolCast(Cast(MainView.userDoc?.activeWorkspace, Doc, null)?.darkScheme); }
 
-    @computed private get userDoc() { return Doc.UserDoc(); }
-    @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; }
+    @computed private static get userDoc() { return Doc.UserDoc(); }
+    @computed private get mainContainer() { return MainView.userDoc ? FieldValue(Cast(MainView.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(this.userDoc["tabs-buttons"], Doc) as Doc; }
+    @computed public get sidebarButtonsDoc() { return Cast(MainView.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;
-        this._urlState = HistoryUtil.parseUrl(window.location) || {} as any;
+        MainView._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 (!this.userDoc) {
+                    if (!MainView.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 && !this.userDoc) {
+        if (received && !MainView.userDoc) {
             reaction(
                 () => CurrentUserUtils.GuestTarget,
                 target => target && this.createNewWorkspace(),
                 { fireImmediately: true }
             );
         } else {
-            if (received && this._urlState.sharing) {
+            if (received && MainView._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,9 +188,9 @@ export class MainView extends React.Component {
                     }),
                 );
             }
-            const doc = this.userDoc && await Cast(this.userDoc.activeWorkspace, Doc);
+            const doc = MainView.userDoc && await Cast(MainView.userDoc.activeWorkspace, Doc);
             if (doc) {
-                this.openWorkspace(doc);
+                MainView.openWorkspace(doc);
             } else {
                 this.createNewWorkspace();
             }
@@ -199,7 +199,7 @@ export class MainView extends React.Component {
 
     @action
     createNewWorkspace = async (id?: string) => {
-        const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc;
+        const workspaces = Cast(MainView.userDoc.myWorkspaces, Doc) as Doc;
         const workspaceCount = DocListCast(workspaces.data).length + 1;
         const freeformOptions: DocumentOptions = {
             x: 0,
@@ -219,19 +219,19 @@ export class MainView extends React.Component {
 
         Doc.AddDocToList(workspaces, "data", workspaceDoc);
         // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
-        setTimeout(() => this.openWorkspace(workspaceDoc), 0);
+        setTimeout(() => MainView.openWorkspace(workspaceDoc), 0);
     }
 
     @action
-    openWorkspace = (doc: Doc, fromHistory = false) => {
+    static openWorkspace = (doc: Doc, fromHistory = false) => {
         CurrentUserUtils.MainDocId = doc[Id];
 
         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" })]));
-            this.userDoc ? (this.userDoc.activeWorkspace = doc) : (CurrentUserUtils.GuestWorkspace = doc);
+            MainView.userDoc ? (MainView.userDoc.activeWorkspace = doc) : (CurrentUserUtils.GuestWorkspace = doc);
         }
-        const state = this._urlState;
-        if (state.sharing === true && !this.userDoc) {
+        const state = MainView._urlState;
+        if (state.sharing === true && !MainView.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 = this.userDoc && await Cast(this.userDoc.rightSidebarCollection, Doc);
+            const col = MainView.userDoc && await Cast(MainView.userDoc.rightSidebarCollection, Doc);
             col && Cast(col.data, listSpec(Doc)) && runInAction(() => MainViewNotifs.NotifsCol = col);
         }, 100);
         return true;
@@ -305,7 +305,7 @@ export class MainView extends React.Component {
             DataDoc={undefined}
             LibraryPath={emptyPath}
             addDocument={undefined}
-            addDocTab={this.addDocTabFunc}
+            addDocTab={MainView.addDocTabFunc}
             pinToPres={emptyFunction}
             rootSelected={returnTrue}
             onClick={undefined}
@@ -378,15 +378,15 @@ export class MainView extends React.Component {
         document.removeEventListener("pointerup", this.onPointerUp);
     }
     flyoutWidthFunc = () => this.flyoutWidth;
-    addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => {
+    static addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => {
         return where === "close" ? CollectionDockingView.CloseRightSplit(doc) :
-            doc.dockingConfig ? this.openWorkspace(doc) :
+            doc.dockingConfig ? MainView.openWorkspace(doc) :
                 CollectionDockingView.AddRightSplit(doc, libraryPath);
     }
     mainContainerXf = () => new Transform(0, -this._buttonBarHeight, 1);
 
     @computed get flyout() {
-        const sidebarContent = this.userDoc?.["tabs-panelContainer"];
+        const sidebarContent = MainView.userDoc?.["tabs-panelContainer"];
         if (!(sidebarContent instanceof Doc)) {
             return (null);
         }
@@ -398,7 +398,7 @@ export class MainView extends React.Component {
                     LibraryPath={emptyPath}
                     addDocument={undefined}
                     rootSelected={returnTrue}
-                    addDocTab={this.addDocTabFunc}
+                    addDocTab={MainView.addDocTabFunc}
                     pinToPres={emptyFunction}
                     removeDocument={undefined}
                     onClick={undefined}
@@ -424,7 +424,7 @@ export class MainView extends React.Component {
                     DataDoc={undefined}
                     LibraryPath={emptyPath}
                     addDocument={undefined}
-                    addDocTab={this.addDocTabFunc}
+                    addDocTab={MainView.addDocTabFunc}
                     pinToPres={emptyFunction}
                     NativeHeight={returnZero}
                     NativeWidth={returnZero}
@@ -458,8 +458,8 @@ export class MainView extends React.Component {
     }
 
     @computed get mainContent() {
-        const sidebar = this.userDoc?.["tabs-panelContainer"];
-        return !this.userDoc || !(sidebar instanceof Doc) ? (null) : (
+        const sidebar = MainView.userDoc?.["tabs-panelContainer"];
+        return !MainView.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%"
@@ -530,7 +530,7 @@ export class MainView extends React.Component {
                     moveDocument={this.moveButtonDoc}
                     CollectionView={undefined}
                     addDocument={this.addButtonDoc}
-                    addDocTab={this.addDocTabFunc}
+                    addDocTab={MainView.addDocTabFunc}
                     pinToPres={emptyFunction}
                     removeDocument={this.remButtonDoc}
                     onClick={undefined}
@@ -627,5 +627,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(() => MainView.Instance.openWorkspace(copiedWorkspace), 0);
+    setTimeout(() => MainView.openWorkspace(copiedWorkspace), 0);
 });
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 6b24f96b1..9fd2b98b1 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -74,7 +74,8 @@ export class LinkMenu extends React.Component<Props> {
     render() {
         const sourceDoc = this.props.docView.props.Document;
         const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc);
-        return <div className="linkMenu-list" ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}>
+        return <div className="linkMenu-list"
+            ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}>
             {!this._editingLink ?
                 this.renderAllGroups(groups) :
                 <LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink} showLinks={action(() => this._editingLink = undefined)} />
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 c51056c7da718a7c0f98f54953f2d7fc287ecf9d Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 1 Jul 2020 11:33:52 -0500
Subject: mainview work

---
 src/client/views/MainView.tsx | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index da76bed11..9328198d0 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -190,7 +190,7 @@ export class MainView extends React.Component {
             }
             const doc = MainView.userDoc && await Cast(MainView.userDoc.activeWorkspace, Doc);
             if (doc) {
-                MainView.openWorkspace(doc);
+                this.openWorkspace(doc);
             } else {
                 this.createNewWorkspace();
             }
@@ -219,11 +219,11 @@ export class MainView extends React.Component {
 
         Doc.AddDocToList(workspaces, "data", workspaceDoc);
         // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
-        setTimeout(() => MainView.openWorkspace(workspaceDoc), 0);
+        setTimeout(() => this.openWorkspace(workspaceDoc), 0);
     }
 
     @action
-    static openWorkspace = (doc: Doc, fromHistory = false) => {
+    openWorkspace = (doc: Doc, fromHistory = false) => {
         CurrentUserUtils.MainDocId = doc[Id];
 
         if (doc) {  // this has the side-effect of setting the main container since we're assigning the active/guest workspace
@@ -305,7 +305,7 @@ export class MainView extends React.Component {
             DataDoc={undefined}
             LibraryPath={emptyPath}
             addDocument={undefined}
-            addDocTab={MainView.addDocTabFunc}
+            addDocTab={this.addDocTabFunc}
             pinToPres={emptyFunction}
             rootSelected={returnTrue}
             onClick={undefined}
@@ -378,9 +378,9 @@ export class MainView extends React.Component {
         document.removeEventListener("pointerup", this.onPointerUp);
     }
     flyoutWidthFunc = () => this.flyoutWidth;
-    static addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => {
+    addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => {
         return where === "close" ? CollectionDockingView.CloseRightSplit(doc) :
-            doc.dockingConfig ? MainView.openWorkspace(doc) :
+            doc.dockingConfig ? this.openWorkspace(doc) :
                 CollectionDockingView.AddRightSplit(doc, libraryPath);
     }
     sidebarScreenToLocal = () => new Transform(0, RichTextMenu.Instance.Pinned ? -35 : 0, 1);
@@ -399,7 +399,7 @@ export class MainView extends React.Component {
                     LibraryPath={emptyPath}
                     addDocument={undefined}
                     rootSelected={returnTrue}
-                    addDocTab={MainView.addDocTabFunc}
+                    addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
                     removeDocument={undefined}
                     onClick={undefined}
@@ -425,7 +425,7 @@ export class MainView extends React.Component {
                     DataDoc={undefined}
                     LibraryPath={emptyPath}
                     addDocument={undefined}
-                    addDocTab={MainView.addDocTabFunc}
+                    addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
                     NativeHeight={returnZero}
                     NativeWidth={returnZero}
@@ -531,7 +531,7 @@ export class MainView extends React.Component {
                     moveDocument={this.moveButtonDoc}
                     CollectionView={undefined}
                     addDocument={this.addButtonDoc}
-                    addDocTab={MainView.addDocTabFunc}
+                    addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
                     removeDocument={this.remButtonDoc}
                     onClick={undefined}
@@ -628,5 +628,7 @@ 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(() => MainView.openWorkspace(copiedWorkspace), 0);
+
+
+    // setTimeout(() => .openWorkspace(copiedWorkspace), 0);
 });
-- 
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/MainView.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 24ac6997048932c4f2717651e992f744e6a5276a Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 1 Jul 2020 17:42:38 -0500
Subject: started clicking mode popup

---
 src/client/views/MainView.tsx                      |  4 +--
 .../views/collections/CollectionLinearView.scss    | 42 +++++++++++++++-------
 .../views/collections/CollectionLinearView.tsx     | 25 ++++++++++++-
 src/client/views/linking/LinkMenu.tsx              |  6 ++--
 src/client/views/linking/LinkMenuItem.tsx          |  3 +-
 src/client/views/nodes/DocumentLinksButton.tsx     | 31 +++++++++++++---
 src/client/views/nodes/DocumentView.tsx            |  1 +
 .../views/nodes/formattedText/FormattedTextBox.tsx | 36 +++++++++++++++++++
 8 files changed, 124 insertions(+), 24 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index f6db1af66..662232810 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -4,7 +4,7 @@ import {
     faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
     faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
     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,
+    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
 } from '@fortawesome/free-solid-svg-icons';
 import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
@@ -138,7 +138,7 @@ export class MainView extends React.Component {
         }
 
         library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
-            faTerminal, faToggleOn, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard, fileSolid,
+            faTerminal, faToggleOn, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faTimesCircle, faWindowMaximize, faAddressCard, fileSolid,
             faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
             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,
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss
index 123a27deb..90c96e08b 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/CollectionLinearView.scss
@@ -1,12 +1,27 @@
 @import "../globalCssVariables";
 @import "../_nodeModuleOverrides";
 
-.collectionLinearView-outer{
+.collectionLinearView-outer {
     overflow: hidden;
-    height:100%;
+    height: 100%;
+
     .collectionLinearView {
-        display:flex;
+        display: flex;
         height: 100%;
+
+        >span {
+            margin-top: "auto";
+            margin-bottom: "auto";
+            background: $dark-color;
+            color: $light-color;
+            display: inline-block;
+            border-radius: 18px;
+            margin-top: auto;
+            margin-bottom: auto;
+            margin-right: 3px;
+            cursor: pointer;
+        }
+
         >label {
             margin-top: "auto";
             margin-bottom: "auto";
@@ -17,15 +32,15 @@
             font-size: 12.5px;
             width: 18px;
             height: 18px;
-            margin-top:auto;
-            margin-bottom:auto;
+            margin-top: auto;
+            margin-bottom: auto;
             margin-right: 3px;
             cursor: pointer;
             transition: transform 0.2s;
         }
 
         label p {
-            padding-left:5px;
+            padding-left: 5px;
         }
 
         label:hover {
@@ -36,13 +51,14 @@
         >input {
             display: none;
         }
+
         >input:not(:checked)~.collectionLinearView-content {
             display: none;
         }
 
         >input:checked~label {
             transform: rotate(45deg);
-            transition: transform 0.5s;
+transition: transform 0.5s;
             cursor: pointer;
         }
 
@@ -52,12 +68,14 @@
             position: relative;
             margin-top: auto;
 
-            .collectionLinearView-docBtn, .collectionLinearView-docBtn-scalable {
-                position:relative;
-                margin:auto;
+            .collectionLinearView-docBtn,
+            .collectionLinearView-docBtn-scalable {
+                position: relative;
+                margin: auto;
                 margin-left: 3px;
                 transform-origin: center 80%;
             }
+
             .collectionLinearView-docBtn-scalable:hover {
                 transform: scale(1.15);
             }
@@ -68,10 +86,10 @@
                 border-radius: 18px;
                 font-size: 15px;
             }
-            
+
             .collectionLinearView-round-button:hover {
                 transform: scale(1.15);
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index f38eeaf41..29deb906a 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -13,6 +13,8 @@ import { CollectionSubView } from './CollectionSubView';
 import { DocumentView } from '../nodes/DocumentView';
 import { documentSchema } from '../../../fields/documentSchemas';
 import { Id } from '../../../fields/FieldSymbols';
+import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 
 
 type LinearDocument = makeInterface<[typeof documentSchema,]>;
@@ -75,6 +77,11 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
         return new Transform(-translateX, -translateY, 1);
     }
 
+    @action
+    exitLongLinks = () => {
+        DocumentLinksButton.StartLink = undefined
+    }
+
     render() {
         const guid = Utils.GenerateGuid();
         const flexDir: any = StrCast(this.Document.flexDirection);
@@ -82,7 +89,12 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
         const color = StrCast(this.props.Document.color, "white");
         return <div className="collectionLinearView-outer">
             <div className="collectionLinearView" ref={this.createDashEventsTarget} >
-                <label htmlFor={`${guid}`} title="Close Menu" style={{ background: backgroundColor === color ? "black" : backgroundColor }}
+                <label htmlFor={`${guid}`} title="Close Menu" style={{
+                    background: backgroundColor === color ? "black" : backgroundColor,
+                    // width: "18px", height: "18px", fontSize: "12.5px",
+                    // transition: this.props.Document.linearViewIsExpanded ? "transform 0.2s" : "transform 0.5s",
+                    // transform: this.props.Document.linearViewIsExpanded ? "" : "rotate(45deg)"
+                }}
                     onPointerDown={e => e.stopPropagation()} >
                     <p>+</p>
                 </label>
@@ -130,6 +142,17 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                         </div>;
                     })}
                 </div>
+                {DocumentLinksButton.StartLink ? <span style={{
+                    background: backgroundColor === color ? "black" : backgroundColor,
+                }}
+                    onPointerDown={e => e.stopPropagation()} >
+                    <span style={{ fontSize: "7px", display: "inline-block" }}>
+                        Creating Link From: {DocumentLinksButton.StartLink.title} </span>
+
+                    <FontAwesomeIcon icon="times-circle" size="lg" style={{ color: "red" }}
+                        onClick={this.exitLongLinks} />
+
+                </span> : null}
             </div>
         </div>;
     }
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 2a9bbed39..c36e7b67c 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -32,9 +32,9 @@ export class LinkMenu extends React.Component<Props> {
             DocumentLinksButton.EditLink = undefined;
         }
 
-        // if (this._linkMenuRef && !this._linkMenuRef.contains(e.target)) {
-        //     DocumentLinksButton.EditLink = undefined;
-        // }
+        if (this._linkMenuRef && !this._linkMenuRef.contains(e.target as any)) {
+            DocumentLinksButton.EditLink = undefined;
+        }
     }
     @action
     componentDidMount() {
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index d5d31d1ba..54dca261d 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -137,6 +137,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
 
     @action.bound
     async followDefault() {
+        console.log("FOLLOWWW");
         DocumentLinksButton.EditLink = undefined;
         LinkDocPreview.LinkInfo = undefined;
         DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false);
@@ -174,7 +175,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                             {/* <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" ref={this._editRef} onPointerDown={this.deleteLink}>
                                 <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
-                            <div title="Follow link" className="button" onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+                            <div title="Follow link" className="button" onClick={e => 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 c625c4cd6..d04cdd34c 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -24,6 +24,8 @@ interface DocumentLinksButtonProps {
 export class DocumentLinksButton extends React.Component<DocumentLinksButtonProps, {}> {
     private _linkButton = React.createRef<HTMLDivElement>();
 
+    @observable public static StartLink: DocumentView | undefined;
+
     @action
     onLinkButtonMoved = (e: PointerEvent) => {
         if (this._linkButton.current !== null) {
@@ -51,11 +53,9 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
         return false;
     }
 
-    @observable static StartLink: DocumentView | undefined;
     onLinkButtonDown = (e: React.PointerEvent): void => {
-
         setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => {
-            if (doubleTap) {
+            if (doubleTap && this.props.InMenu) {
                 DocumentLinksButton.StartLink = this.props.View;
             } else if (!!!this.props.InMenu) {
                 DocumentLinksButton.EditLink = this.props.View;
@@ -63,6 +63,17 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
             }
         }));
     }
+
+    @action
+    onLinkClick = (e: React.MouseEvent): void => {
+        if (this.props.InMenu) {
+            DocumentLinksButton.StartLink = this.props.View;
+        } else if (!!!this.props.InMenu) {
+            DocumentLinksButton.EditLink = this.props.View;
+            DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY];
+        }
+    }
+
     completeLink = (e: React.PointerEvent): void => {
         setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => {
             if (doubleTap) {
@@ -76,6 +87,15 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
         }));
     }
 
+    finishLinkClick = () => {
+        if (DocumentLinksButton.StartLink === this.props.View) {
+            DocumentLinksButton.StartLink = undefined;
+        } else {
+            DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
+                DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
+        }
+    }
+
     @observable
     public static EditLink: DocumentView | undefined;
     public static EditLinkLoc: number[] = [0, 0];
@@ -86,7 +106,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
         return (!links.length || links[0].hidden) && !this.props.AlwaysOn ? (null) :
             <div title="Drag(create link) Tap(view links)" ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
                 <div className={"documentLinksButton"} style={{ backgroundColor: DocumentLinksButton.StartLink ? "transparent" : "" }}
-                    onPointerDown={this.onLinkButtonDown}
+                    onPointerDown={this.onLinkButtonDown} onClick={this.onLinkClick}
                 // onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
                 // onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = {
                 //     addDocTab: this.props.View.props.addDocTab,
@@ -97,7 +117,8 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                 >
                     {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"} onPointerDown={this.completeLink} /> : (null)}
+                {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"}
+                    onPointerDown={this.completeLink} onClick={this.finishLinkClick} /> : (null)}
                 {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"} /> : (null)}
             </div>;
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 09eeaee36..6820b2047 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -116,6 +116,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
     private holdDisposer?: InteractionUtils.MultiTouchEventDisposer;
 
+    public get title() { return this.props.Document.title }
     public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
     public get ContentDiv() { return this._mainCont.current; }
     get active() { return SelectionManager.IsSelected(this, true) || this.props.parentActive(true); }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 2a79e2f13..dc7d8c7ca 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -58,6 +58,7 @@ import { FieldView, FieldViewProps } from "../FieldView";
 import "./FormattedTextBox.scss";
 import { FormattedTextBoxComment, formattedTextBoxCommentPlugin } from './FormattedTextBoxComment';
 import React = require("react");
+import { DocumentManager } from '../../../util/DocumentManager';
 
 library.add(faEdit);
 library.add(faSmile, faTextHeight, faUpload);
@@ -1047,6 +1048,40 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         }
     }
 
+    @action
+    onDoubleClick = (e: React.MouseEvent): void => {
+
+        this.doLinkOnDeselect();
+        FormattedTextBox._downEvent = true;
+        FormattedTextBoxComment.textBox = this;
+        if (this.props.onClick && e.button === 0 && !this.props.isSelected(false)) {
+            e.preventDefault();
+        }
+        if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
+            if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar
+                e.stopPropagation();  // if the text box is selected, then it consumes all down events
+            }
+        }
+        if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
+            e.preventDefault();
+        }
+        FormattedTextBoxComment.Hide();
+        if (FormattedTextBoxComment.linkDoc) {
+            if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+                this.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+            } else {
+                DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, this.props.Document,
+                    (doc: Doc, followLinkLocation: string) => this.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+            }
+        }
+
+        (e.nativeEvent as any).formattedHandled = true;
+
+        if (e.buttons === 1 && this.props.isSelected(true) && !e.altKey) {
+            e.stopPropagation();
+        }
+    }
+
     @action
     onFocused = (e: React.FocusEvent): void => {
         console.log("FOUCSS")
@@ -1317,6 +1352,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                             }
                         }
                     })}
+                    onDoubleClick={this.onDoubleClick}
                 >
                     <div className={`formattedTextBox-outer`} ref={this._scrollRef}
                         style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.isSelected() ? "none" : undefined }}
-- 
cgit v1.2.3-70-g09d2


From 96001ff5b299326de8742a6540acd5017d0f751a Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Thu, 2 Jul 2020 10:40:17 -0500
Subject: started link created popup, tried hihglighting source

---
 package-lock.json                                  | 331 ++++++++++++++++++++-
 package.json                                       |   2 +
 src/client/documents/Documents.ts                  |   9 +-
 src/client/views/GlobalKeyHandler.ts               |   8 +
 src/client/views/MainView.tsx                      |  17 ++
 .../views/collections/CollectionLinearView.scss    |   2 +-
 .../views/collections/CollectionLinearView.tsx     |  17 +-
 src/client/views/nodes/DocumentLinksButton.tsx     |   9 +
 src/client/views/nodes/DocumentView.tsx            |   7 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   4 +-
 src/fields/Doc.ts                                  |   2 +
 11 files changed, 398 insertions(+), 10 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/package-lock.json b/package-lock.json
index d42e286e2..ad181758c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -372,6 +372,101 @@
             "resolved": "https://registry.npmjs.org/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz",
             "integrity": "sha512-6SJfx949YEWooh/CUPpJ+F491y4BYJmknz4hUN1+RHvKoUEynKbRmhnwbk/VLmh4OthLLDNCyWXfbh4DG1cTXA=="
         },
+        "@material-ui/core": {
+            "version": "4.11.0",
+            "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.0.tgz",
+            "integrity": "sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g==",
+            "requires": {
+                "@babel/runtime": "^7.4.4",
+                "@material-ui/styles": "^4.10.0",
+                "@material-ui/system": "^4.9.14",
+                "@material-ui/types": "^5.1.0",
+                "@material-ui/utils": "^4.10.2",
+                "@types/react-transition-group": "^4.2.0",
+                "clsx": "^1.0.4",
+                "hoist-non-react-statics": "^3.3.2",
+                "popper.js": "1.16.1-lts",
+                "prop-types": "^15.7.2",
+                "react-is": "^16.8.0",
+                "react-transition-group": "^4.4.0"
+            },
+            "dependencies": {
+                "dom-helpers": {
+                    "version": "5.1.4",
+                    "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
+                    "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
+                    "requires": {
+                        "@babel/runtime": "^7.8.7",
+                        "csstype": "^2.6.7"
+                    }
+                },
+                "popper.js": {
+                    "version": "1.16.1-lts",
+                    "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
+                    "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
+                },
+                "react-transition-group": {
+                    "version": "4.4.1",
+                    "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
+                    "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
+                    "requires": {
+                        "@babel/runtime": "^7.5.5",
+                        "dom-helpers": "^5.0.1",
+                        "loose-envify": "^1.4.0",
+                        "prop-types": "^15.6.2"
+                    }
+                }
+            }
+        },
+        "@material-ui/styles": {
+            "version": "4.10.0",
+            "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz",
+            "integrity": "sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==",
+            "requires": {
+                "@babel/runtime": "^7.4.4",
+                "@emotion/hash": "^0.8.0",
+                "@material-ui/types": "^5.1.0",
+                "@material-ui/utils": "^4.9.6",
+                "clsx": "^1.0.4",
+                "csstype": "^2.5.2",
+                "hoist-non-react-statics": "^3.3.2",
+                "jss": "^10.0.3",
+                "jss-plugin-camel-case": "^10.0.3",
+                "jss-plugin-default-unit": "^10.0.3",
+                "jss-plugin-global": "^10.0.3",
+                "jss-plugin-nested": "^10.0.3",
+                "jss-plugin-props-sort": "^10.0.3",
+                "jss-plugin-rule-value-function": "^10.0.3",
+                "jss-plugin-vendor-prefixer": "^10.0.3",
+                "prop-types": "^15.7.2"
+            }
+        },
+        "@material-ui/system": {
+            "version": "4.9.14",
+            "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz",
+            "integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==",
+            "requires": {
+                "@babel/runtime": "^7.4.4",
+                "@material-ui/utils": "^4.9.6",
+                "csstype": "^2.5.2",
+                "prop-types": "^15.7.2"
+            }
+        },
+        "@material-ui/types": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
+            "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A=="
+        },
+        "@material-ui/utils": {
+            "version": "4.10.2",
+            "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz",
+            "integrity": "sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw==",
+            "requires": {
+                "@babel/runtime": "^7.4.4",
+                "prop-types": "^15.7.2",
+                "react-is": "^16.8.0"
+            }
+        },
         "@rkusa/linebreak": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/@rkusa/linebreak/-/linebreak-1.0.0.tgz",
@@ -1075,7 +1170,6 @@
             "version": "4.4.0",
             "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz",
             "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==",
-            "dev": true,
             "requires": {
                 "@types/react": "*"
             }
@@ -2478,6 +2572,11 @@
             "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz",
             "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA=="
         },
+        "bowser": {
+            "version": "1.9.4",
+            "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz",
+            "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ=="
+        },
         "boxen": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
@@ -2878,6 +2977,11 @@
                 "type-detect": "^4.0.5"
             }
         },
+        "chain-function": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.1.tgz",
+            "integrity": "sha512-SxltgMwL9uCko5/ZCLiyG2B7R9fY4pDZUw7hJ4MhirdjBLosoDqkWABi3XMucddHdLiFJMb7PD2MZifZriuMTg=="
+        },
         "chalk": {
             "version": "2.4.2",
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -2888,6 +2992,11 @@
                 "supports-color": "^5.3.0"
             }
         },
+        "change-emitter": {
+            "version": "0.1.6",
+            "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz",
+            "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU="
+        },
         "character-parser": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
@@ -3614,6 +3723,11 @@
                 "shallow-clone": "^3.0.0"
             }
         },
+        "clsx": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
+            "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
+        },
         "code-point-at": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@@ -4263,6 +4377,15 @@
             "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
             "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
         },
+        "css-in-js-utils": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz",
+            "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==",
+            "requires": {
+                "hyphenate-style-name": "^1.0.2",
+                "isobject": "^3.0.1"
+            }
+        },
         "css-loader": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz",
@@ -4317,6 +4440,15 @@
                 }
             }
         },
+        "css-vendor": {
+            "version": "2.0.8",
+            "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
+            "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
+            "requires": {
+                "@babel/runtime": "^7.8.3",
+                "is-in-browser": "^1.0.2"
+            }
+        },
         "css-what": {
             "version": "2.1.3",
             "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
@@ -7032,6 +7164,11 @@
                 }
             }
         },
+        "hyphenate-style-name": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz",
+            "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ=="
+        },
         "i": {
             "version": "0.3.6",
             "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz",
@@ -7247,6 +7384,15 @@
             "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
             "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
         },
+        "inline-style-prefixer": {
+            "version": "3.0.8",
+            "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz",
+            "integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=",
+            "requires": {
+                "bowser": "^1.7.3",
+                "css-in-js-utils": "^2.0.0"
+            }
+        },
         "inspect-function": {
             "version": "0.2.2",
             "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz",
@@ -7555,6 +7701,11 @@
                 "is-extglob": "^2.1.1"
             }
         },
+        "is-in-browser": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
+            "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
+        },
         "is-installed-globally": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
@@ -7922,6 +8073,84 @@
                 "verror": "1.10.0"
             }
         },
+        "jss": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss/-/jss-10.3.0.tgz",
+            "integrity": "sha512-B5sTRW9B6uHaUVzSo9YiMEOEp3UX8lWevU0Fsv+xtRnsShmgCfIYX44bTH8bPJe6LQKqEXku3ulKuHLbxBS97Q==",
+            "requires": {
+                "@babel/runtime": "^7.3.1",
+                "csstype": "^2.6.5",
+                "is-in-browser": "^1.1.3",
+                "tiny-warning": "^1.0.2"
+            }
+        },
+        "jss-plugin-camel-case": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.3.0.tgz",
+            "integrity": "sha512-tadWRi/SLWqLK3EUZEdDNJL71F3ST93Zrl9JYMjV0QDqKPAl0Liue81q7m/nFUpnSTXczbKDy4wq8rI8o7WFqA==",
+            "requires": {
+                "@babel/runtime": "^7.3.1",
+                "hyphenate-style-name": "^1.0.3",
+                "jss": "^10.3.0"
+            }
+        },
+        "jss-plugin-default-unit": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.3.0.tgz",
+            "integrity": "sha512-tT5KkIXAsZOSS9WDSe8m8lEHIjoEOj4Pr0WrG0WZZsMXZ1mVLFCSsD2jdWarQWDaRNyMj/I4d7czRRObhOxSuw==",
+            "requires": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0"
+            }
+        },
+        "jss-plugin-global": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.3.0.tgz",
+            "integrity": "sha512-etYTG/y3qIR/vxZnKY+J3wXwObyBDNhBiB3l/EW9/pE3WHE//BZdK8LFvQcrCO48sZW1Z6paHo6klxUPP7WbzA==",
+            "requires": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0"
+            }
+        },
+        "jss-plugin-nested": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.3.0.tgz",
+            "integrity": "sha512-qWiEkoXNEkkZ+FZrWmUGpf+zBsnEOmKXhkjNX85/ZfWhH9dfGxUCKuJFuOWFM+rjQfxV4csfesq4hY0jk8Qt0w==",
+            "requires": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0",
+                "tiny-warning": "^1.0.2"
+            }
+        },
+        "jss-plugin-props-sort": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.3.0.tgz",
+            "integrity": "sha512-boetORqL/lfd7BWeFD3K+IyPqyIC+l3CRrdZr+NPq7Noqp+xyg/0MR7QisgzpxCEulk+j2CRcEUoZsvgPC4nTg==",
+            "requires": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0"
+            }
+        },
+        "jss-plugin-rule-value-function": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.3.0.tgz",
+            "integrity": "sha512-7WiMrKIHH3rwxTuJki9+7nY11r1UXqaUZRhHvqTD4/ZE+SVhvtD5Tx21ivNxotwUSleucA/8boX+NF21oXzr5Q==",
+            "requires": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0",
+                "tiny-warning": "^1.0.2"
+            }
+        },
+        "jss-plugin-vendor-prefixer": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.3.0.tgz",
+            "integrity": "sha512-sZQbrcZyP5V0ADjCLwUA1spVWoaZvM7XZ+2fSeieZFBj31cRsnV7X70FFDerMHeiHAXKWzYek+67nMDjhrZAVQ==",
+            "requires": {
+                "@babel/runtime": "^7.3.1",
+                "css-vendor": "^2.0.8",
+                "jss": "^10.3.0"
+            }
+        },
         "jstransformer": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
@@ -7955,6 +8184,11 @@
             "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
             "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
         },
+        "keycode": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
+            "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
+        },
         "keygrip": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
@@ -8201,6 +8435,11 @@
             "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
             "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
         },
+        "lodash.merge": {
+            "version": "4.6.2",
+            "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+            "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+        },
         "lodash.padend": {
             "version": "4.6.1",
             "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
@@ -8212,6 +8451,11 @@
             "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
             "dev": true
         },
+        "lodash.throttle": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+            "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
+        },
         "lodash.union": {
             "version": "4.6.0",
             "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
@@ -8371,6 +8615,38 @@
             "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
             "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
         },
+        "material-ui": {
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/material-ui/-/material-ui-0.20.2.tgz",
+            "integrity": "sha512-VeqgQkdvtK193w+FFvXDEwlVxI4rWk83eWbpYLeOIHDPWr3rbB9B075JRnJt/8IsI2X8q5Aia5W3+7m4KkleDg==",
+            "requires": {
+                "babel-runtime": "^6.23.0",
+                "inline-style-prefixer": "^3.0.8",
+                "keycode": "^2.1.8",
+                "lodash.merge": "^4.6.0",
+                "lodash.throttle": "^4.1.1",
+                "prop-types": "^15.5.7",
+                "react-event-listener": "^0.6.2",
+                "react-transition-group": "^1.2.1",
+                "recompose": "^0.26.0",
+                "simple-assign": "^0.1.0",
+                "warning": "^3.0.0"
+            },
+            "dependencies": {
+                "react-transition-group": {
+                    "version": "1.2.1",
+                    "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.1.tgz",
+                    "integrity": "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==",
+                    "requires": {
+                        "chain-function": "^1.0.0",
+                        "dom-helpers": "^3.2.0",
+                        "loose-envify": "^1.3.1",
+                        "prop-types": "^15.5.6",
+                        "warning": "^3.0.0"
+                    }
+                }
+            }
+        },
         "md5.js": {
             "version": "1.3.5",
             "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -13888,6 +14164,26 @@
                 "prop-types": "^15.6.0"
             }
         },
+        "react-event-listener": {
+            "version": "0.6.6",
+            "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.6.tgz",
+            "integrity": "sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw==",
+            "requires": {
+                "@babel/runtime": "^7.2.0",
+                "prop-types": "^15.6.0",
+                "warning": "^4.0.1"
+            },
+            "dependencies": {
+                "warning": {
+                    "version": "4.0.3",
+                    "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+                    "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+                    "requires": {
+                        "loose-envify": "^1.0.0"
+                    }
+                }
+            }
+        },
         "react-grid-layout": {
             "version": "0.18.3",
             "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-0.18.3.tgz",
@@ -14224,6 +14520,24 @@
                 "resolve": "^1.1.6"
             }
         },
+        "recompose": {
+            "version": "0.26.0",
+            "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.26.0.tgz",
+            "integrity": "sha512-KwOu6ztO0mN5vy3+zDcc45lgnaUoaQse/a5yLVqtzTK13czSWnFGmXbQVmnoMgDkI5POd1EwIKSbjU1V7xdZog==",
+            "requires": {
+                "change-emitter": "^0.1.2",
+                "fbjs": "^0.8.1",
+                "hoist-non-react-statics": "^2.3.1",
+                "symbol-observable": "^1.0.4"
+            },
+            "dependencies": {
+                "hoist-non-react-statics": {
+                    "version": "2.5.5",
+                    "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
+                    "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
+                }
+            }
+        },
         "redent": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
@@ -14988,6 +15302,11 @@
             "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
             "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
         },
+        "simple-assign": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/simple-assign/-/simple-assign-0.1.0.tgz",
+            "integrity": "sha1-F/0wZqXz13OPUDIbsPFMooHMS6o="
+        },
         "simple-concat": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
@@ -15827,6 +16146,11 @@
                 "has-flag": "^3.0.0"
             }
         },
+        "symbol-observable": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+            "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+        },
         "symbol-tree": {
             "version": "3.2.4",
             "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -16122,6 +16446,11 @@
             "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
             "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
         },
+        "tiny-warning": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
+            "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
+        },
         "tinycolor2": {
             "version": "1.4.1",
             "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
diff --git a/package.json b/package.json
index 5e7598376..75dc817f5 100644
--- a/package.json
+++ b/package.json
@@ -121,6 +121,7 @@
         "@hig/flyout": "^1.2.1",
         "@hig/theme-context": "^2.1.3",
         "@hig/theme-data": "^2.16.1",
+        "@material-ui/core": "^4.11.0",
         "@types/google-maps": "^3.2.2",
         "@types/webscopeio__react-textarea-autocomplete": "^4.6.1",
         "@webscopeio/react-textarea-autocomplete": "^4.7.0",
@@ -172,6 +173,7 @@
         "jsonschema": "^1.2.5",
         "libxmljs": "^0.19.7",
         "lodash": "^4.17.15",
+        "material-ui": "^0.20.2",
         "mobile-detect": "^1.4.4",
         "mobx": "^5.15.3",
         "mobx-react": "^5.3.5",
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 85da621e0..2e0323ede 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,4 +1,4 @@
-import { runInAction } from "mobx";
+import { runInAction, action } from "mobx";
 import { extname, basename } from "path";
 import { DateField } from "../../fields/DateField";
 import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../fields/Doc";
@@ -50,6 +50,7 @@ import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo";
 import { DocumentType } from "./DocumentTypes";
 import { Networking } from "../Network";
 import { Upload } from "../../server/SharedMediaTypes";
+import { MainView } from "../views/MainView";
 const path = require('path');
 
 export interface DocumentOptions {
@@ -866,6 +867,7 @@ export namespace DocUtils {
     export function MakeLinkToActiveAudio(doc: Doc) {
         DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline"));
     }
+
     export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", id?: string) {
         const sv = DocumentManager.Instance.getDocumentView(source.doc);
         if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
@@ -877,6 +879,11 @@ export namespace DocUtils {
 
         Doc.GetProto(source.doc).links = ComputedField.MakeFunction("links(self)");
         Doc.GetProto(target.doc).links = ComputedField.MakeFunction("links(self)");
+
+        runInAction(() => { MainView.linkCreated = true; });
+        console.log("link created");
+        runInAction(() => { setTimeout("MainView.changeLinkCreated()", 2000); });
+
         return linkDoc;
     }
 
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index c85849adb..369d6f4ae 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -79,7 +79,15 @@ export default class KeyManager {
                 // MarqueeView.DragMarquee = !MarqueeView.DragMarquee; // bcz: this needs a better disclosure UI
                 break;
             case "escape":
+                // if (DocumentLinksButton.StartLink) {
+                //     if (DocumentLinksButton.StartLink.Document) {
+                //         action((e: React.PointerEvent<HTMLDivElement>) => {
+                //             Doc.UnBrushDoc(DocumentLinksButton.StartLink?.Document as Doc);
+                //         });
+                //     }
+                // }
                 DocumentLinksButton.StartLink = undefined;
+
                 const main = MainView.Instance;
                 Doc.SetSelectedTool(InkTool.None);
                 var doDeselect = true;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 662232810..4898e114a 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -59,6 +59,7 @@ import { DocumentManager } from '../util/DocumentManager';
 import { DocumentLinksButton } from './nodes/DocumentLinksButton';
 import { LinkMenu } from './linking/LinkMenu';
 import { LinkDocPreview } from './nodes/LinkDocPreview';
+import { Fade } from '@material-ui/core';
 
 @observer
 export class MainView extends React.Component {
@@ -82,6 +83,8 @@ export class MainView extends React.Component {
 
     public isPointerDown = false;
 
+    @observable public static linkCreated: boolean = false;
+
 
     componentDidMount() {
         DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_viewType"]); // can play with these fields on someone else's
@@ -362,6 +365,11 @@ export class MainView extends React.Component {
         }
     }
 
+    @action
+    public static changeLinkCreated = () => {
+        MainView.linkCreated = !MainView.linkCreated;
+    }
+
     @action
     onPointerMove = (e: PointerEvent) => {
         this.flyoutWidth = Math.max(e.clientX, 0);
@@ -606,6 +614,15 @@ export class MainView extends React.Component {
                 {this.mainContent}
             </GestureOverlay>
             <PreviewCursor />
+            {MainView.linkCreated ? <div className="mainView-linkCreated" style={{
+                border: "2px solid red", top: screenTop / 2,
+                left: screenLeft / 2, width: "50px", height: "20px", zIndex: 10000,
+                fontSize: "12px"
+            }}>
+                {/* <Fade in={MainView.linkCreated}> */}
+                link created!
+                {/* </Fade> */}
+            </div> : null}
             {DocumentLinksButton.EditLink ? <LinkMenu location={DocumentLinksButton.EditLinkLoc} docView={DocumentLinksButton.EditLink} addDocTab={DocumentLinksButton.EditLink.props.addDocTab} changeFlyout={emptyFunction} /> : (null)}
             {LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} backgroundColor={this.defaultBackgroundColors}
                 linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href}
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss
index 647ce1b01..134d62d4f 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/CollectionLinearView.scss
@@ -10,6 +10,7 @@
         height: 100%;
 
         >span {
+
             margin-top: 8px;
             margin-left: 4px;
             //margin-bottom: 2px;
@@ -18,7 +19,6 @@
             display: inline-block;
             border-radius: 18px;
             margin-right: 6px;
-            padding: "4px";
             cursor: pointer;
         }
 
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index df8e2c58e..a180991d0 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -79,7 +79,14 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
 
     @action
     exitLongLinks = () => {
-        DocumentLinksButton.StartLink = undefined
+        if (DocumentLinksButton.StartLink) {
+            if (DocumentLinksButton.StartLink.Document) {
+                action((e: React.PointerEvent<HTMLDivElement>) => {
+                    Doc.UnBrushDoc(DocumentLinksButton.StartLink?.Document as Doc);
+                });
+            }
+        }
+        DocumentLinksButton.StartLink = undefined;
     }
 
     render() {
@@ -146,8 +153,12 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                     background: backgroundColor === color ? "black" : backgroundColor,
                 }}
                     onPointerDown={e => e.stopPropagation()} >
-                    <span style={{ fontSize: "12.5px", display: "inline", whiteSpace: "nowrap" }}>
-                        Creating Link From: {DocumentLinksButton.StartLink.title} </span>
+                    <span style={{
+                        fontSize: "12.5px", display: "inline", whiteSpace: "nowrap",
+                        paddingLeft: "8px", paddingRight: "8px", paddingTop: "4px",
+                        paddingBottom: "10px"
+                    }}>
+                        Creating link from: {DocumentLinksButton.StartLink.title} </span>
 
                     <FontAwesomeIcon icon="times-circle" size="lg" style={{ color: "red" }}
                         onClick={this.exitLongLinks} />
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index d04cdd34c..27fbbc7fc 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -10,6 +10,7 @@ import React = require("react");
 import { DocUtils } from "../../documents/Documents";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { LinkDocPreview } from "./LinkDocPreview";
+import { MainView } from "../MainView";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -56,6 +57,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
     onLinkButtonDown = (e: React.PointerEvent): void => {
         setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => {
             if (doubleTap && this.props.InMenu) {
+                //action(() => Doc.BrushDoc(this.props.View.Document));
                 DocumentLinksButton.StartLink = this.props.View;
             } else if (!!!this.props.InMenu) {
                 DocumentLinksButton.EditLink = this.props.View;
@@ -68,6 +70,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
     onLinkClick = (e: React.MouseEvent): void => {
         if (this.props.InMenu) {
             DocumentLinksButton.StartLink = this.props.View;
+            //action(() => Doc.BrushDoc(this.props.View.Document));
         } else if (!!!this.props.InMenu) {
             DocumentLinksButton.EditLink = this.props.View;
             DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY];
@@ -79,6 +82,9 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
             if (doubleTap) {
                 if (DocumentLinksButton.StartLink === this.props.View) {
                     DocumentLinksButton.StartLink = undefined;
+                    // action((e: React.PointerEvent<HTMLDivElement>) => {
+                    //     Doc.UnBrushDoc(this.props.View.Document);
+                    // });
                 } else {
                     DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
                         DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
@@ -90,6 +96,9 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
     finishLinkClick = () => {
         if (DocumentLinksButton.StartLink === this.props.View) {
             DocumentLinksButton.StartLink = undefined;
+            // action((e: React.PointerEvent<HTMLDivElement>) => {
+            //     Doc.UnBrushDoc(this.props.View.Document);
+            // });
         } else {
             DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
                 DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6820b2047..0d7029576 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -116,7 +116,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
     private holdDisposer?: InteractionUtils.MultiTouchEventDisposer;
 
-    public get title() { return this.props.Document.title }
+    public get title() { return this.props.Document.title; }
     public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
     public get ContentDiv() { return this._mainCont.current; }
     get active() { return SelectionManager.IsSelected(this, true) || this.props.parentActive(true); }
@@ -1191,7 +1191,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             id={this.props.Document[Id]}
             ref={this._mainCont} onKeyDown={this.onKeyDown}
             onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
-            onPointerEnter={action(() => Doc.BrushDoc(this.props.Document))}
+            onPointerEnter={action(() => { Doc.BrushDoc(this.props.Document); })}
             onPointerLeave={action((e: React.PointerEvent<HTMLDivElement>) => {
                 let entered = false;
                 const target = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y);
@@ -1200,7 +1200,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                         entered = true;
                     }
                 }
+                // if (this.props.Document !== DocumentLinksButton.StartLink?.Document) {
                 !entered && Doc.UnBrushDoc(this.props.Document);
+                //}
+
             })}
             style={{
                 transformOrigin: this._animateScalingTo ? "center center" : undefined,
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index dc7d8c7ca..276c79453 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1084,7 +1084,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
     @action
     onFocused = (e: React.FocusEvent): void => {
-        console.log("FOUCSS")
+        console.log("FOUCSS");
         FormattedTextBox.FocusedBox = this;
         this.tryUpdateHeight();
 
@@ -1216,7 +1216,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
     public static HadSelection: boolean = false;
     onBlur = (e: any) => {
-        console.log("BLURRR")
+        console.log("BLURRR");
         FormattedTextBox.HadSelection = window.getSelection()?.toString() !== "";
         //DictationManager.Controls.stop(false);
         this.endUndoTypingBatch();
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index e4d11dd4d..8a7b91e49 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -832,12 +832,14 @@ export namespace Doc {
         })(doc);
     }
     export function BrushDoc(doc: Doc) {
+        console.log("brushed");
         if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
         brushManager.BrushedDoc.set(doc, true);
         brushManager.BrushedDoc.set(Doc.GetProto(doc), true);
         return doc;
     }
     export function UnBrushDoc(doc: Doc) {
+        console.log("unbrushed");
         if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
         brushManager.BrushedDoc.delete(doc);
         brushManager.BrushedDoc.delete(Doc.GetProto(doc));
-- 
cgit v1.2.3-70-g09d2


From 37392f606d29547bed46ffcd0f0190ad38f51148 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Fri, 3 Jul 2020 01:06:18 -0500
Subject: link created popup

---
 src/client/documents/Documents.ts                  |  8 ++++----
 src/client/views/MainView.tsx                      | 23 +++++++++++++---------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  5 +++++
 src/client/views/linking/LinkMenu.scss             |  9 ++++-----
 src/client/views/linking/LinkMenu.tsx              |  4 ++++
 src/client/views/linking/LinkMenuItem.tsx          | 11 ++++++++---
 src/client/views/nodes/DocumentLinksButton.tsx     | 14 +++++++++++--
 src/fields/Doc.ts                                  |  4 ++--
 8 files changed, 53 insertions(+), 25 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 2e0323ede..0f434d616 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -868,6 +868,10 @@ export namespace DocUtils {
         DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline"));
     }
 
+    function stopLinkCreated() {
+        MainView.linkCreated = false;
+    }
+
     export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", id?: string) {
         const sv = DocumentManager.Instance.getDocumentView(source.doc);
         if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
@@ -880,10 +884,6 @@ export namespace DocUtils {
         Doc.GetProto(source.doc).links = ComputedField.MakeFunction("links(self)");
         Doc.GetProto(target.doc).links = ComputedField.MakeFunction("links(self)");
 
-        runInAction(() => { MainView.linkCreated = true; });
-        console.log("link created");
-        runInAction(() => { setTimeout("MainView.changeLinkCreated()", 2000); });
-
         return linkDoc;
     }
 
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 4898e114a..617cc19b1 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -84,6 +84,8 @@ export class MainView extends React.Component {
     public isPointerDown = false;
 
     @observable public static linkCreated: boolean = false;
+    @observable public static popupX: number = 600;
+    @observable public static popupY: number = 250;
 
 
     componentDidMount() {
@@ -614,15 +616,18 @@ export class MainView extends React.Component {
                 {this.mainContent}
             </GestureOverlay>
             <PreviewCursor />
-            {MainView.linkCreated ? <div className="mainView-linkCreated" style={{
-                border: "2px solid red", top: screenTop / 2,
-                left: screenLeft / 2, width: "50px", height: "20px", zIndex: 10000,
-                fontSize: "12px"
-            }}>
-                {/* <Fade in={MainView.linkCreated}> */}
-                link created!
-                {/* </Fade> */}
-            </div> : null}
+
+            <Fade in={MainView.linkCreated}>
+                <div style={{
+                    border: "1px solid rgb(111, 144, 175)", top: MainView.popupX ? MainView.popupX : 600
+                    , position: "absolute",
+                    left: MainView.popupY ? MainView.popupY : 250
+                    , width: "auto", height: "auto", zIndex: 10000,
+                    fontSize: "13px", whiteSpace: "nowrap", backgroundColor: "rgb(170, 205, 238)",
+                    padding: "5px", //fontWeight: "bold"
+                }}>Link Created</div>
+            </Fade>
+
             {DocumentLinksButton.EditLink ? <LinkMenu location={DocumentLinksButton.EditLinkLoc} docView={DocumentLinksButton.EditLink} addDocTab={DocumentLinksButton.EditLink.props.addDocTab} changeFlyout={emptyFunction} /> : (null)}
             {LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} backgroundColor={this.defaultBackgroundColors}
                 linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 546a4307c..39bfd8239 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -48,6 +48,7 @@ import { SnappingManager } from "../../../util/SnappingManager";
 import { InkingStroke, ActiveArrowStart, ActiveArrowEnd, ActiveInkColor, ActiveFillColor, ActiveInkWidth, ActiveInkBezierApprox, ActiveDash } from "../../InkingStroke";
 import { DocumentType } from "../../../documents/DocumentTypes";
 import { DocumentLinksButton } from "../../nodes/DocumentLinksButton";
+import { MainView } from "../../MainView";
 
 library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
 
@@ -248,6 +249,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         } else {
             const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" });
             this.props.addDocument(source);
+            MainView.popupX = xp;
+            MainView.popupY = yp;
+            runInAction(() => { MainView.linkCreated = true; });
+            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2500); });
             linkDragData.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: linkDragData.linkSourceDocument }, "doc annotation"); // TODODO this is where in text links get passed
             e.stopPropagation();
             return true;
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index c372e7098..6468ccd3d 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -15,7 +15,7 @@
 }
 
 .linkMenu-group {
-    border-bottom: 0.5px solid lightgray; 
+    border-bottom: 0.5px solid lightgray;
     padding: 5px 0;
 
 
@@ -30,9 +30,11 @@
             p {
                 background-color: lightgray;
             }
+
             p.expand-one {
                 width: calc(100% - 26px);
             }
+
             .linkEditor-tableButton {
                 display: block;
             }
@@ -50,7 +52,4 @@
             display: none;
         }
     }
-}
-
-
-
+}
\ No newline at end of file
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index c36e7b67c..c672511ac 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -10,6 +10,7 @@ import { LinkMenuGroup } from "./LinkMenuGroup";
 import { faTrash } from '@fortawesome/free-solid-svg-icons';
 import { library } from "@fortawesome/fontawesome-svg-core";
 import { DocumentLinksButton } from "../nodes/DocumentLinksButton";
+import { LinkDocPreview } from "../nodes/LinkDocPreview";
 
 library.add(faTrash);
 
@@ -28,6 +29,9 @@ export class LinkMenu extends React.Component<Props> {
 
     @action
     onClick = (e: PointerEvent) => {
+
+        LinkDocPreview.LinkInfo = undefined;
+
         if (this._linkMenuRef?.contains(e.target as any)) {
             DocumentLinksButton.EditLink = undefined;
         }
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 54dca261d..b11a173f3 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -97,6 +97,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
         return (<div className="link-metadata">{mdRows}</div>);
     }
 
+    @action
     onLinkButtonDown = (e: React.PointerEvent): void => {
         this._downX = e.clientX;
         this._downY = e.clientY;
@@ -106,6 +107,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
         document.addEventListener("pointermove", this.onLinkButtonMoved);
         document.removeEventListener("pointerup", this.onLinkButtonUp);
         document.addEventListener("pointerup", this.onLinkButtonUp);
+
+        //if (this._editRef && this._editRef.current?.contains(e.target as any)) {
+        LinkDocPreview.LinkInfo = undefined;
+        //}
     }
 
     onLinkButtonUp = (e: PointerEvent): void => {
@@ -168,14 +173,14 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
                         }))}
                         onPointerDown={this.onLinkButtonDown}>
                         <p >{StrCast(this.props.destinationDoc.title)}</p>
-                        <div className="linkMenu-item-buttons">
+                        <div className="linkMenu-item-buttons" ref={this._editRef} >
                             {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="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" ref={this._editRef} onPointerDown={this.deleteLink}>
+                            <div title="Delete link" className="button" onPointerDown={this.deleteLink}>
                                 <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
-                            <div title="Follow link" className="button" onClick={e => this.followDefault()} onContextMenu={this.onContextMenu}>
+                            <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 d67a01d8b..95c2988da 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -77,6 +77,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
         }
     }
 
+    @action
     completeLink = (e: React.PointerEvent): void => {
         setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => {
             if (doubleTap) {
@@ -88,12 +89,17 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                 } else {
                     DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
                         DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
+                    runInAction(() => { MainView.linkCreated = true; });
+                    runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2500); });
+                    MainView.popupX = e.screenX;
+                    MainView.popupY = e.screenY;
                 }
             }
         }));
     }
 
-    finishLinkClick = () => {
+    @action
+    finishLinkClick = (e: React.MouseEvent) => {
         if (DocumentLinksButton.StartLink === this.props.View) {
             DocumentLinksButton.StartLink = undefined;
             // action((e: React.PointerEvent<HTMLDivElement>) => {
@@ -102,6 +108,10 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
         } else {
             DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
                 DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
+            runInAction(() => { MainView.linkCreated = true; });
+            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2500); });
+            MainView.popupX = e.screenX;
+            MainView.popupY = e.screenY;
         }
     }
 
@@ -131,7 +141,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                 </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={this.finishLinkClick} /> : (null)}
+                    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>;
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index b4bb556c7..7aa1d528d 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -832,14 +832,14 @@ export namespace Doc {
         })(doc);
     }
     export function BrushDoc(doc: Doc) {
-        console.log("brushed");
+
         if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
         brushManager.BrushedDoc.set(doc, true);
         brushManager.BrushedDoc.set(Doc.GetProto(doc), true);
         return doc;
     }
     export function UnBrushDoc(doc: Doc) {
-        console.log("unbrushed");
+
         if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
         brushManager.BrushedDoc.delete(doc);
         brushManager.BrushedDoc.delete(Doc.GetProto(doc));
-- 
cgit v1.2.3-70-g09d2


From c146d9a6165dcfa9ebd98868dfb741a26ede5a9f Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Fri, 3 Jul 2020 12:09:48 -0500
Subject: finished link created popups

---
 src/client/views/MainView.tsx                             | 15 +++++++++------
 .../collectionFreeForm/CollectionFreeFormView.tsx         |  4 ----
 src/client/views/nodes/DocumentLinksButton.tsx            |  6 +++---
 src/client/views/nodes/DocumentView.tsx                   | 12 ++++++++++++
 4 files changed, 24 insertions(+), 13 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index acbeb65cc..3d47d09c8 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -619,12 +619,15 @@ export class MainView extends React.Component {
 
             <Fade in={MainView.linkCreated}>
                 <div style={{
-                    border: "1px solid rgb(111, 144, 175)", top: MainView.popupX ? MainView.popupX : 600
-                    , position: "absolute",
-                    left: MainView.popupY ? MainView.popupY : 250
-                    , width: "auto", height: "auto", zIndex: 10000,
-                    fontSize: "13px", whiteSpace: "nowrap", backgroundColor: "rgb(170, 205, 238)",
-                    padding: "5px", //fontWeight: "bold"
+                    border: "1px solid rgb(100, 100, 100)",
+                    left: MainView.popupX ? MainView.popupX : 600,
+                    position: "absolute",
+                    top: MainView.popupY ? MainView.popupY : 250, width: "auto",
+                    height: "auto", zIndex: 10000, borderRadius: "13px",
+                    fontSize: "13px", whiteSpace: "nowrap",
+                    color: "rgb(100, 100, 100)", backgroundColor: "rgba(250, 250, 250, 0.85)",
+                    paddingTop: "6.5px", paddingBottom: "6.5px", fontWeight: "bold",
+                    paddingLeft: "9px", paddingRight: "9px"
                 }}>Link Created</div>
             </Fade>
 
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 25f724449..7f6d1d506 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -249,10 +249,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         } else {
             const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, x: xp, y: yp, title: "dropped annotation" });
             this.props.addDocument(source);
-            MainView.popupX = xp;
-            MainView.popupY = yp;
-            runInAction(() => { MainView.linkCreated = true; });
-            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2500); });
             linkDragData.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: linkDragData.linkSourceDocument }, "doc annotation"); // TODODO this is where in text links get passed
             e.stopPropagation();
             return true;
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 7faae68bf..6a6624aa0 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -109,9 +109,9 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
             DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
                 DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
             runInAction(() => { MainView.linkCreated = true; });
-            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2500); });
-            MainView.popupX = e.screenX;
-            MainView.popupY = e.screenY;
+            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2000); });
+            MainView.popupX = e.screenX - 25;
+            MainView.popupY = e.screenY - 140;
         }
     }
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 66af29286..3a9e4fcf0 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -42,6 +42,7 @@ import { RadialMenu } from './RadialMenu';
 import React = require("react");
 import { DocumentLinksButton } from './DocumentLinksButton';
 import { MobileInterface } from '../../../mobile/MobileInterface';
+import { MainView } from '../MainView';
 
 library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
     fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -641,12 +642,23 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             e.stopPropagation();
             de.complete.annoDragData.linkedToDoc = true;
 
+            runInAction(() => MainView.popupX = de.x);
+            runInAction(() => MainView.popupY = de.y);
+            runInAction(() => { MainView.linkCreated = true; });
+            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2500); });
+
             DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link");
         }
         if (de.complete.linkDragData) {
             e.stopPropagation();
             // const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
             // const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
+            runInAction(() => MainView.popupX = de.x);
+            runInAction(() => MainView.popupY = de.y);
+
+            runInAction(() => { MainView.linkCreated = true; });
+            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2000); });
+
             de.complete.linkDragData.linkSourceDocument !== this.props.Document &&
                 (de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument },
                     { doc: this.props.Document }, `link`)); // TODODO this is where in text links get passed
-- 
cgit v1.2.3-70-g09d2


From ed74b8b6d6c65a24803c4e0e68aa192a750d60fa Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Fri, 3 Jul 2020 18:47:48 -0500
Subject: restructure

---
 src/client/documents/Documents.ts                  |  5 ----
 src/client/views/MainView.tsx                      | 27 ++---------------
 .../views/collections/CollectionLinearView.scss    | 34 ++++++++++++++++++----
 .../views/collections/CollectionLinearView.tsx     | 32 ++++----------------
 src/client/views/linking/LinkMenuItem.scss         | 34 ++++++++++++----------
 src/client/views/nodes/DocumentLinksButton.tsx     | 24 +++++++++------
 src/client/views/nodes/DocumentView.tsx            | 22 ++++++++------
 src/client/views/nodes/LinkCreatedBox.scss         | 21 +++++++++++++
 src/client/views/nodes/LinkCreatedBox.tsx          | 31 ++++++++++++++++++++
 9 files changed, 134 insertions(+), 96 deletions(-)
 create mode 100644 src/client/views/nodes/LinkCreatedBox.scss
 create mode 100644 src/client/views/nodes/LinkCreatedBox.tsx

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 0f434d616..f81c25bab 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -50,7 +50,6 @@ import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo";
 import { DocumentType } from "./DocumentTypes";
 import { Networking } from "../Network";
 import { Upload } from "../../server/SharedMediaTypes";
-import { MainView } from "../views/MainView";
 const path = require('path');
 
 export interface DocumentOptions {
@@ -868,10 +867,6 @@ export namespace DocUtils {
         DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline"));
     }
 
-    function stopLinkCreated() {
-        MainView.linkCreated = false;
-    }
-
     export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", id?: string) {
         const sv = DocumentManager.Instance.getDocumentView(source.doc);
         if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 3d47d09c8..15f818d1f 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -60,6 +60,7 @@ import { DocumentLinksButton } from './nodes/DocumentLinksButton';
 import { LinkMenu } from './linking/LinkMenu';
 import { LinkDocPreview } from './nodes/LinkDocPreview';
 import { Fade } from '@material-ui/core';
+import { LinkCreatedBox } from './nodes/LinkCreatedBox';
 
 @observer
 export class MainView extends React.Component {
@@ -83,11 +84,6 @@ export class MainView extends React.Component {
 
     public isPointerDown = false;
 
-    @observable public static linkCreated: boolean = false;
-    @observable public static popupX: number = 600;
-    @observable public static popupY: number = 250;
-
-
     componentDidMount() {
         DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_viewType"]); // can play with these fields on someone else's
 
@@ -367,11 +363,6 @@ export class MainView extends React.Component {
         }
     }
 
-    @action
-    public static changeLinkCreated = () => {
-        MainView.linkCreated = !MainView.linkCreated;
-    }
-
     @action
     onPointerMove = (e: PointerEvent) => {
         this.flyoutWidth = Math.max(e.clientX, 0);
@@ -616,21 +607,7 @@ export class MainView extends React.Component {
                 {this.mainContent}
             </GestureOverlay>
             <PreviewCursor />
-
-            <Fade in={MainView.linkCreated}>
-                <div style={{
-                    border: "1px solid rgb(100, 100, 100)",
-                    left: MainView.popupX ? MainView.popupX : 600,
-                    position: "absolute",
-                    top: MainView.popupY ? MainView.popupY : 250, width: "auto",
-                    height: "auto", zIndex: 10000, borderRadius: "13px",
-                    fontSize: "13px", whiteSpace: "nowrap",
-                    color: "rgb(100, 100, 100)", backgroundColor: "rgba(250, 250, 250, 0.85)",
-                    paddingTop: "6.5px", paddingBottom: "6.5px", fontWeight: "bold",
-                    paddingLeft: "9px", paddingRight: "9px"
-                }}>Link Created</div>
-            </Fade>
-
+            <LinkCreatedBox />
             {DocumentLinksButton.EditLink ? <LinkMenu location={DocumentLinksButton.EditLinkLoc} docView={DocumentLinksButton.EditLink} addDocTab={DocumentLinksButton.EditLink.props.addDocTab} changeFlyout={emptyFunction} /> : (null)}
             {LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} backgroundColor={this.defaultBackgroundColors}
                 linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href}
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss
index b3fc5f0e7..5ada79a28 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/CollectionLinearView.scss
@@ -10,18 +10,42 @@
         height: 100%;
 
         >span {
-            //margin-top: 8px;
-            //margin-left: 4px;
-            //margin-bottom: 2px;
             background: $dark-color;
             color: $light-color;
-            //display: inline-block;
             border-radius: 18px;
             margin-right: 6px;
-            //height: 100%;
             cursor: pointer;
         }
 
+        .bottomPopup-background {
+            padding-right: 14px;
+            height: 35;
+            transform: translate3d(6px, 5px, 0px);
+            padding-top: 6.5px;
+            padding-bottom: 7px;
+            padding-left: 5px;
+        }
+
+        .bottomPopup-text {
+            display: inline;
+            white-space: nowrap;
+            padding-left: 8px;
+            padding-right: 4px;
+            vertical-align: middle;
+            font-size: 12.5px;
+        }
+
+        .bottomPopup-exit {
+            display: inline;
+            white-space: nowrap;
+            padding-left: 8px;
+            padding-right: 8px;
+            vertical-align: middle;
+            background-color: lightgrey;
+            border-radius: 5.5px;
+            color: black;
+        }
+
         >label {
             margin-top: "auto";
             margin-bottom: "auto";
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 7635dac24..7cbe5c19d 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -149,36 +149,14 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                         </div>;
                     })}
                 </div>
-                {DocumentLinksButton.StartLink ? <span style={{
-                    background: backgroundColor === color ? "black" : backgroundColor,
-                    paddingRight: "14px",
-                    height: "35",
-                    transform: "translate3d(6px, 5px, 0px)",
-                    paddingTop: "6.5px",
-                    paddingBottom: "7px",
-                    paddingLeft: "5px"
+                {DocumentLinksButton.StartLink ? <span className="bottomPopup-background" style={{
+                    background: backgroundColor === color ? "black" : backgroundColor
                 }}
                     onPointerDown={e => e.stopPropagation()} >
-                    <span style={{
-                        display: "inline",
-                        whiteSpace: "nowrap",
-                        paddingLeft: "8px",
-                        paddingRight: "4px",
-                        verticalAlign: "middle",
-                        fontSize: "12.5px"
-                    }}>
+                    <span className="bottomPopup-text" >
                         Creating link from: {DocumentLinksButton.StartLink.title} </span>
-                    <span onClick={this.exitLongLinks}
-                        style={{
-                            display: "inline",
-                            whiteSpace: "nowrap",
-                            paddingLeft: "8px",
-                            paddingRight: "8px",
-                            verticalAlign: "middle",
-                            backgroundColor: "lightgrey",
-                            borderRadius: "5.5px",
-                            color: "black"
-                        }}>Exit</span>
+                    <span className="bottomPopup-exit" onClick={this.exitLongLinks}
+                    >Exit</span>
 
                     {/* <FontAwesomeIcon icon="times-circle" size="lg" style={{ color: "red" }}
                         onClick={this.exitLongLinks} /> */}
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index c5becae7d..e3ce69cd7 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -31,21 +31,23 @@
         font-size: 10.5px;
     }
 
-    // &:hover {
-    //     .linkMenu-item-buttons {
-    //         display: flex;
-    //     }
-    //     .linkMenu-item-content {
-    //         &.expand-two p {
-    //             width: calc(100% - 52px);
-    //             background-color: lightgray;
-    //         }
-    //         &.expand-three p {
-    //             width: calc(100% - 84px);
-    //             background-color: lightgray;
-    //         }
-    //     }
-    // }
+    &:hover {
+        .linkMenu-item-buttons {
+            display: flex;
+        }
+
+        .linkMenu-item-content {
+            &.expand-two p {
+                width: calc(100% - 52px);
+                background-color: lightgray;
+            }
+
+            &.expand-three p {
+                width: calc(100% - 84px);
+                background-color: lightgray;
+            }
+        }
+    }
 }
 
 .linkMenu-item-buttons {
@@ -53,7 +55,7 @@
     top: 50%;
     right: 0;
     transform: translateY(-50%);
-    display: flex;
+    display: none;
 
     .button {
         width: 20px;
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 6a6624aa0..bfd860f65 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -10,7 +10,7 @@ import React = require("react");
 import { DocUtils } from "../../documents/Documents";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { LinkDocPreview } from "./LinkDocPreview";
-import { MainView } from "../MainView";
+import { LinkCreatedBox } from "./LinkCreatedBox";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -89,10 +89,13 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                 } else {
                     DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
                         DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
-                    runInAction(() => { MainView.linkCreated = true; });
-                    runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2500); });
-                    MainView.popupX = e.screenX;
-                    MainView.popupY = e.screenY;
+
+                    runInAction(() => {
+                        LinkCreatedBox.popupX = e.screenX;
+                        LinkCreatedBox.popupY = e.screenY - 120;
+                        LinkCreatedBox.linkCreated = true;
+                        setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+                    });
                 }
             }
         }));
@@ -108,10 +111,13 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
         } else {
             DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
                 DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
-            runInAction(() => { MainView.linkCreated = true; });
-            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2000); });
-            MainView.popupX = e.screenX - 25;
-            MainView.popupY = e.screenY - 140;
+
+            runInAction(() => {
+                LinkCreatedBox.popupX = e.screenX;
+                LinkCreatedBox.popupY = e.screenY - 120;
+                LinkCreatedBox.linkCreated = true;
+                setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+            });
         }
     }
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3a9e4fcf0..b38db9a1e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -42,7 +42,7 @@ import { RadialMenu } from './RadialMenu';
 import React = require("react");
 import { DocumentLinksButton } from './DocumentLinksButton';
 import { MobileInterface } from '../../../mobile/MobileInterface';
-import { MainView } from '../MainView';
+import { LinkCreatedBox } from './LinkCreatedBox';
 
 library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
     fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -642,10 +642,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             e.stopPropagation();
             de.complete.annoDragData.linkedToDoc = true;
 
-            runInAction(() => MainView.popupX = de.x);
-            runInAction(() => MainView.popupY = de.y);
-            runInAction(() => { MainView.linkCreated = true; });
-            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2500); });
+            runInAction(() => {
+                LinkCreatedBox.popupX = de.x;
+                LinkCreatedBox.popupY = de.y;
+                LinkCreatedBox.linkCreated = true;
+                setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+            });
 
             DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link");
         }
@@ -653,11 +655,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             e.stopPropagation();
             // const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
             // const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
-            runInAction(() => MainView.popupX = de.x);
-            runInAction(() => MainView.popupY = de.y);
 
-            runInAction(() => { MainView.linkCreated = true; });
-            runInAction(() => { setTimeout(function () { runInAction(() => MainView.linkCreated = false); }, 2000); });
+            runInAction(() => {
+                LinkCreatedBox.popupX = de.x;
+                LinkCreatedBox.popupY = de.y;
+                LinkCreatedBox.linkCreated = true;
+                setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+            });
 
             de.complete.linkDragData.linkSourceDocument !== this.props.Document &&
                 (de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument },
diff --git a/src/client/views/nodes/LinkCreatedBox.scss b/src/client/views/nodes/LinkCreatedBox.scss
new file mode 100644
index 000000000..3cbd38b55
--- /dev/null
+++ b/src/client/views/nodes/LinkCreatedBox.scss
@@ -0,0 +1,21 @@
+.linkCreatedBox-fade {
+    border: 1px solid rgb(100, 100, 100);
+
+
+    width: auto;
+    position: absolute;
+
+    height: auto;
+    z-index: 10000;
+    border-radius: 13px;
+    font-size: 13px;
+    white-space: nowrap;
+
+    color: rgb(100, 100, 100);
+    background-color: rgba(250, 250, 250, 0.85);
+    padding-top: 6.5px;
+    padding-bottom: 6.5px;
+    font-weight: bold;
+    padding-left: 9px;
+    padding-right: 9px;
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/LinkCreatedBox.tsx b/src/client/views/nodes/LinkCreatedBox.tsx
new file mode 100644
index 000000000..d157d3fca
--- /dev/null
+++ b/src/client/views/nodes/LinkCreatedBox.tsx
@@ -0,0 +1,31 @@
+import React = require("react");
+import { observer } from "mobx-react";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface } from "../../../fields/Schema";
+import "./LinkCreatedBox.scss";
+import { observable, action } from "mobx";
+import { Fade } from "@material-ui/core";
+
+
+@observer
+export class LinkCreatedBox extends React.Component<{}> {
+
+    @observable public static linkCreated: boolean = false;
+    @observable public static popupX: number = 600;
+    @observable public static popupY: number = 250;
+
+    @action
+    public static changeLinkCreated = () => {
+        LinkCreatedBox.linkCreated = !LinkCreatedBox.linkCreated;
+    }
+
+    render() {
+        return <Fade in={LinkCreatedBox.linkCreated}>
+            <div className="linkCreatedBox-fade"
+                style={{
+                    left: LinkCreatedBox.popupX ? LinkCreatedBox.popupX : 600,
+                    top: LinkCreatedBox.popupY ? LinkCreatedBox.popupY : 250,
+                }}>Link Created</div>
+        </Fade>;
+    }
+} 
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

