From 3a9f6df918ad45e55b0c6a540cb566aff4940288 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 8 Apr 2019 12:49:39 -0400
Subject: added copyOnDrag stuff.

---
 src/client/views/Main.tsx | 64 ++++++++++++++++++-----------------------------
 1 file changed, 24 insertions(+), 40 deletions(-)

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

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 237eb3b6e..b4ab9e21d 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -1,57 +1,41 @@
-import { action, configure, observable, runInAction, trace, computed, reaction } from 'mobx';
+import { IconName, library } from '@fortawesome/fontawesome-svg-core';
+import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, computed, configure, observable, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
 import "normalize.css";
 import * as React from 'react';
 import * as ReactDOM from 'react-dom';
+import Measure from 'react-measure';
+import * as request from 'request';
 import { Document } from '../../fields/Document';
+import { Field, FieldWaiting, Opt } from '../../fields/Field';
 import { KeyStore } from '../../fields/KeyStore';
-import "./Main.scss";
+import { ListField } from '../../fields/ListField';
+import { WorkspacesMenu } from '../../server/authentication/controllers/WorkspacesMenu';
+import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
 import { MessageStore } from '../../server/Message';
+import { RouteStore } from '../../server/RouteStore';
+import { ServerUtils } from '../../server/ServerUtil';
 import { Utils } from '../../Utils';
-import * as request from 'request'
-import * as rp from 'request-promise'
 import { Documents } from '../documents/Documents';
+import { ColumnAttributeModel } from '../northstar/core/attribute/AttributeModel';
+import { AttributeTransformationModel } from '../northstar/core/attribute/AttributeTransformationModel';
+import { Gateway, Settings } from '../northstar/manager/Gateway';
+import { AggregateFunction, Catalog } from '../northstar/model/idea/idea';
+import '../northstar/model/ModelExtensions';
+import { HistogramOperation } from '../northstar/operations/HistogramOperation';
+import '../northstar/utils/Extensions';
 import { Server } from '../Server';
 import { setupDrag } from '../util/DragManager';
 import { Transform } from '../util/Transform';
-import { UndoManager, undoBatch } from '../util/UndoManager';
-import { WorkspacesMenu } from '../../server/authentication/controllers/WorkspacesMenu';
+import { UndoManager } from '../util/UndoManager';
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import { ContextMenu } from './ContextMenu';
 import { DocumentDecorations } from './DocumentDecorations';
-import { DocumentView } from './nodes/DocumentView';
-import "./Main.scss";
-import { observer } from 'mobx-react';
 import { InkingControl } from './InkingControl';
-import { RouteStore } from '../../server/RouteStore';
-import { library, IconName } from '@fortawesome/fontawesome-svg-core';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faFont } from '@fortawesome/free-solid-svg-icons';
-import { faImage } from '@fortawesome/free-solid-svg-icons';
-import { faFilePdf } from '@fortawesome/free-solid-svg-icons';
-import { faObjectGroup } from '@fortawesome/free-solid-svg-icons';
-import { faTable } from '@fortawesome/free-solid-svg-icons';
-import { faGlobeAsia } from '@fortawesome/free-solid-svg-icons';
-import { faUndoAlt } from '@fortawesome/free-solid-svg-icons';
-import { faRedoAlt } from '@fortawesome/free-solid-svg-icons';
-import { faPenNib } from '@fortawesome/free-solid-svg-icons';
-import { faFilm } from '@fortawesome/free-solid-svg-icons';
-import { faMusic } from '@fortawesome/free-solid-svg-icons';
-import { faTree } from '@fortawesome/free-solid-svg-icons';
-import Measure from 'react-measure';
-import { DashUserModel } from '../../server/authentication/models/user_model';
-import { ServerUtils } from '../../server/ServerUtil';
-import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
-import { Field, Opt, FieldWaiting } from '../../fields/Field';
-import { ListField } from '../../fields/ListField';
-import { Gateway, Settings } from '../northstar/manager/Gateway';
-import { Catalog, Schema, Attribute, AttributeGroup, AggregateFunction } from '../northstar/model/idea/idea';
-import { ArrayUtil } from '../northstar/utils/ArrayUtil';
-import '../northstar/model/ModelExtensions'
-import '../northstar/utils/Extensions'
-import { HistogramOperation } from '../northstar/operations/HistogramOperation';
-import { AttributeTransformationModel } from '../northstar/core/attribute/AttributeTransformationModel';
-import { ColumnAttributeModel } from '../northstar/core/attribute/AttributeModel';
-import { CollectionView } from './collections/CollectionView';
+import "./Main.scss";
+import { DocumentView } from './nodes/DocumentView';
 
 @observer
 export class Main extends React.Component {
@@ -247,7 +231,7 @@ export class Main extends React.Component {
         let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" }))
         let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" }));
         let addSchemaNode = action(() => Documents.SchemaDocument([], { width: 200, height: 200, title: "a schema collection" }));
-        let addTreeNode = action(() => Documents.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas" }));
+        let addTreeNode = action(() => Documents.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", copyDraggedItems: true }));
         let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, height: 200, title: "video node" }));
         let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, height: 200, title: "a schema collection" }));
         let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
-- 
cgit v1.2.3-70-g09d2


From a72fcdd0ebc06a3c851007c6ed89ab13a9a0d835 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 8 Apr 2019 18:07:13 -0400
Subject: fixed up a bunch of small things + started on text wackiness.

---
 src/client/util/DocumentManager.ts                 |   2 +-
 src/client/util/DragManager.ts                     |   3 +-
 src/client/util/SelectionManager.ts                |   2 +
 src/client/views/InkingCanvas.scss                 |   3 +
 src/client/views/Main.scss                         |  23 +-
 src/client/views/Main.tsx                          |  66 ++--
 .../CollectionFreeFormLinksView.tsx                |  91 +++---
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   2 +
 src/client/views/nodes/FormattedTextBox.tsx        | 338 ++++++++++++---------
 9 files changed, 313 insertions(+), 217 deletions(-)

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

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index bf59fbb43..341959936 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -29,7 +29,7 @@ export class DocumentManager {
 
     public getAllDocumentViews(collection: Document) {
         return this.DocumentViews.filter(dv =>
-            dv.props.ContainingCollectionView && dv.props.ContainingCollectionView.props.Document == collection);
+            dv.props.ContainingCollectionView && dv.props.ContainingCollectionView.props.Document.Id === collection.Id);
     }
 
     public getDocumentView(toFind: Document): DocumentView | null {
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index c1919093e..0ee7ed2b3 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,7 +1,5 @@
 import { action } from "mobx";
 import { Document } from "../../fields/Document";
-import { ImageField } from "../../fields/ImageField";
-import { KeyStore } from "../../fields/KeyStore";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
 import { CollectionView } from "../views/collections/CollectionView";
 import { DocumentDecorations } from "../views/DocumentDecorations";
@@ -18,6 +16,7 @@ export function setupDrag(
             e.stopPropagation();
             e.preventDefault();
 
+            // TODO: bcz -- this needs to have a drag threshold so that it doesn't trigger when just selecting.
             document.removeEventListener("pointermove", onRowMove);
             document.removeEventListener("pointerup", onRowUp);
             var dragData = new DragManager.DocumentDragData([docFunc()]);
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 958c14491..79d4ceb25 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,6 +1,7 @@
 import { observable, action } from "mobx";
 import { DocumentView } from "../views/nodes/DocumentView";
 import { Document } from "../../fields/Document";
+import { Main } from "../views/Main";
 
 export namespace SelectionManager {
     class Manager {
@@ -40,6 +41,7 @@ export namespace SelectionManager {
         }
         manager.SelectedDocuments.length = 0;
         if (found) manager.SelectedDocuments.push(found);
+        Main.Instance.SetTextDoc(undefined, undefined);
     }
 
     export function SelectedDocuments(): Array<DocumentView> {
diff --git a/src/client/views/InkingCanvas.scss b/src/client/views/InkingCanvas.scss
index c5a2a50cb..42ae38c73 100644
--- a/src/client/views/InkingCanvas.scss
+++ b/src/client/views/InkingCanvas.scss
@@ -1,5 +1,8 @@
 @import "global_variables";
 
+.inkingCanvas {
+    opacity:0.99;
+}
 .inkingCanvas-paths-ink, .inkingCanvas-paths-markers, .inkingCanvas-noSelect, .inkingCanvas-canSelect {
     position: absolute;
     top: 0;
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index 594803aab..fe7f007b0 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -4,7 +4,7 @@ html,
 body {
     width: 100%;
     height: 100%;
-    overflow: hidden;
+    overflow: auto;
     font-family: $sans-serif;
     margin: 0;
     position:absolute;
@@ -157,12 +157,33 @@ button:hover {
         cursor: pointer;
     }
 }
+#root {
+    overflow: visible;
+}
 #main-div {
     width:100%;
     height:100%;
     position:absolute;
     top: 0;
     left:0;
+    overflow: scroll;
+}
+.mainDiv-textInput {
+    background:pink;
+        width: 200px;
+        height: 200px;
+        position:absolute;
+        overflow: visible;
+        top: 0;
+        left: 0;
+        .formattedTextBox-cont {
+            background:pink;
+            width: 100%;
+            height: 100%;
+            position:absolute;
+            top: 0;
+            left: 0;
+    }
 }
 #mainContent-div {
     width:100%;
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index b4ab9e21d..c9467e130 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -1,7 +1,7 @@
 import { IconName, library } from '@fortawesome/fontawesome-svg-core';
 import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, configure, observable, runInAction } from 'mobx';
+import { action, computed, configure, observable, runInAction, trace } from 'mobx';
 import { observer } from 'mobx-react';
 import "normalize.css";
 import * as React from 'react';
@@ -36,6 +36,7 @@ import { DocumentDecorations } from './DocumentDecorations';
 import { InkingControl } from './InkingControl';
 import "./Main.scss";
 import { DocumentView } from './nodes/DocumentView';
+import { FormattedTextBox } from './nodes/FormattedTextBox';
 
 @observer
 export class Main extends React.Component {
@@ -203,6 +204,30 @@ export class Main extends React.Component {
     focusDocument = (doc: Document) => { }
     noScaling = () => 1;
 
+    @observable _textDoc?: Document = undefined;
+    _textRect: any;
+    @action
+    SetTextDoc(textDoc?: Document, div?: HTMLDivElement) {
+        this._textDoc = undefined;
+        this._textDoc = textDoc;
+        if (div)
+            this._textRect = div.getBoundingClientRect();
+    }
+
+    @computed
+    get activeTextBox() {
+        if (this._textDoc) {
+            let x: number = this._textRect.x;
+            let y: number = this._textRect.y;
+            let w: number = this._textRect.width;
+            let h: number = this._textRect.height;
+            return <div className="mainDiv-textInput" style={{ transform: `translate(${x}px, ${y}px)`, width: `${w}px`, height: `${h}px` }} >
+                <FormattedTextBox fieldKey={KeyStore.Archives} doc={this._textDoc} isSelected={() => true} select={() => { }} isTopMost={true} selectOnLoad={true} bindings={undefined} />
+            </ div>
+        }
+        else return (null);
+    }
+
     @computed
     get mainContent() {
         return !this.mainContainer ? (null) :
@@ -296,24 +321,27 @@ export class Main extends React.Component {
                 isShown={this.areWorkspacesShown} toggle={this.toggleWorkspaces} />
         }
         return (
-            <div id="main-div">
-                <DocumentDecorations />
-                <Measure onResize={(r: any) => runInAction(() => {
-                    this.pwidth = r.entry.width;
-                    this.pheight = r.entry.height;
-                })}>
-                    {({ measureRef }) =>
-                        <div ref={measureRef} id="mainContent-div">
-                            {this.mainContent}
-                        </div>
-                    }
-                </Measure>
-                <ContextMenu />
-                {this.nodesMenu}
-                {this.miscButtons}
-                {workspaceMenu}
-                <InkingControl />
-            </div>
+            [
+                <div id="main-div">
+                    <DocumentDecorations />
+                    <Measure onResize={(r: any) => runInAction(() => {
+                        this.pwidth = r.entry.width;
+                        this.pheight = r.entry.height;
+                    })}>
+                        {({ measureRef }) =>
+                            <div ref={measureRef} id="mainContent-div">
+                                {this.mainContent}
+                            </div>
+                        }
+                    </Measure>
+                    <ContextMenu />
+                    {this.nodesMenu}
+                    {this.miscButtons}
+                    {workspaceMenu}
+                    <InkingControl />
+                </div>,
+                this.activeTextBox
+            ]
         );
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index d4809ac1c..1189dd4e8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -1,4 +1,4 @@
-import { computed, reaction, runInAction, trace } from "mobx";
+import { computed, reaction } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../../fields/Document";
 import { FieldWaiting } from "../../../../fields/Field";
@@ -11,59 +11,60 @@ import { CollectionViewProps } from "../CollectionViewBase";
 import "./CollectionFreeFormLinksView.scss";
 import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView";
 import React = require("react");
-import v5 = require("uuid/v5");
-import { find } from "async";
 
 @observer
 export class CollectionFreeFormLinksView extends React.Component<CollectionViewProps> {
 
+    HackToAvoidReactionFiringUnnecessarily?: Document = undefined;
     componentDidMount() {
-        reaction(() => {
-            return DocumentManager.Instance.getAllDocumentViews(this.props.Document).map(dv => dv.props.Document.GetNumber(KeyStore.X, 0))
-        }, () => {
-            let views = DocumentManager.Instance.getAllDocumentViews(this.props.Document);
-            for (let i = 0; i < views.length; i++) {
-                for (let j = 0; j < views.length; j++) {
-                    let srcDoc = views[j].props.Document;
-                    let dstDoc = views[i].props.Document;
-                    let x1 = srcDoc.GetNumber(KeyStore.X, 0);
-                    let x1w = srcDoc.GetNumber(KeyStore.Width, -1);
-                    let x2 = dstDoc.GetNumber(KeyStore.X, 0);
-                    let x2w = dstDoc.GetNumber(KeyStore.Width, -1);
-                    if (x1w < 0 || x2w < 0 || i == j)
-                        continue;
-                    let dstTarg = dstDoc;
-                    let srcTarg = srcDoc;
-                    let findBrush = (field: ListField<Document>) => field.Data.findIndex(brush => {
-                        let bdocs = brush ? brush.GetList(KeyStore.BrushingDocs, [] as Document[]) : [];
-                        return (bdocs.length && ((bdocs[0] == dstTarg && bdocs[1] == srcTarg)) ? true : false)
-                    });
-                    let brushAction = (field: ListField<Document>) => {
-                        let found = findBrush(field);
-                        if (found != -1) {
-                            console.log("REMOVE BRUSH " + srcTarg.Title + " " + dstTarg.Title);
-                            field.Data.splice(found, 1);
-                        }
-                    };
-                    if (Math.abs(x1 + x1w - x2) < 20) {
-                        let linkDoc: Document = new Document();
-                        linkDoc.SetText(KeyStore.Title, "Histogram Brush");
-                        linkDoc.SetText(KeyStore.LinkDescription, "Brush between " + srcTarg.Title + " and " + dstTarg.Title);
-                        linkDoc.SetData(KeyStore.BrushingDocs, [dstTarg, srcTarg], ListField);
-
-                        brushAction = brushAction = (field: ListField<Document>) => {
-                            if (findBrush(field) == -1) {
-                                console.log("ADD BRUSH " + srcTarg.Title + " " + dstTarg.Title);
-                                (findBrush(field) == -1) && field.Data.push(linkDoc);
+        this.HackToAvoidReactionFiringUnnecessarily = this.props.Document
+        reaction(() =>
+            DocumentManager.Instance.getAllDocumentViews(this.HackToAvoidReactionFiringUnnecessarily!).
+                map(dv => dv.props.Document.GetNumber(KeyStore.X, 0)),
+            () => {
+                let views = DocumentManager.Instance.getAllDocumentViews(this.props.Document);
+                for (let i = 0; i < views.length; i++) {
+                    for (let j = 0; j < views.length; j++) {
+                        let srcDoc = views[j].props.Document;
+                        let dstDoc = views[i].props.Document;
+                        let x1 = srcDoc.GetNumber(KeyStore.X, 0);
+                        let x1w = srcDoc.GetNumber(KeyStore.Width, -1);
+                        let x2 = dstDoc.GetNumber(KeyStore.X, 0);
+                        let x2w = dstDoc.GetNumber(KeyStore.Width, -1);
+                        if (x1w < 0 || x2w < 0 || i == j)
+                            continue;
+                        let dstTarg = dstDoc;
+                        let srcTarg = srcDoc;
+                        let findBrush = (field: ListField<Document>) => field.Data.findIndex(brush => {
+                            let bdocs = brush ? brush.GetList(KeyStore.BrushingDocs, [] as Document[]) : [];
+                            return (bdocs.length && ((bdocs[0] == dstTarg && bdocs[1] == srcTarg)) ? true : false)
+                        });
+                        let brushAction = (field: ListField<Document>) => {
+                            let found = findBrush(field);
+                            if (found != -1) {
+                                console.log("REMOVE BRUSH " + srcTarg.Title + " " + dstTarg.Title);
+                                field.Data.splice(found, 1);
                             }
                         };
-                    }
-                    dstTarg.GetOrCreateAsync(KeyStore.BrushingDocs, ListField, brushAction);
-                    srcTarg.GetOrCreateAsync(KeyStore.BrushingDocs, ListField, brushAction);
+                        if (Math.abs(x1 + x1w - x2) < 20) {
+                            let linkDoc: Document = new Document();
+                            linkDoc.SetText(KeyStore.Title, "Histogram Brush");
+                            linkDoc.SetText(KeyStore.LinkDescription, "Brush between " + srcTarg.Title + " and " + dstTarg.Title);
+                            linkDoc.SetData(KeyStore.BrushingDocs, [dstTarg, srcTarg], ListField);
 
+                            brushAction = brushAction = (field: ListField<Document>) => {
+                                if (findBrush(field) == -1) {
+                                    console.log("ADD BRUSH " + srcTarg.Title + " " + dstTarg.Title);
+                                    (findBrush(field) == -1) && field.Data.push(linkDoc);
+                                }
+                            };
+                        }
+                        dstTarg.GetOrCreateAsync(KeyStore.BrushingDocs, ListField, brushAction);
+                        srcTarg.GetOrCreateAsync(KeyStore.BrushingDocs, ListField, brushAction);
+
+                    }
                 }
-            }
-        })
+            })
     }
     documentAnchors(view: DocumentView) {
         let equalViews = [view];
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 1ddb84a99..2a86d0ee1 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -21,6 +21,7 @@ import v5 = require("uuid/v5");
 import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors";
 import { PreviewCursor } from "./PreviewCursor";
 import { NumberField } from "../../../../fields/NumberField";
+import { Main } from "../../Main";
 
 @observer
 export class CollectionFreeFormView extends CollectionViewBase {
@@ -185,6 +186,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
 
     @action
     private SetPan(panX: number, panY: number) {
+        Main.Instance.SetTextDoc(undefined, undefined);
         var x1 = this.getLocalTransform().inverse().Scale;
         const newPanX = Math.min((1 - 1 / x1) * this.nativeWidth, Math.max(0, panX));
         const newPanY = Math.min((1 - 1 / x1) * this.nativeHeight, Math.max(0, panY));
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0c0efc437..e59179874 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -2,19 +2,19 @@ import { action, IReactionDisposer, reaction } from "mobx";
 import { baseKeymap } from "prosemirror-commands";
 import { history, redo, undo } from "prosemirror-history";
 import { keymap } from "prosemirror-keymap";
-import { schema } from "../../util/RichTextSchema";
-import { EditorState, Transaction } from "prosemirror-state";
+import { EditorState, Plugin, Transaction } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
-import { Opt, FieldWaiting } from "../../../fields/Field";
-import "./FormattedTextBox.scss";
-import React = require("react");
+import { FieldWaiting, Opt } from "../../../fields/Field";
+import { KeyStore } from "../../../fields/KeyStore";
 import { RichTextField } from "../../../fields/RichTextField";
-import { FieldViewProps, FieldView } from "./FieldView";
-import { Plugin } from "prosemirror-state";
-import { Decoration, DecorationSet } from "prosemirror-view";
+import { inpRules } from "../../util/RichTextRules";
+import { schema } from "../../util/RichTextSchema";
 import { TooltipTextMenu } from "../../util/TooltipTextMenu";
 import { ContextMenu } from "../../views/ContextMenu";
-import { inpRules } from "../../util/RichTextRules";
+import { Main } from "../Main";
+import { FieldView, FieldViewProps } from "./FieldView";
+import "./FormattedTextBox.scss";
+import React = require("react");
 const { buildMenuItems } = require("prosemirror-example-setup");
 const { menuBar } = require("prosemirror-menu");
 
@@ -35,156 +35,196 @@ const { menuBar } = require("prosemirror-menu");
 //  this will edit the document and assign the new value to that field.
 //]
 export class FormattedTextBox extends React.Component<FieldViewProps> {
-  public static LayoutString(fieldStr: string = "DataKey") {
-    return FieldView.LayoutString(FormattedTextBox, fieldStr);
-  }
-  private _ref: React.RefObject<HTMLDivElement>;
-  private _editorView: Opt<EditorView>;
-  private _reactionDisposer: Opt<IReactionDisposer>;
-
-  constructor(props: FieldViewProps) {
-    super(props);
-
-    this._ref = React.createRef();
-    this.onChange = this.onChange.bind(this);
-  }
-
-  dispatchTransaction = (tx: Transaction) => {
-    if (this._editorView) {
-      const state = this._editorView.state.apply(tx);
-      this._editorView.updateState(state);
-      const { doc, fieldKey } = this.props;
-      doc.SetDataOnPrototype(
-        fieldKey,
-        JSON.stringify(state.toJSON()),
-        RichTextField
-      );
-      // doc.SetData(fieldKey, JSON.stringify(state.toJSON()), RichTextField);
+    public static LayoutString(fieldStr: string = "DataKey") {
+        return FieldView.LayoutString(FormattedTextBox, fieldStr);
+    }
+    private _ref: React.RefObject<HTMLDivElement>;
+    private _editorView: Opt<EditorView>;
+    private _reactionDisposer: Opt<IReactionDisposer>;
+    private _inputReactionDisposer: Opt<IReactionDisposer>;
+
+    constructor(props: FieldViewProps) {
+        super(props);
+
+        this._ref = React.createRef();
+        this.onChange = this.onChange.bind(this);
     }
-  };
-
-  componentDidMount() {
-    let state: EditorState;
-    const config = {
-      schema,
-      inpRules, //these currently don't do anything, but could eventually be helpful
-      plugins: [
-        history(),
-        keymap({ "Mod-z": undo, "Mod-y": redo }),
-        keymap(baseKeymap),
-        this.tooltipMenuPlugin()
-      ]
+
+    dispatchTransaction = (tx: Transaction) => {
+        if (this._editorView) {
+            const state = this._editorView.state.apply(tx);
+            this._editorView.updateState(state);
+            this.FieldDoc.SetDataOnPrototype(
+                this.FieldKey,
+                JSON.stringify(state.toJSON()),
+                RichTextField
+            );
+            // doc.SetData(fieldKey, JSON.stringify(state.toJSON()), RichTextField);
+        }
     };
 
-    let field = this.props.doc.GetT(this.props.fieldKey, RichTextField);
-    if (field && field != FieldWaiting && field.Data) {
-      state = EditorState.fromJSON(config, JSON.parse(field.Data));
-    } else {
-      state = EditorState.create(config);
+    get FieldDoc() { return this.props.fieldKey === KeyStore.Archives ? Main.Instance._textDoc! : this.props.doc; }
+    get FieldKey() { return this.props.fieldKey === KeyStore.Archives ? KeyStore.Data : this.props.fieldKey; }
+
+    componentDidMount() {
+        const config = {
+            schema,
+            inpRules, //these currently don't do anything, but could eventually be helpful
+            plugins: [
+                history(),
+                keymap({ "Mod-z": undo, "Mod-y": redo }),
+                keymap(baseKeymap),
+                this.tooltipMenuPlugin()
+            ]
+        };
+
+        if (this.props.fieldKey === KeyStore.Archives) {
+            this._inputReactionDisposer = reaction(() => Main.Instance._textDoc && Main.Instance._textDoc.Id,
+                () => {
+                    if (this._editorView)
+                        this._editorView!.destroy();
+
+                    this.setupEditor(config);
+                }
+            )
+        }
+
+        this._reactionDisposer = reaction(
+            () => {
+                const field = this.FieldDoc.GetT(this.FieldKey, RichTextField);
+                return field && field != FieldWaiting ? field.Data : undefined;
+            },
+            field => {
+                if (field && this._editorView) {
+                    this._editorView.updateState(
+                        EditorState.fromJSON(config, JSON.parse(field))
+                    );
+                }
+            }
+        );
+        this.setupEditor(config);
+    }
+
+    private setupEditor(config: any) {
+
+        let state: EditorState;
+        let field = this.FieldDoc.GetT(this.FieldKey, RichTextField);
+        if (field && field != FieldWaiting && field.Data) {
+            state = EditorState.fromJSON(config, JSON.parse(field.Data));
+        } else {
+            state = EditorState.create(config);
+        }
+        if (this._ref.current) {
+            this._editorView = new EditorView(this._ref.current, {
+                state,
+                dispatchTransaction: this.dispatchTransaction
+            });
+        }
+
+        if (this.props.selectOnLoad) {
+            this.props.select();
+            this._editorView!.focus();
+        }
     }
-    if (this._ref.current) {
-      this._editorView = new EditorView(this._ref.current, {
-        state,
-        dispatchTransaction: this.dispatchTransaction
-      });
+
+    componentWillUnmount() {
+        if (this._editorView) {
+            this._editorView.destroy();
+        }
+        if (this._reactionDisposer) {
+            this._reactionDisposer();
+        }
+        if (this._inputReactionDisposer) {
+            this._inputReactionDisposer();
+        }
+    }
+
+    shouldComponentUpdate() {
+        return false;
+    }
+
+    @action
+    onChange(e: React.ChangeEvent<HTMLInputElement>) {
+        const { fieldKey, doc } = this.props;
+        doc.SetOnPrototype(fieldKey, new RichTextField(e.target.value));
+        // doc.SetData(fieldKey, e.target.value, RichTextField);
     }
+    onPointerDown = (e: React.PointerEvent): void => {
+        if (e.buttons === 1 && this.props.isSelected() && !e.altKey) {
+            e.stopPropagation();
+        }
+        if (e.buttons === 1 && this.props.fieldKey !== KeyStore.Archives)
+            e.preventDefault();
+    };
+    onPointerUp = (e: React.PointerEvent): void => {
+        if (e.buttons === 1 && this.props.isSelected() && !e.altKey) {
+            e.stopPropagation();
+        }
+        if (this.props.fieldKey !== KeyStore.Archives) {
+            e.preventDefault();
+            Main.Instance.SetTextDoc(this.props.doc, this._ref.current!);
+        }
+    };
 
-    this._reactionDisposer = reaction(
-      () => {
-        const field = this.props.doc.GetT(this.props.fieldKey, RichTextField);
-        return field && field != FieldWaiting ? field.Data : undefined;
-      },
-      field => {
-        if (field && this._editorView) {
-          this._editorView.updateState(
-            EditorState.fromJSON(config, JSON.parse(field))
-          );
+    onFocused = (e: React.FocusEvent): void => {
+        if (this.props.fieldKey !== KeyStore.Archives) {
+            Main.Instance.SetTextDoc(this.props.doc, this._ref.current!);
         }
-      }
-    );
-    if (this.props.selectOnLoad) {
-      this.props.select();
-      this._editorView!.focus();
     }
-  }
 
-  componentWillUnmount() {
-    if (this._editorView) {
-      this._editorView.destroy();
+    //REPLACE THIS WITH CAPABILITIES SPECIFIC TO THIS TYPE OF NODE
+    textCapability = (e: React.MouseEvent): void => { };
+
+    specificContextMenu = (e: React.MouseEvent): void => {
+        ContextMenu.Instance.addItem({
+            description: "Text Capability",
+            event: this.textCapability
+        });
+
+        // ContextMenu.Instance.addItem({
+        //     description: "Submenu",
+        //     items: [
+        //         {
+        //             description: "item 1", event:
+        //     },
+        //         {
+        //             description: "item 2", event:
+        //     }
+        //     ]
+        // })
+        // e.stopPropagation()
+    };
+
+    onPointerWheel = (e: React.WheelEvent): void => {
+        e.stopPropagation();
+    };
+
+    tooltipMenuPlugin() {
+        return new Plugin({
+            view(_editorView) {
+                return new TooltipTextMenu(_editorView);
+            }
+        });
     }
-    if (this._reactionDisposer) {
-      this._reactionDisposer();
+    onKeyPress(e: React.KeyboardEvent) {
+        e.stopPropagation();
+        // stop propagation doesn't seem to stop propagation of native keyboard events.
+        // so we set a flag on the native event that marks that the event's been handled.
+        // (e.nativeEvent as any).DASHFormattedTextBoxHandled = true;
     }
-  }
-
-  shouldComponentUpdate() {
-    return false;
-  }
-
-  @action
-  onChange(e: React.ChangeEvent<HTMLInputElement>) {
-    const { fieldKey, doc } = this.props;
-    doc.SetOnPrototype(fieldKey, new RichTextField(e.target.value));
-    // doc.SetData(fieldKey, e.target.value, RichTextField);
-  }
-  onPointerDown = (e: React.PointerEvent): void => {
-    if (e.buttons === 1 && this.props.isSelected() && !e.altKey) {
-      e.stopPropagation();
+    render() {
+        return (
+            <div
+                className="formattedTextBox-cont"
+                onKeyDown={this.onKeyPress}
+                onKeyPress={this.onKeyPress}
+                onPointerUp={this.onPointerUp}
+                onPointerDown={this.onPointerDown}
+                onContextMenu={this.specificContextMenu}
+                // tfs: do we need this event handler
+                onWheel={this.onPointerWheel}
+                ref={this._ref}
+            />
+        );
     }
-  };
-
-  //REPLACE THIS WITH CAPABILITIES SPECIFIC TO THIS TYPE OF NODE
-  textCapability = (e: React.MouseEvent): void => {};
-
-  specificContextMenu = (e: React.MouseEvent): void => {
-    ContextMenu.Instance.addItem({
-      description: "Text Capability",
-      event: this.textCapability
-    });
-
-    // ContextMenu.Instance.addItem({
-    //     description: "Submenu",
-    //     items: [
-    //         {
-    //             description: "item 1", event:
-    //     },
-    //         {
-    //             description: "item 2", event:
-    //     }
-    //     ]
-    // })
-    // e.stopPropagation()
-  };
-
-  onPointerWheel = (e: React.WheelEvent): void => {
-    e.stopPropagation();
-  };
-
-  tooltipMenuPlugin() {
-    return new Plugin({
-      view(_editorView) {
-        return new TooltipTextMenu(_editorView);
-      }
-    });
-  }
-  onKeyPress(e: React.KeyboardEvent) {
-    e.stopPropagation();
-    // stop propagation doesn't seem to stop propagation of native keyboard events.
-    // so we set a flag on the native event that marks that the event's been handled.
-    // (e.nativeEvent as any).DASHFormattedTextBoxHandled = true;
-  }
-  render() {
-    return (
-      <div
-        className="formattedTextBox-cont"
-        onKeyDown={this.onKeyPress}
-        onKeyPress={this.onKeyPress}
-        onPointerDown={this.onPointerDown}
-        onContextMenu={this.specificContextMenu}
-        // tfs: do we need this event handler
-        onWheel={this.onPointerWheel}
-        ref={this._ref}
-      />
-    );
-  }
 }
-- 
cgit v1.2.3-70-g09d2

