aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2019-02-05 23:19:26 -0500
committerbobzel <zzzman@gmail.com>2019-02-05 23:19:26 -0500
commite59dbb02175ec394a35c496201da71c90cd6a50a (patch)
treecf56fe399dca0fb64fece2ee1ed22044d95ea25c /src
parent4ac7a62d813738b0047caefbcf40d3063ec9e6c1 (diff)
mostly working version, but confused about LayoutKeys needing to inquire value seemingly unecessarily
Diffstat (limited to 'src')
-rw-r--r--src/Main.tsx2
-rw-r--r--src/documents/Documents.ts2
-rw-r--r--src/fields/FieldUpdatedArgs.ts27
-rw-r--r--src/stores/NodeCollectionStore.ts26
-rw-r--r--src/stores/NodeStore.ts24
-rw-r--r--src/stores/StaticTextNodeStore.ts16
-rw-r--r--src/stores/VideoNodeStore.ts17
-rw-r--r--src/views/collections/CollectionDockingView.tsx4
-rw-r--r--src/views/collections/CollectionFreeFormView.tsx2
-rw-r--r--src/views/collections/CollectionSchemaView.tsx2
-rw-r--r--src/views/nodes/CollectionFreeFormDocumentView.tsx5
-rw-r--r--src/views/nodes/DocumentView.tsx13
-rw-r--r--src/views/nodes/FieldTextBox.scss14
-rw-r--r--src/views/nodes/ImageBox.tsx48
-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
18 files changed, 275 insertions, 35 deletions
diff --git a/src/Main.tsx b/src/Main.tsx
index 2b805071f..de4a1de5d 100644
--- a/src/Main.tsx
+++ b/src/Main.tsx
@@ -80,7 +80,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) {
ReactDOM.render((
<div style={{ position: "absolute", width: "100%", height: "100%" }}>
- <DocumentView Document={mainContainer} ContainingCollectionView={undefined} DocumentView={undefined} Data={mainContainer.GetField(KeyStore.Data)} />
+ <DocumentView Document={mainContainer} ContainingCollectionView={undefined} DocumentView={undefined} />
<DocumentDecorations />
<ContextMenu />
</div>),
diff --git a/src/documents/Documents.ts b/src/documents/Documents.ts
index 869e9ab90..c51feedf5 100644
--- a/src/documents/Documents.ts
+++ b/src/documents/Documents.ts
@@ -117,7 +117,9 @@ export namespace Documents {
imageProto.SetFieldValue(KeyStore.Height, 300, NumberField);
imageProto.SetFieldValue(KeyStore.Layout, ImageBox.LayoutString(), TextField);
// imageProto.SetField(KeyStore.Layout, new TextField('<div style={"background-image: " + {Data}} />'));
+ // bcz: use LayoutKeys or LayoutFields?
imageProto.SetFieldValue(KeyStore.LayoutKeys, [KeyStore.Data], ListField);
+ //imageProto.SetFieldValue(KeyStore.LayoutFields, [KeyStore.Data], ListField);
}
return imageProto;
}
diff --git a/src/fields/FieldUpdatedArgs.ts b/src/fields/FieldUpdatedArgs.ts
new file mode 100644
index 000000000..23ccf2a5a
--- /dev/null
+++ b/src/fields/FieldUpdatedArgs.ts
@@ -0,0 +1,27 @@
+import { Field, Opt } from "./Field";
+import { Document } from "./Document";
+import { Key } from "./Key";
+
+export enum FieldUpdatedAction {
+ Add,
+ Remove,
+ Replace,
+ Update
+}
+
+export interface FieldUpdatedArgs {
+ field: Field;
+ action: FieldUpdatedAction;
+}
+
+export interface DocumentUpdatedArgs {
+ field: Document;
+ key: Key;
+
+ oldValue: Opt<Field>;
+ newValue: Opt<Field>;
+
+ fieldArgs?: FieldUpdatedArgs;
+
+ action: FieldUpdatedAction;
+}
diff --git a/src/stores/NodeCollectionStore.ts b/src/stores/NodeCollectionStore.ts
new file mode 100644
index 000000000..7fac83d51
--- /dev/null
+++ b/src/stores/NodeCollectionStore.ts
@@ -0,0 +1,26 @@
+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
new file mode 100644
index 000000000..6a734cf44
--- /dev/null
+++ b/src/stores/NodeStore.ts
@@ -0,0 +1,24 @@
+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/StaticTextNodeStore.ts b/src/stores/StaticTextNodeStore.ts
new file mode 100644
index 000000000..7c342a7a2
--- /dev/null
+++ b/src/stores/StaticTextNodeStore.ts
@@ -0,0 +1,16 @@
+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
new file mode 100644
index 000000000..e5187ab07
--- /dev/null
+++ b/src/stores/VideoNodeStore.ts
@@ -0,0 +1,17 @@
+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/collections/CollectionDockingView.tsx b/src/views/collections/CollectionDockingView.tsx
index adb885859..4bbbeeecd 100644
--- a/src/views/collections/CollectionDockingView.tsx
+++ b/src/views/collections/CollectionDockingView.tsx
@@ -100,7 +100,7 @@ export class CollectionDockingView extends CollectionViewBase {
for (var i: number = 0; i < value.length; i++) {
if (value[i].Id === component) {
var data = value[i].GetField(KeyStore.Data);
- return (<DocumentView key={value[i].Id} ContainingCollectionView={this} Document={value[i]} DocumentView={undefined} Data={data} />);
+ return (<DocumentView key={value[i].Id} ContainingCollectionView={this} Document={value[i]} DocumentView={undefined} />);
}
}
if (component === "text") {
@@ -242,7 +242,7 @@ export class CollectionDockingView extends CollectionViewBase {
setTimeout(function () {
var data = state.doc.GetField(KeyStore.Data);
ReactDOM.render((
- <DocumentView key={state.doc.Id} Document={state.doc} ContainingCollectionView={me} DocumentView={undefined} Data={data} />
+ <DocumentView key={state.doc.Id} Document={state.doc} ContainingCollectionView={me} DocumentView={undefined} />
),
document.getElementById(containingDiv)
);
diff --git a/src/views/collections/CollectionFreeFormView.tsx b/src/views/collections/CollectionFreeFormView.tsx
index ad470f9e2..d48d096ce 100644
--- a/src/views/collections/CollectionFreeFormView.tsx
+++ b/src/views/collections/CollectionFreeFormView.tsx
@@ -206,7 +206,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
<div className="node-container" ref={this._nodeContainerRef}>
{value.map(doc => {
- return (<CollectionFreeFormDocumentView key={doc.Id} ContainingCollectionView={this} Document={doc} DocumentView={undefined} Data={data} />);
+ return (<CollectionFreeFormDocumentView key={doc.Id} ContainingCollectionView={this} Document={doc} DocumentView={undefined} />);
})}
</div>
</div>
diff --git a/src/views/collections/CollectionSchemaView.tsx b/src/views/collections/CollectionSchemaView.tsx
index bde727fea..59d54e8c4 100644
--- a/src/views/collections/CollectionSchemaView.tsx
+++ b/src/views/collections/CollectionSchemaView.tsx
@@ -75,7 +75,7 @@ export class CollectionSchemaView extends CollectionViewBase {
let content;
if (this.selectedIndex != -1) {
var data = this.props.DocumentForCollection.GetField(KS.Data);
- content = (<DocumentView Document={children[this.selectedIndex]} DocumentView={undefined} ContainingCollectionView={this} Data={data} />)
+ content = (<DocumentView Document={children[this.selectedIndex]} DocumentView={undefined} ContainingCollectionView={this} />)
} else {
content = <div />
}
diff --git a/src/views/nodes/CollectionFreeFormDocumentView.tsx b/src/views/nodes/CollectionFreeFormDocumentView.tsx
index 9f13733c9..06ea0c64b 100644
--- a/src/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -207,8 +207,7 @@ export class CollectionFreeFormDocumentView extends DocumentView {
render() {
var freestyling = this.props.ContainingCollectionView instanceof CollectionFreeFormView;
- let data = this.props.Document.GetFieldT(KeyStore.Data, ImageField);
- console.log("CollectionFFDocView " + this.props.Document.Title + "<" + data + "> x=" + this.x);
+ console.log("CollectionFFDocView " + this.props.Document.Title);
return (
<div className="node" ref={this._mainCont} style={{
transform: freestyling ? this.transform : "",
@@ -220,7 +219,7 @@ export class CollectionFreeFormDocumentView extends DocumentView {
onContextMenu={this.onContextMenu}
onPointerDown={this.onPointerDown}>
- <DocumentView {...this.props} DocumentView={this} Data={data} />
+ <DocumentView {...this.props} DocumentView={this} />
</div>
);
}
diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx
index 94fe0440f..69184cf16 100644
--- a/src/views/nodes/DocumentView.tsx
+++ b/src/views/nodes/DocumentView.tsx
@@ -21,7 +21,6 @@ export interface DocumentViewProps {
Document: Document;
DocumentView: Opt<DocumentView> // needed only to set ContainingDocumentView on CollectionViewProps when invoked from JsxParser -- is there a better way?
ContainingCollectionView: Opt<CollectionViewBase>;
- Data: any;
}
@observer
export class DocumentView extends React.Component<DocumentViewProps> {
@@ -128,19 +127,19 @@ export class DocumentView extends React.Component<DocumentViewProps> {
render() {
- let doc = this.props.Document;
let bindings = { ...this.props } as any;
for (const key of this.layoutKeys) {
+ //let val = this.props.Document.GetField(key); // bcz: ARGH! Why do I need to call this here? (e.g., it's needed and used in ImageBox- shouldn't that trigger a re-render?)
bindings[key.Name + "Key"] = key;
- let val = this.props.Document.GetField(key);
}
- if (bindings.DocumentView === undefined)
- bindings.DocumentView = this;
for (const key of this.layoutFields) {
- let field = doc.GetField(key);
+ let field = this.props.Document.GetField(key);
bindings[key.Name] = field && field != WAITING ? field.GetValue() : field;
}
- console.log("DocumentView Rendering " + doc.Title + " data = " + this.props.Data);
+ if (bindings.DocumentView === undefined) {
+ bindings.DocumentView = this;
+ }
+ console.log("DocumentView Rendering " + this.props.Document.Title);
return (
<div className="node" ref={this._mainCont} style={{ width: "100%", height: "100%", }}>
<JsxParser
diff --git a/src/views/nodes/FieldTextBox.scss b/src/views/nodes/FieldTextBox.scss
new file mode 100644
index 000000000..b6ce2fabc
--- /dev/null
+++ b/src/views/nodes/FieldTextBox.scss
@@ -0,0 +1,14 @@
+.ProseMirror {
+ margin-top: -1em;
+ width: 100%;
+ height: 100%;
+}
+
+.ProseMirror:focus {
+ outline: none !important
+}
+
+.fieldTextBox-cont {
+ background: white;
+ padding: 1vw;
+} \ No newline at end of file
diff --git a/src/views/nodes/ImageBox.tsx b/src/views/nodes/ImageBox.tsx
index fa55c6811..9b086d373 100644
--- a/src/views/nodes/ImageBox.tsx
+++ b/src/views/nodes/ImageBox.tsx
@@ -17,7 +17,7 @@ interface ImageBoxState {
export class ImageBox extends React.Component<FieldViewProps, ImageBoxState> {
- public static LayoutString() { return FieldView.LayoutString("ImageBox"); }
+ public static LayoutString() { return FieldView.LayoutString("ImageBox DataVal={Data} "); }
private _ref: React.RefObject<HTMLDivElement>;
private _downX: number = 0;
private _downY: number = 0;
@@ -60,33 +60,41 @@ export class ImageBox extends React.Component<FieldViewProps, ImageBoxState> {
e.stopPropagation();
}
+ lightbox = (path: string) => {
+ const images = [path, "http://www.cs.brown.edu/~bcz/face.gif"];
+ const { photoIndex } = this.state;
+ if (this.state.isOpen && this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)) {
+ return (<Lightbox
+ mainSrc={images[photoIndex]}
+ nextSrc={images[(photoIndex + 1) % images.length]}
+ prevSrc={images[(photoIndex + images.length - 1) % images.length]}
+ onCloseRequest={() => this.setState({ isOpen: false })}
+ onMovePrevRequest={() =>
+ this.setState({ photoIndex: (photoIndex + images.length - 1) % images.length, })
+ }
+ onMoveNextRequest={() =>
+ this.setState({ photoIndex: (photoIndex + 1) % images.length, })
+ }
+ />)
+ }
+ }
+
render() {
+
+ // bcz: use LayoutFields (here) or LayoutKeys (below)?
+ // let field = (this.props as any).DataVal;//this.props.doc.GetFieldT(this.props.fieldKey, ImageField);
+ // let path = field == WAITING ? "https://image.flaticon.com/icons/svg/66/66163.svg" :
+ // field instanceof URL ? field.href : "";
+
let field = this.props.doc.GetFieldT(this.props.fieldKey, ImageField);
let path = field == WAITING ? "https://image.flaticon.com/icons/svg/66/66163.svg" :
field instanceof ImageField ? field.Data.href : "";
console.log("ImageBox Rendering " + this.props.doc.Title);
- var lightbox = () => {
- const images = [path, "http://www.cs.brown.edu/~bcz/face.gif"];
- const { photoIndex } = this.state;
- if (this.state.isOpen && this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)) {
- return (<Lightbox
- mainSrc={images[photoIndex]}
- nextSrc={images[(photoIndex + 1) % images.length]}
- prevSrc={images[(photoIndex + images.length - 1) % images.length]}
- onCloseRequest={() => this.setState({ isOpen: false })}
- onMovePrevRequest={() =>
- this.setState({ photoIndex: (photoIndex + images.length - 1) % images.length, })
- }
- onMoveNextRequest={() =>
- this.setState({ photoIndex: (photoIndex + 1) % images.length, })
- }
- />)
- }
- }
+
return (
<div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} >
<img src={path} width="100%" alt="Image not found" />
- {lightbox()}
+ {this.lightbox(path)}
</div>)
}
} \ No newline at end of file
diff --git a/src/views/nodes/TextNodeView.tsx b/src/views/nodes/TextNodeView.tsx
new file mode 100644
index 000000000..ab762df12
--- /dev/null
+++ b/src/views/nodes/TextNodeView.tsx
@@ -0,0 +1,28 @@
+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
new file mode 100644
index 000000000..bb126e8b5
--- /dev/null
+++ b/src/views/nodes/TopBar.tsx
@@ -0,0 +1,46 @@
+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
new file mode 100644
index 000000000..f412c3519
--- /dev/null
+++ b/src/views/nodes/VideoNodeView.scss
@@ -0,0 +1,5 @@
+.node {
+ video {
+ width: 100%;
+ }
+} \ No newline at end of file
diff --git a/src/views/nodes/VideoNodeView.tsx b/src/views/nodes/VideoNodeView.tsx
new file mode 100644
index 000000000..0a7b3d174
--- /dev/null
+++ b/src/views/nodes/VideoNodeView.tsx
@@ -0,0 +1,29 @@
+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