aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/Server.ts66
-rw-r--r--src/client/SocketStub.ts78
-rw-r--r--src/client/documents/Documents.ts (renamed from src/documents/Documents.ts)19
-rw-r--r--src/client/util/DragManager.ts (renamed from src/util/DragManager.ts)6
-rw-r--r--src/client/util/Scripting.ts (renamed from src/util/Scripting.ts)25
-rw-r--r--src/client/util/ScrollBox.tsx (renamed from src/util/ScrollBox.tsx)0
-rw-r--r--src/client/util/SelectionManager.ts (renamed from src/util/SelectionManager.ts)0
-rw-r--r--src/client/util/TypedEvent.ts (renamed from src/util/TypedEvent.ts)0
-rw-r--r--src/client/views/ContextMenu.scss (renamed from src/views/ContextMenu.scss)0
-rw-r--r--src/client/views/ContextMenu.tsx (renamed from src/views/ContextMenu.tsx)0
-rw-r--r--src/client/views/ContextMenuItem.tsx (renamed from src/views/ContextMenuItem.tsx)0
-rw-r--r--src/client/views/DocumentDecorations.scss (renamed from src/DocumentDecorations.scss)0
-rw-r--r--src/client/views/DocumentDecorations.tsx (renamed from src/DocumentDecorations.tsx)4
-rw-r--r--src/client/views/EditableView.tsx39
-rw-r--r--src/client/views/Main.scss (renamed from src/Main.scss)0
-rw-r--r--src/client/views/Main.tsx (renamed from src/Main.tsx)37
-rw-r--r--src/client/views/collections/CollectionDockingView.scss (renamed from src/views/collections/CollectionDockingView.scss)10
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx (renamed from src/views/collections/CollectionDockingView.tsx)14
-rw-r--r--src/client/views/collections/CollectionFreeFormView.scss (renamed from src/views/collections/CollectionFreeFormView.scss)0
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx (renamed from src/views/collections/CollectionFreeFormView.tsx)39
-rw-r--r--src/client/views/collections/CollectionSchemaView.scss (renamed from src/views/collections/CollectionSchemaView.scss)0
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx (renamed from src/views/collections/CollectionSchemaView.tsx)39
-rw-r--r--src/client/views/collections/CollectionViewBase.tsx (renamed from src/views/collections/CollectionViewBase.tsx)15
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx (renamed from src/views/nodes/CollectionFreeFormDocumentView.tsx)7
-rw-r--r--src/client/views/nodes/DocumentView.tsx (renamed from src/views/nodes/DocumentView.tsx)26
-rw-r--r--src/client/views/nodes/FieldTextBox.scss (renamed from src/views/nodes/FieldTextBox.scss)0
-rw-r--r--src/client/views/nodes/FieldView.tsx (renamed from src/views/nodes/FieldView.tsx)16
-rw-r--r--src/client/views/nodes/FormattedTextBox.scss (renamed from src/views/nodes/FormattedTextBox.scss)0
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx (renamed from src/views/nodes/FormattedTextBox.tsx)12
-rw-r--r--src/client/views/nodes/ImageBox.scss (renamed from src/views/nodes/ImageBox.scss)0
-rw-r--r--src/client/views/nodes/ImageBox.tsx (renamed from src/views/nodes/ImageBox.tsx)4
-rw-r--r--src/client/views/nodes/NodeView.scss (renamed from src/views/nodes/NodeView.scss)0
-rw-r--r--src/fields/Document.ts20
-rw-r--r--src/fields/DocumentReference.ts11
-rw-r--r--src/fields/Field.ts16
-rw-r--r--src/fields/ImageField.ts6
-rw-r--r--src/fields/Key.ts3
-rw-r--r--src/fields/ListField.ts4
-rw-r--r--src/fields/NumberField.ts4
-rw-r--r--src/fields/RichTextField.ts4
-rw-r--r--src/fields/TextField.ts4
-rw-r--r--src/server/index.js13
-rw-r--r--src/server/index.ts29
-rw-r--r--src/stores/NodeCollectionStore.ts26
-rw-r--r--src/stores/NodeStore.ts24
-rw-r--r--src/stores/RootStore.ts15
-rw-r--r--src/stores/StaticTextNodeStore.ts16
-rw-r--r--src/stores/VideoNodeStore.ts17
-rw-r--r--src/views/nodes/TextNodeView.tsx28
-rw-r--r--src/views/nodes/TopBar.tsx46
-rw-r--r--src/views/nodes/VideoNodeView.scss5
-rw-r--r--src/views/nodes/VideoNodeView.tsx29
52 files changed, 426 insertions, 350 deletions
diff --git a/src/client/Server.ts b/src/client/Server.ts
new file mode 100644
index 000000000..66ba92497
--- /dev/null
+++ b/src/client/Server.ts
@@ -0,0 +1,66 @@
+import { Field, FieldWaiting, FIELD_ID, FIELD_WAITING, FieldValue } from "../fields/Field"
+import { Key, KeyStore } from "../fields/Key"
+import { ObservableMap, action } from "mobx";
+import { Document } from "../fields/Document"
+import { SocketStub } from "./SocketStub";
+import * as OpenSocket from 'socket.io-client';
+import { Utils } from "./../Utils";
+import { MessageStore } from "./../server/Message";
+
+export class Server {
+ private static ClientFieldsCached: ObservableMap<FIELD_ID, Field | FIELD_WAITING> = new ObservableMap();
+ static Socket: SocketIOClient.Socket = OpenSocket("http://localhost:8080")
+ static GUID: string = Utils.GenerateGuid()
+
+ // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached).
+ // Call this is from within a reaction and test whether the return value is FieldWaiting.
+ // 'hackTimeout' is here temporarily for simplicity when debugging things.
+ public static GetField(fieldid: FIELD_ID, callback: (field: Field) => void = (f) => { }, hackTimeout: number = -1) {
+ if (!this.ClientFieldsCached.get(fieldid)) {
+ this.ClientFieldsCached.set(fieldid, FieldWaiting);
+ //simulating a server call with a registered callback action
+ SocketStub.SEND_FIELD_REQUEST(fieldid,
+ action((field: Field) => callback(Server.cacheField(field))),
+ hackTimeout);
+ } else if (this.ClientFieldsCached.get(fieldid) != FieldWaiting) {
+ callback(this.ClientFieldsCached.get(fieldid) as Field);
+ }
+ return this.ClientFieldsCached.get(fieldid);
+ }
+
+ static times = 0; // hack for testing
+ public static GetDocumentField(doc: Document, key: Key) {
+ var hackTimeout: number = key == KeyStore.Data ? (this.times++ == 0 ? 5000 : 1000) : key == KeyStore.X ? 2500 : 500;
+
+ return this.GetField(doc._proxies.get(key),
+ action((fieldfromserver: Field) => {
+ doc._proxies.delete(key);
+ doc.fields.set(key, fieldfromserver);
+ })
+ , hackTimeout);
+ }
+
+ public static AddDocument(document: Document) {
+ SocketStub.SEND_ADD_DOCUMENT(document);
+ }
+ public static AddDocumentField(doc: Document, key: Key, value: Field) {
+ SocketStub.SEND_ADD_DOCUMENT_FIELD(doc, key, value);
+ }
+ public static DeleteDocumentField(doc: Document, key: Key) {
+ SocketStub.SEND_DELETE_DOCUMENT_FIELD(doc, key);
+ }
+ public static SetFieldValue(field: Field, value: any) {
+ SocketStub.SEND_SET_FIELD(field, value);
+ }
+
+ @action
+ private static cacheField(clientField: Field) {
+ var cached = this.ClientFieldsCached.get(clientField.Id);
+ if (!cached || cached == FieldWaiting) {
+ this.ClientFieldsCached.set(clientField.Id, clientField);
+ } else {
+ // probably should overwrite the values within any field that was already here...
+ }
+ return this.ClientFieldsCached.get(clientField.Id) as Field;
+ }
+}
diff --git a/src/client/SocketStub.ts b/src/client/SocketStub.ts
new file mode 100644
index 000000000..58dedbf82
--- /dev/null
+++ b/src/client/SocketStub.ts
@@ -0,0 +1,78 @@
+import { Field, FIELD_ID } from "../fields/Field"
+import { Key, KeyStore } from "../fields/Key"
+import { ObservableMap, action } from "mobx";
+import { Document } from "../fields/Document"
+
+export class SocketStub {
+
+ static FieldStore: ObservableMap<FIELD_ID, Field> = new ObservableMap();
+ public static SEND_ADD_DOCUMENT(document: Document) {
+
+ // Send a serialized version of the document to the server
+ // ...SOCKET(ADD_DOCUMENT, serialied document)
+
+ // server stores each document field in its repository of stored fields
+ document.fields.forEach((f, key) => this.FieldStore.set((f as Field).Id, f as Field));
+
+ // server stores stripped down document (w/ only field id proxies) in the field store
+ this.FieldStore.set(document.Id, new Document(document.Id));
+ document.fields.forEach((f, key) => (this.FieldStore.get(document.Id) as Document)._proxies.set(key, (f as Field).Id));
+ }
+
+ public static SEND_FIELD_REQUEST(fieldid: FIELD_ID, callback: (field: Field) => void, timeout: number) {
+
+ if (timeout < 0)// this is a hack to make things easier to setup until we have a server... won't be neededa fter that.
+ callback(this.FieldStore.get(fieldid) as Field);
+ else { // actual logic here...
+
+ // Send a request for fieldid to the server
+ // ...SOCKET(RETRIEVE_FIELD, fieldid)
+
+ // server responds (simulated with a timeout) and the callback is invoked
+ setTimeout(() =>
+
+ // when the field data comes back, call the callback() function
+ callback(this.FieldStore.get(fieldid) as Field),
+
+
+ timeout);
+ }
+ }
+
+ public static SEND_ADD_DOCUMENT_FIELD(doc: Document, key: Key, value: Field) {
+
+ // Send a serialized version of the field to the server along with the
+ // associated info of the document id and key where it is used.
+
+ // ...SOCKET(ADD_DOCUMENT_FIELD, document id, key id, serialized field)
+
+ // server updates its document to hold a proxy mapping from key => fieldId
+ var document = this.FieldStore.get(doc.Id) as Document;
+ if (document)
+ document._proxies.set(key, value.Id);
+
+ // server adds the field to its repository of fields
+ this.FieldStore.set(value.Id, value);
+ }
+
+ public static SEND_DELETE_DOCUMENT_FIELD(doc: Document, key: Key) {
+ // Send a request to delete the field stored under the specified key from the document
+
+ // ...SOCKET(DELETE_DOCUMENT_FIELD, document id, key id)
+
+ // Server removes the field id from the document's list of field proxies
+ var document = this.FieldStore.get(doc.Id) as Document;
+ if (document)
+ document._proxies.delete(key);
+ }
+
+ public static SEND_SET_FIELD(field: Field, value: any) {
+ // Send a request to set the value of a field
+
+ // ...SOCKET(SET_FIELD, field id, serialized field value)
+
+ // Server updates the value of the field in its fieldstore
+ if (this.FieldStore.get(field.Id))
+ this.FieldStore.get(field.Id)!.TrySetValue(value);
+ }
+}
diff --git a/src/documents/Documents.ts b/src/client/documents/Documents.ts
index 90124d36c..6925234fe 100644
--- a/src/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,16 +1,16 @@
-import { Document } from "../fields/Document";
+import { Document } from "../../fields/Document";
import { Server } from "../Server";
-import { KeyStore } from "../fields/Key";
-import { TextField } from "../fields/TextField";
-import { NumberField } from "../fields/NumberField";
-import { ListField } from "../fields/ListField";
+import { KeyStore } from "../../fields/Key";
+import { TextField } from "../../fields/TextField";
+import { NumberField } from "../../fields/NumberField";
+import { ListField } from "../../fields/ListField";
import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
import { CollectionSchemaView } from "../views/collections/CollectionSchemaView";
-import { ImageField } from "../fields/ImageField";
+import { ImageField } from "../../fields/ImageField";
import { ImageBox } from "../views/nodes/ImageBox";
import { CollectionFreeFormView } from "../views/collections/CollectionFreeFormView";
-import { FIELD_ID } from "../fields/Field";
+import { FIELD_ID } from "../../fields/Field";
interface DocumentOptions {
x?: number;
@@ -123,7 +123,7 @@ export namespace Documents {
Server.AddDocument(imageProto);
return imageProto;
}
- return Server.GetDocument(imageProtoId, true)!;
+ return Server.GetField(imageProtoId) as Document;
}
export function ImageDocument(url: string, options: DocumentOptions = {}): Document {
@@ -131,7 +131,8 @@ export namespace Documents {
setupOptions(doc, options);
doc.Set(KeyStore.Data, new ImageField(new URL(url)));
Server.AddDocument(doc);
- return Server.GetDocument(doc.Id, true)!;
+ var sdoc = Server.GetField(doc.Id) as Document;
+ return sdoc;
}
let collectionProto: Document;
diff --git a/src/util/DragManager.ts b/src/client/util/DragManager.ts
index 63d6a88f8..f4dcce7c8 100644
--- a/src/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,9 +1,3 @@
-import { Opt } from "../fields/Field";
-import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView";
-import { DocumentDecorations } from "../DocumentDecorations";
-import { SelectionManager } from "./SelectionManager";
-import { CollectionDockingView } from "../views/collections/CollectionDockingView";
-import { Document } from "../fields/Document";
export namespace DragManager {
export function Root() {
diff --git a/src/util/Scripting.ts b/src/client/util/Scripting.ts
index 804c67bc5..6bc5fa412 100644
--- a/src/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -1,11 +1,12 @@
// import * as ts from "typescript"
let ts = (window as any).ts;
-import { Opt, Field, FieldWaiting } from "../fields/Field";
-import { Document as DocumentImport } from "../fields/Document";
-import { NumberField as NumberFieldImport } from "../fields/NumberField";
-import { TextField as TextFieldImport } from "../fields/TextField";
-import { RichTextField as RichTextFieldImport } from "../fields/RichTextField";
-import { KeyStore as KeyStoreImport } from "../fields/Key";
+import { Opt, Field } from "../../fields/Field";
+import { Document as DocumentImport } from "../../fields/Document";
+import { NumberField as NumberFieldImport, NumberField } from "../../fields/NumberField";
+import { ImageField as ImageFieldImport } from "../../fields/ImageField";
+import { TextField as TextFieldImport, TextField } from "../../fields/TextField";
+import { RichTextField as RichTextFieldImport } from "../../fields/RichTextField";
+import { KeyStore as KeyStoreImport } from "../../fields/Key";
export interface ExecutableScript {
(): any;
@@ -14,7 +15,7 @@ export interface ExecutableScript {
}
function ExecScript(script: string, diagnostics: Opt<any[]>): ExecutableScript {
- const compiled = !(diagnostics && diagnostics != FieldWaiting && diagnostics.some(diag => diag.category == ts.DiagnosticCategory.Error));
+ const compiled = !(diagnostics && diagnostics.some(diag => diag.category == ts.DiagnosticCategory.Error));
let func: () => Opt<Field>;
if (compiled) {
@@ -23,6 +24,7 @@ function ExecScript(script: string, diagnostics: Opt<any[]>): ExecutableScript {
let Document = DocumentImport;
let NumberField = NumberFieldImport;
let TextField = TextFieldImport;
+ let ImageField = ImageFieldImport;
let RichTextField = RichTextFieldImport;
let window = undefined;
let document = undefined;
@@ -44,4 +46,13 @@ export function CompileScript(script: string): ExecutableScript {
let result = (window as any).ts.transpileModule(script, {})
return ExecScript(result.outputText, result.diagnostics);
+}
+
+export function ToField(data: any): Opt<Field> {
+ if (typeof data == "string") {
+ return new TextField(data);
+ } else if (typeof data == "number") {
+ return new NumberField(data);
+ }
+ return undefined;
} \ No newline at end of file
diff --git a/src/util/ScrollBox.tsx b/src/client/util/ScrollBox.tsx
index b6b088170..b6b088170 100644
--- a/src/util/ScrollBox.tsx
+++ b/src/client/util/ScrollBox.tsx
diff --git a/src/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 0759ae110..0759ae110 100644
--- a/src/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
diff --git a/src/util/TypedEvent.ts b/src/client/util/TypedEvent.ts
index 0714a7f5c..0714a7f5c 100644
--- a/src/util/TypedEvent.ts
+++ b/src/client/util/TypedEvent.ts
diff --git a/src/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 234f82eb9..234f82eb9 100644
--- a/src/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
diff --git a/src/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index 4f26a75d2..4f26a75d2 100644
--- a/src/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
diff --git a/src/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 8f00f8b3d..8f00f8b3d 100644
--- a/src/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
diff --git a/src/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index e8b93a18b..e8b93a18b 100644
--- a/src/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
diff --git a/src/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 1cf875ea5..8a94bff36 100644
--- a/src/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,9 +1,9 @@
import { observable, computed } from "mobx";
import React = require("react");
-import { SelectionManager } from "./util/SelectionManager";
+import { SelectionManager } from "../util/SelectionManager";
import { observer } from "mobx-react";
import './DocumentDecorations.scss'
-import { CollectionFreeFormView } from "./views/collections/CollectionFreeFormView";
+import { CollectionFreeFormView } from "./collections/CollectionFreeFormView";
@observer
export class DocumentDecorations extends React.Component {
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
new file mode 100644
index 000000000..2e784d3f9
--- /dev/null
+++ b/src/client/views/EditableView.tsx
@@ -0,0 +1,39 @@
+import React = require('react')
+import { observer } from 'mobx-react';
+import { observable, action } from 'mobx';
+
+export interface EditableProps {
+ GetValue(): string;
+ SetValue(value: string): boolean;
+ contents: any;
+}
+
+@observer
+export class EditableView extends React.Component<EditableProps> {
+ @observable
+ editing: boolean = false;
+
+ @action
+ onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
+ if (e.key == "Enter" && !e.ctrlKey) {
+ this.props.SetValue(e.currentTarget.value);
+ this.editing = false;
+ } else if (e.key == "Escape") {
+ this.editing = false;
+ }
+ }
+
+ render() {
+ if (this.editing) {
+ return <input defaultValue={this.props.GetValue()} onKeyDown={this.onKeyDown} autoFocus onBlur={action(() => this.editing = false)}
+ style={{ width: "100%" }}></input>
+ } else {
+ return (
+ <div>
+ {this.props.contents}
+ <button onClick={action(() => this.editing = true)}>Edit</button>
+ </div>
+ )
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Main.scss b/src/client/views/Main.scss
index e73f62904..e73f62904 100644
--- a/src/Main.scss
+++ b/src/client/views/Main.scss
diff --git a/src/Main.tsx b/src/client/views/Main.tsx
index 6730cf799..9a359e868 100644
--- a/src/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -3,16 +3,16 @@ 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, KeyStore as KS } from './fields/Key';
-import { ListField } from './fields/ListField';
-import { NumberField } from './fields/NumberField';
-import { TextField } from './fields/TextField';
+import { Documents } from '../documents/Documents';
+import { Document } from '../../fields/Document';
+import { KeyStore, KeyStore as KS } from '../../fields/Key';
+import { ListField } from '../../fields/ListField';
+import { NumberField } from '../../fields/NumberField';
+import { TextField } from '../../fields/TextField';
import "./Main.scss";
-import { ContextMenu } from './views/ContextMenu';
-import { DocumentView } from './views/nodes/DocumentView';
-import { CompileScript } from './util/Scripting';
+import { ContextMenu } from './ContextMenu';
+import { DocumentView } from './nodes/DocumentView';
+import { ImageField } from '../../fields/ImageField';
configure({
@@ -44,16 +44,17 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
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: 500, title: "cat 1"
+ x: 450, y: 100, title: "cat 1"
});
- // 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)
- const docset = [doc3]; // [doc1, doc2, doc3, doc7];
+ 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)
+ const docset = [doc1, doc2, doc3, doc7];
let doc4 = Documents.CollectionDocument(docset, {
x: 0, y: 400, title: "mini collection"
});
diff --git a/src/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index db924b57f..7c0b512a7 100644
--- a/src/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -126,7 +126,7 @@
}
.flexlayout__tab_button:hover .flexlayout__tab_button_trailing,
.flexlayout__tab_button--selected .flexlayout__tab_button_trailing {
- background: transparent url("../../../node_modules/flexlayout-react/images/close_white.png") no-repeat center;
+ background: transparent url("../../../../node_modules/flexlayout-react/images/close_white.png") no-repeat center;
}
.flexlayout__tab_button_overflow {
float: left;
@@ -138,7 +138,7 @@
font-size: 10px;
color: lightgray;
font-family: Arial, sans-serif;
- background: transparent url("../../../node_modules/flexlayout-react/images/more.png") no-repeat left;
+ background: transparent url("../../../../node_modules/flexlayout-react/images/more.png") no-repeat left;
}
.flexlayout__tabset_header {
position: absolute;
@@ -186,14 +186,14 @@
height: 20px;
border: none;
outline-width: 0;
- background: transparent url("../../../node_modules/flexlayout-react/images/maximize.png") no-repeat center;
+ background: transparent url("../../../../node_modules/flexlayout-react/images/maximize.png") no-repeat center;
}
.flexlayout__tab_toolbar_button-max {
width: 20px;
height: 20px;
border: none;
outline-width: 0;
- background: transparent url("../../../node_modules/flexlayout-react/images/restore.png") no-repeat center;
+ background: transparent url("../../../../node_modules/flexlayout-react/images/restore.png") no-repeat center;
}
.flexlayout__popup_menu {}
.flexlayout__popup_menu_item {
@@ -295,7 +295,7 @@
}
.flexlayout__border_button:hover .flexlayout__border_button_trailing,
.flexlayout__border_button--selected .flexlayout__border_button_trailing {
- background: transparent url("../../../node_modules/flexlayout-react/images/close_white.png") no-repeat center;
+ background: transparent url("../../../../node_modules/flexlayout-react/images/close_white.png") no-repeat center;
}
.flexlayout__border_toolbar_left {
position: absolute;
diff --git a/src/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index e489e319a..9aee9c10f 100644
--- a/src/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -1,13 +1,12 @@
import { observer } from "mobx-react";
-import { KeyStore } from "../../fields/Key";
+import { KeyStore } from "../../../fields/Key";
import React = require("react");
import FlexLayout from "flexlayout-react";
import { action, observable, computed } from "mobx";
-import { Document } from "../../fields/Document";
+import { Document } from "../../../fields/Document";
import { DocumentView } from "../nodes/DocumentView";
-import { ListField } from "../../fields/ListField";
-import { NumberField } from "../../fields/NumberField";
-import { SSL_OP_SINGLE_DH_USE } from "constants";
+import { ListField } from "../../../fields/ListField";
+import { NumberField } from "../../../fields/NumberField";
import "./CollectionDockingView.scss"
import 'golden-layout/src/css/goldenlayout-base.css';
import 'golden-layout/src/css/goldenlayout-dark-theme.css';
@@ -15,7 +14,6 @@ import * as GoldenLayout from "golden-layout";
import * as ReactDOM from 'react-dom';
import { DragManager } from "../../util/DragManager";
import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase";
-import { FieldWaiting } from "../../fields/Field";
@observer
export class CollectionDockingView extends CollectionViewBase {
@@ -70,8 +68,6 @@ export class CollectionDockingView extends CollectionViewBase {
@action
onResize = (event: any) => {
- if (this.props.ContainingDocumentView == FieldWaiting)
- return;
var cur = this.props.ContainingDocumentView!.MainContent.current;
// bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed
@@ -255,8 +251,6 @@ export class CollectionDockingView extends CollectionViewBase {
render() {
- if (this.props.ContainingDocumentView == FieldWaiting)
- return;
const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props;
const value: Document[] = Document.GetData(fieldKey, ListField, []);
// bcz: not sure why, but I need these to force the flexlayout to update when the collection size changes.
diff --git a/src/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss
index e9d134e7b..e9d134e7b 100644
--- a/src/views/collections/CollectionFreeFormView.scss
+++ b/src/client/views/collections/CollectionFreeFormView.scss
diff --git a/src/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 45d37ca4f..9cf29d000 100644
--- a/src/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -1,19 +1,18 @@
import { observer } from "mobx-react";
-import { Key, KeyStore } from "../../fields/Key";
import React = require("react");
import { action, observable, computed } from "mobx";
-import { Document } from "../../fields/Document";
import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
-import { ListField } from "../../fields/ListField";
-import { NumberField } from "../../fields/NumberField";
-import { SSL_OP_SINGLE_DH_USE } from "constants";
-import { Documents } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
import "./CollectionFreeFormView.scss";
-import { Utils } from "../../Utils";
+import { Utils } from "../../../Utils";
import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase";
import { SelectionManager } from "../../util/SelectionManager";
-import { FieldWaiting } from "../../fields/Field";
+import { Key, KeyStore } from "../../../fields/Key";
+import { Document } from "../../../fields/Document";
+import { ListField } from "../../../fields/ListField";
+import { NumberField } from "../../../fields/NumberField";
+import { Documents } from "../../documents/Documents";
+import { FieldWaiting } from "../../../fields/Field";
@observer
export class CollectionFreeFormView extends CollectionViewBase {
@@ -33,23 +32,21 @@ export class CollectionFreeFormView extends CollectionViewBase {
const doc = de.data["document"];
var me = this;
if (doc instanceof CollectionFreeFormDocumentView) {
- if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this && doc.props.ContainingCollectionView != FieldWaiting) {
+ if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) {
doc.props.ContainingCollectionView.removeDocument(doc.props.Document);
this.addDocument(doc.props.Document);
}
const xOffset = de.data["xOffset"] as number || 0;
const yOffset = de.data["yOffset"] as number || 0;
const { scale, translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!);
- if (this.props.ContainingDocumentView != FieldWaiting) {
- let sscale = this.props.ContainingDocumentView!.props.Document.GetData(KeyStore.Scale, NumberField, Number(1))
- const screenX = de.x - xOffset;
- const screenY = de.y - yOffset;
- const docX = (screenX - translateX) / sscale / scale;
- const docY = (screenY - translateY) / sscale / scale;
- doc.x = docX;
- doc.y = docY;
- this.bringToFront(doc);
- }
+ let sscale = this.props.ContainingDocumentView!.props.Document.GetData(KeyStore.Scale, NumberField, Number(1))
+ const screenX = de.x - xOffset;
+ const screenY = de.y - yOffset;
+ const docX = (screenX - translateX) / sscale / scale;
+ const docY = (screenY - translateY) / sscale / scale;
+ doc.x = docX;
+ doc.y = docY;
+ this.bringToFront(doc);
}
e.stopPropagation();
}
@@ -88,7 +85,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
@action
onPointerMove = (e: PointerEvent): void => {
var me = this;
- if (!e.cancelBubble && this.active && this.props.ContainingDocumentView != FieldWaiting) {
+ if (!e.cancelBubble && this.active) {
e.preventDefault();
e.stopPropagation();
let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace;
@@ -105,8 +102,6 @@ export class CollectionFreeFormView extends CollectionViewBase {
onPointerWheel = (e: React.WheelEvent): void => {
e.stopPropagation();
- if (this.props.ContainingDocumentView == FieldWaiting)
- return;
let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY);
var deltaScale = (1 - (e.deltaY / 1000)) * Ss;
diff --git a/src/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 707b44db6..707b44db6 100644
--- a/src/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
diff --git a/src/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 8817cb496..2d5bd6c99 100644
--- a/src/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,8 +1,6 @@
import React = require("react")
import ReactTable, { ReactTableDefaults, CellInfo, ComponentPropsGetterRC, ComponentPropsGetterR } from "react-table";
import { observer } from "mobx-react";
-import { KeyStore as KS, Key } from "../../fields/Key";
-import { Document } from "../../fields/Document";
import { FieldView, FieldViewProps } from "../nodes/FieldView";
import "react-table/react-table.css"
import { observable, action, computed } from "mobx";
@@ -11,6 +9,11 @@ import "./CollectionSchemaView.scss"
import { ScrollBox } from "../../util/ScrollBox";
import { CollectionViewBase } from "./CollectionViewBase";
import { DocumentView } from "../nodes/DocumentView";
+import { EditableView } from "../EditableView";
+import { CompileScript, ToField } from "../../util/Scripting";
+import { KeyStore as KS, Key } from "../../../fields/Key";
+import { Document } from "../../../fields/Document";
+import { Field } from "../../../fields/Field";
@observer
export class CollectionSchemaView extends CollectionViewBase {
@@ -25,9 +28,35 @@ export class CollectionSchemaView extends CollectionViewBase {
fieldKey: rowProps.value[1],
DocumentViewForField: undefined
}
- return (
+ let contents = (
<FieldView {...props} />
)
+ return (
+ <EditableView contents={contents} GetValue={() => {
+ let field = props.doc.Get(props.fieldKey);
+ if (field && field instanceof Field) {
+ return field.ToScriptString();
+ }
+ return field || "";
+ }} SetValue={(value: string) => {
+ let script = CompileScript(value);
+ if (!script.compiled) {
+ return false;
+ }
+ let field = script();
+ if (field instanceof Field) {
+ props.doc.Set(props.fieldKey, field);
+ return true;
+ } else {
+ let dataField = ToField(field);
+ if (dataField) {
+ props.doc.Set(props.fieldKey, dataField);
+ return true;
+ }
+ }
+ return false;
+ }}></EditableView>
+ )
}
private getTrProps: ComponentPropsGetterR = (state, rowInfo) => {
@@ -74,7 +103,9 @@ export class CollectionSchemaView extends CollectionViewBase {
[KS.Title, KS.Data, KS.Author])
let content;
if (this.selectedIndex != -1) {
- content = (<DocumentView Document={children[this.selectedIndex]} DocumentView={undefined} ContainingCollectionView={this} />)
+ content = (
+ <DocumentView Document={children[this.selectedIndex]} DocumentView={undefined} ContainingCollectionView={this} />
+ )
} else {
content = <div />
}
diff --git a/src/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx
index 4fce02ef6..09e8ec729 100644
--- a/src/views/collections/CollectionViewBase.tsx
+++ b/src/client/views/collections/CollectionViewBase.tsx
@@ -1,9 +1,9 @@
import { action, computed } from "mobx";
import { observer } from "mobx-react";
-import { Document } from "../../fields/Document";
-import { Opt, FieldWaiting } from "../../fields/Field";
-import { Key, KeyStore } from "../../fields/Key";
-import { ListField } from "../../fields/ListField";
+import { Document } from "../../../fields/Document";
+import { Opt } from "../../../fields/Field";
+import { Key, KeyStore } from "../../../fields/Key";
+import { ListField } from "../../../fields/ListField";
import { SelectionManager } from "../../util/SelectionManager";
import { ContextMenu } from "../ContextMenu";
import React = require("react");
@@ -30,10 +30,9 @@ export class CollectionViewBase extends React.Component<CollectionViewProps> {
public get active(): boolean {
var isSelected = (this.props.ContainingDocumentView instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.ContainingDocumentView));
var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this);
- var topMost = this.props.ContainingDocumentView != undefined &&
- this.props.ContainingDocumentView != FieldWaiting && this.props.ContainingDocumentView.props.ContainingCollectionView != FieldWaiting && (
- this.props.ContainingDocumentView.props.ContainingCollectionView == undefined ||
- this.props.ContainingDocumentView.props.ContainingCollectionView instanceof CollectionDockingView);
+ var topMost = this.props.ContainingDocumentView != undefined && (
+ this.props.ContainingDocumentView.props.ContainingCollectionView == undefined ||
+ this.props.ContainingDocumentView.props.ContainingCollectionView instanceof CollectionDockingView);
return isSelected || childSelected || topMost;
}
@action
diff --git a/src/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 25d67d96a..1d53cedc4 100644
--- a/src/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,7 +1,7 @@
import { action, computed } from "mobx";
import { observer } from "mobx-react";
-import { Key, KeyStore } from "../../fields/Key";
-import { NumberField } from "../../fields/NumberField";
+import { Key, KeyStore } from "../../../fields/Key";
+import { NumberField } from "../../../fields/NumberField";
import { DragManager } from "../../util/DragManager";
import { SelectionManager } from "../../util/SelectionManager";
import { CollectionDockingView } from "../collections/CollectionDockingView";
@@ -10,7 +10,6 @@ import { ContextMenu } from "../ContextMenu";
import "./NodeView.scss";
import React = require("react");
import { DocumentView, DocumentViewProps } from "./DocumentView";
-import { FieldWaiting } from "../../fields/Field";
@observer
@@ -86,7 +85,7 @@ export class CollectionFreeFormDocumentView extends DocumentView {
@computed
get active(): boolean {
return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined ||
- (this.props.ContainingCollectionView != FieldWaiting && this.props.ContainingCollectionView!.active);
+ this.props.ContainingCollectionView.active;
}
@computed
diff --git a/src/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 81353cd60..730ce62f2 100644
--- a/src/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,12 +1,12 @@
import { action, computed } from "mobx";
import { observer } from "mobx-react";
-import { Document } from "../../fields/Document";
-import { Opt, FieldWaiting } from "../../fields/Field";
-import { Key, KeyStore } from "../../fields/Key";
-import { ListField } from "../../fields/ListField";
-import { NumberField } from "../../fields/NumberField";
-import { TextField } from "../../fields/TextField";
-import { Utils } from "../../Utils";
+import { Document } from "../../../fields/Document";
+import { Opt, FieldWaiting } from "../../../fields/Field";
+import { Key, KeyStore } from "../../../fields/Key";
+import { ListField } from "../../../fields/ListField";
+import { NumberField } from "../../../fields/NumberField";
+import { TextField } from "../../../fields/TextField";
+import { Utils } from "../../../Utils";
import { CollectionDockingView } from "../collections/CollectionDockingView";
import { CollectionFreeFormView } from "../collections/CollectionFreeFormView";
import { CollectionSchemaView } from "../collections/CollectionSchemaView";
@@ -49,8 +49,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
//
@computed
public get ScalingToScreenSpace(): number {
- if (this.props.ContainingCollectionView != undefined && this.props.ContainingCollectionView != FieldWaiting &&
- this.props.ContainingCollectionView.props.ContainingDocumentView != undefined && this.props.ContainingCollectionView.props.ContainingDocumentView != FieldWaiting) {
+ if (this.props.ContainingCollectionView != undefined &&
+ this.props.ContainingCollectionView.props.ContainingDocumentView != undefined) {
let ss = this.props.ContainingCollectionView.props.DocumentForCollection.GetData(KeyStore.Scale, NumberField, Number(1));
return this.props.ContainingCollectionView.props.ContainingDocumentView.ScalingToScreenSpace * ss;
}
@@ -63,8 +63,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
public TransformToLocalPoint(screenX: number, screenY: number) {
// if this collection view is nested within another collection view, then
// first transform the screen point into the parent collection's coordinate space.
- let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView != undefined && this.props.ContainingCollectionView != FieldWaiting &&
- this.props.ContainingCollectionView.props.ContainingDocumentView != undefined && this.props.ContainingCollectionView.props.ContainingDocumentView != FieldWaiting ?
+ let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView != undefined &&
+ this.props.ContainingCollectionView.props.ContainingDocumentView != undefined ?
this.props.ContainingCollectionView.props.ContainingDocumentView.TransformToLocalPoint(screenX, screenY) :
{ LocalX: screenX, LocalY: screenY };
let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH;
@@ -113,8 +113,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
// if this collection view is nested within another collection view, then
// first transform the local point into the parent collection's coordinate space.
- let containingDocView = this.props.ContainingCollectionView != undefined && this.props.ContainingCollectionView != FieldWaiting ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined;
- if (containingDocView != undefined && containingDocView != FieldWaiting) {
+ let containingDocView = this.props.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined;
+ if (containingDocView != undefined) {
let ss = containingDocView.props.Document.GetData(KeyStore.Scale, NumberField, Number(1));
let panxx = containingDocView.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss;
let panyy = containingDocView.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss;
diff --git a/src/views/nodes/FieldTextBox.scss b/src/client/views/nodes/FieldTextBox.scss
index b6ce2fabc..b6ce2fabc 100644
--- a/src/views/nodes/FieldTextBox.scss
+++ b/src/client/views/nodes/FieldTextBox.scss
diff --git a/src/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 05a7b91b9..12371eb2e 100644
--- a/src/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -1,15 +1,15 @@
import React = require("react")
-import { Document } from "../../fields/Document";
import { observer } from "mobx-react";
import { computed } from "mobx";
-import { Field, Opt, FieldWaiting } from "../../fields/Field";
-import { TextField } from "../../fields/TextField";
-import { NumberField } from "../../fields/NumberField";
-import { RichTextField } from "../../fields/RichTextField";
+import { Field, Opt, FieldWaiting, FieldValue } from "../../../fields/Field";
+import { Document } from "../../../fields/Document";
+import { TextField } from "../../../fields/TextField";
+import { NumberField } from "../../../fields/NumberField";
+import { RichTextField } from "../../../fields/RichTextField";
+import { ImageField } from "../../../fields/ImageField";
+import { Key } from "../../../fields/Key";
import { FormattedTextBox } from "./FormattedTextBox";
-import { ImageField } from "../../fields/ImageField";
import { ImageBox } from "./ImageBox";
-import { Key } from "../../fields/Key";
import { DocumentView } from "./DocumentView";
//
@@ -27,7 +27,7 @@ export interface FieldViewProps {
export class FieldView extends React.Component<FieldViewProps> {
public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} />`; }
@computed
- get field(): Opt<Field> {
+ get field(): FieldValue<Field> {
const { doc, fieldKey } = this.props;
return doc.Get(fieldKey);
}
diff --git a/src/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss
index 492367fce..492367fce 100644
--- a/src/views/nodes/FormattedTextBox.scss
+++ b/src/client/views/nodes/FormattedTextBox.scss
diff --git a/src/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 3e3e22e46..8bc4c902c 100644
--- a/src/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -6,11 +6,11 @@ import { keymap } from "prosemirror-keymap";
import { schema } from "prosemirror-schema-basic";
import { EditorState, Transaction } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
-import { Opt, FieldWaiting } from "../../fields/Field";
+import { Opt, FieldWaiting, FieldValue } from "../../../fields/Field";
import { SelectionManager } from "../../util/SelectionManager";
import "./FormattedTextBox.scss";
import React = require("react")
-import { RichTextField } from "../../fields/RichTextField";
+import { RichTextField } from "../../../fields/RichTextField";
import { FieldViewProps, FieldView } from "./FieldView";
import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
@@ -48,7 +48,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
}
dispatchTransaction = (tx: Transaction) => {
- if (this._editorView && this._editorView != FieldWaiting) {
+ if (this._editorView) {
const state = this._editorView.state.apply(tx);
this._editorView.updateState(state);
const { doc, fieldKey } = this.props;
@@ -85,17 +85,17 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
const field = this.props.doc.GetT(this.props.fieldKey, RichTextField);
return field && field != FieldWaiting ? field.Data : undefined;
}, (field) => {
- if (field && this._editorView && this._editorView != FieldWaiting) {
+ if (field && this._editorView) {
this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field)));
}
})
}
componentWillUnmount() {
- if (this._editorView && this._editorView != FieldWaiting) {
+ if (this._editorView) {
this._editorView.destroy();
}
- if (this._reactionDisposer && this._reactionDisposer != FieldWaiting) {
+ if (this._reactionDisposer) {
this._reactionDisposer();
}
}
diff --git a/src/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index 136fda1d0..136fda1d0 100644
--- a/src/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
diff --git a/src/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 123c76d19..ab20f140c 100644
--- a/src/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -4,10 +4,10 @@ import 'react-image-lightbox/style.css'; // This only needs to be imported once
import { SelectionManager } from "../../util/SelectionManager";
import "./ImageBox.scss";
import React = require("react")
-import { ImageField } from '../../fields/ImageField';
+import { ImageField } from '../../../fields/ImageField';
import { FieldViewProps, FieldView } from './FieldView';
import { CollectionFreeFormDocumentView } from './CollectionFreeFormDocumentView';
-import { FieldWaiting } from '../../fields/Field';
+import { FieldWaiting } from '../../../fields/Field';
import { observer } from "mobx-react"
import { observable, action } from 'mobx';
diff --git a/src/views/nodes/NodeView.scss b/src/client/views/nodes/NodeView.scss
index dac1c0a8e..dac1c0a8e 100644
--- a/src/views/nodes/NodeView.scss
+++ b/src/client/views/nodes/NodeView.scss
diff --git a/src/fields/Document.ts b/src/fields/Document.ts
index 3d74c047c..6f9752a8e 100644
--- a/src/fields/Document.ts
+++ b/src/fields/Document.ts
@@ -1,11 +1,11 @@
-import { Field, Cast, Opt, FieldWaiting, FIELD_ID, DOC_ID } from "./Field"
+import { Field, Cast, Opt, FieldWaiting, FIELD_ID, FieldValue } from "./Field"
import { Key, KeyStore } from "./Key"
import { NumberField } from "./NumberField";
import { ObservableMap, computed, action, observable } from "mobx";
import { TextField } from "./TextField";
import { ListField } from "./ListField";
import { findDOMNode } from "react-dom";
-import { Server } from "../Server";
+import { Server } from "../client/Server";
export class Document extends Field {
public fields: ObservableMap<Key, Opt<Field>> = new ObservableMap();
@@ -16,8 +16,8 @@ export class Document extends Field {
return this.GetText(KeyStore.Title, "<untitled>");
}
- Get(key: Key, ignoreProto: boolean = false): Opt<Field> {
- let field: Opt<Field>;
+ Get(key: Key, ignoreProto: boolean = false): FieldValue<Field> {
+ let field: FieldValue<Field>;
if (ignoreProto) {
if (this.fields.has(key)) {
field = this.fields.get(key);
@@ -25,7 +25,7 @@ export class Document extends Field {
field = Server.GetDocumentField(this, key);
}
} else {
- let doc: Opt<Document> = this;
+ let doc: FieldValue<Document> = this;
while (doc && doc != FieldWaiting && field != FieldWaiting) {
if (!doc.fields.has(key)) {
if (doc._proxies.has(key)) {
@@ -46,7 +46,7 @@ export class Document extends Field {
return field;
}
- GetT<T extends Field = Field>(key: Key, ctor: { new(...args: any[]): T }, ignoreProto: boolean = false): Opt<T> {
+ GetT<T extends Field = Field>(key: Key, ctor: { new(...args: any[]): T }, ignoreProto: boolean = false): FieldValue<T> {
var getfield = this.Get(key, ignoreProto);
if (getfield != FieldWaiting) {
return Cast(getfield, ctor);
@@ -119,13 +119,13 @@ export class Document extends Field {
this.SetData(key, value, NumberField, replaceWrongType);
}
- GetPrototype(): Opt<Document> {
+ GetPrototype(): FieldValue<Document> {
return this.GetT(KeyStore.Prototype, Document, true);
}
GetAllPrototypes(): Document[] {
let protos: Document[] = [];
- let doc: Opt<Document> = this;
+ let doc: FieldValue<Document> = this;
while (doc && doc != FieldWaiting) {
protos.push(doc);
doc = doc.GetPrototype();
@@ -141,6 +141,10 @@ export class Document extends Field {
return delegate;
}
+ ToScriptString(): string {
+ return "";
+ }
+
TrySetValue(value: any): boolean {
throw new Error("Method not implemented.");
}
diff --git a/src/fields/DocumentReference.ts b/src/fields/DocumentReference.ts
index 10dac9f92..983b162a3 100644
--- a/src/fields/DocumentReference.ts
+++ b/src/fields/DocumentReference.ts
@@ -1,4 +1,4 @@
-import { Field, Opt } from "./Field";
+import { Field, Opt, FieldValue } from "./Field";
import { Document } from "./Document";
import { Key } from "./Key";
@@ -15,12 +15,12 @@ export class DocumentReference extends Field {
super();
}
- Dereference(): Opt<Field> {
+ Dereference(): FieldValue<Field> {
return this.document.Get(this.key);
}
- DereferenceToRoot(): Opt<Field> {
- let field: Opt<Field> = this;
+ DereferenceToRoot(): FieldValue<Field> {
+ let field: FieldValue<Field> = this;
while (field instanceof DocumentReference) {
field = field.Dereference();
}
@@ -37,5 +37,8 @@ export class DocumentReference extends Field {
throw new Error("Method not implemented.");
}
+ ToScriptString(): string {
+ return "";
+ }
} \ No newline at end of file
diff --git a/src/fields/Field.ts b/src/fields/Field.ts
index 9880116c0..6adee9b61 100644
--- a/src/fields/Field.ts
+++ b/src/fields/Field.ts
@@ -1,7 +1,7 @@
import { Utils } from "../Utils";
-export function Cast<T extends Field>(field: Opt<Field>, ctor: { new(): T }): Opt<T> {
+export function Cast<T extends Field>(field: FieldValue<Field>, ctor: { new(): T }): Opt<T> {
if (field) {
if (ctor && field instanceof ctor) {
return field;
@@ -13,8 +13,8 @@ export function Cast<T extends Field>(field: Opt<Field>, ctor: { new(): T }): Op
export let FieldWaiting: FIELD_WAITING = "<Waiting>";
export type FIELD_WAITING = "<Waiting>";
export type FIELD_ID = string | undefined;
-export type DOC_ID = FIELD_ID;
-export type Opt<T> = T | undefined | FIELD_WAITING;
+export type Opt<T> = T | undefined;
+export type FieldValue<T> = Opt<T> | FIELD_WAITING;
export abstract class Field {
//FieldUpdated: TypedEvent<Opt<FieldUpdatedArgs>> = new TypedEvent<Opt<FieldUpdatedArgs>>();
@@ -28,18 +28,18 @@ export abstract class Field {
this.id = id || Utils.GenerateGuid();
}
- Dereference(): Opt<Field> {
+ Dereference(): FieldValue<Field> {
return this;
}
- DereferenceToRoot(): Opt<Field> {
+ DereferenceToRoot(): FieldValue<Field> {
return this;
}
- DereferenceT<T extends Field = Field>(ctor: { new(): T }): Opt<T> {
+ DereferenceT<T extends Field = Field>(ctor: { new(): T }): FieldValue<T> {
return Cast(this.Dereference(), ctor);
}
- DereferenceToRootT<T extends Field = Field>(ctor: { new(): T }): Opt<T> {
+ DereferenceToRootT<T extends Field = Field>(ctor: { new(): T }): FieldValue<T> {
return Cast(this.DereferenceToRoot(), ctor);
}
@@ -47,6 +47,8 @@ export abstract class Field {
return this.id === other.id;
}
+ abstract ToScriptString(): string;
+
abstract TrySetValue(value: any): boolean;
abstract GetValue(): any;
diff --git a/src/fields/ImageField.ts b/src/fields/ImageField.ts
index bc2e7cdf4..d82260f54 100644
--- a/src/fields/ImageField.ts
+++ b/src/fields/ImageField.ts
@@ -3,13 +3,17 @@ import { Field } from "./Field";
export class ImageField extends BasicField<URL> {
constructor(data: URL | undefined = undefined) {
- super(data == undefined ? new URL("http://cs.brown.edu/~bcz/face.gif") : data);
+ super(data == undefined ? new URL("http://cs.brown.edu/~bcz/bob_fettucine.jpg") : data);
}
toString(): string {
return this.Data.href;
}
+ ToScriptString(): string {
+ return `new ImageField("${this.Data}")`;
+ }
+
Copy(): Field {
return new ImageField(this.Data);
}
diff --git a/src/fields/Key.ts b/src/fields/Key.ts
index 5cd43f55e..993102613 100644
--- a/src/fields/Key.ts
+++ b/src/fields/Key.ts
@@ -27,6 +27,9 @@ export class Key extends Field {
return this;
}
+ ToScriptString(): string {
+ return name;
+ }
}
diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts
index 8607ebe43..8843338c1 100644
--- a/src/fields/ListField.ts
+++ b/src/fields/ListField.ts
@@ -6,6 +6,10 @@ export class ListField<T extends Field> extends BasicField<T[]> {
super(data.slice());
}
+ ToScriptString(): string {
+ return "new ListField([" + this.Data.map(field => field.ToScriptString()).join(", ") + "])";
+ }
+
Copy(): Field {
return new ListField<T>(this.Data);
}
diff --git a/src/fields/NumberField.ts b/src/fields/NumberField.ts
index c3444f644..03926d696 100644
--- a/src/fields/NumberField.ts
+++ b/src/fields/NumberField.ts
@@ -5,6 +5,10 @@ export class NumberField extends BasicField<number> {
super(data);
}
+ ToScriptString(): string {
+ return "new NumberField(this.Data)";
+ }
+
Copy() {
return new NumberField(this.Data);
}
diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts
index 24c7472d8..4a77c669c 100644
--- a/src/fields/RichTextField.ts
+++ b/src/fields/RichTextField.ts
@@ -5,6 +5,10 @@ export class RichTextField extends BasicField<string> {
super(data);
}
+ ToScriptString(): string {
+ return `new RichTextField(${this.Data})`;
+ }
+
Copy() {
return new RichTextField(this.Data);
}
diff --git a/src/fields/TextField.ts b/src/fields/TextField.ts
index 95825d2ae..11d2ed7cd 100644
--- a/src/fields/TextField.ts
+++ b/src/fields/TextField.ts
@@ -5,6 +5,10 @@ export class TextField extends BasicField<string> {
super(data);
}
+ ToScriptString(): string {
+ return `new TextField("${this.Data}")`;
+ }
+
Copy() {
return new TextField(this.Data);
}
diff --git a/src/server/index.js b/src/server/index.js
new file mode 100644
index 000000000..15e763f9d
--- /dev/null
+++ b/src/server/index.js
@@ -0,0 +1,13 @@
+"use strict";
+exports.__esModule = true;
+var express = require("express");
+var app = express();
+var port = 8080; // default port to listen
+// define a route handler for the default home page
+app.get("/", function (req, res) {
+ res.send("Hello world!");
+});
+// start the Express server
+app.listen(port, function () {
+ console.log("server started at http://localhost:" + port);
+});
diff --git a/src/server/index.ts b/src/server/index.ts
new file mode 100644
index 000000000..640ad8180
--- /dev/null
+++ b/src/server/index.ts
@@ -0,0 +1,29 @@
+import * as express from 'express'
+const app = express()
+import * as webpack from 'webpack'
+import * as wdm from 'webpack-dev-middleware';
+import * as whm from 'webpack-hot-middleware';
+import * as path from 'path'
+const config = require('../../webpack.config')
+const compiler = webpack(config)
+const port = 1050; // default port to listen
+
+// define a route handler for the default home page
+app.get("/", (req, res) => {
+ res.sendFile(path.join(__dirname, '../../deploy/index.html'));
+});
+
+app.get("/hello", (req, res) => {
+ res.send("<p>Hello</p>");
+})
+
+app.use(wdm(compiler, {
+ publicPath: config.output.publicPath
+}))
+
+app.use(whm(compiler))
+
+// start the Express server
+app.listen(port, () => {
+ console.log(`server started at http://localhost:${port}`);
+}); \ No newline at end of file
diff --git a/src/stores/NodeCollectionStore.ts b/src/stores/NodeCollectionStore.ts
deleted file mode 100644
index 7fac83d51..000000000
--- a/src/stores/NodeCollectionStore.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { computed, observable, action } from "mobx";
-import { NodeStore } from "./NodeStore";
-import { Document } from "../fields/Document";
-
-export class NodeCollectionStore extends NodeStore {
-
- @observable
- public Scale: number = 1;
-
- @observable
- public Nodes: NodeStore[] = new Array<NodeStore>();
-
- @observable
- public Docs: Document[] = [];
-
- @computed
- public get Transform(): string {
- const halfWidth = window.innerWidth / 2, halfHeight = window.innerHeight / 2;
- return `translate(${this.X + halfWidth}px, ${this.Y + halfHeight}px) scale(${this.Scale}) translate(${-halfWidth}px, ${-halfHeight}px)`;
- }
-
- @action
- public AddNodes(stores: NodeStore[]): void {
- stores.forEach(store => this.Nodes.push(store));
- }
-} \ No newline at end of file
diff --git a/src/stores/NodeStore.ts b/src/stores/NodeStore.ts
deleted file mode 100644
index 6a734cf44..000000000
--- a/src/stores/NodeStore.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { computed, observable } from "mobx";
-import { Utils } from "../Utils";
-
-export class NodeStore {
-
- public Id: string = Utils.GenerateGuid();
-
- @observable
- public X: number = 0;
-
- @observable
- public Y: number = 0;
-
- @observable
- public Width: number = 0;
-
- @observable
- public Height: number = 0;
-
- @computed
- public get Transform(): string {
- return "translate(" + this.X + "px, " + this.Y + "px)";
- }
-} \ No newline at end of file
diff --git a/src/stores/RootStore.ts b/src/stores/RootStore.ts
deleted file mode 100644
index 847fb6807..000000000
--- a/src/stores/RootStore.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { action, observable } from "mobx";
-
-// This globally accessible store might come in handy, although you may decide that you don't need it.
-export class RootStore {
-
- private constructor() {
- // initialization code
- }
-
- private static _instance: RootStore;
-
- public static get Instance(): RootStore {
- return this._instance || (this._instance = new this());
- }
-} \ No newline at end of file
diff --git a/src/stores/StaticTextNodeStore.ts b/src/stores/StaticTextNodeStore.ts
deleted file mode 100644
index 7c342a7a2..000000000
--- a/src/stores/StaticTextNodeStore.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { observable } from "mobx";
-import { NodeStore } from "./NodeStore";
-
-export class StaticTextNodeStore extends NodeStore {
-
- constructor(initializer: Partial<StaticTextNodeStore>) {
- super();
- Object.assign(this, initializer);
- }
-
- @observable
- public Title: string = "";
-
- @observable
- public Text: string = "";
-} \ No newline at end of file
diff --git a/src/stores/VideoNodeStore.ts b/src/stores/VideoNodeStore.ts
deleted file mode 100644
index e5187ab07..000000000
--- a/src/stores/VideoNodeStore.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { observable } from "mobx";
-import { NodeStore } from "./NodeStore";
-
-export class VideoNodeStore extends NodeStore {
-
- constructor(initializer: Partial<VideoNodeStore>) {
- super();
- Object.assign(this, initializer);
- }
-
- @observable
- public Title: string = "";
-
- @observable
- public Url: string = "";
-
-} \ No newline at end of file
diff --git a/src/views/nodes/TextNodeView.tsx b/src/views/nodes/TextNodeView.tsx
deleted file mode 100644
index ab762df12..000000000
--- a/src/views/nodes/TextNodeView.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import {observer} from "mobx-react";
-import {StaticTextNodeStore} from "../../stores/StaticTextNodeStore";
-import "./NodeView.scss";
-import {TopBar} from "./TopBar";
-import React = require("react");
-
-interface IProps {
- store: StaticTextNodeStore;
-}
-
-@observer
-export class TextNodeView extends React.Component<IProps> {
-
- render() {
- let store = this.props.store;
- return (
- <div className="node text-node" style={{transform: store.Transform}}>
- <TopBar store={store} />
- <div className="scroll-box">
- <div className="content">
- <h3 className="title">{store.Title}</h3>
- <p className="paragraph">{store.Text}</p>
- </div>
- </div>
- </div>
- );
- }
-} \ No newline at end of file
diff --git a/src/views/nodes/TopBar.tsx b/src/views/nodes/TopBar.tsx
deleted file mode 100644
index bb126e8b5..000000000
--- a/src/views/nodes/TopBar.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { observer } from "mobx-react";
-import { NodeStore } from "../../stores/NodeStore";
-import "./NodeView.scss";
-import React = require("react");
-
-interface IProps {
- store: NodeStore;
-}
-
-@observer
-export class TopBar extends React.Component<IProps> {
-
- private _isPointerDown = false;
-
- onPointerDown = (e: React.PointerEvent): void => {
- e.stopPropagation();
- e.preventDefault();
- this._isPointerDown = true;
- document.removeEventListener("pointermove", this.onPointerMove);
- document.addEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
- document.addEventListener("pointerup", this.onPointerUp);
- }
-
- onPointerUp = (e: PointerEvent): void => {
- e.stopPropagation();
- e.preventDefault();
- this._isPointerDown = false;
- document.removeEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
- }
-
- onPointerMove = (e: PointerEvent): void => {
- e.stopPropagation();
- e.preventDefault();
- if (!this._isPointerDown) {
- return;
- }
- this.props.store.X += e.movementX;
- this.props.store.Y += e.movementY;
- }
-
- render() {
- return <div className="top" onPointerDown={this.onPointerDown}></div>
- }
-}
diff --git a/src/views/nodes/VideoNodeView.scss b/src/views/nodes/VideoNodeView.scss
deleted file mode 100644
index f412c3519..000000000
--- a/src/views/nodes/VideoNodeView.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-.node {
- video {
- width: 100%;
- }
-} \ No newline at end of file
diff --git a/src/views/nodes/VideoNodeView.tsx b/src/views/nodes/VideoNodeView.tsx
deleted file mode 100644
index 0a7b3d174..000000000
--- a/src/views/nodes/VideoNodeView.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { observer } from "mobx-react";
-import { VideoNodeStore } from "../../stores/VideoNodeStore";
-import "./NodeView.scss";
-import { TopBar } from "./TopBar";
-import "./VideoNodeView.scss";
-import React = require("react");
-
-interface IProps {
- store: VideoNodeStore;
-}
-
-@observer
-export class VideoNodeView extends React.Component<IProps> {
-
- render() {
- let store = this.props.store;
- return (
- <div className="node text-node" style={{ transform: store.Transform }}>
- <TopBar store={store} />
- <div className="scroll-box">
- <div className="content">
- <h3 className="title">{store.Title}</h3>
- <video src={store.Url} controls />
- </div>
- </div>
- </div>
- );
- }
-} \ No newline at end of file