aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/Main.tsx
diff options
context:
space:
mode:
authorSam Wilkins <abdullah_ahmed@brown.edu>2019-03-02 17:43:55 -0500
committerSam Wilkins <abdullah_ahmed@brown.edu>2019-03-02 17:43:55 -0500
commit950c656d06d7c6b25b82030feaa7c5c70102fe6a (patch)
treef5ff6112a6d0c34c225479e94a85450559b3f769 /src/client/views/Main.tsx
parentbf26137803c09807b6e7e3d9d9ad086a7ead32ac (diff)
parentbde8aabad7e5745b4797e73b564e4efb19faeca9 (diff)
Merge with master and initial pass at converting main to a component
Diffstat (limited to 'src/client/views/Main.tsx')
-rw-r--r--src/client/views/Main.tsx303
1 files changed, 115 insertions, 188 deletions
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index db7138965..88bf0934c 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -1,216 +1,143 @@
-import { action, configure, reaction, computed, observable } from 'mobx';
+import { action, configure, observable } from 'mobx';
import "normalize.css";
import * as React from 'react';
import * as ReactDOM from 'react-dom';
-import { DocumentDecorations } from './DocumentDecorations';
-import { Documents } from '../documents/Documents';
import { Document } from '../../fields/Document';
import { KeyStore } from '../../fields/KeyStore';
-import "./Main.scss";
-import { ContextMenu } from './ContextMenu';
-import { DocumentView } from './nodes/DocumentView';
-import { Server } from '../Server';
import { Utils } from '../../Utils';
import { ServerUtils } from '../../server/ServerUtil';
import { MessageStore, DocumentTransfer } from '../../server/Message';
import { Database } from '../../server/database';
import * as request from 'request'
+import { Documents } from '../documents/Documents';
+import { Server } from '../Server';
+import { setupDrag } from '../util/DragManager';
import { Transform } from '../util/Transform';
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { FieldWaiting } from '../../fields/Field';
import { UndoManager } from '../util/UndoManager';
import { WorkspacesMenu } from '../../server/authentication/controllers/WorkspacesMenu';
+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';
+@observer
+export class Main extends React.Component {
+ @observable private mainDocId = "mainDoc";
+ // dummy document initializations keep the compiler happy
+ @observable private mainContainer: Document = new Document;
+ @observable private mainfreeform: Document = new Document;
-configure({
- enforceActions: "observed"
-});
-window.addEventListener("drop", function (e) {
- e.preventDefault();
-}, false)
-window.addEventListener("dragover", function (e) {
- e.preventDefault();
-}, false)
-document.addEventListener("pointerdown", action(function (e: PointerEvent) {
- if (!ContextMenu.Instance.intersects(e.pageX, e.pageY)) {
- ContextMenu.Instance.clearItems()
+ constructor(props: Readonly<{}>) {
+ super(props);
+ // causes errors to be generated when modifying an observable outside of an action
+ configure({ enforceActions: "observed" });
+ this.initEventListeners();
+ this.initAuthenticationRouters();
}
-}), true)
-// Load the user's active workspace, or create a new one if initial session after signup
-request.get(window.location.origin + "/getActiveWorkspaceId", (error, response, body) => {
- init(body ? body : getNewWorkspace());
-});
+ initEventListeners = () => {
+ window.addEventListener("drop", (e) => e.preventDefault(), false) // drop event handler
+ window.addEventListener("dragover", (e) => e.preventDefault(), false) // drag event handler
+ // click interactions for the context menu
+ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
+ if (!ContextMenu.Instance.intersects(e.pageX, e.pageY)) {
+ ContextMenu.Instance.clearItems();
+ }
+ }), true);
+ }
-function getNewWorkspace(): string {
- let newId = Utils.GenerateGuid();
- const here = window.location.origin;
- request.post(here + "/addWorkspaceId", {
- body: {
- target: newId
- },
- json: true
- })
- request.post(here + "/setActiveWorkspaceId", {
- body: {
- target: newId
- },
- json: true
- })
- return newId;
-}
+ initAuthenticationRouters = () => {
+ // Load the user's active workspace, or create a new one if initial session after signup
+ request.get(window.location.origin + "/getActiveWorkspaceId", (error, response, body) => {
+ this.initRender(body ? body : this.getNewWorkspace());
+ });
+ }
-//runInAction(() =>
-// let doc1 = Documents.TextDocument({ title: "hello" });
-// let doc2 = doc1.MakeDelegate();
-// doc2.Set(KS.X, new NumberField(150));
-// doc2.Set(KS.Y, new NumberField(20));
-// let doc3 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", {
-// x: 450, y: 100, title: "cat 1"
-// });
-// doc3.Set(KeyStore.Data, new ImageField);
-// const schemaDocs = Array.from(Array(5).keys()).map(v => Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", {
-// x: 50 + 100 * v, y: 50, width: 100, height: 100, title: "cat" + v
-// }));
-// schemaDocs[0].SetData(KS.Author, "Tyler", TextField);
-// schemaDocs[4].SetData(KS.Author, "Bob", TextField);
-// schemaDocs.push(doc2);
-// const doc7 = Documents.SchemaDocument(schemaDocs)
-function init(mainDocId: string) {
- Documents.initProtos(() => {
- Utils.EmitCallback(Server.Socket, MessageStore.GetField, mainDocId, (res: any) => {
- console.log("HELLO WORLD")
- console.log("RESPONSE: " + res)
- let mainContainer: Document;
- let mainfreeform: Document;
- if (res) {
- mainContainer = ServerUtils.FromJson(res) as Document;
- mainContainer.GetAsync(KeyStore.ActiveFrame, field => mainfreeform = field as Document);
+ getNewWorkspace = (): string => {
+ let newId = Utils.GenerateGuid();
+ const here = window.location.origin;
+ request.post(here + "/addWorkspaceId", {
+ body: { target: newId },
+ json: true
+ })
+ request.post(here + "/setActiveWorkspaceId", {
+ body: { target: newId },
+ json: true
+ })
+ return newId;
+ }
+
+ initRender = (activeWorkspaceId: string) => {
+ Documents.initProtos(activeWorkspaceId, (res?: Document) => {
+ if (res instanceof Document) {
+ this.mainContainer = res;
+ this.mainContainer.GetAsync(KeyStore.ActiveFrame, field => this.mainfreeform = field as Document);
}
else {
- mainContainer = Documents.DockDocument(JSON.stringify({ content: [{ type: 'row', content: [] }] }), { title: "main container" }, mainDocId);
- Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(mainContainer.ToJson()))
+ this.mainContainer = Documents.DockDocument(JSON.stringify({ content: [{ type: 'row', content: [] }] }), { title: "main container" }, this.mainDocId);
- mainfreeform = Documents.FreeformDocument([], { x: 0, y: 400, title: "mini collection" });
- Utils.Emit(Server.Socket, MessageStore.AddDocument, new DocumentTransfer(mainfreeform.ToJson()));
+ // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
+ setTimeout(() => {
+ this.mainfreeform = Documents.FreeformDocument([], { x: 0, y: 400, title: "mini collection" });
- var docs = [mainfreeform].map(doc => CollectionDockingView.makeDocumentConfig(doc));
- mainContainer.SetText(KeyStore.Data, JSON.stringify({ content: [{ type: 'row', content: docs }] }));
- mainContainer.Set(KeyStore.ActiveFrame, mainfreeform);
+ var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(this.mainfreeform)] }] };
+ this.mainContainer.SetText(KeyStore.Data, JSON.stringify(dockingLayout));
+ this.mainContainer.Set(KeyStore.ActiveFrame, this.mainfreeform);
+ }, 0);
}
+ });
+ }
- let addImageNode = action(() => {
- mainfreeform.GetList<Document>(KeyStore.Data, []).push(Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", {
- x: 0, y: 300, width: 200, height: 200, title: "added note"
- }));
- })
- let addTextNode = action(() => {
- mainfreeform.GetList<Document>(KeyStore.Data, []).push(Documents.TextDocument({
- x: 0, y: 300, width: 200, height: 200, title: "added note"
- }));
- })
- let addColNode = action(() => {
- mainfreeform.GetList<Document>(KeyStore.Data, []).push(Documents.FreeformDocument([], {
- x: 0, y: 300, width: 200, height: 200, title: "added note"
- }));
- })
- let addSchemaNode = action(() => {
- mainfreeform.GetList<Document>(KeyStore.Data, []).push(Documents.SchemaDocument([Documents.TextDocument()], {
- x: 0, y: 300, width: 200, height: 200, title: "added note"
- }));
- })
+ render() {
+ let imgRef = React.createRef<HTMLDivElement>();
+ let webRef = React.createRef<HTMLDivElement>();
+ let textRef = React.createRef<HTMLDivElement>();
+ let schemaRef = React.createRef<HTMLDivElement>();
+ let colRef = React.createRef<HTMLDivElement>();
- let clearDatabase = action(() => {
- Utils.Emit(Server.Socket, MessageStore.DeleteAll, {});
- })
+ let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg";
+ let weburl = "https://cs.brown.edu/courses/cs166/";
+ 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 feeform collection" }));
+ let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" }));
+ let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
+ let addWebNode = action(() => Documents.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" }));
- ReactDOM.render((
- <div style={{ position: "absolute", width: "100%", height: "100%" }}>
- <DocumentView Document={mainContainer}
- AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
- ContentScaling={() => 1}
- PanelWidth={() => 0}
- PanelHeight={() => 0}
- isTopMost={true}
- ContainingCollectionView={undefined} />
- <DocumentDecorations />
- <ContextMenu />
- <button style={{
- position: 'absolute',
- bottom: '0px',
- left: '0px',
- width: '150px'
- }} onClick={addImageNode}>Add Image</button>
- <button style={{
- position: 'absolute',
- bottom: '25px',
- left: '0px',
- width: '150px'
- }} onClick={addTextNode}>Add Text</button>
- <button style={{
- position: 'absolute',
- bottom: '50px',
- left: '0px',
- width: '150px'
- }} onClick={addColNode}>Add Collection</button>
- <button style={{
- position: 'absolute',
- bottom: '100',
- left: '0px',
- width: '150px'
- }} onClick={addSchemaNode}>Add Schema</button>
- <button style={{
- position: 'absolute',
- bottom: '75px',
- left: '0px',
- width: '150px'
- }} onClick={clearDatabase}>Clear Database</button>
- <button style={{
- position: 'absolute',
- bottom: '25',
- right: '0px',
- width: '150px'
- }} onClick={() => UndoManager.Undo()}>Undo</button>
- <button style={{
- position: 'absolute',
- bottom: '0',
- right: '0px',
- width: '150px'
- }} onClick={() => UndoManager.Redo()}>Redo</button>
- <button style={{
- position: 'absolute',
- top: '24px',
- right: '0px',
- width: '150px'
- }} onClick={() => window.location.pathname = "/logout"}>Logout</button>
- <button style={{
- position: 'absolute',
- top: '24px',
- left: '4px',
- width: '150px'
- }} onClick={() => WorkspacesMenu.Instance.toggle()}>Workspaces</button>
- <WorkspacesMenu load={init} new={getNewWorkspace} active={mainDocId} />
- </div>),
- document.getElementById('root'));
- })
- });
+ let addClick = (creator: () => Document) => action(() => this.mainfreeform.GetList<Document>(KeyStore.Data, []).push(creator()));
+
+ return (
+ <div style={{ position: "absolute", width: "100%", height: "100%" }}>
+ <DocumentView Document={this.mainContainer}
+ AddDocument={undefined} RemoveDocument={undefined} ScreenToLocalTransform={() => Transform.Identity}
+ ContentScaling={() => 1}
+ PanelWidth={() => 0}
+ PanelHeight={() => 0}
+ isTopMost={true}
+ SelectOnLoad={false}
+ ContainingCollectionView={undefined} />
+ <DocumentDecorations />
+ <ContextMenu />
+ <div className="main-buttonDiv" style={{ bottom: '0px' }} ref={imgRef} >
+ <button onPointerDown={setupDrag(imgRef, addImageNode)} onClick={addClick(addImageNode)}>Add Image</button></div>
+ <div className="main-buttonDiv" style={{ bottom: '25px' }} ref={webRef} >
+ <button onPointerDown={setupDrag(webRef, addWebNode)} onClick={addClick(addWebNode)}>Add Web</button></div>
+ <div className="main-buttonDiv" style={{ bottom: '50px' }} ref={textRef}>
+ <button onPointerDown={setupDrag(textRef, addTextNode)} onClick={addClick(addTextNode)}>Add Text</button></div>
+ <div className="main-buttonDiv" style={{ bottom: '75px' }} ref={colRef}>
+ <button onPointerDown={setupDrag(colRef, addColNode)} onClick={addClick(addColNode)}>Add Collection</button></div>
+ <div className="main-buttonDiv" style={{ bottom: '100px' }} ref={schemaRef}>
+ <button onPointerDown={setupDrag(schemaRef, addSchemaNode)} onClick={addClick(addSchemaNode)}>Add Schema</button></div>
+ <div className="main-buttonDiv" style={{ bottom: '125px' }} >
+ <button onClick={clearDatabase}>Clear Database</button></div>
+ <button className="main-undoButtons" style={{ bottom: '25px' }} onClick={() => UndoManager.Undo()}>Undo</button>
+ <button className="main-undoButtons" style={{ bottom: '0px' }} onClick={() => UndoManager.Redo()}>Redo</button>
+ <WorkspacesMenu active={this.mainDocId} load={this.initRender} new={this.getNewWorkspace} />
+ </div>
+ );
+ }
}
-// let doc5 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", {
-// x: 650, y: 500, width: 600, height: 600, title: "cat 2"
-// });
-// let docset2 = new Array<Document>(doc4);//, doc1, doc3);
-// let doc6 = Documents.CollectionDocument(docset2, {
-// x: 350, y: 100, width: 600, height: 600, title: "docking collection"
-// });
-// let mainNodes = mainContainer.GetOrCreate(KeyStore.Data, ListField);
-// mainNodes.Data.push(doc6);
-// mainNodes.Data.push(doc2);
-// mainNodes.Data.push(doc4);
-// mainNodes.Data.push(doc3);
-// mainNodes.Data.push(doc5);
-// mainNodes.Data.push(doc1);
-//mainNodes.Data.push(doc2);
-//mainNodes.Data.push(doc6);
-// mainContainer.Set(KeyStore.Data, mainNodes);
-//}
-//);
+
+ReactDOM.render(<Main />, document.getElementById('root')); \ No newline at end of file