From b8c0dc61d535caeb2142678dffea2a841776e3a8 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 13 Mar 2019 16:39:45 -0400
Subject: moved DocumentContents into DocumentContentsView file.

---
 src/client/views/nodes/DocumentView.tsx | 40 +++++----------------------------
 1 file changed, 6 insertions(+), 34 deletions(-)

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

diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a91d2071b..8cd406d7d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,32 +1,22 @@
-import { action, computed, IReactionDisposer, runInAction, reaction, trace } from "mobx";
+import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { Field, FieldWaiting, Opt } from "../../../fields/Field";
 import { Key } from "../../../fields/Key";
 import { KeyStore } from "../../../fields/KeyStore";
 import { ListField } from "../../../fields/ListField";
+import { TextField } from "../../../fields/TextField";
+import { Documents } from "../../documents/Documents";
+import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
 import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionFreeFormView } from "../collections/CollectionFreeFormView";
-import { CollectionSchemaView } from "../collections/CollectionSchemaView";
 import { CollectionView, CollectionViewType } from "../collections/CollectionView";
-import { CollectionPDFView } from "../collections/CollectionPDFView";
-import { CollectionVideoView } from "../collections/CollectionVideoView";
 import { ContextMenu } from "../ContextMenu";
-import { FormattedTextBox } from "../nodes/FormattedTextBox";
-import { ImageBox } from "../nodes/ImageBox";
-import { VideoBox } from "../nodes/VideoBox";
-import { AudioBox } from "../nodes/AudioBox";
-import { Documents } from "../../documents/Documents"
-import { KeyValueBox } from "./KeyValueBox"
-import { WebBox } from "../nodes/WebBox";
-import { PDFBox } from "../nodes/PDFBox";
 import "./DocumentView.scss";
 import React = require("react");
-import { TextField } from "../../../fields/TextField";
-import { DocumentManager } from "../../util/DocumentManager";
+import { DocumentContentsView } from "./DocumentContentsView";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 
@@ -85,24 +75,6 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs {
     return args;
 }
 
-interface JsxBindings {
-    Document: Document;
-    layout: string;
-    [prop: string]: any;
-}
-
-export class DocumentContents extends React.PureComponent<JsxBindings> {
-    render() {
-        return <JsxParser
-            components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox }}
-            bindings={this.props}
-            jsx={this.props.layout}
-            showWarnings={true}
-            onError={(test: any) => { console.log(test) }}
-        />
-    }
-}
-
 @observer
 export class DocumentView extends React.Component<DocumentViewProps> {
     private _mainCont = React.createRef<HTMLDivElement>();
@@ -343,7 +315,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                 }}
                 onContextMenu={this.onContextMenu}
                 onPointerDown={this.onPointerDown} >
-                <DocumentContents {...this.getProps} />
+                <DocumentContentsView {...this.getProps} />
             </div>
         )
     }
-- 
cgit v1.2.3-70-g09d2


From a3678862b48d6bb44f37533b827d290c883ce542 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 14 Mar 2019 16:54:48 -0400
Subject: added a background color

---
 src/client/documents/Documents.ts       | 2 ++
 src/client/views/Main.tsx               | 2 +-
 src/client/views/nodes/DocumentView.tsx | 2 ++
 src/fields/KeyStore.ts                  | 1 +
 4 files changed, 6 insertions(+), 1 deletion(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 15e16a491..4e0eefcc6 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -40,6 +40,7 @@ export interface DocumentOptions {
     layout?: string;
     layoutKeys?: Key[];
     viewType?: number;
+    backgroundColor?: string;
 }
 
 export namespace Documents {
@@ -83,6 +84,7 @@ export namespace Documents {
         if (options.page !== undefined) { doc.SetNumber(KeyStore.Page, options.page); }
         if (options.scale !== undefined) { doc.SetNumber(KeyStore.Scale, options.scale); }
         if (options.viewType !== undefined) { doc.SetNumber(KeyStore.ViewType, options.viewType); }
+        if (options.backgroundColor !== undefined) { doc.SetText(KeyStore.BackgroundColor, options.backgroundColor); }
         if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); }
         if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); }
         return doc;
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index d73e9b8fe..8ee028076 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -58,7 +58,7 @@ Documents.initProtos(mainDocId, (res?: Document) => {
     let videourl = "http://techslides.com/demos/sample-videos/small.mp4";
     let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {}))
     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 addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, backgroundColor: "Transparent", title: "a freeform collection" }));
     let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" }));
     let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, title: "video node" }));
     let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, title: "a schema collection" }));
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8cd406d7d..4b50e40a3 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -305,9 +305,11 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         var scaling = this.props.ContentScaling();
         var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
         var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
+        var backgroundcolor = this.props.Document.GetText(KeyStore.BackgroundColor, "");
         return (
             <div className="documentView-node" ref={this._mainCont}
                 style={{
+                    background: backgroundcolor,
                     width: nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%",
                     height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%",
                     transformOrigin: "left top",
diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts
index f93a68c85..0c8b7e260 100644
--- a/src/fields/KeyStore.ts
+++ b/src/fields/KeyStore.ts
@@ -19,6 +19,7 @@ export namespace KeyStore {
     export const Annotations = new Key("Annotations");
     export const ViewType = new Key("ViewType");
     export const Layout = new Key("Layout");
+    export const BackgroundColor = new Key("BackgroundColor");
     export const BackgroundLayout = new Key("BackgroundLayout");
     export const OverlayLayout = new Key("OverlayLayout");
     export const LayoutKeys = new Key("LayoutKeys");
-- 
cgit v1.2.3-70-g09d2


From 0a1b68e534aebf6f5fa6af31fd6a1e3d63f299d1 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 16 Mar 2019 20:38:24 -0400
Subject: Added context menu option to copy document id Added route to handle
 going to any doc id

---
 deploy/index.html                       | 2 +-
 src/client/views/Main.tsx               | 4 ++--
 src/client/views/nodes/DocumentView.tsx | 7 +++++++
 src/server/index.ts                     | 7 ++++++-
 4 files changed, 16 insertions(+), 4 deletions(-)

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

diff --git a/deploy/index.html b/deploy/index.html
index 130da1cb9..acb085214 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -7,7 +7,7 @@
 
 <body>
   <div id="root"></div>
-  <script src="./bundle.js"></script>
+  <script src="/bundle.js"></script>
 </body>
 
 </html>
\ No newline at end of file
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 3a68b98ce..f938e83b9 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -41,8 +41,8 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
         ContextMenu.Instance.clearItems()
     }
 }), true)
-
-const mainDocId = "mainDoc";
+const pathname = window.location.pathname.split("/");
+const mainDocId = pathname[pathname.length - 1];
 let mainContainer: Document;
 let mainfreeform: Document;
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4b50e40a3..6b305fb96 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -17,6 +17,7 @@ import { ContextMenu } from "../ContextMenu";
 import "./DocumentView.scss";
 import React = require("react");
 import { DocumentContentsView } from "./DocumentContentsView";
+import { Utils } from "../../../Utils";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 
@@ -253,6 +254,12 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked })
         ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) })
         ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) })
+        ContextMenu.Instance.addItem({
+            description: "Copy ID",
+            event: () => {
+                Utils.CopyText(this.props.Document.Id);
+            }
+        });
         //ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) })
         ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15)
         if (!this.topMost) {
diff --git a/src/server/index.ts b/src/server/index.ts
index 83fa84746..7f1e95964 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -100,9 +100,14 @@ let FieldStore: ObservableMap<FieldId, Field> = new ObservableMap();
 
 // define a route handler for the default home page
 app.get("/", (req, res) => {
-    res.sendFile(path.join(__dirname, '../../deploy/index.html'));
+    res.redirect("/doc/mainDoc");
+    // res.sendFile(path.join(__dirname, '../../deploy/index.html'));
 });
 
+app.get("/doc/:docId", (req, res) => {
+    res.sendFile(path.join(__dirname, '../../deploy/index.html'));
+})
+
 app.get("/hello", (req, res) => {
     res.send("<p>Hello</p>");
 })
-- 
cgit v1.2.3-70-g09d2


From 88b175395307e31ce713ff66c3e2ae9c62e1a369 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 16 Mar 2019 21:48:13 -0400
Subject: Everything but the actual template works

---
 src/client/documents/Documents.ts                  | 15 ++++++++++++++-
 .../views/collections/CollectionFreeFormView.tsx   | 22 +---------------------
 .../views/collections/CollectionViewBase.tsx       |  8 ++++++--
 src/client/views/nodes/DocumentView.tsx            | 15 +++++++++++++++
 4 files changed, 36 insertions(+), 24 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 983253347..7b6409a62 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -209,10 +209,23 @@ export namespace Documents {
             + FormattedTextBox.LayoutString("CaptionKey") +
             `</div> 
         </div>` };
-    export function FixedCaption(fieldName: string = "Caption") {
+    function FixedCaption(fieldName: string = "Caption") {
         return `<div style="position:absolute; height:30px; bottom:0; width:100%">
             <div style="position:absolute; width:100%; height:100%; text-align:center;bottom:0;">`
             + FormattedTextBox.LayoutString(fieldName + "Key") +
             `</div> 
         </div>` };
+
+    function Caption() {
+        return (`
+<div>
+    <div style="margin:auto; height:85%; width:85%;">
+        {layout}
+    </div>
+    <div style="height:15%">
+        <FormattedTextBox doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={"CaptionKey"} isSelected={isSelected} select={select} selectOnLoad={SelectOnLoad} isTopMost={isTopMost}/>
+    </div>
+</div>       
+        `)
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 79ea77c77..0a4b57ffb 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -209,27 +209,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
     @action
     onDrop = (e: React.DragEvent): void => {
         var pt = this.getTransform().transformPoint(e.pageX, e.pageY);
-
-        let text = e.dataTransfer.getData("text/plain");
-        let start = text.startsWith("<div")
-        if (start) {
-            console.log(e.target);
-            console.log(this.props.Document.GetData(KeyStore.Layout, TextField, new String))
-            var children = this.props.Document.GetList<Document>(KeyStore.Data, []);
-            console.log(children);
-            if (children) {
-                children.forEach(f => {
-                    console.log(f.GetData(KeyStore.Layout, TextField, new String));
-                });
-            }
-            // let xx = this.props.Document.GetT(KeyStore.Thumbnail, ImageField)
-            // if (xx) {
-            //     console.log(xx.toString())
-            // }
-            this.props.Document.SetData(KeyStore.Layout, text, TextField);
-            e.stopPropagation();
-        }
-        else { super.onDrop(e, { x: pt[0], y: pt[1] }); }
+        super.onDrop(e, { x: pt[0], y: pt[1] });
     }
 
     onDragOver = (): void => {
diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index dd05837d8..b0f42125a 100644
--- a/src/client/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -68,13 +68,17 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps>
 
     @action
     protected onDrop(e: React.DragEvent, options: DocumentOptions): void {
-        e.stopPropagation()
-        e.preventDefault()
         let that = this;
 
         let html = e.dataTransfer.getData("text/html");
         let text = e.dataTransfer.getData("text/plain");
 
+        if (text && text.startsWith("<div")) {
+            return;
+        }
+        e.stopPropagation()
+        e.preventDefault()
+
         if (html && html.indexOf("<img") != 0) {
             console.log("not good");
             let htmlDoc = Documents.HtmlDocument(html, { ...options, width: 300, height: 300 });
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4b50e40a3..2be5407fd 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -239,6 +239,20 @@ export class DocumentView extends React.Component<DocumentViewProps> {
         e.stopPropagation();
     }
 
+    onDrop = (e: React.DragEvent) => {
+        if (e.isDefaultPrevented()) {
+            return;
+        }
+        let text = e.dataTransfer.getData("text/plain");
+        if (text && text.startsWith("<div")) {
+            let oldLayout = this.props.Document.GetText(KeyStore.Layout, "");
+            let layout = text.replace("{layout}", oldLayout);
+            this.props.Document.SetText(KeyStore.Layout, layout);
+            e.stopPropagation();
+            e.preventDefault();
+        }
+    }
+
     @action
     onContextMenu = (e: React.MouseEvent): void => {
         e.stopPropagation();
@@ -315,6 +329,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                     transformOrigin: "left top",
                     transform: `scale(${scaling} , ${scaling})`
                 }}
+                onDrop={this.onDrop}
                 onContextMenu={this.onContextMenu}
                 onPointerDown={this.onPointerDown} >
                 <DocumentContentsView {...this.getProps} />
-- 
cgit v1.2.3-70-g09d2


From 8601bcbb46c80282d1fac6863544f9c72050ebd4 Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 16 Mar 2019 23:16:26 -0400
Subject: Fixed server bug

---
 src/client/Server.ts                    | 30 +++++++++++++++++++++++++++---
 src/client/SocketStub.ts                |  1 +
 src/client/documents/Documents.ts       |  2 +-
 src/client/views/nodes/DocumentView.tsx |  6 +++++-
 4 files changed, 34 insertions(+), 5 deletions(-)

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

diff --git a/src/client/Server.ts b/src/client/Server.ts
index f0cf0bb9b..f2d7de75c 100644
--- a/src/client/Server.ts
+++ b/src/client/Server.ts
@@ -40,8 +40,8 @@ export class Server {
                 return this.ClientFieldsCached.get(fieldid);
             }, (field, reaction) => {
                 if (field !== "<Waiting>") {
-                    callback(field)
                     reaction.dispose()
+                    callback(field)
                 }
             })
         }
@@ -49,14 +49,38 @@ export class Server {
     }
 
     public static GetFields(fieldIds: FieldId[], callback: (fields: { [id: string]: Field }) => any) {
-        SocketStub.SEND_FIELDS_REQUEST(fieldIds, (fields) => {
+        let neededFieldIds: FieldId[] = [];
+        let waitingFieldIds: FieldId[] = [];
+        let existingFields: { [id: string]: Field } = {};
+        for (let id of fieldIds) {
+            let field = this.ClientFieldsCached.get(id);
+            if (!field) {
+                neededFieldIds.push(id);
+            } else if (field === FieldWaiting) {
+                waitingFieldIds.push(id);
+            } else {
+                existingFields[id] = field;
+            }
+        }
+        SocketStub.SEND_FIELDS_REQUEST(neededFieldIds, (fields) => {
             for (let key in fields) {
                 let field = fields[key];
                 if (!this.ClientFieldsCached.has(field.Id)) {
                     this.ClientFieldsCached.set(field.Id, field)
                 }
             }
-            callback(fields)
+            reaction(() => {
+                return waitingFieldIds.map(this.ClientFieldsCached.get);
+            }, (cachedFields, reaction) => {
+                if (!cachedFields.some(field => !field || field === FieldWaiting)) {
+                    reaction.dispose();
+                    for (let field of cachedFields) {
+                        let realField = field as Field;
+                        existingFields[realField.Id] = realField;
+                    }
+                    callback({ ...fields, ...existingFields })
+                }
+            }, { fireImmediately: true })
         });
     }
 
diff --git a/src/client/SocketStub.ts b/src/client/SocketStub.ts
index 18df4ca0a..a0b89b7c9 100644
--- a/src/client/SocketStub.ts
+++ b/src/client/SocketStub.ts
@@ -7,6 +7,7 @@ import { Utils } from "../Utils";
 import { Server } from "./Server";
 import { ServerUtils } from "../server/ServerUtil";
 
+//TODO tfs: I think it might be cleaner to not have SocketStub deal with turning what the server gives it into Fields (in other words not call ServerUtils.FromJson), and leave that for the Server class.
 export class SocketStub {
 
     static FieldStore: ObservableMap<FieldId, Field> = new ObservableMap();
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 7b6409a62..bec4dd697 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -175,7 +175,7 @@ export namespace Documents {
         return SetInstanceOptions(GetAudioPrototype(), options, [new URL(url), AudioField]);
     }
     export function TextDocument(options: DocumentOptions = {}) {
-        return SetInstanceOptions(GetTextPrototype(), options, ["", RichTextField]);
+        return SetInstanceOptions(GetTextPrototype(), options, ["", TextField]);
     }
     export function PdfDocument(url: string, options: DocumentOptions = {}) {
         return SetInstanceOptions(GetPdfPrototype(), options, [new URL(url), PDFField]);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 3c1f98ef8..7a43c34d0 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -188,6 +188,9 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             SelectionManager.SelectDoc(this, e.ctrlKey);
         }
     }
+    stopPropogation = (e: React.SyntheticEvent) => {
+        e.stopPropagation();
+    }
 
     deleteClicked = (): void => {
         if (this.props.RemoveDocument) {
@@ -338,7 +341,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                 }}
                 onDrop={this.onDrop}
                 onContextMenu={this.onContextMenu}
-                onPointerDown={this.onPointerDown} >
+                onPointerDown={this.onPointerDown}
+                onPointerUp={this.stopPropogation} >
                 <DocumentContentsView {...this.getProps} />
             </div>
         )
-- 
cgit v1.2.3-70-g09d2

